Codebase list ruby-iniparse / 5e01313
Import upstream version 1.5.0 Debian Janitor 2 years ago
23 changed file(s) with 624 addition(s) and 493 deletion(s). Raw diff Collapse all Expand all
0 ---
1 BUNDLE_WITHOUT: extras
00 language: ruby
11 script: "bundle exec rspec"
22 bundler_args: "--without extras"
3 before_install:
4 - gem update --system
5 - gem update bundler
6 - gem cleanup bundler
37 rvm:
4 - "2.1.0"
5 - "1.9.3"
6 - "jruby-19mode"
8 - 2.4
9 - 2.3
10 - 2.2
0 ### 1.5.0
1
2 * OptionCollection no longer yields duplicate keys as an array, but instead yields each key in turn.
3
4 For example, given an INI file:
5
6 [test]
7 a = 1
8 a = 2
9 b = 3
10
11 IniParse would previously yield a single "a" key: an array containing two `Line`s:
12
13 doc['test'].map { |line| line }
14 # => [[<a = 1>, <a = 2>], <b = 3>]
15
16 Instead, each key/value pair will be yielded in turn:
17
18 doc['test'].map { |line| line }
19 # => [<a = 1>, <a = 2>, <b = 3>]
20
21 Directly accessing values via `[]` will still return an array of values as before:
22
23 doc['test']['a']
24 # => [1, 2]
25
26 * LineCollection#each may be called without a block, returning an Enumerator.
27
28 doc = IniParse.parse(<<~EOF)
29 [test]
30 a = x
31 b = y
32 EOF
33
34 doc[test].each
35 # => #<Enumerator: ...>
36
37 This allows for chaining as in the standard library:
38
39 doc['test'].map.with_index { |a, i| { index: i, value: a.value } }
40 # => [{ index: 0, value: 'x' }, { index: 1, value: 'y' }]
2020
2121 def date
2222 Date.today.to_s
23 end
24
25 def rubyforge_project
26 name
2723 end
2824
2925 def gemspec_file
7672 replace_header(head, :name)
7773 replace_header(head, :version)
7874 replace_header(head, :date)
79 #comment this out if your rubyforge_project has a different name
80 replace_header(head, :rubyforge_project)
8175
8276 # determine file list from git ls-files
8377 files = `git ls-files`.
1111 ## If your rubyforge_project name is different, then edit it and comment out
1212 ## the sub! line in the Rakefile
1313 s.name = 'iniparse'
14 s.version = '1.4.2'
15 s.date = '2015-12-03'
16 s.rubyforge_project = 'iniparse'
14 s.version = '1.5.0'
15 s.date = '2020-02-27'
1716
1817 s.summary = 'A pure Ruby library for parsing INI documents.'
1918 s.authors = ['Anthony Williams']
3130 s.extra_rdoc_files = %w(LICENSE README.rdoc)
3231
3332 # Dependencies.
34 s.add_development_dependency('rspec', '~> 2.14')
33 s.add_development_dependency('rspec', '~> 3.4')
3534
3635 # = MANIFEST =
3736 s.files = %w[
37 CHANGELOG.md
3838 Gemfile
3939 LICENSE
4040 README.rdoc
5656 # include_blank<Boolean>:: Include blank/comment lines?
5757 #
5858 def each(include_blank = false)
59 return enum_for(:each, include_blank) unless block_given?
60
5961 @lines.each do |line|
6062 if include_blank || ! (line.is_a?(Array) ? line.empty? : line.blank?)
6163 yield(line)
110112 include LineCollection
111113
112114 def <<(line)
113 if line.kind_of?(IniParse::Lines::Option)
115 if line.kind_of?(IniParse::Lines::Option) || (has_key?('__anonymous__') && (line.blank? || line.kind_of?(IniParse::Lines::Comment)))
114116 option = line
115117 line = IniParse::Lines::AnonymousSection.new
116118
160162 self
161163 end
162164
165 def each(*args)
166 return enum_for(:each, *args) unless block_given?
167
168 super(*args) do |value|
169 if value.is_a?(Array)
170 value.each { |item| yield(item) }
171 else
172 yield value
173 end
174 end
175 end
176
163177 # Return an array containing the keys for the lines added to this
164178 # collection.
165179 def keys
166 map { |line| line.kind_of?(Array) ? line.first.key : line.key }
180 map(&:key).uniq
167181 end
168182 end
169183 end
1010 @comment_prefix = opts.fetch(:comment_prefix, ' ')
1111 @comment_offset = opts.fetch(:comment_offset, 0)
1212 @indent = opts.fetch(:indent, '')
13 @option_sep = opts.fetch(:option_sep, nil)
1314 end
1415
1516 # Returns if this line has an inline comment.
5354 comment_sep: @comment_sep,
5455 comment_prefix: @comment_prefix,
5556 comment_offset: @comment_offset,
56 indent: @indent
57 indent: @indent,
58 option_sep: @option_sep
5759 }
5860 end
5961 end
247249 class Option
248250 include Line
249251
250 @regex = /^\s*([^=]+) # Option
251 =
252 (.*?)$ # Value
252 @regex = /^\s*([^=]+?) # Option, not greedy
253 (\s*=\s*) # Separator, greedy
254 (.*?)$ # Value
253255 /x
254256
255257 attr_accessor :key, :value
262264 def initialize(key, value, opts = {})
263265 super(opts)
264266 @key, @value = key.to_s, value
267 @option_sep = opts.fetch(:option_sep, ' = ')
265268 end
266269
267270 def self.parse(line, opts)
268271 if m = @regex.match(line)
269 [:option, m[1].strip, typecast(m[2].strip), opts]
272 opts[:option_sep] = m[2]
273 [:option, m[1].strip, typecast(m[3].strip), opts]
270274 end
271275 end
272276
290294 # because of options key duplication
291295 def line_contents
292296 if value.kind_of?(Array)
293 value.map { |v, i| "#{key} = #{v}" }
297 value.map { |v, i| "#{key}#{@option_sep}#{v}" }
294298 else
295 "#{key} = #{value}"
299 "#{key}#{@option_sep}#{value}"
296300 end
297301 end
298302 end
6363 if parsed.nil?
6464 raise IniParse::ParseError,
6565 "A line of your INI document could not be parsed to a " \
66 "LineType: '#{line}'."
66 "LineType: #{line.inspect}."
6767 end
6868
6969 parsed
8888
8989 line = m[1]
9090 else
91 line.rstrip!
91 line = line.chomp
9292 end
9393
9494 [line, opts]
66 require File.join(dir, 'parser')
77
88 module IniParse
9 VERSION = '1.4.2'
9 VERSION = '1.5.0'.freeze
1010
1111 # A base class for IniParse errors.
1212 class IniParseError < StandardError; end
22 describe "IniParse::Document" do
33 it 'should have a +lines+ reader' do
44 methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
5 methods.should include(:lines)
5 expect(methods).to include(:lines)
66 end
77
88 it 'should not have a +lines+ writer' do
99 methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
10 methods.should_not include(:lines=)
10 expect(methods).not_to include(:lines=)
1111 end
1212
1313 it 'should delegate #[] to +lines+' do
1414 doc = IniParse::Document.new
15 doc.lines.should_receive(:[]).with('key')
15 expect(doc.lines).to receive(:[]).with('key')
1616 doc['key']
1717 end
1818
1919 it 'should call #each to +lines+' do
2020 doc = IniParse::Document.new
21 doc.lines.should_receive(:each)
21 expect(doc.lines).to receive(:each)
2222 doc.each { |l| }
2323 end
2424
2525 it 'should be enumerable' do
26 IniParse::Document.included_modules.should include(Enumerable)
26 expect(IniParse::Document.included_modules).to include(Enumerable)
2727
2828 sections = [
2929 IniParse::Lines::Section.new('first section'),
3333 doc = IniParse::Document.new
3434 doc.lines << sections[0] << sections[1]
3535
36 doc.map { |line| line }.should == sections
36 expect(doc.map { |line| line }).to eq(sections)
3737 end
3838
3939 describe '#has_section?' do
4444 end
4545
4646 it 'should return true if a section with the given key exists' do
47 @doc.should have_section('first section')
48 @doc.should have_section('another section')
47 expect(@doc).to have_section('first section')
48 expect(@doc).to have_section('another section')
4949 end
5050
5151 it 'should return true if no section with the given key exists' do
52 @doc.should_not have_section('second section')
52 expect(@doc).not_to have_section('second section')
5353 end
5454 end
5555
6969 end
7070
7171 it 'removes the section given a key' do
72 lambda { document.delete('first') }.
73 should change { document['first'] }.to(nil)
72 expect { document.delete('first') }.
73 to change { document['first'] }.to(nil)
7474 end
7575
7676 it 'removes the section given a Section' do
77 lambda { document.delete(document['first']) }.
78 should change { document['first'] }.to(nil)
77 expect { document.delete(document['first']) }.
78 to change { document['first'] }.to(nil)
7979 end
8080
8181 it 'removes the lines' do
82 lambda { document.delete('first') }.
83 should change { document.to_ini.match(/alpha/) }.to(nil)
82 expect { document.delete('first') }.
83 to change { document.to_ini.match(/alpha/) }.to(nil)
8484 end
8585
8686 it 'returns the document' do
87 document.delete('first').should eql(document)
87 expect(document.delete('first')).to eql(document)
8888 end
8989 end
9090
121121 describe 'when no path is given to save' do
122122 it 'should save the INI document if a path was given when initialized' do
123123 doc = IniParse::Document.new('/a/path/to/a/file.ini')
124 File.should_receive(:open).with('/a/path/to/a/file.ini', 'w')
124 expect(File).to receive(:open).with('/a/path/to/a/file.ini', 'w')
125125 doc.save
126126 end
127127
128128 it 'should raise IniParseError if no path was given when initialized' do
129 lambda { IniParse::Document.new.save }.should \
129 expect { IniParse::Document.new.save }.to \
130130 raise_error(IniParse::IniParseError)
131131 end
132132 end
133133
134134 describe 'when a path is given to save' do
135135 it "should update the document's +path+" do
136 File.stub(:open).and_return(true)
136 allow(File).to receive(:open).and_return(true)
137137 doc = IniParse::Document.new('/a/path/to/a/file.ini')
138138 doc.save('/a/new/path.ini')
139 doc.path.should == '/a/new/path.ini'
139 expect(doc.path).to eq('/a/new/path.ini')
140140 end
141141
142142 it 'should save the INI document to the given path' do
143 File.should_receive(:open).with('/a/new/path.ini', 'w')
143 expect(File).to receive(:open).with('/a/new/path.ini', 'w')
144144 IniParse::Document.new('/a/path/to/a/file.ini').save('/a/new/path.ini')
145145 end
146146
147147 it 'should raise IniParseError if no path was given when initialized' do
148 lambda { IniParse::Document.new.save }.should \
148 expect { IniParse::Document.new.save }.to \
149149 raise_error(IniParse::IniParseError)
150150 end
151151 end
66 end
77
88 it 'should parse without any errors' do
9 lambda { IniParse.parse(@fixture) }.should_not raise_error
10 end
11
12 it 'should have the correct sections' do
13 IniParse.parse(fixture('openttd.ini')).lines.keys.should == [
9 expect { IniParse.parse(@fixture) }.not_to raise_error
10 end
11
12 it 'should have the correct sections' do
13 expect(IniParse.parse(fixture('openttd.ini')).lines.keys).to eq([
1414 'misc', 'music', 'difficulty', 'game_creation', 'vehicle',
1515 'construction', 'station', 'economy', 'pf', 'order', 'gui', 'ai',
1616 'locale', 'network', 'currency', 'servers', 'bans', 'news_display',
1717 'version', 'preset-J', 'newgrf', 'newgrf-static'
18 ]
18 ])
1919 end
2020
2121 it 'should have the correct options' do
2323 doc = IniParse.parse(@fixture)
2424 section = doc['misc']
2525
26 section.lines.keys.should == [
26 expect(section.lines.keys).to eq([
2727 'display_opt', 'news_ticker_sound', 'fullscreen', 'language',
2828 'resolution', 'screenshot_format', 'savegame_format',
2929 'rightclick_emulate', 'small_font', 'medium_font', 'large_font',
3131 'large_aa', 'sprite_cache_size', 'player_face',
3232 'transparency_options', 'transparency_locks', 'invisibility_options',
3333 'keyboard', 'keyboard_caps'
34 ]
34 ])
3535
3636 # Test some of the options.
37 section['display_opt'].should == 'SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS'
38 section['news_ticker_sound'].should be_false
39 section['language'].should == 'english_US.lng'
40 section['resolution'].should == '1680,936'
41 section['large_size'].should == 16
37 expect(section['display_opt']).to eq('SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS')
38 expect(section['news_ticker_sound']).to be_falsey
39 expect(section['language']).to eq('english_US.lng')
40 expect(section['resolution']).to eq('1680,936')
41 expect(section['large_size']).to eq(16)
4242
4343 # Test some other options.
44 doc['currency']['suffix'].should == '" credits"'
45 doc['news_display']['production_nobody'].should == 'summarized'
46 doc['version']['version_number'].should == '070039B0'
47
48 doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf'].should be_nil
49 doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf'].should be_nil
50 end
51
52 it 'should be identical to the original when calling #to_ini' do
53 IniParse.parse(@fixture).to_ini.should == @fixture
44 expect(doc['currency']['suffix']).to eq('" credits"')
45 expect(doc['news_display']['production_nobody']).to eq('summarized')
46 expect(doc['version']['version_number']).to eq('070039B0')
47
48 expect(doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf']).to be_nil
49 expect(doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf']).to be_nil
50 end
51
52 it 'should be identical to the original when calling #to_ini' do
53 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
5454 end
5555 end
5656
6060 end
6161
6262 it 'should parse without any errors' do
63 lambda { IniParse.parse(@fixture) }.should_not raise_error
64 end
65
66 it 'should have the correct sections' do
67 IniParse.parse(fixture('race07.ini')).lines.keys.should == [
63 expect { IniParse.parse(@fixture) }.not_to raise_error
64 end
65
66 it 'should have the correct sections' do
67 expect(IniParse.parse(fixture('race07.ini')).lines.keys).to eq([
6868 'Header', 'Race', 'Slot010', 'Slot016', 'Slot013', 'Slot018',
6969 'Slot002', 'END'
70 ]
70 ])
7171 end
7272
7373 it 'should have the correct options' do
7575 doc = IniParse.parse(@fixture)
7676 section = doc['Slot010']
7777
78 section.lines.keys.should == [
78 expect(section.lines.keys).to eq([
7979 'Driver', 'SteamUser', 'SteamId', 'Vehicle', 'Team', 'QualTime',
8080 'Laps', 'Lap', 'LapDistanceTravelled', 'BestLap', 'RaceTime'
81 ]
81 ])
8282
8383 # Test some of the options.
84 section['Driver'].should == 'Mark Voss'
85 section['SteamUser'].should == 'mvoss'
86 section['SteamId'].should == 1865369
87 section['Vehicle'].should == 'Chevrolet Lacetti 2007'
88 section['Team'].should == 'TEMPLATE_TEAM'
89 section['QualTime'].should == '1:37.839'
90 section['Laps'].should == 13
91 section['LapDistanceTravelled'].should == 3857.750244
92 section['BestLap'].should == '1:38.031'
93 section['RaceTime'].should == '0:21:38.988'
94
95 section['Lap'].should == [
84 expect(section['Driver']).to eq('Mark Voss')
85 expect(section['SteamUser']).to eq('mvoss')
86 expect(section['SteamId']).to eq(1865369)
87 expect(section['Vehicle']).to eq('Chevrolet Lacetti 2007')
88 expect(section['Team']).to eq('TEMPLATE_TEAM')
89 expect(section['QualTime']).to eq('1:37.839')
90 expect(section['Laps']).to eq(13)
91 expect(section['LapDistanceTravelled']).to eq(3857.750244)
92 expect(section['BestLap']).to eq('1:38.031')
93 expect(section['RaceTime']).to eq('0:21:38.988')
94
95 expect(section['Lap']).to eq([
9696 '(0, -1.000, 1:48.697)', '(1, 89.397, 1:39.455)',
9797 '(2, 198.095, 1:38.060)', '(3, 297.550, 1:38.632)',
9898 '(4, 395.610, 1:38.031)', '(5, 494.242, 1:39.562)',
100100 '(8, 791.785, 1:39.889)', '(9, 890.151, 1:39.420)',
101101 '(10, 990.040, 1:39.401)', '(11, 1089.460, 1:39.506)',
102102 '(12, 1188.862, 1:40.017)'
103 ]
104
105 doc['Header']['Version'].should == '1.1.1.14'
106 doc['Header']['TimeString'].should == '2008/09/13 23:26:32'
107 doc['Header']['Aids'].should == '0,0,0,0,0,1,1,0,0'
108
109 doc['Race']['AIDB'].should == 'GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW'
110 doc['Race']['Race Length'].should == 0.1
111 end
112
113 it 'should be identical to the original when calling #to_ini' do
114 pending('awaiting presevation (or lack) of whitespace around =') do
115 IniParse.parse(@fixture).to_ini.should == @fixture
116 end
103 ])
104
105 expect(doc['Header']['Version']).to eq('1.1.1.14')
106 expect(doc['Header']['TimeString']).to eq('2008/09/13 23:26:32')
107 expect(doc['Header']['Aids']).to eq('0,0,0,0,0,1,1,0,0')
108
109 expect(doc['Race']['AIDB']).to eq('GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW')
110 expect(doc['Race']['Race Length']).to eq(0.1)
111 end
112
113 it 'should be identical to the original when calling #to_ini' do
114 pending('awaiting presevation (or lack) of whitespace around =')
115 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
117116 end
118117 end
119118
123122 end
124123
125124 it 'should parse without any errors' do
126 lambda { IniParse.parse(@fixture) }.should_not raise_error
127 end
128
129 it 'should have the correct sections' do
130 IniParse.parse(@fixture).lines.keys.should == [
125 expect { IniParse.parse(@fixture) }.not_to raise_error
126 end
127
128 it 'should have the correct sections' do
129 expect(IniParse.parse(@fixture).lines.keys).to eq([
131130 'global', 'printers'
132 ]
131 ])
133132 end
134133
135134 it 'should have the correct options' do
137136 doc = IniParse.parse(@fixture)
138137 section = doc['global']
139138
140 section.lines.keys.should == [
139 expect(section.lines.keys).to eq([
141140 'debug pid', 'log level', 'server string', 'printcap name',
142141 'printing', 'encrypt passwords', 'use spnego', 'passdb backend',
143142 'idmap domains', 'idmap config default: default',
151150 'usershare allow full config', 'com.apple:filter shares by access',
152151 'obey pam restrictions', 'acl check permissions',
153152 'name resolve order', 'include'
154 ]
155
156 section['display charset'].should == 'UTF-8-MAC'
157 section['vfs objects'].should == 'darwinacl,darwin_streams'
158 section['usershare path'].should == '/var/samba/shares'
159 end
160
161 it 'should be identical to the original when calling #to_ini' do
162 IniParse.parse(@fixture).to_ini.should == @fixture
153 ])
154
155 expect(section['display charset']).to eq('UTF-8-MAC')
156 expect(section['vfs objects']).to eq('darwinacl,darwin_streams')
157 expect(section['usershare path']).to eq('/var/samba/shares')
158 end
159
160 it 'should be identical to the original when calling #to_ini' do
161 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
163162 end
164163 end
165164
169168 end
170169
171170 it 'should be identical to the original when calling #to_ini' do
172 IniParse.parse(@fixture).to_ini.should == @fixture
171 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
173172 end
174173 end
175174
179178 end
180179
181180 it 'should be identical to the original when calling #to_ini' do
182 IniParse.parse(@fixture).to_ini.should == @fixture
181 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
182 end
183 end
184
185 describe 'DOS line endings' do
186 before(:all) do
187 @fixture = fixture(:dos_endings)
188 end
189
190 it 'should have the correct sections' do
191 expect(IniParse.parse(@fixture).lines.keys).to eq(%w[database])
192 end
193
194 it 'should have the correct options' do
195 # Test the keys from one section.
196 doc = IniParse.parse(@fixture)
197 section = doc['database']
198
199 expect(section.lines.keys).to eq(%w[first second])
200
201 expect(section['first']).to eq(true)
202 expect(section['second']).to eq(false)
203 end
204
205 pending 'should be identical to the original when calling #to_ini' do
206 expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
207 end
208 end
209
210 describe 'anonymous-order.ini fixture' do
211 # https://github.com/antw/iniparse/issues/17
212 let(:raw) { fixture(:anon_section_with_comments) }
213
214 it 'should be identical to the original when calling #to_ini' do
215 expect(IniParse.parse(raw).to_ini).to eq(raw)
183216 end
184217 end
185218 end
77 screenshot_format =
88 savegame_format =
99 rightclick_emulate = false
10 small_font =
11 medium_font =
12 large_font =
10 small_font =
11 medium_font =
12 large_font =
1313 small_size = 6
1414 medium_size = 10
1515 large_size = 16
2121 transparency_options = 3
2222 transparency_locks = 0
2323 invisibility_options = 30
24 keyboard =
25 keyboard_caps =
24 keyboard =
25 keyboard_caps =
2626
2727 [music]
2828 playlist = 0
2222 IniParse::Generator.gen do |doc|
2323 doc.a_section do |section|
2424 %w( option comment blank ).each do |meth|
25 section.should respond_to(meth)
25 expect(section).to respond_to(meth)
2626 end
2727 end
2828 end
2929 end
3030
3131 it 'should add a Section to the document' do
32 IniParse::Generator.gen do |doc|
32 expect(IniParse::Generator.gen do |doc|
3333 doc.a_section { |section| }
34 end.should have_section("a_section")
34 end).to have_section("a_section")
3535 end
3636
3737 it 'should change the Generator context to the section during the section block' do
3838 IniParse::Generator.gen do |doc|
3939 doc.a_section do |section|
40 section.context.should be_kind_of(IniParse::Lines::Section)
41 section.context.key.should == "a_section"
40 expect(section.context).to be_kind_of(IniParse::Lines::Section)
41 expect(section.context.key).to eq("a_section")
4242 end
4343 end
4444 end
4646 it 'should reset the Generator context to the document after the section block' do
4747 IniParse::Generator.gen do |doc|
4848 doc.a_section { |section| }
49 doc.context.should be_kind_of(IniParse::Document)
49 expect(doc.context).to be_kind_of(IniParse::Document)
5050 end
5151 end
5252
5353 it 'should append a blank line to the document, after the section' do
54 IniParse::Generator.gen do |doc|
54 expect(IniParse::Generator.gen do |doc|
5555 doc.a_section { |section| }
56 end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
56 end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
5757 end
5858
5959 it 'should raise a LineNotAllowed if you attempt to nest a section' do
60 lambda do
60 expect do
6161 IniParse::Generator.gen do |doc|
6262 doc.a_section do |section_one|
6363 section_one.another_section { |section_two| }
6464 end
6565 end
66 end.should raise_error(IniParse::LineNotAllowed)
66 end.to raise_error(IniParse::LineNotAllowed)
6767 end
6868 end
6969
7777 describe 'when the context is a Document' do
7878 it "adds the option to an __anonymous__ section" do
7979 doc = IniParse::Generator.gen { |doc| doc.my_option = "a value" }
80 doc['__anonymous__']['my_option'].should eql('a value')
80 expect(doc['__anonymous__']['my_option']).to eql('a value')
8181 end
8282 end
8383
9090 end
9191
9292 section = document["a_section"]
93 section.should have_option("my_option")
94 section["my_option"].should == "a value"
93 expect(section).to have_option("my_option")
94 expect(section["my_option"]).to eq("a value")
9595 end
9696 end
9797 end
1212 describe 'When generating a document using Generator with section blocks,' do
1313
1414 it 'should be able to compile an empty document' do
15 lambda { IniParse::Generator.gen { |doc| } }.should_not raise_error
15 expect { IniParse::Generator.gen { |doc| } }.not_to raise_error
1616 end
1717
1818 it 'should raise LocalJumpError if no block is given' do
19 lambda { IniParse::Generator.gen }.should raise_error(LocalJumpError)
19 expect { IniParse::Generator.gen }.to raise_error(LocalJumpError)
2020 end
2121
2222 it "should yield an object with generator methods" do
2323 IniParse::Generator.gen do |doc|
2424 %w( section option comment blank ).each do |meth|
25 doc.should respond_to(meth)
25 expect(doc).to respond_to(meth)
2626 end
2727 end
2828 end
3838 IniParse::Generator.gen do |doc|
3939 doc.section("a section") do |section|
4040 %w( option comment blank ).each do |meth|
41 section.should respond_to(meth)
41 expect(section).to respond_to(meth)
4242 end
4343 end
4444 end
4545 end
4646
4747 it 'should add a Section to the document' do
48 IniParse::Generator.gen do |doc|
48 expect(IniParse::Generator.gen do |doc|
4949 doc.section("a section") { |section| }
50 end.should have_section("a section")
50 end).to have_section("a section")
5151 end
5252
5353 it 'should change the Generator context to the section during the section block' do
5454 IniParse::Generator.gen do |doc|
5555 doc.section("a section") do |section|
56 section.context.should be_kind_of(IniParse::Lines::Section)
57 section.context.key.should == "a section"
56 expect(section.context).to be_kind_of(IniParse::Lines::Section)
57 expect(section.context.key).to eq("a section")
5858 end
5959 end
6060 end
6262 it 'should reset the Generator context to the document after the section block' do
6363 IniParse::Generator.gen do |doc|
6464 doc.section("a section") { |section| }
65 doc.context.should be_kind_of(IniParse::Document)
65 expect(doc.context).to be_kind_of(IniParse::Document)
6666 end
6767 end
6868
7171 doc.section("a section") { |section| }
7272 end
7373
74 document["a section"].to_ini.should match(/\A /)
74 expect(document["a section"].to_ini).to match(/\A /)
7575 end
7676
7777 it 'should pass extra options to the Section instance' do
7979 doc.section("a section", :indent => ' ') { |section| }
8080 end
8181
82 document["a section"].to_ini.should match(/\A /)
82 expect(document["a section"].to_ini).to match(/\A /)
8383 end
8484
8585 it 'should append a blank line to the document, after the section' do
86 IniParse::Generator.gen do |doc|
86 expect(IniParse::Generator.gen do |doc|
8787 doc.section("a section") { |section| }
88 end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
88 end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
8989 end
9090
9191 it 'should raise a LineNotAllowed if you attempt to nest a section' do
92 lambda do
92 expect do
9393 IniParse::Generator.gen do |doc|
9494 doc.section("a section") do |section_one|
9595 section_one.section("another_section") { |section_two| }
9696 end
9797 end
98 end.should raise_error(IniParse::LineNotAllowed)
98 end.to raise_error(IniParse::LineNotAllowed)
9999 end
100100 end
101101
113113 doc.option("my option", "a value")
114114 end
115115
116 document['__anonymous__']['my option'].should eql('a value')
116 expect(document['__anonymous__']['my option']).to eql('a value')
117117 end
118118 end
119119
126126 end
127127
128128 section = document["a section"]
129 section.should have_option("my option")
130 section["my option"].should == "a value"
129 expect(section).to have_option("my option")
130 expect(section["my option"]).to eq("a value")
131131 end
132132
133133 it 'should pass extra options to the Option instance' do
137137 end
138138 end
139139
140 document["a section"].option("my option").to_ini.should match(/^ /)
140 expect(document["a section"].option("my option").to_ini).to match(/^ /)
141141 end
142142
143143 it "should use the parent document's options as a base" do
147147 end
148148 end
149149
150 document["a section"].option("my option").to_ini.should match(/^ /)
150 expect(document["a section"].option("my option").to_ini).to match(/^ /)
151151 end
152152
153153 it "should use the parent section's options as a base" do
157157 end
158158 end
159159
160 document["a section"].option("my option").to_ini.should match(/^ /)
160 expect(document["a section"].option("my option").to_ini).to match(/^ /)
161161 end
162162
163163 it "should allow customisation of the parent's options" do
170170 end
171171
172172 option_ini = document["a section"].option("my option").to_ini
173 option_ini.should match(/^ /)
174 option_ini.should match(/ # a comment/)
173 expect(option_ini).to match(/^ /)
174 expect(option_ini).to match(/ # a comment/)
175175 end
176176
177177 it "should not use the parent section's comment when setting line options" do
181181 end
182182 end
183183
184 document["a section"].option("my option").to_ini.should_not match(/My section$/)
184 expect(document["a section"].option("my option").to_ini).not_to match(/My section$/)
185185 end
186186 end
187187 end
198198 doc.comment("My comment", :indent => ' ')
199199 end
200200
201 document.lines.to_a.first.to_ini.should match(/\A /)
201 expect(document.lines.to_a.first.to_ini).to match(/\A /)
202202 end
203203
204204 it 'should ignore any extra :comment option' do
206206 doc.comment("My comment", :comment => 'Ignored')
207207 end
208208
209 document.lines.to_a.first.to_ini.should match(/My comment/)
210 document.lines.to_a.first.to_ini.should_not match(/Ignored/)
209 expect(document.lines.to_a.first.to_ini).to match(/My comment/)
210 expect(document.lines.to_a.first.to_ini).not_to match(/Ignored/)
211211 end
212212
213213 describe 'when the context is a Document' do
217217 end
218218
219219 comment = document.lines.to_a.first
220 comment.should be_kind_of(IniParse::Lines::Comment)
221 comment.to_ini.should match(/My comment/)
220 expect(comment).to be_kind_of(IniParse::Lines::Comment)
221 expect(comment.to_ini).to match(/My comment/)
222222 end
223223
224224 it 'should use the default line options as a base' do
229229 comment_ini = document.lines.to_a.first.to_ini
230230
231231 # Match separator (;) and offset (0).
232 comment_ini.should == '; My comment'
232 expect(comment_ini).to eq('; My comment')
233233 end
234234 end
235235
242242 end
243243
244244 comment = document['a section'].lines.to_a.first
245 comment.should be_kind_of(IniParse::Lines::Comment)
246 comment.to_ini.should match(/My comment/)
245 expect(comment).to be_kind_of(IniParse::Lines::Comment)
246 expect(comment.to_ini).to match(/My comment/)
247247 end
248248
249249 it "should use the parent document's line options as a base" do
253253 end
254254 end
255255
256 document['a section'].lines.to_a.first.to_ini.should match(/^ ;/)
256 expect(document['a section'].lines.to_a.first.to_ini).to match(/^ ;/)
257257 end
258258
259259 it "should use the parent section's line options as a base" do
263263 end
264264 end
265265
266 document['a section'].lines.to_a.first.to_ini.should match(/^ ;/)
266 expect(document['a section'].lines.to_a.first.to_ini).to match(/^ ;/)
267267 end
268268
269269 it "should allow customisation of the parent's options" do
274274 end
275275
276276 # Match separator (#) and offset (5)
277 document['a section'].lines.to_a.first.to_ini.should \
278 == ' # My comment'
277 expect(document['a section'].lines.to_a.first.to_ini).to \
278 eq(' # My comment')
279279 end
280280
281281 it "should not use the parent section's comment when setting line options" do
286286 end
287287
288288 comment_ini = document['a section'].lines.to_a.first.to_ini
289 comment_ini.should match(/My comment/)
290 comment_ini.should_not match(/My section/)
289 expect(comment_ini).to match(/My comment/)
290 expect(comment_ini).not_to match(/My section/)
291291 end
292292 end
293293 end
304304 doc.blank
305305 end
306306
307 document.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
307 expect(document.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
308308 end
309309
310310 it 'should add a blank line to the section when it is the context' do
314314 end
315315 end
316316
317 document['a section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
317 expect(document['a section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
318318 end
319319 end
320320
2828 describe 'adding a section' do
2929 it 'should add a Section to the document' do
3030 @gen.section("a section")
31 @gen.document.should have_section("a section")
31 expect(@gen.document).to have_section("a section")
3232 end
3333
3434 it 'should change the Generator context to the section' do
3535 @gen.section("a section")
36 @gen.context.should == @gen.document['a section']
36 expect(@gen.context).to eq(@gen.document['a section'])
3737 end
3838
3939 it 'should pass extra options to the Section instance' do
4040 @gen.section("a section", :indent => ' ')
41 @gen.document["a section"].to_ini.should match(/\A /)
41 expect(@gen.document["a section"].to_ini).to match(/\A /)
4242 end
4343 end
4444
5252 it 'should pass extra options to the Option instance' do
5353 @gen.section("a section")
5454 @gen.option("my option", "a value", :indent => ' ')
55 @gen.document["a section"].option("my option").to_ini.should match(/^ /)
55 expect(@gen.document["a section"].option("my option").to_ini).to match(/^ /)
5656 end
5757
5858 describe 'when the context is a Document' do
5959 it "should add the option to an __anonymous__ section" do
6060 @gen.option("key", "value")
61 @gen.document['__anonymous__']['key'].should eql('value')
61 expect(@gen.document['__anonymous__']['key']).to eql('value')
6262 end
6363 end
6464
6666 it 'should add the option to the section' do
6767 @gen.section("a section")
6868 @gen.option("my option", "a value")
69 @gen.document["a section"].should have_option("my option")
70 @gen.document["a section"]["my option"].should == "a value"
69 expect(@gen.document["a section"]).to have_option("my option")
70 expect(@gen.document["a section"]["my option"]).to eq("a value")
7171 end
7272 end
7373 end
8181 describe 'adding a comment' do
8282 it 'should pass extra options to the Option instance' do
8383 @gen.comment("My comment", :indent => ' ')
84 @gen.document.lines.to_a.first.to_ini.should match(/^ /)
84 expect(@gen.document.lines.to_a.first.to_ini).to match(/^ /)
8585 end
8686
8787 it 'should ignore any extra :comment option' do
8888 @gen.comment("My comment", :comment => 'Ignored')
8989 comment_ini = @gen.document.lines.to_a.first.to_ini
90 comment_ini.should match(/My comment/)
91 comment_ini.should_not match(/Ignored/)
90 expect(comment_ini).to match(/My comment/)
91 expect(comment_ini).not_to match(/Ignored/)
9292 end
9393
9494 describe 'when the context is a Document' do
9595 it 'should add a comment to the document' do
9696 @gen.comment('My comment')
9797 comment = @gen.document.lines.to_a.first
98 comment.should be_kind_of(IniParse::Lines::Comment)
99 comment.to_ini.should match(/; My comment/)
98 expect(comment).to be_kind_of(IniParse::Lines::Comment)
99 expect(comment.to_ini).to match(/; My comment/)
100100 end
101101 end
102102
105105 @gen.section('a section')
106106 @gen.comment('My comment')
107107 comment = @gen.document['a section'].lines.to_a.first
108 comment.should be_kind_of(IniParse::Lines::Comment)
109 comment.to_ini.should match(/My comment/)
108 expect(comment).to be_kind_of(IniParse::Lines::Comment)
109 expect(comment.to_ini).to match(/My comment/)
110110 end
111111 end
112112 end
121121 it 'should add a blank line to the document when it is the context' do
122122 @gen.blank
123123 comment = @gen.document.lines.to_a.first
124 comment.should be_kind_of(IniParse::Lines::Blank)
124 expect(comment).to be_kind_of(IniParse::Lines::Blank)
125125 end
126126
127127 it 'should add a blank line to the section when it is the context' do
128128 @gen.section('a section')
129129 @gen.blank
130130 comment = @gen.document['a section'].lines.to_a.first
131 comment.should be_kind_of(IniParse::Lines::Blank)
131 expect(comment).to be_kind_of(IniParse::Lines::Blank)
132132 end
133133 end
134134
4444 end
4545
4646 describe '.open' do
47 before(:each) { File.stub(:read).and_return('[section]') }
47 before(:each) { allow(File).to receive(:read).and_return('[section]') }
4848
4949 it 'should return an IniParse::Document' do
50 IniParse.open('/my/path.ini').should be_kind_of(IniParse::Document)
50 expect(IniParse.open('/my/path.ini')).to be_kind_of(IniParse::Document)
5151 end
5252
5353 it 'should set the path on the returned Document' do
54 IniParse.open('/my/path.ini').path.should == '/my/path.ini'
54 expect(IniParse.open('/my/path.ini').path).to eq('/my/path.ini')
5555 end
5656
5757 it 'should read the file at the given path' do
58 File.should_receive(:read).with('/my/path.ini').and_return('[section]')
58 expect(File).to receive(:read).with('/my/path.ini').and_return('[section]')
5959 IniParse.open('/my/path.ini')
6060 end
6161 end
33 # Shared specs for all Collection types...
44 # ----------------------------------------------------------------------------
55
6 share_examples_for "LineCollection" do
6 shared_examples_for "LineCollection" do
77 before(:each) do
88 @collection << (@c1 = IniParse::Lines::Comment.new)
99 @collection << @i1
1515
1616 describe '#each' do
1717 it 'should remove blanks and comments by default' do
18 @collection.each { |l| l.should be_kind_of(@i1.class) }
18 @collection.each { |l| expect(l).to be_kind_of(@i1.class) }
1919 end
2020
2121 it 'should not remove blanks and comments if true is given' do
2626 arr << line
2727 end
2828
29 arr.should == [@c1, @i1, @i2, @b1, @i3, @b2]
29 expect(arr).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
3030 end
3131 end
3232
3333 describe '#[]' do
3434 it 'should fetch the correct value' do
35 @collection['first'].should == @i1
36 @collection['second'].should == @i2
37 @collection['third'].should == @i3
35 expect(@collection['first']).to eq(@i1)
36 expect(@collection['second']).to eq(@i2)
37 expect(@collection['third']).to eq(@i3)
3838 end
3939
4040 it 'should return nil if the given key does not exist' do
41 @collection['does not exist'].should be_nil
41 expect(@collection['does not exist']).to be_nil
4242 end
4343 end
4444
4545 describe '#[]=' do
4646 it 'should successfully add a new key' do
4747 @collection['fourth'] = @new
48 @collection['fourth'].should == @new
48 expect(@collection['fourth']).to eq(@new)
4949 end
5050
5151 it 'should successfully update an existing key' do
5252 @collection['second'] = @new
53 @collection['second'].should == @new
53 expect(@collection['second']).to eq(@new)
5454
5555 # Make sure the old data is gone.
56 @collection.detect { |s| s.key == 'second' }.should be_nil
56 expect(@collection.detect { |s| s.key == 'second' }).to be_nil
5757 end
5858
5959 it 'should typecast given keys to a string' do
6060 @collection[:a_symbol] = @new
61 @collection['a_symbol'].should == @new
61 expect(@collection['a_symbol']).to eq(@new)
6262 end
6363 end
6464
6565 describe '#<<' do
6666 it 'should set the key correctly if given a new item' do
67 @collection.should_not have_key(@new.key)
67 expect(@collection).not_to have_key(@new.key)
6868 @collection << @new
69 @collection.should have_key(@new.key)
69 expect(@collection).to have_key(@new.key)
7070 end
7171
7272 it 'should append Blank lines' do
7373 @collection << IniParse::Lines::Blank.new
74 @collection.instance_variable_get(:@lines).last.should \
74 expect(@collection.instance_variable_get(:@lines).last).to \
7575 be_kind_of(IniParse::Lines::Blank)
7676 end
7777
7878 it 'should append Comment lines' do
7979 @collection << IniParse::Lines::Comment.new
80 @collection.instance_variable_get(:@lines).last.should \
80 expect(@collection.instance_variable_get(:@lines).last).to \
8181 be_kind_of(IniParse::Lines::Comment)
8282 end
8383
8484 it 'should return self' do
85 (@collection << @new).should == @collection
85 expect(@collection << @new).to eq(@collection)
8686 end
8787 end
8888
8989 describe '#delete' do
9090 it 'should remove the given value and adjust the indicies' do
91 @collection['second'].should_not be_nil
91 expect(@collection['second']).not_to be_nil
9292 @collection.delete('second')
93 @collection['second'].should be_nil
94 @collection['first'].should == @i1
95 @collection['third'].should == @i3
93 expect(@collection['second']).to be_nil
94 expect(@collection['first']).to eq(@i1)
95 expect(@collection['third']).to eq(@i3)
9696 end
9797
9898 it "should do nothing if the supplied key does not exist" do
9999 @collection.delete('does not exist')
100 @collection['first'].should == @i1
101 @collection['third'].should == @i3
100 expect(@collection['first']).to eq(@i1)
101 expect(@collection['third']).to eq(@i3)
102102 end
103103 end
104104
105105 describe '#to_a' do
106106 it 'should return an array' do
107 @collection.to_a.should be_kind_of(Array)
107 expect(@collection.to_a).to be_kind_of(Array)
108108 end
109109
110110 it 'should include all lines' do
111 @collection.to_a.should == [@c1, @i1, @i2, @b1, @i3, @b2]
111 expect(@collection.to_a).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
112112 end
113113
114114 it 'should include references to the same line objects as the collection' do
115115 @collection << @new
116 @collection.to_a.last.object_id.should == @new.object_id
116 expect(@collection.to_a.last.object_id).to eq(@new.object_id)
117117 end
118118 end
119119
120120 describe '#to_hash' do
121121 it 'should return a hash' do
122 @collection.to_hash.should be_kind_of(Hash)
122 expect(@collection.to_hash).to be_kind_of(Hash)
123123 end
124124
125125 it 'should have the correct keys' do
126126 hash = @collection.to_hash
127 hash.keys.length.should == 3
128 hash.should have_key('first')
129 hash.should have_key('second')
130 hash.should have_key('third')
127 expect(hash.keys.length).to eq(3)
128 expect(hash).to have_key('first')
129 expect(hash).to have_key('second')
130 expect(hash).to have_key('third')
131131 end
132132
133133 it 'should have the correct values' do
134134 hash = @collection.to_hash
135 hash['first'].should == @i1
136 hash['second'].should == @i2
137 hash['third'].should == @i3
135 expect(hash['first']).to eq(@i1)
136 expect(hash['second']).to eq(@i2)
137 expect(hash['third']).to eq(@i3)
138138 end
139139 end
140140
141141 describe '#keys' do
142142 it 'should return an array of strings' do
143 @collection.keys.should == ['first', 'second', 'third']
143 expect(@collection.keys).to eq(['first', 'second', 'third'])
144144 end
145145 end
146146 end
162162
163163 describe '#<<' do
164164 it 'should raise a LineNotAllowed exception if a Section is pushed' do
165 lambda { @collection << IniParse::Lines::Section.new('s') }.should \
165 expect { @collection << IniParse::Lines::Section.new('s') }.to \
166166 raise_error(IniParse::LineNotAllowed)
167167 end
168168
173173 @collection << option_one
174174 @collection << option_two
175175
176 @collection['k'].should == [option_one, option_two]
176 expect(@collection['k']).to eq([option_one, option_two])
177177 end
178178 end
179179
181181 it 'should handle duplicates' do
182182 @collection << @i1 << @i2 << @i3
183183 @collection << IniParse::Lines::Option.new('first', 'v5')
184 @collection.keys.should == ['first', 'second', 'third']
184 expect(@collection.keys).to eq(['first', 'second', 'third'])
185 end
186 end
187
188 context 'with duplicate lines' do
189 let(:collection) { IniParse::OptionCollection.new }
190
191 let(:opt_1) { IniParse::Lines::Option.new('my_key', 'value_1') }
192 let(:opt_2) { IniParse::Lines::Option.new('my_key', 'value_2') }
193
194 before do
195 collection << opt_1
196 collection << opt_2
197 end
198
199 it 'yields each item in turn' do
200 expect { |b| collection.each(&b) }.to yield_successive_args(opt_1, opt_2)
185201 end
186202 end
187203 end
201217 it 'should add merge Section with the other, if it is a duplicate' do
202218 new_section = IniParse::Lines::Section.new('first')
203219 @collection << @i1
204 @i1.should_receive(:merge!).with(new_section).once
220 expect(@i1).to receive(:merge!).with(new_section).once
205221 @collection << new_section
206222 end
207223 end
1212 describe "IniParse::Lines::Line module" do
1313 describe '#to_ini' do
1414 it 'should return +line_contents+' do
15 IniParse::Test::FakeLine.new.to_ini.should == 'fake line'
15 expect(IniParse::Test::FakeLine.new.to_ini).to eq('fake line')
1616 end
1717
1818 it 'should preserve line indents' do
19 IniParse::Test::FakeLine.new(
19 expect(IniParse::Test::FakeLine.new(
2020 :indent => ' '
21 ).to_ini.should == ' fake line'
21 ).to_ini).to eq(' fake line')
2222 end
2323
2424 describe 'when a comment is set' do
2525 it 'should correctly include the comment' do
26 IniParse::Test::FakeLine.new(
26 expect(IniParse::Test::FakeLine.new(
2727 :comment => 'comment', :comment_sep => ';', :comment_offset => 10
28 ).to_ini.should == 'fake line ; comment'
28 ).to_ini).to eq('fake line ; comment')
2929 end
3030
3131 it 'should correctly indent the comment' do
32 IniParse::Test::FakeLine.new(
32 expect(IniParse::Test::FakeLine.new(
3333 :comment => 'comment', :comment_sep => ';', :comment_offset => 15
34 ).to_ini.should == 'fake line ; comment'
34 ).to_ini).to eq('fake line ; comment')
3535 end
3636
3737 it 'should use ";" as a default comment seperator' do
38 IniParse::Test::FakeLine.new(
38 expect(IniParse::Test::FakeLine.new(
3939 :comment => 'comment'
40 ).to_ini.should == 'fake line ; comment'
40 ).to_ini).to eq('fake line ; comment')
4141 end
4242
4343 it 'should use the correct seperator' do
44 IniParse::Test::FakeLine.new(
44 expect(IniParse::Test::FakeLine.new(
4545 :comment => 'comment', :comment_sep => '#'
46 ).to_ini.should == 'fake line # comment'
46 ).to_ini).to eq('fake line # comment')
4747 end
4848
4949 it 'should use the ensure a space is added before the comment seperator' do
50 IniParse::Test::FakeLine.new(
50 expect(IniParse::Test::FakeLine.new(
5151 :comment => 'comment', :comment_sep => ';', :comment_offset => 0
52 ).to_ini.should == 'fake line ; comment'
52 ).to_ini).to eq('fake line ; comment')
5353 end
5454
5555 it 'should not add an extra space if the line is blank' do
5757 :comment => 'comment', :comment_sep => ';', :comment_offset => 0
5858 )
5959
60 line.stub(:line_contents).and_return('')
61 line.to_ini.should == '; comment'
60 allow(line).to receive(:line_contents).and_return('')
61 expect(line.to_ini).to eq('; comment')
6262 end
6363 end
6464
6565 describe 'when no comment is set' do
6666 it 'should not add trailing space if :comment_offset has a value' do
67 IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini.should == 'fake line'
67 expect(IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini).to eq('fake line')
6868 end
6969
7070 it 'should not add a comment seperator :comment_sep has a value' do
71 IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini.should == 'fake line'
71 expect(IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini).to eq('fake line')
7272 end
7373 end
7474 end
7575
7676 describe '#has_comment?' do
7777 it 'should return true if :comment has a non-blank value' do
78 IniParse::Test::FakeLine.new(:comment => 'comment').should have_comment
78 expect(IniParse::Test::FakeLine.new(:comment => 'comment')).to have_comment
7979 end
8080
8181 it 'should return true if :comment has a blank value' do
82 IniParse::Test::FakeLine.new(:comment => '').should have_comment
82 expect(IniParse::Test::FakeLine.new(:comment => '')).to have_comment
8383 end
8484
8585 it 'should return false if :comment has a nil value' do
86 IniParse::Test::FakeLine.new.should_not have_comment
87 IniParse::Test::FakeLine.new(:comment => nil).should_not have_comment
86 expect(IniParse::Test::FakeLine.new).not_to have_comment
87 expect(IniParse::Test::FakeLine.new(:comment => nil)).not_to have_comment
8888 end
8989 end
9090 end
9797 before(:each) { @section = IniParse::Lines::Section.new('a section') }
9898
9999 it 'should respond_to +lines+' do
100 @section.should respond_to(:lines)
100 expect(@section).to respond_to(:lines)
101101 end
102102
103103 it 'should not respond_to +lines=+' do
104 @section.should_not respond_to(:lines=)
104 expect(@section).not_to respond_to(:lines=)
105105 end
106106
107107 it 'should include Enumerable' do
108 IniParse::Lines::Section.included_modules.should include(Enumerable)
108 expect(IniParse::Lines::Section.included_modules).to include(Enumerable)
109109 end
110110
111111 describe '#initialize' do
112112 it 'should typecast the given key to a string' do
113 IniParse::Lines::Section.new(:symbol).key.should == 'symbol'
113 expect(IniParse::Lines::Section.new(:symbol).key).to eq('symbol')
114114 end
115115 end
116116
118118 it 'should retrieve the line identified by the given key' do
119119 option = IniParse::Lines::Option.new('k', 'value one')
120120 @section.lines << option
121 @section.option('k').should == option
121 expect(@section.option('k')).to eq(option)
122122 end
123123
124124 it 'should return nil if the given key does not exist' do
125 @section.option('does_not_exist').should be_nil
125 expect(@section.option('does_not_exist')).to be_nil
126126 end
127127 end
128128
129129 describe '#each' do
130130 it 'should call #each on +lines+' do
131 @section.lines.should_receive(:each)
131 expect(@section.lines).to receive(:each)
132132 @section.each { |l| }
133133 end
134134 end
135135
136136 describe '#[]' do
137137 it 'should return nil if the given key does not exist' do
138 @section['k'].should be_nil
138 expect(@section['k']).to be_nil
139139 end
140140
141141 it 'should return a value if the given key exists' do
142142 @section.lines << IniParse::Lines::Option.new('k', 'v')
143 @section['k'].should == 'v'
143 expect(@section['k']).to eq('v')
144144 end
145145
146146 it 'should return an array of values if the key is a duplicate' do
147147 @section.lines << IniParse::Lines::Option.new('k', 'v1')
148148 @section.lines << IniParse::Lines::Option.new('k', 'v2')
149149 @section.lines << IniParse::Lines::Option.new('k', 'v3')
150 @section['k'].should == ['v1', 'v2', 'v3']
150 expect(@section['k']).to eq(['v1', 'v2', 'v3'])
151151 end
152152
153153 it 'should typecast the key to a string' do
154154 @section.lines << IniParse::Lines::Option.new('k', 'v')
155 @section[:k].should == 'v'
155 expect(@section[:k]).to eq('v')
156156 end
157157 end
158158
159159 describe '#[]=' do
160160 it 'should add a new Option with the given key and value' do
161161 @section['k'] = 'a value'
162 @section.option('k').should be_kind_of(IniParse::Lines::Option)
163 @section['k'].should == 'a value'
162 expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
163 expect(@section['k']).to eq('a value')
164164 end
165165
166166 it 'should update the Option if one already exists' do
167167 @section.lines << IniParse::Lines::Option.new('k', 'orig value')
168168 @section['k'] = 'new value'
169 @section['k'].should == 'new value'
169 expect(@section['k']).to eq('new value')
170170 end
171171
172172 it 'should replace the existing Option if it is an array' do
173173 @section.lines << IniParse::Lines::Option.new('k', 'v1')
174174 @section.lines << IniParse::Lines::Option.new('k', 'v2')
175175 @section['k'] = 'new value'
176 @section.option('k').should be_kind_of(IniParse::Lines::Option)
177 @section['k'].should == 'new value'
176 expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
177 expect(@section['k']).to eq('new value')
178178 end
179179
180180 it 'should typecast the key to a string' do
181181 @section[:k] = 'a value'
182 @section['k'].should == 'a value'
182 expect(@section['k']).to eq('a value')
183183 end
184184 end
185185
198198 @new_section.lines << IniParse::Lines::Option.new('d', 'val4')
199199
200200 @section.merge!(@new_section)
201 @section['a'].should == 'val1'
202 @section['b'].should == 'val2'
203 @section['c'].should == 'val3'
204 @section['d'].should == 'val4'
201 expect(@section['a']).to eq('val1')
202 expect(@section['b']).to eq('val2')
203 expect(@section['c']).to eq('val3')
204 expect(@section['d']).to eq('val4')
205205 end
206206
207207 it 'should handle duplicates' do
208208 @new_section.lines << IniParse::Lines::Option.new('a', 'val2')
209209 @section.merge!(@new_section)
210 @section['a'].should == ['val1', 'val2']
210 expect(@section['a']).to eq(['val1', 'val2'])
211211 end
212212
213213 it 'should handle duplicates on both sides' do
216216 @new_section.lines << IniParse::Lines::Option.new('a', 'val4')
217217
218218 @section.merge!(@new_section)
219 @section['a'].should == ['val1', 'val2', 'val3', 'val4']
219 expect(@section['a']).to eq(['val1', 'val2', 'val3', 'val4'])
220220 end
221221
222222 it 'should copy blank lines' do
224224 @section.merge!(@new_section)
225225 line = nil
226226 @section.each(true) { |l| line = l }
227 line.should be_kind_of(IniParse::Lines::Blank)
227 expect(line).to be_kind_of(IniParse::Lines::Blank)
228228 end
229229
230230 it 'should copy comments' do
232232 @section.merge!(@new_section)
233233 line = nil
234234 @section.each(true) { |l| line = l }
235 line.should be_kind_of(IniParse::Lines::Comment)
235 expect(line).to be_kind_of(IniParse::Lines::Comment)
236236 end
237237 end
238238
246246 end
247247
248248 it 'removes the option given a key' do
249 lambda { @section.delete('a') }.
250 should change { @section['a'] }.to(nil)
249 expect { @section.delete('a') }.
250 to change { @section['a'] }.to(nil)
251251 end
252252
253253 it 'removes the option given an Option' do
254 lambda { @section.delete(opt_one) }.
255 should change { @section['a'] }.to(nil)
254 expect { @section.delete(opt_one) }.
255 to change { @section['a'] }.to(nil)
256256 end
257257
258258 it 'should not remove non-matching lines' do
259 lambda { @section.delete('a') }.should_not change { @section['c'] }
259 expect { @section.delete('a') }.not_to change { @section['c'] }
260260 end
261261
262262 it 'returns the section' do
263 @section.delete('a').should eql(@section)
263 expect(@section.delete('a')).to eql(@section)
264264 end
265265 end
266266
267267 describe '#to_ini' do
268268 it 'should include the section key' do
269 IniParse::Lines::Section.new('a section').to_ini.should == '[a section]'
269 expect(IniParse::Lines::Section.new('a section').to_ini).to eq('[a section]')
270270 end
271271
272272 it 'should include lines belonging to the section' do
277277 )
278278 @section.lines << IniParse::Lines::Option.new('b', 'val2')
279279
280 @section.to_ini.should ==
280 expect(@section.to_ini).to eq(
281281 "[a section]\n" \
282282 "a = val1\n" \
283283 "\n" \
284284 "; my comment\n" \
285285 "b = val2"
286 )
286287 end
287288
288289 it 'should include duplicate lines' do
289290 @section.lines << IniParse::Lines::Option.new('a', 'val1')
290291 @section.lines << IniParse::Lines::Option.new('a', 'val2')
291292
292 @section.to_ini.should ==
293 expect(@section.to_ini).to eq(
293294 "[a section]\n" \
294295 "a = val1\n" \
295296 "a = val2"
297 )
296298 end
297299 end
298300
302304 end
303305
304306 it 'should return true if an option with the given key exists' do
305 @section.should have_option('first')
307 expect(@section).to have_option('first')
306308 end
307309
308310 it 'should return true if no option with the given key exists' do
309 @section.should_not have_option('second')
311 expect(@section).not_to have_option('second')
310312 end
311313 end
312314 end
318320 describe 'Iniparse::Lines::Option' do
319321 describe '#initialize' do
320322 it 'should typecast the given key to a string' do
321 IniParse::Lines::Option.new(:symbol, '').key.should == 'symbol'
323 expect(IniParse::Lines::Option.new(:symbol, '').key).to eq('symbol')
322324 end
323325 end
324326
325327 describe '#to_ini' do
326328 it 'should include the key and value' do
327 IniParse::Lines::Option.new('key', 'value').to_ini.should == 'key = value'
329 expect(IniParse::Lines::Option.new('key', 'value').to_ini).to eq('key = value')
328330 end
329331 end
330332
334336 end
335337
336338 it 'should typecast empty values to nil' do
337 parse('key =').should be_option_tuple('key', nil)
338 parse('key = ').should be_option_tuple('key', nil)
339 parse('key = ').should be_option_tuple('key', nil)
339 expect(parse('key =')).to be_option_tuple('key', nil)
340 expect(parse('key = ')).to be_option_tuple('key', nil)
341 expect(parse('key = ')).to be_option_tuple('key', nil)
340342 end
341343
342344 it 'should not typecast "true" if true is part of a word' do
343 parse('key = TestTrueTest').should be_option_tuple('key', 'TestTrueTest')
344 parse('key = TrueTest').should be_option_tuple('key', 'TrueTest')
345 parse('key = TestTrue').should be_option_tuple('key', 'TestTrue')
345 expect(parse('key = TestTrueTest')).to be_option_tuple('key', 'TestTrueTest')
346 expect(parse('key = TrueTest')).to be_option_tuple('key', 'TrueTest')
347 expect(parse('key = TestTrue')).to be_option_tuple('key', 'TestTrue')
346348 end
347349
348350 it 'should not typecast "false" if false is part of a word' do
349 parse('key = TestFalseTest').should be_option_tuple('key', 'TestFalseTest')
350 parse('key = FalseTest').should be_option_tuple('key', 'FalseTest')
351 parse('key = TestFalse').should be_option_tuple('key', 'TestFalse')
351 expect(parse('key = TestFalseTest')).to be_option_tuple('key', 'TestFalseTest')
352 expect(parse('key = FalseTest')).to be_option_tuple('key', 'FalseTest')
353 expect(parse('key = TestFalse')).to be_option_tuple('key', 'TestFalse')
352354 end
353355
354356 it 'should typecast "true" to TrueClass' do
355 parse('key = true').should be_option_tuple('key', true)
356 parse('key = TRUE').should be_option_tuple('key', true)
357 expect(parse('key = true')).to be_option_tuple('key', true)
358 expect(parse('key = TRUE')).to be_option_tuple('key', true)
357359 end
358360
359361 it 'should typecast "false" to FalseClass' do
360 parse('key = false').should be_option_tuple('key', false)
361 parse('key = FALSE').should be_option_tuple('key', false)
362 expect(parse('key = false')).to be_option_tuple('key', false)
363 expect(parse('key = FALSE')).to be_option_tuple('key', false)
362364 end
363365
364366 it 'should typecast integer values to Integer' do
365 parse('key = 1').should be_option_tuple('key', 1)
366 parse('key = 10').should be_option_tuple('key', 10)
367 expect(parse('key = 1')).to be_option_tuple('key', 1)
368 expect(parse('key = 10')).to be_option_tuple('key', 10)
367369 end
368370
369371 it 'should not typecast integers with a leading 0 to Integer' do
370 parse('key = 0700').should be_option_tuple('key', '0700')
372 expect(parse('key = 0700')).to be_option_tuple('key', '0700')
371373 end
372374
373375 it 'should typecast negative integer values to Integer' do
374 parse('key = -1').should be_option_tuple('key', -1)
376 expect(parse('key = -1')).to be_option_tuple('key', -1)
375377 end
376378
377379 it 'should typecast float values to Float' do
378 parse('key = 3.14159265').should be_option_tuple('key', 3.14159265)
380 expect(parse('key = 3.14159265')).to be_option_tuple('key', 3.14159265)
379381 end
380382
381383 it 'should typecast negative float values to Float' do
382 parse('key = -3.14159265').should be_option_tuple('key', -3.14159265)
384 expect(parse('key = -3.14159265')).to be_option_tuple('key', -3.14159265)
383385 end
384386
385387 it 'should typecast scientific notation numbers to Float' do
386 parse('key = 10e5').should be_option_tuple('key', 10e5)
387 parse('key = 10e+5').should be_option_tuple('key', 10e5)
388 parse('key = 10e-5').should be_option_tuple('key', 10e-5)
389
390 parse('key = -10e5').should be_option_tuple('key', -10e5)
391 parse('key = -10e+5').should be_option_tuple('key', -10e5)
392 parse('key = -10e-5').should be_option_tuple('key', -10e-5)
393
394 parse('key = 3.14159265e5').should be_option_tuple('key', 3.14159265e5)
395 parse('key = 3.14159265e+5').should be_option_tuple('key', 3.14159265e5)
396 parse('key = 3.14159265e-5').should be_option_tuple('key', 3.14159265e-5)
397
398 parse('key = -3.14159265e5').should be_option_tuple('key', -3.14159265e5)
399 parse('key = -3.14159265e+5').should be_option_tuple('key', -3.14159265e5)
400 parse('key = -3.14159265e-5').should be_option_tuple('key', -3.14159265e-5)
388 expect(parse('key = 10e5')).to be_option_tuple('key', 10e5)
389 expect(parse('key = 10e+5')).to be_option_tuple('key', 10e5)
390 expect(parse('key = 10e-5')).to be_option_tuple('key', 10e-5)
391
392 expect(parse('key = -10e5')).to be_option_tuple('key', -10e5)
393 expect(parse('key = -10e+5')).to be_option_tuple('key', -10e5)
394 expect(parse('key = -10e-5')).to be_option_tuple('key', -10e-5)
395
396 expect(parse('key = 3.14159265e5')).to be_option_tuple('key', 3.14159265e5)
397 expect(parse('key = 3.14159265e+5')).to be_option_tuple('key', 3.14159265e5)
398 expect(parse('key = 3.14159265e-5')).to be_option_tuple('key', 3.14159265e-5)
399
400 expect(parse('key = -3.14159265e5')).to be_option_tuple('key', -3.14159265e5)
401 expect(parse('key = -3.14159265e+5')).to be_option_tuple('key', -3.14159265e5)
402 expect(parse('key = -3.14159265e-5')).to be_option_tuple('key', -3.14159265e-5)
401403 end
402404 end
403405 end
413415 describe 'IniParse::Lines::Comment' do
414416 describe '#has_comment?' do
415417 it 'should return true if :comment has a non-blank value' do
416 IniParse::Lines::Comment.new(:comment => 'comment').should have_comment
418 expect(IniParse::Lines::Comment.new(:comment => 'comment')).to have_comment
417419 end
418420
419421 it 'should return true if :comment has a blank value' do
420 IniParse::Lines::Comment.new(:comment => '').should have_comment
422 expect(IniParse::Lines::Comment.new(:comment => '')).to have_comment
421423 end
422424
423425 it 'should return true if :comment has a nil value' do
424 IniParse::Lines::Comment.new.should have_comment
425 IniParse::Lines::Comment.new(:comment => nil).should have_comment
426 expect(IniParse::Lines::Comment.new).to have_comment
427 expect(IniParse::Lines::Comment.new(:comment => nil)).to have_comment
426428 end
427429 end
428430
429431 describe '#to_ini' do
430432 it 'should return the comment' do
431 IniParse::Lines::Comment.new(
433 expect(IniParse::Lines::Comment.new(
432434 :comment => 'a comment'
433 ).to_ini.should == '; a comment'
435 ).to_ini).to eq('; a comment')
434436 end
435437
436438 it 'should preserve comment offset' do
437 IniParse::Lines::Comment.new(
439 expect(IniParse::Lines::Comment.new(
438440 :comment => 'a comment', :comment_offset => 10
439 ).to_ini.should == ' ; a comment'
441 ).to_ini).to eq(' ; a comment')
440442 end
441443
442444 it 'should return just the comment_sep if the comment is blank' do
443 IniParse::Lines::Comment.new.to_ini.should == ';'
445 expect(IniParse::Lines::Comment.new.to_ini).to eq(';')
444446 end
445447 end
446448 end
88 end
99
1010 it 'should have a comment as the first line' do
11 @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Comment)
11 expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Comment)
1212 end
1313
1414 it 'should have one section' do
15 @doc.lines.keys.should == ['first_section']
15 expect(@doc.lines.keys).to eq(['first_section'])
1616 end
1717
1818 it 'should have one option belonging to `first_section`' do
19 @doc['first_section']['key'].should == 'value'
19 expect(@doc['first_section']['key']).to eq('value')
2020 end
2121 end
2222
2323 it 'should allow blank lines to preceed the first section' do
24 lambda {
24 expect {
2525 @doc = IniParse::Parser.new(fixture(:blank_before_section)).parse
26 }.should_not raise_error
26 }.not_to raise_error
2727
28 @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
28 expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
2929 end
3030
3131 it 'should allow a blank line to belong to a section' do
32 lambda {
32 expect {
3333 @doc = IniParse::Parser.new(fixture(:blank_in_section)).parse
34 }.should_not raise_error
34 }.not_to raise_error
3535
36 @doc['first_section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
36 expect(@doc['first_section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
3737 end
3838
3939 it 'should permit comments on their own line' do
40 lambda {
40 expect {
4141 @doc = IniParse::Parser.new(fixture(:comment_line)).parse
42 }.should_not raise_error
42 }.not_to raise_error
4343
4444 line = @doc['first_section'].lines.to_a.first
45 line.comment.should eql('; block comment ;')
45 expect(line.comment).to eql('; block comment ;')
4646 end
4747
4848 it 'should permit options before the first section' do
4949 doc = IniParse::Parser.new(fixture(:option_before_section)).parse
5050
51 doc.lines.should have_key('__anonymous__')
52 doc['__anonymous__']['foo'].should eql('bar')
53 doc['foo']['another'].should eql('thing')
51 expect(doc.lines).to have_key('__anonymous__')
52 expect(doc['__anonymous__']['foo']).to eql('bar')
53 expect(doc['foo']['another']).to eql('thing')
5454 end
5555
5656 it 'should raise ParseError if a line could not be parsed' do
57 lambda { IniParse::Parser.new(fixture(:invalid_line)).parse }.should \
57 expect { IniParse::Parser.new(fixture(:invalid_line)).parse }.to \
5858 raise_error(IniParse::ParseError)
5959 end
6060
6464 end
6565
6666 it 'should have two sections' do
67 @doc.lines.to_a.length.should == 2
67 expect(@doc.lines.to_a.length).to eq(2)
6868 end
6969
7070 it 'should have one section' do
71 @doc.lines.keys.should == ['first_section = name',
72 'another_section = a name']
71 expect(@doc.lines.keys).to eq(['first_section = name',
72 'another_section = a name'])
7373 end
7474
7575 it 'should have one option belonging to `first_section = name`' do
76 @doc['first_section = name']['key'].should == 'value'
76 expect(@doc['first_section = name']['key']).to eq('value')
7777 end
7878
7979 it 'should have one option belonging to `another_section = a name`' do
80 @doc['another_section = a name']['another'].should == 'thing'
80 expect(@doc['another_section = a name']['another']).to eq('thing')
8181 end
8282 end
8383
8888
8989 it 'should only add the section once' do
9090 # "first_section" and "second_section".
91 @doc.lines.to_a.length.should == 2
91 expect(@doc.lines.to_a.length).to eq(2)
9292 end
9393
9494 it 'should retain values from the first time' do
95 @doc['first_section']['key'].should == 'value'
95 expect(@doc['first_section']['key']).to eq('value')
9696 end
9797
9898 it 'should add new keys' do
99 @doc['first_section']['third'].should == 'fourth'
99 expect(@doc['first_section']['third']).to eq('fourth')
100100 end
101101
102102 it 'should merge in duplicate keys' do
103 @doc['first_section']['another'].should == %w( thing again )
103 expect(@doc['first_section']['another']).to eq(%w( thing again ))
104104 end
105105 end
106106 end
33
44 describe 'Parsing a line' do
55 it 'should strip leading whitespace and set the :indent option' do
6 IniParse::Parser.parse_line(' [section]').should \
6 expect(IniParse::Parser.parse_line(' [section]')).to \
77 be_section_tuple(:any, {:indent => ' '})
88 end
99
1010 it 'should raise an error if the line could not be matched' do
11 lambda { IniParse::Parser.parse_line('invalid line') }.should \
11 expect { IniParse::Parser.parse_line('invalid line') }.to \
1212 raise_error(IniParse::ParseError)
1313 end
1414
1616 begin
1717 # Remove last type.
1818 type = IniParse::Parser.parse_types.pop
19 type.should_not_receive(:parse)
19 expect(type).not_to receive(:parse)
2020 IniParse::Parser.parse_line('[section]')
2121 ensure
2222 IniParse::Parser.parse_types << type
3535 end
3636
3737 it 'should return an option tuple' do
38 @tuple.should be_option_tuple('k', 'v')
38 expect(@tuple).to be_option_tuple('k', 'v')
3939 end
4040
4141 it 'should set no indent, comment, offset or separator' do
42 @tuple.last[:indent].should be_nil
43 @tuple.last[:comment].should be_nil
44 @tuple.last[:comment_offset].should be_nil
45 @tuple.last[:comment_sep].should be_nil
42 expect(@tuple.last[:indent]).to be_nil
43 expect(@tuple.last[:comment]).to be_nil
44 expect(@tuple.last[:comment_offset]).to be_nil
45 expect(@tuple.last[:comment_sep]).to be_nil
4646 end
4747 end
4848
4949 describe 'with "k = a value with spaces"' do
5050 it 'should return an option tuple' do
51 IniParse::Parser.parse_line('k = a value with spaces').should \
51 expect(IniParse::Parser.parse_line('k = a value with spaces')).to \
5252 be_option_tuple('k', 'a value with spaces')
5353 end
5454 end
5959 end
6060
6161 it 'should return an option tuple' do
62 @tuple.should be_option_tuple('k', 'v')
62 expect(@tuple).to be_option_tuple('k', 'v')
6363 end
6464
6565 it 'should set the comment to "a comment"' do
66 @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
67 end
68
69 it 'should set the comment separator to ";"' do
70 @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
66 expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
67 end
68
69 it 'should set the comment separator to ";"' do
70 expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
7171 end
7272
7373 it 'should set the comment offset to 6' do
74 @tuple.should be_option_tuple(:any, :any, :comment_offset => 6)
74 expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 6)
7575 end
7676 end
7777
8181 end
8282
8383 it 'should return an option tuple with the correct value' do
84 @tuple.should be_option_tuple(:any, 'v;w;x y;z')
84 expect(@tuple).to be_option_tuple(:any, 'v;w;x y;z')
8585 end
8686
8787 it 'should not set a comment' do
88 @tuple.last[:comment].should be_nil
89 @tuple.last[:comment_offset].should be_nil
90 @tuple.last[:comment_sep].should be_nil
88 expect(@tuple.last[:comment]).to be_nil
89 expect(@tuple.last[:comment_offset]).to be_nil
90 expect(@tuple.last[:comment_sep]).to be_nil
9191 end
9292 end
9393
9797 end
9898
9999 it 'should return an option tuple with the correct value' do
100 @tuple.should be_option_tuple(:any, 'v;w')
100 expect(@tuple).to be_option_tuple(:any, 'v;w')
101101 end
102102
103103 it 'should set the comment to "a comment"' do
104 @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
105 end
106
107 it 'should set the comment separator to ";"' do
108 @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
104 expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
105 end
106
107 it 'should set the comment separator to ";"' do
108 expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
109109 end
110110
111111 it 'should set the comment offset to 8' do
112 @tuple.should be_option_tuple(:any, :any, :comment_offset => 8)
112 expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 8)
113113 end
114114 end
115115
116116 describe 'with "key=value"' do
117117 it 'should return an option tuple with the correct key and value' do
118 IniParse::Parser.parse_line('key=value').should \
118 expect(IniParse::Parser.parse_line('key=value')).to \
119119 be_option_tuple('key', 'value')
120120 end
121121 end
122122
123123 describe 'with "key= value"' do
124124 it 'should return an option tuple with the correct key and value' do
125 IniParse::Parser.parse_line('key= value').should \
125 expect(IniParse::Parser.parse_line('key= value')).to \
126126 be_option_tuple('key', 'value')
127127 end
128128 end
129129
130130 describe 'with "key =value"' do
131131 it 'should return an option tuple with the correct key and value' do
132 IniParse::Parser.parse_line('key =value').should \
132 expect(IniParse::Parser.parse_line('key =value')).to \
133133 be_option_tuple('key', 'value')
134134 end
135135 end
136136
137137 describe 'with "key = value"' do
138138 it 'should return an option tuple with the correct key and value' do
139 IniParse::Parser.parse_line('key = value').should \
139 expect(IniParse::Parser.parse_line('key = value')).to \
140140 be_option_tuple('key', 'value')
141141 end
142142 end
143143
144144 describe 'with "key ="' do
145145 it 'should return an option tuple with the correct key' do
146 IniParse::Parser.parse_line('key =').should \
146 expect(IniParse::Parser.parse_line('key =')).to \
147147 be_option_tuple('key')
148148 end
149149
150150 it 'should set the option value to nil' do
151 IniParse::Parser.parse_line('key =').should \
151 expect(IniParse::Parser.parse_line('key =')).to \
152152 be_option_tuple(:any, nil)
153153 end
154154 end
156156
157157 describe 'with "key = EEjDDJJjDJDJD233232=="' do
158158 it 'should include the "equals" in the option value' do
159 IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==').should \
159 expect(IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==')).to \
160160 be_option_tuple('key', 'EEjDDJJjDJDJD233232==')
161161 end
162162 end
163163
164164 describe 'with "key = ==EEjDDJJjDJDJD233232"' do
165165 it 'should include the "equals" in the option value' do
166 IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232').should \
166 expect(IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232')).to \
167167 be_option_tuple('key', '==EEjDDJJjDJDJD233232')
168168 end
169169 end
170170
171171 describe 'with "key.two = value"' do
172172 it 'should return an option tuple with the correct key' do
173 IniParse::Parser.parse_line('key.two = value').should \
173 expect(IniParse::Parser.parse_line('key.two = value')).to \
174174 be_option_tuple('key.two')
175175 end
176176 end
177177
178178 describe 'with "key/with/slashes = value"' do
179179 it 'should return an option tuple with the correct key' do
180 IniParse::Parser.parse_line('key/with/slashes = value').should \
180 expect(IniParse::Parser.parse_line('key/with/slashes = value')).to \
181181 be_option_tuple('key/with/slashes', 'value')
182182 end
183183 end
184184
185185 describe 'with "key_with_underscores = value"' do
186186 it 'should return an option tuple with the correct key' do
187 IniParse::Parser.parse_line('key_with_underscores = value').should \
187 expect(IniParse::Parser.parse_line('key_with_underscores = value')).to \
188188 be_option_tuple('key_with_underscores', 'value')
189189 end
190190 end
191191
192192 describe 'with "key-with-dashes = value"' do
193193 it 'should return an option tuple with the correct key' do
194 IniParse::Parser.parse_line('key-with-dashes = value').should \
194 expect(IniParse::Parser.parse_line('key-with-dashes = value')).to \
195195 be_option_tuple('key-with-dashes', 'value')
196196 end
197197 end
198198
199199 describe 'with "key with spaces = value"' do
200200 it 'should return an option tuple with the correct key' do
201 IniParse::Parser.parse_line('key with spaces = value').should \
201 expect(IniParse::Parser.parse_line('key with spaces = value')).to \
202202 be_option_tuple('key with spaces', 'value')
203203 end
204204 end
215215 end
216216
217217 it 'should return a section tuple' do
218 @tuple.should be_section_tuple('section')
218 expect(@tuple).to be_section_tuple('section')
219219 end
220220
221221 it 'should set no indent, comment, offset or separator' do
222 @tuple.last[:indent].should be_nil
223 @tuple.last[:comment].should be_nil
224 @tuple.last[:comment_offset].should be_nil
225 @tuple.last[:comment_sep].should be_nil
222 expect(@tuple.last[:indent]).to be_nil
223 expect(@tuple.last[:comment]).to be_nil
224 expect(@tuple.last[:comment_offset]).to be_nil
225 expect(@tuple.last[:comment_sep]).to be_nil
226226 end
227227 end
228228
229229 describe 'with "[section with whitespace]"' do
230230 it 'should return a section tuple with the correct key' do
231 IniParse::Parser.parse_line('[section with whitespace]').should \
231 expect(IniParse::Parser.parse_line('[section with whitespace]')).to \
232232 be_section_tuple('section with whitespace')
233233 end
234234 end
235235
236236 describe 'with "[ section with surounding whitespace ]"' do
237237 it 'should return a section tuple with the correct key' do
238 IniParse::Parser.parse_line('[ section with surounding whitespace ]').should \
238 expect(IniParse::Parser.parse_line('[ section with surounding whitespace ]')).to \
239239 be_section_tuple(' section with surounding whitespace ')
240240 end
241241 end
246246 end
247247
248248 it 'should return a section tuple' do
249 @tuple.should be_section_tuple('section')
249 expect(@tuple).to be_section_tuple('section')
250250 end
251251
252252 it 'should set the comment to "a comment"' do
253 @tuple.should be_section_tuple(:any, :comment => 'a comment')
254 end
255
256 it 'should set the comment separator to ";"' do
257 @tuple.should be_section_tuple(:any, :comment_sep => ';')
253 expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
254 end
255
256 it 'should set the comment separator to ";"' do
257 expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
258258 end
259259
260260 it 'should set the comment offset to 10' do
261 @tuple.should be_section_tuple(:any, :comment_offset => 10)
261 expect(@tuple).to be_section_tuple(:any, :comment_offset => 10)
262262 end
263263 end
264264
268268 end
269269
270270 it 'should return a section tuple with the correct key' do
271 @tuple.should be_section_tuple('section;with#comment;chars')
271 expect(@tuple).to be_section_tuple('section;with#comment;chars')
272272 end
273273
274274 it 'should not set a comment' do
275 @tuple.last[:indent].should be_nil
276 @tuple.last[:comment].should be_nil
277 @tuple.last[:comment_offset].should be_nil
278 @tuple.last[:comment_sep].should be_nil
275 expect(@tuple.last[:indent]).to be_nil
276 expect(@tuple.last[:comment]).to be_nil
277 expect(@tuple.last[:comment_offset]).to be_nil
278 expect(@tuple.last[:comment_sep]).to be_nil
279279 end
280280 end
281281
285285 end
286286
287287 it 'should return a section tuple with the correct key' do
288 @tuple.should be_section_tuple('section;with#comment;chars')
288 expect(@tuple).to be_section_tuple('section;with#comment;chars')
289289 end
290290
291291 it 'should set the comment to "a comment"' do
292 @tuple.should be_section_tuple(:any, :comment => 'a comment')
293 end
294
295 it 'should set the comment separator to ";"' do
296 @tuple.should be_section_tuple(:any, :comment_sep => ';')
292 expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
293 end
294
295 it 'should set the comment separator to ";"' do
296 expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
297297 end
298298
299299 it 'should set the comment offset to 29' do
300 @tuple.should be_section_tuple(:any, :comment_offset => 29)
300 expect(@tuple).to be_section_tuple(:any, :comment_offset => 29)
301301 end
302302 end
303303
313313 end
314314
315315 it 'should return a comment tuple with the correct comment' do
316 @tuple.should be_comment_tuple('a comment')
317 end
318
319 it 'should set the comment separator to ";"' do
320 @tuple.should be_comment_tuple(:any, :comment_sep => ';')
316 expect(@tuple).to be_comment_tuple('a comment')
317 end
318
319 it 'should set the comment separator to ";"' do
320 expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
321321 end
322322
323323 it 'should set the comment offset to 0' do
324 @tuple.should be_comment_tuple(:any, :comment_offset => 0)
324 expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
325325 end
326326 end
327327
331331 end
332332
333333 it 'should return a comment tuple with the correct comment' do
334 @tuple.should be_comment_tuple('a comment')
335 end
336
337 it 'should set the comment separator to ";"' do
338 @tuple.should be_comment_tuple(:any, :comment_sep => ';')
334 expect(@tuple).to be_comment_tuple('a comment')
335 end
336
337 it 'should set the comment separator to ";"' do
338 expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
339339 end
340340
341341 it 'should set the comment offset to 1' do
342 @tuple.should be_comment_tuple(:any, :comment_offset => 1)
342 expect(@tuple).to be_comment_tuple(:any, :comment_offset => 1)
343343 end
344344 end
345345
349349 end
350350
351351 it 'should return a comment tuple with an empty value' do
352 @tuple.should be_comment_tuple('')
353 end
354
355 it 'should set the comment separator to ";"' do
356 @tuple.should be_comment_tuple(:any, :comment_sep => ';')
352 expect(@tuple).to be_comment_tuple('')
353 end
354
355 it 'should set the comment separator to ";"' do
356 expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
357357 end
358358
359359 it 'should set the comment offset to 0' do
360 @tuple.should be_comment_tuple(:any, :comment_offset => 0)
360 expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
361361 end
362362 end
363363
369369
370370 describe 'with ""' do
371371 it 'should return a blank tuple' do
372 IniParse::Parser.parse_line('').should be_blank_tuple
372 expect(IniParse::Parser.parse_line('')).to be_blank_tuple
373373 end
374374 end
375375
376376 describe 'with " "' do
377377 it 'should return a blank tuple' do
378 IniParse::Parser.parse_line(' ').should be_blank_tuple
378 expect(IniParse::Parser.parse_line(' ')).to be_blank_tuple
379379 end
380380 end
381381 end
7373 third = fourth
7474 another = again
7575 FIX
76
77 IniParse::Test::Fixtures[:dos_endings] =
78 "[database]\r\n" \
79 "first = true\r\n" \
80 "second = false\r\n"
81
82 # https://github.com/antw/iniparse/issues/17
83 IniParse::Test::Fixtures[:anon_section_with_comments] = <<-FIX.gsub(/^ /, '')
84 #####################
85 # A lot of comments #
86 #####################
87
88 # optiona comment
89 optiona = A
90
91 # optionb comment
92 optionb = B
93
94 # optionc comment
95 optionc = C
96 FIX
2525 "expected #{@expected} but got #{@target.class}"
2626 end
2727
28 def negative_failure_message
28 def failure_message_when_negated
2929 "expected #{@expected} to not be #{@target.class}"
3030 end
3131
6767 "expected #{@expected_type} tuple #{@failure_message}"
6868 end
6969
70 def negative_failure_message
70 def failure_message_when_negated
7171 "expected #{@tuple.inspect} to not be #{@expected_type} tuple"
7272 end
7373
77
88 describe 'An empty array' do
99 it 'should not pass be_section_tuple' do
10 [].should_not be_section_tuple
10 expect([]).not_to be_section_tuple
1111 end
1212
1313 it 'should not pass be_option_tuple' do
14 [].should_not be_option_tuple
14 expect([]).not_to be_option_tuple
1515 end
1616
1717 it 'should not pass be_blank_tuple' do
18 [].should_not be_blank_tuple
18 expect([]).not_to be_blank_tuple
1919 end
2020
2121 it 'should not pass be_comment_tuple' do
22 [].should_not be_comment_tuple
22 expect([]).not_to be_comment_tuple
2323 end
2424 end
2525
3333 before(:all) { @tuple = [:section, "key", {:opt => "val"}] }
3434
3535 it 'should pass be_section_tuple' do
36 @tuple.should be_section_tuple
36 expect(@tuple).to be_section_tuple
3737 end
3838
3939 it 'should pass be_section_tuple("key")' do
40 @tuple.should be_section_tuple("key")
40 expect(@tuple).to be_section_tuple("key")
4141 end
4242
4343 it 'should fail be_section_tuple("invalid")' do
44 @tuple.should_not be_section_tuple("invalid")
44 expect(@tuple).not_to be_section_tuple("invalid")
4545 end
4646
4747 it 'should pass be_section_tuple("key", {:opt => "val"})' do
48 @tuple.should be_section_tuple("key", {:opt => "val"})
48 expect(@tuple).to be_section_tuple("key", {:opt => "val"})
4949 end
5050
5151 it 'should not pass be_section_tuple("key", {:invalid => "val"})' do
52 @tuple.should_not be_section_tuple("key", {:invalid => "val"})
52 expect(@tuple).not_to be_section_tuple("key", {:invalid => "val"})
5353 end
5454
5555 it 'should not pass be_section_tuple("key", {:opt => "invalid"})' do
56 @tuple.should_not be_section_tuple("key", {:opt => "invalid"})
56 expect(@tuple).not_to be_section_tuple("key", {:opt => "invalid"})
5757 end
5858
5959 it 'should fail be_option_tuple' do
60 @tuple.should_not be_option_tuple
60 expect(@tuple).not_to be_option_tuple
6161 end
6262
6363 it 'should fail be_blank_tuple' do
64 @tuple.should_not be_blank_tuple
64 expect(@tuple).not_to be_blank_tuple
6565 end
6666
6767 it 'should fail be_comment_tuple' do
68 @tuple.should_not be_comment_tuple
68 expect(@tuple).not_to be_comment_tuple
6969 end
7070 end
7171
7979 before(:all) { @tuple = [:option, "key", "val", {:opt => "val"}] }
8080
8181 it 'should fail be_section_tuple' do
82 @tuple.should_not be_section_tuple
82 expect(@tuple).not_to be_section_tuple
8383 end
8484
8585 it 'should pass be_option_tuple' do
86 @tuple.should be_option_tuple
86 expect(@tuple).to be_option_tuple
8787 end
8888
8989 it 'should pass be_option_tuple("key")' do
90 @tuple.should be_option_tuple("key")
90 expect(@tuple).to be_option_tuple("key")
9191 end
9292
9393 it 'should fail be_option_tuple("invalid")' do
94 @tuple.should_not be_option_tuple("invalid")
94 expect(@tuple).not_to be_option_tuple("invalid")
9595 end
9696
9797 it 'should pass be_option_tuple("key", "val")' do
98 @tuple.should be_option_tuple("key", "val")
98 expect(@tuple).to be_option_tuple("key", "val")
9999 end
100100
101101 it 'should pass be_option_tuple(:any, "val")' do
102 @tuple.should be_option_tuple(:any, "val")
102 expect(@tuple).to be_option_tuple(:any, "val")
103103 end
104104
105105 it 'should fail be_option_tuple("key", "invalid")' do
106 @tuple.should_not be_option_tuple("key", "invalid")
106 expect(@tuple).not_to be_option_tuple("key", "invalid")
107107 end
108108
109109 it 'should pass be_option_tuple("key", "val", { :opt => "val" })' do
110 @tuple.should be_option_tuple("key", "val", { :opt => "val" })
110 expect(@tuple).to be_option_tuple("key", "val", { :opt => "val" })
111111 end
112112
113113 it 'should fail be_option_tuple("key", "val", { :invalid => "val" })' do
114 @tuple.should_not be_option_tuple("key", "val", { :invalid => "val" })
114 expect(@tuple).not_to be_option_tuple("key", "val", { :invalid => "val" })
115115 end
116116
117117 it 'should fail be_option_tuple("key", "val", { :opt => "invalid" })' do
118 @tuple.should_not be_option_tuple("key", "val", { :opt => "invalid" })
118 expect(@tuple).not_to be_option_tuple("key", "val", { :opt => "invalid" })
119119 end
120120
121121 it 'should fail be_blank_tuple' do
122 @tuple.should_not be_blank_tuple
122 expect(@tuple).not_to be_blank_tuple
123123 end
124124
125125 it 'should fail be_comment_tuple' do
126 @tuple.should_not be_comment_tuple
126 expect(@tuple).not_to be_comment_tuple
127127 end
128128 end
129129
137137 before(:all) { @tuple = [:blank] }
138138
139139 it 'should fail be_section_tuple' do
140 @tuple.should_not be_section_tuple
140 expect(@tuple).not_to be_section_tuple
141141 end
142142
143143 it 'should fail be_option_tuple' do
144 @tuple.should_not be_option_tuple
144 expect(@tuple).not_to be_option_tuple
145145 end
146146
147147 it 'should pass be_blank_tuple' do
148 @tuple.should be_blank_tuple
148 expect(@tuple).to be_blank_tuple
149149 end
150150
151151 it 'should fail be_comment_tuple' do
152 @tuple.should_not be_comment_tuple
152 expect(@tuple).not_to be_comment_tuple
153153 end
154154 end
155155
163163 before(:all) { @tuple = [:comment, "A comment", {:opt => "val"}] }
164164
165165 it 'should fail be_section_tuple' do
166 @tuple.should_not be_section_tuple
166 expect(@tuple).not_to be_section_tuple
167167 end
168168
169169 it 'should fail be_option_tuple' do
170 @tuple.should_not be_option_tuple
170 expect(@tuple).not_to be_option_tuple
171171 end
172172
173173 it 'should fail be_blank_tuple' do
174 @tuple.should_not be_blank_tuple
174 expect(@tuple).not_to be_blank_tuple
175175 end
176176
177177 it 'should pass be_comment_tuple' do
178 @tuple.should be_comment_tuple
178 expect(@tuple).to be_comment_tuple
179179 end
180180
181181 it 'should pass be_comment_tuple("A comment")' do
182 @tuple.should be_comment_tuple("A comment")
182 expect(@tuple).to be_comment_tuple("A comment")
183183 end
184184
185185 it 'should fail be_comment_tuple("Invalid")' do
186 @tuple.should_not be_comment_tuple("Invalid")
186 expect(@tuple).not_to be_comment_tuple("Invalid")
187187 end
188188
189189 it 'should pass be_comment_tuple("A comment", {:opt => "val"})' do
190 @tuple.should be_comment_tuple("A comment", {:opt => "val"})
190 expect(@tuple).to be_comment_tuple("A comment", {:opt => "val"})
191191 end
192192
193193 it 'should fail be_comment_tuple("A comment", {:invalid => "val"})' do
194 @tuple.should_not be_comment_tuple("A comment", {:invalid => "val"})
194 expect(@tuple).not_to be_comment_tuple("A comment", {:invalid => "val"})
195195 end
196196
197197 it 'should fail be_comment_tuple("A comment", {:opt => "invalid"})' do
198 @tuple.should_not be_comment_tuple("A comment", {:opt => "invalid"})
199 end
200 end
198 expect(@tuple).not_to be_comment_tuple("A comment", {:opt => "invalid"})
199 end
200 end