I have a bunch of repeated code that manipulates the Puppet catalogue object (notice the repeated content =
lines):
require 'nokogiri'
describe 'role::jenkins' do
before(:each) do
@jobs = catalogue.resource_keys.select{|k,v| k == 'Jenkins::Jobs'}.map{|k,v| v}
end
it 'Jenkins jobs should be valid XML' do
@jobs.each do |j|
content = catalogue.resource('file', "/tmp/#{j}.xml").send(:parameters)[:content]
result = Nokogiri::XML(content).errors.empty?
if ! result
puts " Job #{j} does NOT have valid XML"
end
expect(result).to be true
end
end
it "XML should contain a variables.json snippet that is valid JSON" do
@jobs.each do |j|
content = catalogue.resource('file', "/tmp/#{j}.xml").send(:parameters)[:content]
if content.match(/cat << EOF > #{json_file}.*?EOF/m)
json_snippet = content.match(/#{json_file}(.*?)EOF/m)[1]
expect { JSON.parse(json_snippet) }.to_not raise_error
end
end
end
end
As can be seen, I have moved a long query into a before(:each)
block and saved it in an instance variable. That makes it available in the it
blocks.
What I do not understand is how I could define a method for the content =
lines, like:
def content(file_name)
catalogue.resource('file', file_name).send(:parameters)[:content]
end
If I knew how to do that I could clean up this code considerably. What I cannot figure out is where I could place this def
block, if it is even possible to do this.
I have made a silly mistake (thought I had already tried something when actually I had not).
The answer is just put the def
inside the before
block as well:
require 'nokogiri'
describe 'role::jenkins' do
before(:each) do
@jobs = catalogue.resource_keys.select{|k,v| k == 'Jenkins::Jobs'}.map{|k,v| v}
def content(file_name)
catalogue.resource('file', file_name).send(:parameters)[:content]
end
end
it 'Jenkins jobs should be valid XML' do
@jobs.each do |j|
result = Nokogiri::XML(content("/tmp/#{j}.xml").errors.empty?
if ! result
puts " Job #{j} does NOT have valid XML"
end
expect(result).to be true
end
end
it 'XML should contain a variables.json snippet that is valid JSON' do
@jobs.each do |j|
content = content("/tmp/#{j}.xml")
if content.match(/cat << EOF > #{json_file}.*?EOF/m)
json_snippet = content.match(/#{json_file}(.*?)EOF/m)[1]
expect { JSON.parse(json_snippet) }.to_not raise_error
end
end
end
end
Please let me know though if anyone can see any further improvements that could be made!