class Umami::Test::Unit

Attributes

test_root[R]
tested_cookbook[R]

Public Class Methods

new(root_dir) click to toggle source
Calls superclass method Umami::Test::new
# File lib/chef-umami/test/unit.rb, line 27
def initialize(root_dir)
  super
  @test_root = File.join(self.root_dir, 'umami', 'unit', 'recipes')
  @tested_cookbook = File.basename(Dir.pwd)
end

Public Instance Methods

framework() click to toggle source
# File lib/chef-umami/test/unit.rb, line 33
def framework
  'chefspec'
end
generate(recipe_resources = {}) click to toggle source
# File lib/chef-umami/test/unit.rb, line 88
def generate(recipe_resources = {})
  test_files_written = []
  recipe_resources.each do |canonical_recipe, resources|
    (cookbook, recipe) = canonical_recipe.split('::')
    # Only write unit tests for the cookbook we're in.
    next unless cookbook == tested_cookbook

    content = [preamble(cookbook, recipe)]
    resources.each do |resource|
      content << write_test(resource)
    end
    content << 'end'
    test_file_name = test_file(recipe)
    test_file_content = content.join("\n") + "\n"
    write_file(test_file_name, test_file_content)
    test_files_written << test_file_name
  end

  enforce_styling(test_root)
  write_spec_helper
  test_files_written << spec_helper_path

  unless test_files_written.empty?
    puts 'Wrote the following unit test files:'
    test_files_written.each do |f|
      puts "\t#{f}"
    end
  end
end
preamble(cookbook = '', recipe = '') click to toggle source
# File lib/chef-umami/test/unit.rb, line 45
def preamble(cookbook = '', recipe = '')
  "# #{test_file(recipe)} - Originally written by Umami!\n" \
  "\n" \
  "require_relative '../spec_helper'\n" \
  "\n" \
  "describe '#{cookbook}::#{recipe}' do\n" \
  "let(:chef_run) { ChefSpec::ServerRunner.new(platform: '#{os[:platform]}', version: '#{os[:version]}').converge(described_recipe) }"
end
spec_helper_path() click to toggle source
# File lib/chef-umami/test/unit.rb, line 41
def spec_helper_path
  File.join(test_root, '..', 'spec_helper.rb')
end
test_file(recipe = '') click to toggle source
# File lib/chef-umami/test/unit.rb, line 37
def test_file(recipe = '')
  "#{test_root}/#{recipe}_spec.rb"
end
write_spec_helper() click to toggle source
# File lib/chef-umami/test/unit.rb, line 54
def write_spec_helper
  content = ["require '#{framework}'"]
  content << "require '#{framework}/policyfile'"
  content << "at_exit { ChefSpec::Coverage.report! }\n"
  write_file(spec_helper_path, content.join("\n"))
end
write_test(resource = nil) click to toggle source
# File lib/chef-umami/test/unit.rb, line 61
def write_test(resource = nil)
  state_attrs = [] # Attribute hash to be used with #with()
  resource.state_for_resource_reporter.each do |attr, value|
    next if value.nil? || (value.respond_to?(:empty) && value.empty?)

    if value.is_a? String
      value = value.gsub("'", "\\\\'") # Escape any single quotes in the value.
    end
    state_attrs << "#{attr}: '#{value}'"
  end
  action = ''
  if resource.action.is_a? Array
    action = resource.action.first
  else
    action = resource.action
  end
  resource_name = resource.name.gsub("'", "\\\\'") # Escape any single quotes in the resource name.
  test_output = ["\nit '#{action}s #{resource.declared_type} \"#{resource_name}\"' do"]
  if state_attrs.empty?
    test_output << "expect(chef_run).to #{action}_#{resource.declared_type}('#{resource_name}')"
  else
    test_output << "expect(chef_run).to #{action}_#{resource.declared_type}('#{resource_name}').with(#{state_attrs.join(', ')})"
  end
  test_output << "end\n"
  test_output.join("\n")
end