summaryrefslogtreecommitdiffstats
path: root/spec/unit/parser/ast
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2009-12-01 16:41:38 -0800
committerJames Turnbull <james@lovedthanlost.net>2009-12-09 02:13:03 +1100
commit8971d8beae2c409f9052f27c3f80ad3bdfff4de2 (patch)
treec6f7eda0523c31c2b2f3a02b3761bf43ef716ebf /spec/unit/parser/ast
parent39d4a935d47f1d42241ce492c48818dc5b533c29 (diff)
downloadpuppet-8971d8beae2c409f9052f27c3f80ad3bdfff4de2.tar.gz
puppet-8971d8beae2c409f9052f27c3f80ad3bdfff4de2.tar.xz
puppet-8971d8beae2c409f9052f27c3f80ad3bdfff4de2.zip
Fixing #2596 - Node, Class, Definition are not AST
This commit extracts these three classes into a single ResourceType class in the Parser heirarchy, now completely independent of the AST heirarchy. Most of the other changes are just changing the interface to the new class, which is greatly simplified over the previous classes. This opens up the possibility of drastically simplifying a lot of this other code, too -- in particular, replacing the reference to the parser with a reference to the (soon to be renamed) LoadedCode class. Signed-off-by: Luke Kanies <luke@madstop.com>
Diffstat (limited to 'spec/unit/parser/ast')
-rwxr-xr-xspec/unit/parser/ast/definition.rb213
-rwxr-xr-xspec/unit/parser/ast/hostclass.rb148
-rwxr-xr-xspec/unit/parser/ast/leaf.rb72
-rwxr-xr-xspec/unit/parser/ast/node.rb145
-rwxr-xr-xspec/unit/parser/ast/resource_reference.rb6
5 files changed, 3 insertions, 581 deletions
diff --git a/spec/unit/parser/ast/definition.rb b/spec/unit/parser/ast/definition.rb
deleted file mode 100755
index c26706524..000000000
--- a/spec/unit/parser/ast/definition.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-describe Puppet::Parser::AST::Definition, "when initializing" do
-end
-
-describe Puppet::Parser::AST::Definition, "when evaluating" do
- before do
- @type = Puppet::Parser::Resource
- @parser = Puppet::Parser::Parser.new :Code => ""
- @source = @parser.newclass ""
- @definition = @parser.newdefine "mydefine"
- @node = Puppet::Node.new("yaynode")
- @compiler = Puppet::Parser::Compiler.new(@node, @parser)
- @scope = @compiler.topscope
-
- @resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "myresource", :scope => @scope, :source => @source)
- end
-
- it "should create a new scope" do
- scope = nil
- code = mock 'code'
- code.expects(:safeevaluate).with do |scope|
- scope.object_id.should_not == @scope.object_id
- true
- end
- @definition.stubs(:code).returns(code)
- @definition.evaluate_code(@resource)
- end
-
- it "should have a get_classname method" do
- @definition.should respond_to(:get_classname)
- end
-
- it "should return the current classname with get_classname" do
- @definition.expects(:classname)
-
- @definition.get_classname(@scope)
- end
-
- describe "when evaluating" do
- it "should create a resource whose title comes from get_classname" do
- @definition.expects(:get_classname).returns("classname")
-
- @definition.evaluate(@scope)
- end
- end
-
-# it "should copy its namespace to the scope"
-#
-# it "should mark the scope virtual if the resource is virtual"
-#
-# it "should mark the scope exported if the resource is exported"
-#
-# it "should set the resource's parameters as variables in the scope"
-#
-# it "should set the resource's title as a variable in the scope"
-#
-# it "should copy the resource's title in a 'name' variable in the scope"
-#
-# it "should not copy the resource's title as the name if 'name' is one of the resource parameters"
-#
-# it "should evaluate the associated code with the new scope"
-
- def old_test_initialize
- parser = mkparser
-
- # Create a new definition
- klass = parser.newdefine "yayness",
- :arguments => [["owner", stringobj("nobody")], %w{mode}],
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/$name",
- "owner" => varref("owner"), "mode" => varref("mode"))]
- )
-
- # Test validattr? a couple different ways
- [:owner, "owner", :schedule, "schedule"].each do |var|
- assert(klass.validattr?(var), "%s was not considered valid" % var.inspect)
- end
-
- [:random, "random"].each do |var|
- assert(! klass.validattr?(var), "%s was considered valid" % var.inspect)
- end
-
- end
-
- def oldtest_evaluate
- parser = mkparser
- config = mkcompiler
- config.send(:evaluate_main)
- scope = config.topscope
- klass = parser.newdefine "yayness",
- :arguments => [["owner", stringobj("nobody")], %w{mode}],
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/$name",
- "owner" => varref("owner"), "mode" => varref("mode"))]
- )
-
- resource = Puppet::Parser::Resource.new(
- :title => "first",
- :type => "yayness",
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
- resource.send(:set_parameter, "name", "first")
- resource.send(:set_parameter, "mode", "755")
-
- resource.stubs(:title)
- assert_nothing_raised do
- klass.evaluate_code(resource)
- end
-
- firstobj = config.findresource("File[/tmp/first]")
- assert(firstobj, "Did not create /tmp/first obj")
-
- assert_equal("File", firstobj.type)
- assert_equal("/tmp/first", firstobj.title)
- assert_equal("nobody", firstobj[:owner])
- assert_equal("755", firstobj[:mode])
-
- # Make sure we can't evaluate it with the same args
- assert_raise(Puppet::ParseError) do
- klass.evaluate_code(resource)
- end
-
- # Now create another with different args
- resource2 = Puppet::Parser::Resource.new(
- :title => "second",
- :type => "yayness",
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
- resource2.send(:set_parameter, "name", "second")
- resource2.send(:set_parameter, "mode", "755")
- resource2.send(:set_parameter, "owner", "daemon")
-
- assert_nothing_raised do
- klass.evaluate_code(resource2)
- end
-
- secondobj = config.findresource("File[/tmp/second]")
- assert(secondobj, "Did not create /tmp/second obj")
-
- assert_equal("File", secondobj.type)
- assert_equal("/tmp/second", secondobj.title)
- assert_equal("daemon", secondobj[:owner])
- assert_equal("755", secondobj[:mode])
- end
-
- # #539 - definitions should support both names and titles
- def oldtest_names_and_titles
- parser = mkparser
- scope = mkscope :parser => parser
-
- [
- {:name => "one", :title => "two"},
- {:title => "mytitle"}
- ].each_with_index do |hash, i|
- # Create a definition that uses both name and title. Put this
- # inside the loop so the subscope expectations work.
- klass = parser.newdefine "yayness%s" % i
-
- resource = Puppet::Parser::Resource.new(
- :title => hash[:title],
- :type => "yayness%s" % i,
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
-
- subscope = klass.subscope(scope, resource)
-
- klass.expects(:subscope).returns(subscope)
-
- if hash[:name]
- resource.stubs(:to_hash).returns({:name => hash[:name]})
- end
-
- assert_nothing_raised("Could not evaluate definition with %s" % hash.inspect) do
- klass.evaluate_code(resource)
- end
-
- name = hash[:name] || hash[:title]
- title = hash[:title]
-
- assert_equal(name, subscope.lookupvar("name"),
- "Name did not get set correctly")
- assert_equal(title, subscope.lookupvar("title"),
- "title did not get set correctly")
-
- [:name, :title].each do |param|
- val = resource.send(param)
- assert(subscope.tags.include?(val),
- "Scope was not tagged with %s '%s'" % [param, val])
- end
- end
- end
-
- # Testing the root cause of #615. We should be using the fqname for the type, instead
- # of just the short name.
- def oldtest_fully_qualified_types
- parser = mkparser
- klass = parser.newclass("one::two")
-
- assert_equal("one::two", klass.classname, "Class did not get fully qualified class name")
- end
-end
diff --git a/spec/unit/parser/ast/hostclass.rb b/spec/unit/parser/ast/hostclass.rb
deleted file mode 100755
index 10aa62176..000000000
--- a/spec/unit/parser/ast/hostclass.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-describe Puppet::Parser::AST::HostClass do
- before :each do
- @node = Puppet::Node.new "testnode"
- @parser = Puppet::Parser::Parser.new :environment => "development"
- @scope_resource = stub 'scope_resource', :builtin? => true
- @compiler = Puppet::Parser::Compiler.new(@node, @parser)
-
- @scope = @compiler.topscope
- end
-
- describe Puppet::Parser::AST::HostClass, "when evaluating" do
-
- before do
- @top = @parser.newclass "top"
- @middle = @parser.newclass "middle", :parent => "top"
- end
-
- it "should create a resource that references itself" do
- @top.evaluate(@scope)
-
- @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
- end
-
- it "should evaluate the parent class if one exists" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
- end
-
- it "should fail to evaluate if a parent class is defined but cannot be found" do
- othertop = @parser.newclass "something", :parent => "yay"
- lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
- end
-
- it "should not create a new resource if one already exists" do
- @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
- @compiler.catalog.expects(:add_resource).never
- @top.evaluate(@scope)
- end
-
- it "should return the existing resource when not creating a new one" do
- @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
- @compiler.catalog.expects(:add_resource).never
- @top.evaluate(@scope).should == "something"
- end
-
- it "should not create a new parent resource if one already exists and it has a parent class" do
- @top.evaluate(@scope)
-
- top_resource = @compiler.catalog.resource(:class, "top")
-
- @middle.evaluate(@scope)
-
- @compiler.catalog.resource(:class, "top").should equal(top_resource)
- end
-
- # #795 - tag before evaluation.
- it "should tag the catalog with the resource tags when it is evaluated" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.should be_tagged("middle")
- end
-
- it "should tag the catalog with the parent class tags when it is evaluated" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.should be_tagged("top")
- end
- end
-
- describe Puppet::Parser::AST::HostClass, "when evaluating code" do
-
- before do
- @top_resource = stub "top_resource"
- @top = @parser.newclass "top", :code => @top_resource
-
- @middle_resource = stub "middle_resource"
- @middle = @parser.newclass "top::middle", :parent => "top", :code => @middle_resource
- end
-
- it "should set its namespace to its fully qualified name" do
- @middle.namespace.should == "top::middle"
- end
-
- it "should evaluate the code referred to by the class" do
- @top_resource.expects(:safeevaluate)
-
- resource = @top.evaluate(@scope)
-
- @top.evaluate_code(resource)
- end
-
- it "should evaluate the parent class's code if it has a parent" do
- @top_resource.expects(:safeevaluate)
- @middle_resource.expects(:safeevaluate)
-
- resource = @middle.evaluate(@scope)
-
- @middle.evaluate_code(resource)
- end
-
- it "should not evaluate the parent class's code if the parent has already been evaluated" do
- @top_resource.stubs(:safeevaluate)
- resource = @top.evaluate(@scope)
- @top.evaluate_code(resource)
-
- @top_resource.expects(:safeevaluate).never
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
- end
-
- it "should use the parent class's scope as its parent scope" do
- @top_resource.stubs(:safeevaluate)
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
-
- @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
- end
-
- it "should add the class's name and title to its own scope" do
- @top_resource.stubs(:safeevaluate)
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- scope = stub_everything 'scope', :compiler => @compiler
- @middle.stubs(:subscope).returns(scope)
-
- scope.expects(:setvar).with("title","top::middle")
- scope.expects(:setvar).with("name","top::middle")
-
- @middle.evaluate_code(resource)
- end
-
- it "should add the parent class's namespace to its namespace search path" do
- @top_resource.stubs(:safeevaluate)
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
-
- @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
- end
- end
-end
diff --git a/spec/unit/parser/ast/leaf.rb b/spec/unit/parser/ast/leaf.rb
index fecfba386..ee1ee04a7 100755
--- a/spec/unit/parser/ast/leaf.rb
+++ b/spec/unit/parser/ast/leaf.rb
@@ -195,40 +195,6 @@ describe Puppet::Parser::AST::HostName do
@host.evaluate(@scope).should == @value
end
- it "should implement to_classname" do
- @host.should respond_to(:to_classname)
- end
-
- it "should return the downcased nodename as classname" do
- host = Puppet::Parser::AST::HostName.new( :value => "KLASSNAME" )
- host.to_classname.should == "klassname"
- end
-
- it "should preserve '_' in to_classname with a string nodename" do
- host = Puppet::Parser::AST::HostName.new( :value => "node_with_underscore")
- host.to_classname.should == "node_with_underscore"
- end
-
- it "should preserve '_' in to_classname with a regex nodename" do
- host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/\dnode_with_underscore\.+/") )
- host.to_classname.should == "dnode_with_underscore."
- end
-
- it "should return a string usable as classname when calling to_classname" do
- host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/^this-is not@a classname$/") )
- host.to_classname.should == "this-isnotaclassname"
- end
-
- it "should return a string usable as a tag when calling to_classname" do
- host = Puppet::Parser::AST::HostName.new( :value => Puppet::Parser::AST::Regex.new(:value => "/.+.reductivelabs\.com/") )
- host.to_classname.should == "reductivelabs.com"
- end
-
- it "should delegate 'match' to the underlying value if it is an HostName" do
- @value.expects(:match).with("value")
- @host.match("value")
- end
-
it "should delegate eql? to the underlying value if it is an HostName" do
@value.expects(:eql?).with("value")
@host.eql?("value")
@@ -244,42 +210,4 @@ describe Puppet::Parser::AST::HostName do
@value.expects(:hash)
@host.hash
end
-
- it "should return true when regex? is called and value is a Regex" do
- @value.expects(:is_a?).with(Puppet::Parser::AST::Regex).returns(true)
- @host.regex?.should be_true
- end
-
- it "should return the results of comparing the regexes if asked whether a regex matches another regex" do
- hosts = [1,2].collect do |num|
- vreg = /vreg#{num}/
- value = Puppet::Parser::AST::Regex.new(:value => vreg)
- Puppet::Parser::AST::HostName.new(:value => value)
- end
-
- hosts[0].match(hosts[1]).should be_false
- hosts[0].match(hosts[0]).should be_true
- end
-
- it "should return false when comparing a non-regex to a regex" do
- vreg = /vreg/
- value = Puppet::Parser::AST::Regex.new(:value => vreg)
- regex = Puppet::Parser::AST::HostName.new(:value => value)
-
- value = Puppet::Parser::AST::Regex.new(:value => "foo")
- normal = Puppet::Parser::AST::HostName.new(:value => value)
-
- normal.match(regex).should be_false
- end
-
- it "should true when a provided string matches a regex" do
- vreg = /r/
- value = Puppet::Parser::AST::Regex.new(:value => vreg)
- regex = Puppet::Parser::AST::HostName.new(:value => value)
-
- value = Puppet::Parser::AST::Leaf.new(:value => "bar")
- normal = Puppet::Parser::AST::HostName.new(:value => value)
-
- regex.match(normal).should be_true
- end
end
diff --git a/spec/unit/parser/ast/node.rb b/spec/unit/parser/ast/node.rb
deleted file mode 100755
index 5a4a5efe4..000000000
--- a/spec/unit/parser/ast/node.rb
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-describe Puppet::Parser::AST::Node do
- before :each do
- @node = Puppet::Node.new "testnode"
- @parser = Puppet::Parser::Parser.new :environment => "development"
- @scope_resource = stub 'scope_resource', :builtin? => true
- @compiler = Puppet::Parser::Compiler.new(@node, @parser)
-
- @scope = @compiler.topscope
- end
-
- describe "when calling get_classname" do
- it "should return current node name if name is a Regex" do
- name = stub 'name', :regex? => true
- node = @parser.newnode("node").shift
- node.stubs(:name).returns(name)
-
- @scope.expects(:host).returns("testnode")
-
- node.get_classname(@scope).should == "testnode"
- end
-
- it "should return the current node classname if name is not a Regex" do
- name = stub 'name', :regex? => false
- node = @parser.newnode("node").shift
- node.stubs(:name).returns(name)
-
- node.get_classname(@scope).should == "node"
- end
- end
-
- describe Puppet::Parser::AST::Node, "when evaluating" do
-
- before do
- @top = @parser.newnode("top").shift
- @middle = @parser.newnode("middle", :parent => "top").shift
- end
-
- it "should create a resource that references itself" do
- @top.evaluate(@scope)
-
- @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
- end
-
- it "should evaluate the parent class if one exists" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
- end
-
- it "should fail to evaluate if a parent class is defined but cannot be found" do
- othertop = @parser.newnode("something", :parent => "yay").shift
- lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
- end
-
- it "should not create a new resource if one already exists" do
- @compiler.catalog.expects(:resource).with(:node, "top").returns("something")
- @compiler.catalog.expects(:add_resource).never
- @top.evaluate(@scope)
- end
-
- it "should not create a new parent resource if one already exists and it has a parent class" do
- @top.evaluate(@scope)
-
- top_resource = @compiler.catalog.resource(:node, "top")
-
- @middle.evaluate(@scope)
-
- @compiler.catalog.resource(:node, "top").should equal(top_resource)
- end
-
- # #795 - tag before evaluation.
- it "should tag the catalog with the resource tags when it is evaluated" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.should be_tagged("middle")
- end
-
- it "should tag the catalog with the parent class tags when it is evaluated" do
- @middle.evaluate(@scope)
-
- @compiler.catalog.should be_tagged("top")
- end
- end
-
- describe Puppet::Parser::AST::Node, "when evaluating code" do
-
- before do
- @top_resource = stub "top_resource"
- @top = @parser.newnode("top", :code => @top_resource).shift
-
- @middle_resource = stub "middle_resource"
- @middle = @parser.newnode("middle", :parent => "top", :code => @middle_resource).shift
- end
-
- it "should evaluate the code referred to by the class" do
- @top_resource.expects(:safeevaluate)
-
- resource = @top.evaluate(@scope)
-
- @top.evaluate_code(resource)
- end
-
- it "should evaluate the parent class's code if it has a parent" do
- @top_resource.expects(:safeevaluate)
- @middle_resource.expects(:safeevaluate)
-
- resource = @middle.evaluate(@scope)
-
- @middle.evaluate_code(resource)
- end
-
- it "should not evaluate the parent class's code if the parent has already been evaluated" do
- @top_resource.stubs(:safeevaluate)
- resource = @top.evaluate(@scope)
- @top.evaluate_code(resource)
-
- @top_resource.expects(:safeevaluate).never
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
- end
-
- it "should use the parent class's scope as its parent scope" do
- @top_resource.stubs(:safeevaluate)
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
-
- @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
- end
-
- it "should add the parent class's namespace to its namespace search path" do
- @top_resource.stubs(:safeevaluate)
- @middle_resource.stubs(:safeevaluate)
- resource = @middle.evaluate(@scope)
- @middle.evaluate_code(resource)
-
- @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
- end
- end
-end
diff --git a/spec/unit/parser/ast/resource_reference.rb b/spec/unit/parser/ast/resource_reference.rb
index 24865e846..10d9678c3 100755
--- a/spec/unit/parser/ast/resource_reference.rb
+++ b/spec/unit/parser/ast/resource_reference.rb
@@ -21,7 +21,7 @@ describe Puppet::Parser::AST::ResourceReference do
%{ "one::two" "one-two"}.each do |type|
it "should evaluate correctly reference to define" do
- klass = stub 'klass', :title => "three", :classname => type
+ klass = stub 'klass', :title => "three", :name => type
@scope.stubs(:find_definition).returns(klass)
newref("three", type).evaluate(@scope).to_ref.should == Puppet::Parser::Resource::Reference.new( :type => type, :title => "three" ).to_ref
@@ -29,13 +29,13 @@ describe Puppet::Parser::AST::ResourceReference do
end
it "should be able to call qualified_class" do
- klass = stub 'klass', :title => "three", :classname => "one"
+ klass = stub 'klass', :title => "three", :name => "one"
@scope.expects(:find_hostclass).with("one").returns(klass)
newref("three","class").qualified_class(@scope,"one").should == "one"
end
it "should be able to find qualified classes when evaluating" do
- klass = stub 'klass', :title => "one", :classname => "one"
+ klass = stub 'klass', :title => "one", :name => "one"
@scope.stubs(:find_hostclass).returns(klass)
evaled = newref("one", "class").evaluate(@scope)