From c57dab4903a6a23fb14dc79c76efea989e694460 Mon Sep 17 00:00:00 2001 From: Chris Price Date: Fri, 17 Aug 2012 04:48:28 -0700 Subject: Add support for "global" section at beginning of file This commit does the following: * Fixes a bug in ExternalIterator * Adds support for a "global" section before the first named section at the beginning of the INI file * Improves test coverage --- spec/unit/puppet/provider/ini_setting/ruby_spec.rb | 154 +++++++++++++++++---- spec/unit/puppet/util/external_iterator_spec.rb | 35 +++++ spec/unit/puppet/util/ini_file_spec.rb | 77 +++++++++-- 3 files changed, 231 insertions(+), 35 deletions(-) create mode 100644 spec/unit/puppet/util/external_iterator_spec.rb (limited to 'spec') diff --git a/spec/unit/puppet/provider/ini_setting/ruby_spec.rb b/spec/unit/puppet/provider/ini_setting/ruby_spec.rb index 72a5da0..d26c78d 100644 --- a/spec/unit/puppet/provider/ini_setting/ruby_spec.rb +++ b/spec/unit/puppet/provider/ini_setting/ruby_spec.rb @@ -7,24 +7,12 @@ describe provider_class do let(:tmpfile) { tmpfilename("ini_setting_test") } let(:emptyfile) { tmpfilename("ini_setting_test_empty") } - let(:orig_content) { - <<-EOS -# This is a comment -[section1] -; This is also a comment -foo=foovalue -bar = barvalue -master = true -[section2] - -foo= foovalue2 -baz=bazvalue -url = http://192.168.1.1:8080 - #another comment - ; yet another comment - EOS -} + let(:common_params) { { + :title => 'ini_setting_ensure_present_test', + :path => tmpfile, + :section => 'section2', + } } def validate_file(expected_content,tmpfile = tmpfile) File.read(tmpfile).should == expected_content @@ -41,11 +29,24 @@ url = http://192.168.1.1:8080 end context "when ensuring that a setting is present" do - let(:common_params) { { - :title => 'ini_setting_ensure_present_test', - :path => tmpfile, - :section => 'section2', - } } + let(:orig_content) { + <<-EOS +# This is a comment +[section1] +; This is also a comment +foo=foovalue + +bar = barvalue +master = true +[section2] + +foo= foovalue2 +baz=bazvalue +url = http://192.168.1.1:8080 + #another comment + ; yet another comment + EOS + } it "should add a missing setting to the correct section" do resource = Puppet::Type::Ini_setting.new(common_params.merge( @@ -75,7 +76,7 @@ yahoo = yippee it "should modify an existing setting with a different value" do resource = Puppet::Type::Ini_setting.new(common_params.merge( - :setting => 'baz', :value => 'bazvalue2')) + :setting => 'baz', :value => 'bazvalue2')) provider = described_class.new(resource) provider.exists?.should == false provider.create @@ -100,7 +101,7 @@ url = http://192.168.1.1:8080 it "should be able to handle settings with non alphanumbering settings " do resource = Puppet::Type::Ini_setting.new(common_params.merge( - :setting => 'url', :value => 'http://192.168.0.1:8080')) + :setting => 'url', :value => 'http://192.168.0.1:8080')) provider = described_class.new(resource) provider.exists?.should == false provider.create @@ -126,7 +127,7 @@ url = http://192.168.0.1:8080 it "should recognize an existing setting with the specified value" do resource = Puppet::Type::Ini_setting.new(common_params.merge( - :setting => 'baz', :value => 'bazvalue')) + :setting => 'baz', :value => 'bazvalue')) provider = described_class.new(resource) provider.exists?.should == true end @@ -179,6 +180,109 @@ setting1 = hellowworld provider.create end + end + context "when dealing with a global section" do + let(:orig_content) { + <<-EOS +# This is a comment +foo=blah +[section2] +foo = http://192.168.1.1:8080 + ; yet another comment + EOS + } + + + it "should add a missing setting if it doesn't exist" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => '', :setting => 'bar', :value => 'yippee')) + provider = described_class.new(resource) + provider.exists?.should == false + provider.create + validate_file(<<-EOS +# This is a comment +foo=blah +bar = yippee +[section2] +foo = http://192.168.1.1:8080 + ; yet another comment + EOS + ) + end + + it "should modify an existing setting with a different value" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => '', :setting => 'foo', :value => 'yippee')) + provider = described_class.new(resource) + provider.exists?.should == false + provider.create + validate_file(<<-EOS +# This is a comment +foo = yippee +[section2] +foo = http://192.168.1.1:8080 + ; yet another comment + EOS + ) + end + + it "should recognize an existing setting with the specified value" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => '', :setting => 'foo', :value => 'blah')) + provider = described_class.new(resource) + provider.exists?.should == true + end + end + + context "when the first line of the file is a section" do + let(:orig_content) { + <<-EOS +[section2] +foo = http://192.168.1.1:8080 + EOS + } + + it "should be able to add a global setting" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => '', :setting => 'foo', :value => 'yippee')) + provider = described_class.new(resource) + provider.exists?.should == false + provider.create + validate_file(<<-EOS +foo = yippee +[section2] +foo = http://192.168.1.1:8080 + EOS + ) + end + + it "should modify an existing setting" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => 'section2', :setting => 'foo', :value => 'yippee')) + provider = described_class.new(resource) + provider.exists?.should == false + provider.create + validate_file(<<-EOS +[section2] +foo = yippee + EOS + ) + end + + it "should add a new setting" do + resource = Puppet::Type::Ini_setting.new(common_params.merge( + :section => 'section2', :setting => 'bar', :value => 'baz')) + provider = described_class.new(resource) + provider.exists?.should == false + provider.create + validate_file(<<-EOS +[section2] +foo = http://192.168.1.1:8080 +bar = baz + EOS + ) + end end + end diff --git a/spec/unit/puppet/util/external_iterator_spec.rb b/spec/unit/puppet/util/external_iterator_spec.rb new file mode 100644 index 0000000..92b17af --- /dev/null +++ b/spec/unit/puppet/util/external_iterator_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' +require 'puppet/util/external_iterator' + +describe Puppet::Util::ExternalIterator do + let(:subject) { Puppet::Util::ExternalIterator.new(["a", "b", "c"]) } + + context "#next" do + it "should iterate over the items" do + subject.next.should == ["a", 0] + subject.next.should == ["b", 1] + subject.next.should == ["c", 2] + end + end + + context "#peek" do + it "should return the 0th item repeatedly" do + subject.peek.should == ["a", 0] + subject.peek.should == ["a", 0] + end + + it "should not advance the iterator, but should reflect calls to #next" do + subject.peek.should == ["a", 0] + subject.peek.should == ["a", 0] + subject.next.should == ["a", 0] + subject.peek.should == ["b", 1] + subject.next.should == ["b", 1] + subject.peek.should == ["c", 2] + subject.next.should == ["c", 2] + subject.peek.should == [nil, nil] + subject.next.should == [nil, nil] + end + end + + +end diff --git a/spec/unit/puppet/util/ini_file_spec.rb b/spec/unit/puppet/util/ini_file_spec.rb index f2c6e20..f30c8cd 100644 --- a/spec/unit/puppet/util/ini_file_spec.rb +++ b/spec/unit/puppet/util/ini_file_spec.rb @@ -2,8 +2,16 @@ require 'spec_helper' require 'puppet/util/ini_file' describe Puppet::Util::IniFile do + let(:subject) { Puppet::Util::IniFile.new("/my/ini/file/path") } + + before :each do + File.should_receive(:file?).with("/my/ini/file/path") { true } + described_class.should_receive(:readlines).once.with("/my/ini/file/path") do + sample_content + end + end + context "when parsing a file" do - let(:subject) { Puppet::Util::IniFile.new("/my/ini/file/path") } let(:sample_content) { template = <<-EOS # This is a comment @@ -22,19 +30,14 @@ baz=bazvalue template.split("\n") } - before :each do - File.should_receive(:file?).with("/my/ini/file/path") { true } - described_class.should_receive(:readlines).once.with("/my/ini/file/path") do - sample_content - end - end - it "should parse the correct number of sections" do - subject.section_names.length.should == 2 + # there is always a "global" section, so our count should be 3. + subject.section_names.length.should == 3 end it "should parse the correct section_names" do - subject.section_names.should == ["section1", "section2"] + # there should always be a "global" section named "" at the beginning of the list + subject.section_names.should == ["", "section1", "section2"] end it "should expose settings for sections" do @@ -45,4 +48,58 @@ baz=bazvalue end end + + context "when parsing a file whose first line is a section" do + let(:sample_content) { + template = <<-EOS +[section1] +; This is a comment +foo=foovalue + EOS + template.split("\n") + } + + it "should parse the correct number of sections" do + # there is always a "global" section, so our count should be 2. + subject.section_names.length.should == 2 + end + + it "should parse the correct section_names" do + # there should always be a "global" section named "" at the beginning of the list + subject.section_names.should == ["", "section1"] + end + + it "should expose settings for sections" do + subject.get_value("section1", "foo").should == "foovalue" + end + + end + + context "when parsing a file with a 'global' section" do + let(:sample_content) { + template = <<-EOS +foo = bar +[section1] +; This is a comment +foo=foovalue + EOS + template.split("\n") + } + + it "should parse the correct number of sections" do + # there is always a "global" section, so our count should be 2. + subject.section_names.length.should == 2 + end + + it "should parse the correct section_names" do + # there should always be a "global" section named "" at the beginning of the list + subject.section_names.should == ["", "section1"] + end + + it "should expose settings for sections" do + subject.get_value("", "foo").should == "bar" + subject.get_value("section1", "foo").should == "foovalue" + end + + end end \ No newline at end of file -- cgit v1.2.3