hosts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/.gitignore +12 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/.yardopts +5 -0
- data/Gemfile +23 -0
- data/HISTORY.md +6 -0
- data/LICENSE.md +15 -0
- data/README.md +347 -0
- data/Rakefile +48 -0
- data/hosts.gemspec +57 -0
- data/lib/aef/hosts.rb +51 -0
- data/lib/aef/hosts/comment.rb +73 -0
- data/lib/aef/hosts/element.rb +108 -0
- data/lib/aef/hosts/empty_element.rb +50 -0
- data/lib/aef/hosts/entry.rb +123 -0
- data/lib/aef/hosts/file.rb +252 -0
- data/lib/aef/hosts/helpers.rb +121 -0
- data/lib/aef/hosts/section.rb +141 -0
- data/lib/aef/hosts/version.rb +29 -0
- data/lib/hosts.rb +25 -0
- data/lib/hosts/bare.rb +23 -0
- data/spec/aef/hosts/comment_spec.rb +136 -0
- data/spec/aef/hosts/element_spec.rb +12 -0
- data/spec/aef/hosts/empty_element_spec.rb +96 -0
- data/spec/aef/hosts/entry_spec.rb +252 -0
- data/spec/aef/hosts/file_spec.rb +290 -0
- data/spec/aef/hosts/helpers_spec.rb +103 -0
- data/spec/aef/hosts/section_spec.rb +299 -0
- data/spec/fixtures/linux_hosts +21 -0
- data/spec/fixtures/windows_hosts +14 -0
- data/spec/integration/integration_spec.rb +384 -0
- data/spec/spec_helper.rb +47 -0
- metadata +202 -0
- metadata.gz.sig +4 -0
@@ -0,0 +1,290 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'spec_helper'
|
21
|
+
|
22
|
+
describe Aef::Hosts::File do
|
23
|
+
let(:hosts_file) { fixtures_dir + 'linux_hosts' }
|
24
|
+
let(:file) { described_class.new }
|
25
|
+
|
26
|
+
describe "path attribute" do
|
27
|
+
it "should exist" do
|
28
|
+
file.should respond_to(:path)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be nil by default" do
|
32
|
+
file.path.should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be settable" do
|
36
|
+
file.should respond_to(:path=)
|
37
|
+
|
38
|
+
file.path = Pathname.pwd
|
39
|
+
|
40
|
+
file.path.should == Pathname.pwd
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should automatically convert strings to Pathname objects when set" do
|
44
|
+
file.path = Dir.pwd
|
45
|
+
|
46
|
+
file.path.should == Pathname.pwd
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be settable through the constructor" do
|
50
|
+
file = Aef::Hosts::File.new(Pathname.pwd)
|
51
|
+
|
52
|
+
file.path.should == Pathname.pwd
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "reading from file" do
|
57
|
+
before(:each) do
|
58
|
+
file.path = hosts_file
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be possible through the .read method" do
|
62
|
+
file = Aef::Hosts::File.read(hosts_file)
|
63
|
+
|
64
|
+
file.elements.should_not be_empty
|
65
|
+
file.path.should eql Pathname.new(hosts_file)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should be possible through the #read method" do
|
69
|
+
file.should respond_to(:read)
|
70
|
+
|
71
|
+
expect {
|
72
|
+
file.read.should == file
|
73
|
+
}.to change{ file.elements.length }
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should allow the path attribute to be temporarily overridden" do
|
77
|
+
file.path = nil
|
78
|
+
|
79
|
+
return_value = file.read(hosts_file)
|
80
|
+
return_value.should == file
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "parsing" do
|
85
|
+
before(:each) do
|
86
|
+
file.path = hosts_file
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should be possible through the .parse method" do
|
90
|
+
file = Aef::Hosts::File.parse(hosts_file.read)
|
91
|
+
|
92
|
+
file.elements.should_not be_empty
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be possible through the #parse method" do
|
96
|
+
file.should respond_to(:parse)
|
97
|
+
|
98
|
+
expect {
|
99
|
+
file.parse(hosts_file.read).should == file
|
100
|
+
}.to change{ file.elements.length }
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be able to parse an empty element" do
|
104
|
+
file.parse(<<-HOSTS)
|
105
|
+
|
106
|
+
HOSTS
|
107
|
+
|
108
|
+
file.elements.should have(1).item
|
109
|
+
file.elements.first.should be_a(Aef::Hosts::EmptyElement)
|
110
|
+
file.elements.first.cache_filled?.should be_true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should be able to parse a comment" do
|
114
|
+
file.parse(<<-HOSTS)
|
115
|
+
# test
|
116
|
+
HOSTS
|
117
|
+
|
118
|
+
file.elements.should have(1).item
|
119
|
+
element = file.elements.first
|
120
|
+
element.should be_a(Aef::Hosts::Comment)
|
121
|
+
element.cache_filled?.should be_true
|
122
|
+
element.comment.should eql ' test'
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should be able to parse an entry" do
|
126
|
+
file.parse(<<-HOSTS)
|
127
|
+
10.23.5.17 myhost myhost.mydomain altname # entry
|
128
|
+
HOSTS
|
129
|
+
|
130
|
+
file.elements.should have(1).item
|
131
|
+
element = file.elements.first
|
132
|
+
element.should be_a(Aef::Hosts::Entry)
|
133
|
+
element.cache_filled?.should be_true
|
134
|
+
element.address.should eql '10.23.5.17'
|
135
|
+
element.name.should eql 'myhost'
|
136
|
+
element.aliases.should eql ['myhost.mydomain', 'altname']
|
137
|
+
element.comment.should eql ' entry'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should be able to parse a section" do
|
141
|
+
file.parse(<<-HOSTS)
|
142
|
+
# -----BEGIN SECTION test-----
|
143
|
+
# -----END SECTION test-----
|
144
|
+
HOSTS
|
145
|
+
|
146
|
+
file.elements.should have(1).item
|
147
|
+
element = file.elements.first
|
148
|
+
element.should be_a(Aef::Hosts::Section)
|
149
|
+
element.cache_filled?.should be_true
|
150
|
+
element.name.should eql 'test'
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should complain about nested sections" do
|
154
|
+
hosts = <<-HOSTS
|
155
|
+
# -----BEGIN SECTION outer-----
|
156
|
+
# -----BEGIN SECTION inner-----
|
157
|
+
# -----END SECTION inner-----
|
158
|
+
# -----END SECTION outer-----
|
159
|
+
HOSTS
|
160
|
+
|
161
|
+
expect {
|
162
|
+
file.parse(hosts)
|
163
|
+
}.to raise_error(Aef::Hosts::ParserError, "Invalid cascading of sections. Cannot start new section 'inner' without first closing section 'outer' on line 2.")
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should complain about closing the wrong section" do
|
167
|
+
hosts = <<-HOSTS
|
168
|
+
# -----BEGIN SECTION correct-----
|
169
|
+
# -----END SECTION incorrect-----
|
170
|
+
HOSTS
|
171
|
+
|
172
|
+
expect {
|
173
|
+
file.parse(hosts)
|
174
|
+
}.to raise_error(Aef::Hosts::ParserError, "Invalid closing of section. Found attempt to close section 'incorrect' in body of section 'correct' on line 2.")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "#invalidate_cache!" do
|
179
|
+
it "should clear the cache of the file's elements" do
|
180
|
+
child_a = 'markov'
|
181
|
+
child_b = 'chainey'
|
182
|
+
|
183
|
+
child_a.should_receive(:invalidate_cache!)
|
184
|
+
child_b.should_receive(:invalidate_cache!)
|
185
|
+
|
186
|
+
file.elements << child_a
|
187
|
+
file.elements << child_b
|
188
|
+
|
189
|
+
file.invalidate_cache!
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "#inspect" do
|
194
|
+
it "should be able to generate a debugging String" do
|
195
|
+
file.inspect.should eql %{#<Aef::Hosts::File: path=nil elements=[]>}
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should be able to generate a debugging String with path" do
|
199
|
+
file.path = hosts_file
|
200
|
+
file.inspect.should eql %{#<Aef::Hosts::File: path=#<Pathname:#{hosts_file}> elements=[]>}
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should be able to generate a debugging String with cascaded elements" do
|
204
|
+
section = Aef::Hosts::Section.new('new section', :elements => [
|
205
|
+
'fnord',
|
206
|
+
'eris'
|
207
|
+
])
|
208
|
+
|
209
|
+
file.elements << section
|
210
|
+
file.elements << 'hagbard'
|
211
|
+
|
212
|
+
file.inspect.should eql <<-STRING.chomp
|
213
|
+
#<Aef::Hosts::File: path=nil elements=[
|
214
|
+
#<Aef::Hosts::Section: name="new section" elements=[
|
215
|
+
"fnord",
|
216
|
+
"eris"
|
217
|
+
]>,
|
218
|
+
"hagbard"
|
219
|
+
]>
|
220
|
+
STRING
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should be able to generate a debugging String with elements" do
|
224
|
+
file.elements << 'fnord'
|
225
|
+
file.elements << 'eris'
|
226
|
+
file.inspect.should eql <<-STRING.chomp
|
227
|
+
#<Aef::Hosts::File: path=nil elements=[
|
228
|
+
"fnord",
|
229
|
+
"eris"
|
230
|
+
]>
|
231
|
+
STRING
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "string generation" do
|
236
|
+
it "should produce unchanged output if nothing changed" do
|
237
|
+
file.path = hosts_file
|
238
|
+
file.read
|
239
|
+
|
240
|
+
file.to_s.should == hosts_file.read
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should be able to re-encode the linebreaks of generated output" do
|
244
|
+
hosts_file = fixtures_dir + 'windows_hosts'
|
245
|
+
file.path = hosts_file
|
246
|
+
file.read
|
247
|
+
|
248
|
+
original_document = hosts_file.read
|
249
|
+
|
250
|
+
file.to_s.should_not == original_document
|
251
|
+
file.to_s(:linebreak_encoding => :windows).should == original_document
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "writing to file" do
|
256
|
+
before(:each) do
|
257
|
+
@dir = create_temp_dir
|
258
|
+
end
|
259
|
+
|
260
|
+
after(:each) do
|
261
|
+
@dir.rmtree
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should be possible through the #write method" do
|
265
|
+
file.should respond_to(:write)
|
266
|
+
|
267
|
+
result_file = @dir + 'hosts'
|
268
|
+
data = hosts_file.read
|
269
|
+
|
270
|
+
file.parse(data)
|
271
|
+
file.path = result_file
|
272
|
+
file.write
|
273
|
+
|
274
|
+
result_file.read.should == data
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should allow the path attribute to be temporarily overridden" do
|
278
|
+
result_file = @dir + 'hosts'
|
279
|
+
wrong_file = @dir + 'wrong_file'
|
280
|
+
data = hosts_file.read
|
281
|
+
|
282
|
+
file.parse(data)
|
283
|
+
file.path = wrong_file
|
284
|
+
|
285
|
+
file.write(:path => result_file)
|
286
|
+
|
287
|
+
result_file.read.should == data
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Aef::Hosts::Helpers do
|
5
|
+
include Aef::Hosts::Helpers
|
6
|
+
|
7
|
+
let(:model) {
|
8
|
+
model = OpenStruct.new(
|
9
|
+
:name => 'test',
|
10
|
+
:cache_filled => true,
|
11
|
+
:elements => ['fnord', 'eris']
|
12
|
+
)
|
13
|
+
|
14
|
+
def model.cache_filled?
|
15
|
+
cache_filled
|
16
|
+
end
|
17
|
+
|
18
|
+
model
|
19
|
+
}
|
20
|
+
|
21
|
+
context "#validate_options" do
|
22
|
+
it "should accept options with a subset of valid option keys" do
|
23
|
+
options = {:valid1 => 123, :valid2 => 456}
|
24
|
+
|
25
|
+
expect {
|
26
|
+
validate_options(options, :valid1, :valid2, :valid3)
|
27
|
+
}.not_to raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should accept options with exactly the valid option keys" do
|
31
|
+
options = {:valid1 => 123, :valid2 => 456, :valid3 => 789}
|
32
|
+
|
33
|
+
expect {
|
34
|
+
validate_options(options, :valid1, :valid2, :valid3)
|
35
|
+
}.not_to raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should deny options with invalid option keys" do
|
39
|
+
options = {:valid1 => 123, :invalid => 'test'}
|
40
|
+
|
41
|
+
expect {
|
42
|
+
validate_options(options, :valid1, :valid2, :valid3)
|
43
|
+
}.to raise_error(ArgumentError, 'Invalid option keys: :invalid')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "#to_pathname" do
|
48
|
+
it "should return nil when nil is given" do
|
49
|
+
to_pathname(nil).should be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return a Pathname when a String is given" do
|
53
|
+
to_pathname('abc/def').should eql Pathname.new('abc/def')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return a Pathname when a Pathname is given" do
|
57
|
+
to_pathname(Pathname.new('abc/def')).should eql Pathname.new('abc/def')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "generate_inspect" do
|
62
|
+
it "should be able to render a minimal inspect output" do
|
63
|
+
generate_inspect(model).should eql %{#<OpenStruct>}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be able to render a normal attribute in inspect output" do
|
67
|
+
generate_inspect(model, :name).should eql %{#<OpenStruct: name="test">}
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be able to render an attribute by custom String in inspect output" do
|
71
|
+
generate_inspect(model, 'abc=123').should eql %{#<OpenStruct: abc=123>}
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be able to render a special cache attribute in inspect output" do
|
75
|
+
generate_inspect(model, :cache).should eql %{#<OpenStruct: cached!>}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not render a special cache attribute in inspect output if cache is not filled" do
|
79
|
+
model.cache_filled = false
|
80
|
+
generate_inspect(model, :cache).should eql %{#<OpenStruct>}
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be able to render elements in inspect output" do
|
84
|
+
generate_inspect(model, :elements).should eql <<-STRING.chomp
|
85
|
+
#<OpenStruct: elements=[
|
86
|
+
"fnord",
|
87
|
+
"eris"
|
88
|
+
]>
|
89
|
+
STRING
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "generate_elements_partial" do
|
94
|
+
it "should be able to render elements in inspect output" do
|
95
|
+
generate_elements_partial(['fnord', 'eris']).should eql <<-STRING.chomp
|
96
|
+
elements=[
|
97
|
+
"fnord",
|
98
|
+
"eris"
|
99
|
+
]
|
100
|
+
STRING
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright Alexander E. Fischer <aef@raxys.net>, 2012
|
4
|
+
|
5
|
+
This file is part of Hosts.
|
6
|
+
|
7
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
8
|
+
purpose with or without fee is hereby granted, provided that the above
|
9
|
+
copyright notice and this permission notice appear in all copies.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
12
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
13
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
14
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
15
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
16
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'spec_helper'
|
21
|
+
|
22
|
+
describe Aef::Hosts::Section do
|
23
|
+
let(:element) { described_class.new('some name') }
|
24
|
+
|
25
|
+
describe "name attribute" do
|
26
|
+
it "should exist" do
|
27
|
+
element.should respond_to(:name)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be settable" do
|
31
|
+
element.should respond_to(:name=)
|
32
|
+
|
33
|
+
element.name = 'demo section'
|
34
|
+
|
35
|
+
element.name.should == 'demo section'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be settable through the constructor" do
|
39
|
+
element = Aef::Hosts::Section.new('demo section')
|
40
|
+
|
41
|
+
element.name.should == 'demo section'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be a mandatory argument of the constructor" do
|
45
|
+
expect {
|
46
|
+
element = Aef::Hosts::Section.new(nil)
|
47
|
+
}.to raise_error(ArgumentError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should flag the object as changed if modified" do
|
51
|
+
element = Aef::Hosts::Section.new('some name', :cache => {
|
52
|
+
:header => "# -----BEGIN SECTION some name----- \n",
|
53
|
+
:footer => "# -----END SECTION some name----- \n"
|
54
|
+
})
|
55
|
+
|
56
|
+
expect {
|
57
|
+
element.name = 'demo section'
|
58
|
+
}.to change{ element.cache_filled? }.from(true).to(false)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "elements attribute" do
|
63
|
+
it "should exist" do
|
64
|
+
element.should respond_to(:elements)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be settable" do
|
68
|
+
element.should respond_to(:elements=)
|
69
|
+
|
70
|
+
element.elements = ['abc', 'def']
|
71
|
+
|
72
|
+
element.elements.should eql ['abc', 'def']
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be settable through the constructor" do
|
76
|
+
element = Aef::Hosts::Section.new('name', :elements => ['abc', 'def'])
|
77
|
+
|
78
|
+
element.elements.should eql ['abc', 'def']
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should flag the object as changed if modified" do
|
82
|
+
child_element = 'abc'
|
83
|
+
element = Aef::Hosts::Section.new('some name', :cache => {
|
84
|
+
:header => "# -----BEGIN SECTION some name----- \n",
|
85
|
+
:footer => "# -----END SECTION some name----- \n"
|
86
|
+
}, :elements => [child_element])
|
87
|
+
|
88
|
+
child_element.should_not_receive(:invalidate_cache!)
|
89
|
+
|
90
|
+
expect {
|
91
|
+
element.elements = [child_element, 'def']
|
92
|
+
}.to change{ element.cache_filled? }.from(true).to(false)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "cache attribute" do
|
97
|
+
it "should exist" do
|
98
|
+
element.should respond_to(:cache)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should be nil by default" do
|
102
|
+
element.cache.should == {:footer => nil, :header => nil}
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not be allowed to be set" do
|
106
|
+
element.should_not respond_to(:cache=)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should be settable through the constructor" do
|
110
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {
|
111
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
112
|
+
:footer => "# -----END SECTION demo section-----\t\t\t\n"
|
113
|
+
})
|
114
|
+
|
115
|
+
element.cache.should == {
|
116
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
117
|
+
:footer => "# -----END SECTION demo section-----\t\t\t\n"
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be correctly reported as empty by cache_filled?" do
|
122
|
+
element.should respond_to(:cache_filled?)
|
123
|
+
|
124
|
+
element.cache_filled?.should be_false
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should be correctly reported as filled by cache_filled?" do
|
128
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {
|
129
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
130
|
+
:footer => "# -----END SECTION demo section-----\t\t\t\n"
|
131
|
+
})
|
132
|
+
|
133
|
+
element.should respond_to(:cache_filled?)
|
134
|
+
|
135
|
+
element.cache_filled?.should be_true
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should be invalidatable" do
|
139
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {
|
140
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
141
|
+
:footer => "# -----END SECTION demo section-----\t\t\t\n"
|
142
|
+
})
|
143
|
+
|
144
|
+
element.invalidate_cache!
|
145
|
+
|
146
|
+
element.cache[:header].should be_nil
|
147
|
+
element.cache[:footer].should be_nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "#invalidate_cache!" do
|
152
|
+
it "should clear the cache of the section and its elements" do
|
153
|
+
child_a = 'markov'
|
154
|
+
child_b = 'chainey'
|
155
|
+
|
156
|
+
child_a.should_receive(:invalidate_cache!)
|
157
|
+
child_b.should_receive(:invalidate_cache!)
|
158
|
+
|
159
|
+
element.elements << child_a
|
160
|
+
element.elements << child_b
|
161
|
+
|
162
|
+
element.invalidate_cache!
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should clear the cache of the section only if :only_section is set" do
|
166
|
+
child_a = 'markov'
|
167
|
+
child_b = 'chainey'
|
168
|
+
|
169
|
+
child_a.should_not_receive(:invalidate_cache!)
|
170
|
+
child_b.should_not_receive(:invalidate_cache!)
|
171
|
+
|
172
|
+
element.elements << child_a
|
173
|
+
element.elements << child_b
|
174
|
+
|
175
|
+
element.invalidate_cache!(:only_section => true)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "#inspect" do
|
180
|
+
it "should be able to generate a debugging String" do
|
181
|
+
element.inspect.should eql %{#<Aef::Hosts::Section: name="some name" elements=[]>}
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should be able to generate a debugging String with elements" do
|
185
|
+
element.elements << 'fnord'
|
186
|
+
element.elements << 'eris'
|
187
|
+
element.inspect.should eql <<-STRING.chomp
|
188
|
+
#<Aef::Hosts::Section: name="some name" elements=[
|
189
|
+
"fnord",
|
190
|
+
"eris"
|
191
|
+
]>
|
192
|
+
STRING
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should be able to generate a debugging String with cache filled" do
|
196
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {:header => 'abc', :footer => 'xyz'})
|
197
|
+
element.inspect.should eql %{#<Aef::Hosts::Section: name="demo section" cached! elements=[]>}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "string generation" do
|
202
|
+
before(:all) do
|
203
|
+
class Aef::Hosts::ChildElement < Aef::Hosts::Element
|
204
|
+
def generate_string(options = {})
|
205
|
+
"uncached element representation\n"
|
206
|
+
end
|
207
|
+
|
208
|
+
def cache=(cache)
|
209
|
+
@cache = cache
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should generate a new representation if no cache is available" do
|
215
|
+
element = Aef::Hosts::Section.new('demo section')
|
216
|
+
|
217
|
+
element.to_s.should == <<-EOS
|
218
|
+
# -----BEGIN SECTION demo section-----
|
219
|
+
# -----END SECTION demo section-----
|
220
|
+
EOS
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should respond with a duplicate of the cached representation if cache is filled" do
|
224
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {
|
225
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
226
|
+
:footer => "# -----END SECTION demo section----- \n"
|
227
|
+
})
|
228
|
+
|
229
|
+
element.to_s.should == <<-EOS
|
230
|
+
# -----BEGIN SECTION demo section-----
|
231
|
+
# -----END SECTION demo section-----
|
232
|
+
EOS
|
233
|
+
|
234
|
+
# Should not be identical
|
235
|
+
element.to_s.should_not equal(element.cache[:footer])
|
236
|
+
element.to_s.should_not equal(element.cache[:header])
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should respond with a duplicate of the cached representation if cache is filled" do
|
240
|
+
element = Aef::Hosts::Section.new('demo section', :cache => {
|
241
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
242
|
+
:footer => "# -----END SECTION demo section----- \n"
|
243
|
+
})
|
244
|
+
|
245
|
+
element.to_s(:force_generation => true).should == <<-EOS
|
246
|
+
# -----BEGIN SECTION demo section-----
|
247
|
+
# -----END SECTION demo section-----
|
248
|
+
EOS
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should correctly display including elements" do
|
252
|
+
sub_element_without_cache = Aef::Hosts::ChildElement.new
|
253
|
+
sub_element_with_cache = Aef::Hosts::ChildElement.new
|
254
|
+
sub_element_with_cache.cache = "cached element representation\n"
|
255
|
+
|
256
|
+
element = Aef::Hosts::Section.new('demo section',
|
257
|
+
:elements => [
|
258
|
+
sub_element_with_cache,
|
259
|
+
sub_element_without_cache
|
260
|
+
],
|
261
|
+
:cache => {
|
262
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
263
|
+
:footer => "# -----END SECTION demo section----- \n"
|
264
|
+
}
|
265
|
+
)
|
266
|
+
|
267
|
+
element.to_s.should == <<-EOS
|
268
|
+
# -----BEGIN SECTION demo section-----
|
269
|
+
cached element representation
|
270
|
+
uncached element representation
|
271
|
+
# -----END SECTION demo section-----
|
272
|
+
EOS
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should correctly display including elements with forced generation" do
|
276
|
+
sub_element_without_cache = Aef::Hosts::ChildElement.new
|
277
|
+
sub_element_with_cache = Aef::Hosts::ChildElement.new
|
278
|
+
sub_element_with_cache.cache = "cached element representation\n"
|
279
|
+
|
280
|
+
element = Aef::Hosts::Section.new('demo section',
|
281
|
+
:elements => [
|
282
|
+
sub_element_with_cache,
|
283
|
+
sub_element_without_cache
|
284
|
+
],
|
285
|
+
:cache => {
|
286
|
+
:header => "# -----BEGIN SECTION demo section----- \n",
|
287
|
+
:footer => "# -----END SECTION demo section----- \n"
|
288
|
+
}
|
289
|
+
)
|
290
|
+
|
291
|
+
element.to_s(:force_generation => true).should == <<-EOS
|
292
|
+
# -----BEGIN SECTION demo section-----
|
293
|
+
uncached element representation
|
294
|
+
uncached element representation
|
295
|
+
# -----END SECTION demo section-----
|
296
|
+
EOS
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|