puppet 3.5.0.rc3 → 3.5.1.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/lib/puppet.rb +11 -2
- data/lib/puppet/defaults.rb +3 -2
- data/lib/puppet/environments.rb +16 -0
- data/lib/puppet/network/http/api/v1.rb +6 -2
- data/lib/puppet/network/http/issues.rb +1 -0
- data/lib/puppet/node/environment.rb +9 -5
- data/lib/puppet/pops/parser/interpolation_support.rb +8 -4
- data/lib/puppet/provider/yumrepo/inifile.rb +60 -20
- data/lib/puppet/test/test_helper.rb +1 -8
- data/lib/puppet/type/yumrepo.rb +43 -9
- data/lib/puppet/util/inifile.rb +209 -86
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/application/apply_spec.rb +3 -1
- data/spec/integration/directory_environments_spec.rb +2 -1
- data/spec/integration/indirector/file_content/file_server_spec.rb +1 -1
- data/spec/integration/node/environment_spec.rb +2 -2
- data/spec/integration/resource/type_collection_spec.rb +1 -1
- data/spec/unit/application/apply_spec.rb +1 -1
- data/spec/unit/environments_spec.rb +35 -36
- data/spec/unit/face/module/install_spec.rb +1 -1
- data/spec/unit/face/module/list_spec.rb +3 -3
- data/spec/unit/face/module/uninstall_spec.rb +1 -1
- data/spec/unit/face/parser_spec.rb +1 -1
- data/spec/unit/indirector/node/active_record_spec.rb +1 -1
- data/spec/unit/indirector/node/ldap_spec.rb +4 -4
- data/spec/unit/indirector/node/plain_spec.rb +1 -1
- data/spec/unit/indirector/request_spec.rb +3 -3
- data/spec/unit/module_spec.rb +6 -6
- data/spec/unit/module_tool/applications/installer_spec.rb +1 -1
- data/spec/unit/module_tool/applications/uninstaller_spec.rb +1 -1
- data/spec/unit/module_tool_spec.rb +1 -1
- data/spec/unit/network/http/api/v1_spec.rb +11 -1
- data/spec/unit/network/http/api/v2/environments_spec.rb +1 -1
- data/spec/unit/node/environment_spec.rb +1 -1
- data/spec/unit/node_spec.rb +1 -1
- data/spec/unit/parser/ast/collection_spec.rb +1 -1
- data/spec/unit/parser/compiler_spec.rb +1 -1
- data/spec/unit/parser/files_spec.rb +2 -2
- data/spec/unit/parser/functions_spec.rb +2 -2
- data/spec/unit/parser/parser_spec.rb +2 -2
- data/spec/unit/parser/resource_spec.rb +1 -1
- data/spec/unit/parser/scope_spec.rb +3 -3
- data/spec/unit/pops/parser/lexer2_spec.rb +11 -0
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +15 -1
- data/spec/unit/provider/yumrepo/inifile_spec.rb +71 -23
- data/spec/unit/rails/host_spec.rb +1 -1
- data/spec/unit/resource/type_collection_spec.rb +1 -1
- data/spec/unit/resource/type_spec.rb +1 -1
- data/spec/unit/resource_spec.rb +1 -1
- data/spec/unit/type/yumrepo_spec.rb +214 -49
- data/spec/unit/util/autoload_spec.rb +1 -1
- data/spec/unit/util/inifile_spec.rb +492 -0
- data/spec/unit/util/rdoc/parser_spec.rb +2 -2
- metadata +3009 -3030
@@ -24,7 +24,7 @@ describe Puppet::Util::Autoload do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should collect all of the lib directories that exist in the current environment's module path" do
|
27
|
-
environment = Puppet::Node::Environment.create(:foo, [@dira, @dirb, @dirc]
|
27
|
+
environment = Puppet::Node::Environment.create(:foo, [@dira, @dirb, @dirc])
|
28
28
|
Dir.expects(:entries).with(@dira).returns %w{. .. one two}
|
29
29
|
Dir.expects(:entries).with(@dirb).returns %w{. .. one two}
|
30
30
|
|
@@ -0,0 +1,492 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/util/inifile'
|
3
|
+
|
4
|
+
describe Puppet::Util::IniConfig::Section do
|
5
|
+
|
6
|
+
subject { described_class.new('testsection', '/some/imaginary/file') }
|
7
|
+
|
8
|
+
describe "determining if the section is dirty" do
|
9
|
+
it "is not dirty on creation" do
|
10
|
+
expect(subject).to_not be_dirty
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is dirty if a key is changed" do
|
14
|
+
subject['hello'] = 'world'
|
15
|
+
expect(subject).to be_dirty
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is dirty if the section has been explicitly marked as dirty" do
|
19
|
+
subject.mark_dirty
|
20
|
+
expect(subject).to be_dirty
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is dirty if the section is marked for deletion" do
|
24
|
+
subject.destroy = true
|
25
|
+
expect(subject).to be_dirty
|
26
|
+
end
|
27
|
+
|
28
|
+
it "is clean if the section has been explicitly marked as clean" do
|
29
|
+
subject['hello'] = 'world'
|
30
|
+
subject.mark_clean
|
31
|
+
expect(subject).to_not be_dirty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "reading an entry" do
|
36
|
+
it "returns nil if the key is not present" do
|
37
|
+
expect(subject['hello']).to be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the value if the key is specified" do
|
41
|
+
subject.entries << ['hello', 'world']
|
42
|
+
expect(subject['hello']).to eq 'world'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "ignores comments when looking for a match" do
|
46
|
+
subject.entries << '#this = comment'
|
47
|
+
expect(subject['#this']).to be_nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "formatting the section" do
|
52
|
+
it "prefixes the output with the section header" do
|
53
|
+
expect(subject.format).to eq "[testsection]\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "restores comments and blank lines" do
|
57
|
+
subject.entries << "#comment\n"
|
58
|
+
subject.entries << " "
|
59
|
+
expect(subject.format).to eq(
|
60
|
+
"[testsection]\n" +
|
61
|
+
"#comment\n" +
|
62
|
+
" "
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "adds all keys that have values" do
|
67
|
+
subject.entries << ['somekey', 'somevalue']
|
68
|
+
expect(subject.format).to eq("[testsection]\nsomekey=somevalue\n")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "excludes keys that have a value of nil" do
|
72
|
+
subject.entries << ['empty', nil]
|
73
|
+
expect(subject.format).to eq("[testsection]\n")
|
74
|
+
end
|
75
|
+
|
76
|
+
it "preserves the order of the section" do
|
77
|
+
subject.entries << ['firstkey', 'firstval']
|
78
|
+
subject.entries << "# I am a comment, hear me roar\n"
|
79
|
+
subject.entries << ['secondkey', 'secondval']
|
80
|
+
|
81
|
+
expect(subject.format).to eq(
|
82
|
+
"[testsection]\n" +
|
83
|
+
"firstkey=firstval\n" +
|
84
|
+
"# I am a comment, hear me roar\n" +
|
85
|
+
"secondkey=secondval\n"
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "is empty if the section is marked for deletion" do
|
90
|
+
subject.entries << ['firstkey', 'firstval']
|
91
|
+
subject.destroy = true
|
92
|
+
expect(subject.format).to eq('')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe Puppet::Util::IniConfig::PhysicalFile do
|
98
|
+
subject { described_class.new('/some/nonexistent/file') }
|
99
|
+
|
100
|
+
let(:first_sect) do
|
101
|
+
sect = Puppet::Util::IniConfig::Section.new('firstsection', '/some/imaginary/file')
|
102
|
+
sect.entries << "# comment\n" << ['onefish', 'redfish'] << "\n"
|
103
|
+
sect
|
104
|
+
end
|
105
|
+
|
106
|
+
let(:second_sect) do
|
107
|
+
sect = Puppet::Util::IniConfig::Section.new('secondsection', '/some/imaginary/file')
|
108
|
+
sect.entries << ['twofish', 'bluefish']
|
109
|
+
sect
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "when reading a file" do
|
113
|
+
it "raises an error if the file does not exist" do
|
114
|
+
subject.filetype.stubs(:read)
|
115
|
+
expect {
|
116
|
+
subject.read
|
117
|
+
}.to raise_error(%r[Cannot read nonexistent file .*/some/nonexistent/file])
|
118
|
+
end
|
119
|
+
|
120
|
+
it "passes the contents of the file to #parse" do
|
121
|
+
subject.filetype.stubs(:read).returns "[section]"
|
122
|
+
subject.expects(:parse).with("[section]")
|
123
|
+
|
124
|
+
subject.read
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "when parsing a file" do
|
130
|
+
describe "parsing sections" do
|
131
|
+
it "creates new sections the first time that the section is found" do
|
132
|
+
text = "[mysect]\n"
|
133
|
+
|
134
|
+
subject.parse(text)
|
135
|
+
|
136
|
+
expect(subject.contents).to have(1).items
|
137
|
+
sect = subject.contents[0]
|
138
|
+
expect(sect.name).to eq "mysect"
|
139
|
+
end
|
140
|
+
|
141
|
+
it "raises an error if a section is redefined in the file" do
|
142
|
+
text = "[mysect]\n[mysect]\n"
|
143
|
+
|
144
|
+
expect {
|
145
|
+
subject.parse(text)
|
146
|
+
}.to raise_error(Puppet::Util::IniConfig::IniParseError,
|
147
|
+
/Section "mysect" is already defined, cannot redefine/)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "raises an error if a section is redefined in the file collection" do
|
151
|
+
subject.file_collection = stub('file collection', :get_section => true)
|
152
|
+
text = "[mysect]\n[mysect]\n"
|
153
|
+
|
154
|
+
expect {
|
155
|
+
subject.parse(text)
|
156
|
+
}.to raise_error(Puppet::Util::IniConfig::IniParseError,
|
157
|
+
/Section "mysect" is already defined, cannot redefine/)
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "parsing properties" do
|
163
|
+
it "raises an error if the property is not within a section" do
|
164
|
+
text = "key=val\n"
|
165
|
+
|
166
|
+
expect {
|
167
|
+
subject.parse(text)
|
168
|
+
}.to raise_error(Puppet::Util::IniConfig::IniParseError,
|
169
|
+
/Property with key "key" outside of a section/)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "adds the property to the current section" do
|
173
|
+
text = "[main]\nkey=val\n"
|
174
|
+
|
175
|
+
subject.parse(text)
|
176
|
+
expect(subject.contents).to have(1).items
|
177
|
+
sect = subject.contents[0]
|
178
|
+
expect(sect['key']).to eq "val"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "parsing line continuations" do
|
183
|
+
|
184
|
+
it "adds the continued line to the last parsed property" do
|
185
|
+
text = "[main]\nkey=val\n moreval"
|
186
|
+
|
187
|
+
subject.parse(text)
|
188
|
+
expect(subject.contents).to have(1).items
|
189
|
+
sect = subject.contents[0]
|
190
|
+
expect(sect['key']).to eq "val\n moreval"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "parsing comments and whitespace" do
|
195
|
+
it "treats # as a comment leader" do
|
196
|
+
text = "# octothorpe comment"
|
197
|
+
|
198
|
+
subject.parse(text)
|
199
|
+
expect(subject.contents).to eq ["# octothorpe comment"]
|
200
|
+
end
|
201
|
+
|
202
|
+
it "treats ; as a comment leader" do
|
203
|
+
text = "; semicolon comment"
|
204
|
+
|
205
|
+
subject.parse(text)
|
206
|
+
expect(subject.contents).to eq ["; semicolon comment"]
|
207
|
+
end
|
208
|
+
|
209
|
+
it "treates 'rem' as a comment leader" do
|
210
|
+
text = "rem rapid eye movement comment"
|
211
|
+
|
212
|
+
subject.parse(text)
|
213
|
+
expect(subject.contents).to eq ["rem rapid eye movement comment"]
|
214
|
+
end
|
215
|
+
|
216
|
+
it "stores comments and whitespace in a section in the correct section" do
|
217
|
+
text = "[main]\n; main section comment"
|
218
|
+
|
219
|
+
subject.parse(text)
|
220
|
+
|
221
|
+
sect = subject.get_section("main")
|
222
|
+
expect(sect.entries).to eq ["; main section comment"]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
it "can return all sections" do
|
228
|
+
text = "[first]\n" +
|
229
|
+
"; comment\n" +
|
230
|
+
"[second]\n" +
|
231
|
+
"key=value"
|
232
|
+
|
233
|
+
subject.parse(text)
|
234
|
+
|
235
|
+
sections = subject.sections
|
236
|
+
expect(sections).to have(2).items
|
237
|
+
expect(sections[0].name).to eq "first"
|
238
|
+
expect(sections[1].name).to eq "second"
|
239
|
+
end
|
240
|
+
|
241
|
+
it "can retrieve a specific section" do
|
242
|
+
text = "[first]\n" +
|
243
|
+
"; comment\n" +
|
244
|
+
"[second]\n" +
|
245
|
+
"key=value"
|
246
|
+
|
247
|
+
subject.parse(text)
|
248
|
+
|
249
|
+
section = subject.get_section("second")
|
250
|
+
expect(section.name).to eq "second"
|
251
|
+
expect(section["key"]).to eq "value"
|
252
|
+
end
|
253
|
+
|
254
|
+
describe "formatting" do
|
255
|
+
|
256
|
+
it "concatenates each formatted section in order" do
|
257
|
+
subject.contents << first_sect << second_sect
|
258
|
+
|
259
|
+
expected = "[firstsection]\n" +
|
260
|
+
"# comment\n" +
|
261
|
+
"onefish=redfish\n" +
|
262
|
+
"\n" +
|
263
|
+
"[secondsection]\n" +
|
264
|
+
"twofish=bluefish\n"
|
265
|
+
|
266
|
+
expect(subject.format).to eq expected
|
267
|
+
end
|
268
|
+
|
269
|
+
it "includes comments that are not within a section" do
|
270
|
+
subject.contents << "# This comment is not in a section\n" << first_sect << second_sect
|
271
|
+
|
272
|
+
expected = "# This comment is not in a section\n" +
|
273
|
+
"[firstsection]\n" +
|
274
|
+
"# comment\n" +
|
275
|
+
"onefish=redfish\n" +
|
276
|
+
"\n" +
|
277
|
+
"[secondsection]\n" +
|
278
|
+
"twofish=bluefish\n"
|
279
|
+
|
280
|
+
expect(subject.format).to eq expected
|
281
|
+
end
|
282
|
+
|
283
|
+
it "excludes sections that are marked to be destroyed" do
|
284
|
+
subject.contents << first_sect << second_sect
|
285
|
+
first_sect.destroy = true
|
286
|
+
|
287
|
+
expected = "[secondsection]\n" + "twofish=bluefish\n"
|
288
|
+
|
289
|
+
expect(subject.format).to eq expected
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "storing the file" do
|
294
|
+
describe "with empty contents" do
|
295
|
+
describe "and destroy_empty is true" do
|
296
|
+
before { subject.destroy_empty = true }
|
297
|
+
it "removes the file if there are no sections" do
|
298
|
+
File.expects(:unlink)
|
299
|
+
subject.store
|
300
|
+
end
|
301
|
+
|
302
|
+
it "removes the file if all sections are marked to be destroyed" do
|
303
|
+
subject.contents << first_sect << second_sect
|
304
|
+
first_sect.destroy = true
|
305
|
+
second_sect.destroy = true
|
306
|
+
|
307
|
+
File.expects(:unlink)
|
308
|
+
subject.store
|
309
|
+
end
|
310
|
+
|
311
|
+
it "doesn't remove the file if not all sections are marked to be destroyed" do
|
312
|
+
subject.contents << first_sect << second_sect
|
313
|
+
first_sect.destroy = true
|
314
|
+
second_sect.destroy = false
|
315
|
+
|
316
|
+
File.expects(:unlink).never
|
317
|
+
subject.filetype.stubs(:write)
|
318
|
+
subject.store
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
it "rewrites the file if destroy_empty is false" do
|
323
|
+
subject.contents << first_sect << second_sect
|
324
|
+
first_sect.destroy = true
|
325
|
+
second_sect.destroy = true
|
326
|
+
|
327
|
+
File.expects(:unlink).never
|
328
|
+
subject.stubs(:format).returns "formatted"
|
329
|
+
subject.filetype.expects(:write).with("formatted")
|
330
|
+
subject.store
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
it "rewrites the file if any section is dirty" do
|
335
|
+
subject.contents << first_sect << second_sect
|
336
|
+
first_sect.mark_dirty
|
337
|
+
second_sect.mark_clean
|
338
|
+
|
339
|
+
subject.stubs(:format).returns "formatted"
|
340
|
+
subject.filetype.expects(:write).with("formatted")
|
341
|
+
subject.store
|
342
|
+
end
|
343
|
+
|
344
|
+
it "doesn't modify the file if all sections are clean" do
|
345
|
+
subject.contents << first_sect << second_sect
|
346
|
+
first_sect.mark_clean
|
347
|
+
second_sect.mark_clean
|
348
|
+
|
349
|
+
subject.stubs(:format).returns "formatted"
|
350
|
+
subject.filetype.expects(:write).never
|
351
|
+
subject.store
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe Puppet::Util::IniConfig::FileCollection do
|
357
|
+
|
358
|
+
let(:path_a) { '/some/nonexistent/file/a' }
|
359
|
+
let(:path_b) { '/some/nonexistent/file/b' }
|
360
|
+
|
361
|
+
let(:file_a) { Puppet::Util::IniConfig::PhysicalFile.new(path_a) }
|
362
|
+
let(:file_b) { Puppet::Util::IniConfig::PhysicalFile.new(path_b) }
|
363
|
+
|
364
|
+
let(:sect_a1) { Puppet::Util::IniConfig::Section.new('sect_a1', path_a) }
|
365
|
+
let(:sect_a2) { Puppet::Util::IniConfig::Section.new('sect_a2', path_a) }
|
366
|
+
|
367
|
+
let(:sect_b1) { Puppet::Util::IniConfig::Section.new('sect_b1', path_b) }
|
368
|
+
let(:sect_b2) { Puppet::Util::IniConfig::Section.new('sect_b2', path_b) }
|
369
|
+
|
370
|
+
before do
|
371
|
+
file_a.contents << sect_a1 << sect_a2
|
372
|
+
file_b.contents << sect_b1 << sect_b2
|
373
|
+
end
|
374
|
+
|
375
|
+
describe "reading a file" do
|
376
|
+
let(:stub_file) { stub('Physical file') }
|
377
|
+
|
378
|
+
it "creates a new PhysicalFile and uses that to read the file" do
|
379
|
+
stub_file.expects(:read)
|
380
|
+
stub_file.expects(:file_collection=)
|
381
|
+
Puppet::Util::IniConfig::PhysicalFile.expects(:new).with(path_a).returns stub_file
|
382
|
+
|
383
|
+
subject.read(path_a)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "stores the PhysicalFile and the path to the file" do
|
387
|
+
stub_file.stubs(:read)
|
388
|
+
stub_file.stubs(:file_collection=)
|
389
|
+
Puppet::Util::IniConfig::PhysicalFile.stubs(:new).with(path_a).returns stub_file
|
390
|
+
subject.read(path_a)
|
391
|
+
|
392
|
+
path, physical_file = subject.files.first
|
393
|
+
|
394
|
+
expect(path).to eq(path_a)
|
395
|
+
expect(physical_file).to eq stub_file
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
describe "storing all files" do
|
400
|
+
before do
|
401
|
+
subject.files[path_a] = file_a
|
402
|
+
subject.files[path_b] = file_b
|
403
|
+
end
|
404
|
+
|
405
|
+
it "stores all files in the collection" do
|
406
|
+
file_a.expects(:store).once
|
407
|
+
file_b.expects(:store).once
|
408
|
+
|
409
|
+
subject.store
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
describe "iterating over sections" do
|
414
|
+
before do
|
415
|
+
subject.files[path_a] = file_a
|
416
|
+
subject.files[path_b] = file_b
|
417
|
+
end
|
418
|
+
|
419
|
+
it "yields every section from every file" do
|
420
|
+
[sect_a1, sect_a2, sect_b1, sect_b2].each do |sect|
|
421
|
+
sect.expects(:touch).once
|
422
|
+
end
|
423
|
+
|
424
|
+
subject.each_section do |sect|
|
425
|
+
sect.touch
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
describe "iterating over files" do
|
431
|
+
before do
|
432
|
+
subject.files[path_a] = file_a
|
433
|
+
subject.files[path_b] = file_b
|
434
|
+
end
|
435
|
+
|
436
|
+
it "yields the path to every file in the collection" do
|
437
|
+
seen = []
|
438
|
+
subject.each_file do |file|
|
439
|
+
seen << file
|
440
|
+
end
|
441
|
+
|
442
|
+
expect(seen).to include(path_a)
|
443
|
+
expect(seen).to include(path_b)
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe "retrieving a specific section" do
|
448
|
+
before do
|
449
|
+
subject.files[path_a] = file_a
|
450
|
+
subject.files[path_b] = file_b
|
451
|
+
end
|
452
|
+
|
453
|
+
it "retrieves the first section defined" do
|
454
|
+
expect(subject.get_section('sect_b1')).to eq sect_b1
|
455
|
+
end
|
456
|
+
|
457
|
+
it "returns nil if there was no section with the given name" do
|
458
|
+
expect(subject.get_section('nope')).to be_nil
|
459
|
+
end
|
460
|
+
|
461
|
+
it "allows #[] to be used as an alias to #get_section" do
|
462
|
+
expect(subject['b2']).to eq subject.get_section('b2')
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
describe "checking if a section has been defined" do
|
467
|
+
before do
|
468
|
+
subject.files[path_a] = file_a
|
469
|
+
subject.files[path_b] = file_b
|
470
|
+
end
|
471
|
+
|
472
|
+
it "is true if a section with the given name is defined" do
|
473
|
+
expect(subject.include?('sect_a1')).to be_true
|
474
|
+
end
|
475
|
+
|
476
|
+
it "is false if a section with the given name can't be found" do
|
477
|
+
expect(subject.include?('nonexistent')).to be_false
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
describe "adding a new section" do
|
482
|
+
before do
|
483
|
+
subject.files[path_a] = file_a
|
484
|
+
subject.files[path_b] = file_b
|
485
|
+
end
|
486
|
+
|
487
|
+
it "adds the section to the appropriate file" do
|
488
|
+
file_a.expects(:add_section).with('newsect')
|
489
|
+
subject.add_section('newsect', path_a)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|