#! /usr/bin/env ruby require 'spec_helper' require 'puppet_spec/compiler' require 'puppet/parser/functions' require 'matchers/containment_matchers' require 'matchers/resource' require 'matchers/include_in_order' require 'unit/parser/functions/shared' describe 'The "contain" function' do include PuppetSpec::Compiler include ContainmentMatchers include Matchers::Resource it "includes the class" do catalog = compile_to_catalog(<<-MANIFEST) class contained { notify { "contained": } } class container { contain contained } include container MANIFEST expect(catalog.classes).to include("contained") end it "includes the class when using a fully qualified anchored name" do catalog = compile_to_catalog(<<-MANIFEST) class contained { notify { "contained": } } class container { contain ::contained } include container MANIFEST expect(catalog.classes).to include("contained") end it "ensures that the edge is with the correct class" do catalog = compile_to_catalog(<<-MANIFEST) class outer { class named { } contain named } class named { } include named include outer MANIFEST expect(catalog).to have_resource("Class[Named]") expect(catalog).to have_resource("Class[Outer]") expect(catalog).to have_resource("Class[Outer::Named]") expect(catalog).to contain_class("outer::named").in("outer") end it "makes the class contained in the current class" do catalog = compile_to_catalog(<<-MANIFEST) class contained { notify { "contained": } } class container { contain contained } include container MANIFEST expect(catalog).to contain_class("contained").in("container") end it "can contain multiple classes" do catalog = compile_to_catalog(<<-MANIFEST) class a { notify { "a": } } class b { notify { "b": } } class container { contain a, b } include container MANIFEST expect(catalog).to contain_class("a").in("container") expect(catalog).to contain_class("b").in("container") end context "when containing a class in multiple classes" do it "creates a catalog with all containment edges" do catalog = compile_to_catalog(<<-MANIFEST) class contained { notify { "contained": } } class container { contain contained } class another { contain contained } include container include another MANIFEST expect(catalog).to contain_class("contained").in("container") expect(catalog).to contain_class("contained").in("another") end it "and there are no dependencies applies successfully" do manifest = <<-MANIFEST class contained { notify { "contained": } } class container { contain contained } class another { contain contained } include container include another MANIFEST expect { apply_compiled_manifest(manifest) }.not_to raise_error end it "and there are explicit dependencies on the containing class causes a dependency cycle" do manifest = <<-MANIFEST class contained { notify { "contained": } } class container { contain contained } class another { contain contained } include container include another Class["container"] -> Class["another"] MANIFEST expect { apply_compiled_manifest(manifest) }.to raise_error( Puppet::Error, /Found 1 dependency cycle/ ) end end it "does not create duplicate edges" do catalog = compile_to_catalog(<<-MANIFEST) class contained { notify { "contained": } } class container { contain contained contain contained } include container MANIFEST contained = catalog.resource("Class", "contained") container = catalog.resource("Class", "container") expect(catalog.edges_between(container, contained)).to have(1).item end context "when a containing class has a dependency order" do it "the contained class is applied in that order" do catalog = compile_to_relationship_graph(<<-MANIFEST) class contained { notify { "contained": } } class container { contain contained } class first { notify { "first": } } class last { notify { "last": } } include container, first, last Class["first"] -> Class["container"] -> Class["last"] MANIFEST expect(order_resources_traversed_in(catalog)).to include_in_order( "Notify[first]", "Notify[contained]", "Notify[last]" ) end end describe "When the future parser is in use" do require 'puppet/pops' before(:each) do Puppet[:parser] = 'future' compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo")) @scope = Puppet::Parser::Scope.new(compiler) end it_should_behave_like 'all functions transforming relative to absolute names', :function_contain it_should_behave_like 'an inclusion function, regardless of the type of class reference,', :contain end end