Skip to content

Commit

Permalink
Add experimental MiniTest support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Crump committed Jul 22, 2012
1 parent 66cc40e commit 1e5939a
Show file tree
Hide file tree
Showing 15 changed files with 443 additions and 40 deletions.
25 changes: 21 additions & 4 deletions Rakefile
Expand Up @@ -9,10 +9,27 @@ task :default => [:install, :spec, :features]
Bundler.setup
Bundler::GemHelper.install_tasks

RSpec::Core::RakeTask.new
YARD::Rake::YardocTask.new

require 'chef'
Cucumber::Rake::Task.new(:features) do |t|
t.cucumber_opts = "features --format pretty#{' -t ~@requires_chef_10' if Chef::VERSION.start_with? '0.9.'}"

def register_spec_features(spec_type)
Cucumber::Rake::Task.new(feature_task_name(spec_type),
"Run Cucumber features (#{spec_type} support only)") do |t|
t.cucumber_opts = "CS_SPEC_TYPE=#{spec_type} features --format pretty"
t.cucumber_opts << ' -t ~@requires_chef_10' if Chef::VERSION.start_with? '0.9.'
t.cucumber_opts << " -t ~@not_implemented_#{spec_type.downcase}"
end
end

RSpec::Core::RakeTask.new
YARD::Rake::YardocTask.new
def feature_task_name(spec_type)
"features_#{spec_type.downcase}".to_sym
end

desc "Run all Cucumber features"
task :features
['RSpec', 'MiniTest'].each do |spec_type|
register_spec_features(spec_type)
task :features => feature_task_name(spec_type)
end
1 change: 1 addition & 0 deletions chefspec.gemspec
Expand Up @@ -14,5 +14,6 @@ Gem::Specification.new do |s|
s.files = Dir['lib/**/*.rb']
s.add_dependency('chef', chef_version)
s.add_dependency('erubis', '>= 0')
s.add_dependency('minitest-chef-handler', '~> 0.6.0')
s.add_dependency('rspec', '~> 2.10.0')
end
2 changes: 1 addition & 1 deletion features/generate_placeholder_examples.feature
@@ -1,4 +1,4 @@
@requires_chef_10
@requires_chef_10 @not_implemented_minitest
Feature: Generate placeholder examples

If you are using Chef 0.10.0 or greater then ChefSpec can generate placeholder RSpec examples for you. Knife will
Expand Down
1 change: 1 addition & 0 deletions features/set_node_attributes.feature
@@ -1,3 +1,4 @@
@not_implemented_minitest
Feature: Set node attributes

Chef recipes often need to behave differently depending on the attributes of the node they are executing on:
Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/gem_package_steps.rb
Expand Up @@ -6,7 +6,7 @@
recipe_with_gem_no_action
end

Given 'a Chef cookbook with a recipe that declares a gem_package resource at a fixed version' do
Given 'a Chef cookbook with a recipe that declares a gem package resource at a fixed version' do
recipe_installs_specific_gem_version
end

Expand Down
5 changes: 5 additions & 0 deletions features/support/env.rb
Expand Up @@ -6,3 +6,8 @@
Before do
@aruba_timeout_seconds = 300
end

unless ENV['CS_SPEC_TYPE']
raise ArgumentError,
'Please set CS_SPEC_TYPE to specify the test framework to be tested against'
end
169 changes: 169 additions & 0 deletions features/support/minitest_helpers.rb
@@ -0,0 +1,169 @@
module ChefSpec
module MiniTestHelpers

def run_examples_successfully
run_simple 'ruby cookbooks/example/spec/default_spec.rb'
assert_success(true)
assert_partial_output ', 0 failures', all_output
end

def run_examples_unsuccessfully(failure_message)
run_simple 'ruby cookbooks/example/spec/default_spec.rb', false
assert_success(false)
assert_partial_output 'No such file or directory', all_output
end

def spec_expects_directory
generate_spec %q{
it "creates the directory" do
directory("foo").must_exist
end
}
end

def spec_expects_directory_to_be_deleted
generate_spec %q{
it "deletes the directory" do
directory("foo").wont_exist
end
}
end

def spec_expects_directory_with_ownership
generate_spec %q{
it "sets directory ownership" do
directory('foo').must_exist.with(:owner, 'user').and(:group, 'group')
end
}
end

def spec_expects_file(resource_type, path = 'hello-world.txt')
generate_spec %Q{
it "creates #{path}" do
file("#{path}").must_exist
end
}
end

def spec_expects_file_to_be_deleted
generate_spec %q{
it "deletes hello-world.txt" do
file("hello-world.txt").wont_exist
end
}
end

def spec_expects_file_with_content
generate_spec %q{
it "creates hello-world.txt with content" do
file("hello-world.txt").must_include 'hello world'
end
}
end

def spec_expects_file_with_rendered_content
generate_spec %q{
it "should create a file with the node platform" do
expected_content = <<-EOF.gsub /^\s*/, ''
# Config file generated by Chef
platform: chefspec
EOF
file('/etc/config_file').must_include expected_content
end
}
end

def spec_expects_file_with_ownership(resource_type)
generate_spec %q{
it "sets file ownership" do
file("hello-world.txt").must_exist.with(:owner, 'user').and(:group, 'group')
end
}
end

def spec_expects_gem_action(action)
assertion = case action
when :remove, :purge then 'wont_be_installed'
else 'must_be_installed'
end
generate_spec %Q{
it "#{action}s the gem" do
gem_package("gem_package_does_not_exist").#{assertion}
end
}
end

def spec_expects_gem_at_specific_version
generate_spec %q{
it "installs the gem at a specific version" do
gem_package("gem_package_does_not_exist").must_be_installed.with(:version, '1.2.3')
end
}
end

def spec_expects_package_action(action)
assertion = case action
when :remove, :purge then 'wont_be_installed'
when :upgrade then raise NotImplementedError, 'The :upgrade action is not supported'
else 'must_be_installed'
end

generate_spec %Q{
it "#{action}s package_does_not_exist" do
package('package_does_not_exist').#{assertion}
end
}
end

def spec_expects_package_at_specific_version
generate_spec %q{
it "installs package_does_not_exist" do
package('package_does_not_exist').must_be_installed.with(:version, '1.2.3')
end
}
end

def spec_expects_service_action(action)
assertion = case action
when :stop then 'wont_be_running'
else 'must_be_running'
end
generate_spec %Q{
it "#{action.to_s} the food service" do
service('food').#{assertion}
end
}
end

def spec_expects_service_to_be_started_and_enabled
generate_spec %q{
it "ensures the food service is started and enabled" do
service('food').must_be_running
service('food').must_be_enabled
end
}
end

private

def generate_spec(example)
write_file 'cookbooks/example/spec/default_spec.rb', %Q{
require "chefspec"
require "minitest/autorun"
require "minitest/spec"
require "minitest-chef-handler"
describe_recipe "example::default" do
include MiniTest::Chef::Assertions
include MiniTest::Chef::Context
include MiniTest::Chef::Resources
include ChefSpec::MiniTest
#{example}
end
}
end

end
end
4 changes: 1 addition & 3 deletions features/support/rspec_helpers.rb
Expand Up @@ -199,7 +199,7 @@ def spec_expects_gem_at_specific_version
describe "example::default" do
let (:chef_run) {ChefSpec::ChefRunner.new.converge 'example::default'}
it "should install gem_package_does_not_exist at a specific version" do
chef_run.should install_gem_package_at_version 'package_does_not_exist', '1.2.3'
chef_run.should install_gem_package_at_version 'gem_package_does_not_exist', '1.2.3'
end
end
}
Expand Down Expand Up @@ -297,5 +297,3 @@ def spec_sets_node_attribute

end
end

World(ChefSpec::RSpecHelpers)
1 change: 1 addition & 0 deletions features/support/spec_helpers.rb
@@ -0,0 +1 @@
World(ChefSpec::const_get("#{ENV['CS_SPEC_TYPE']}Helpers"))
3 changes: 2 additions & 1 deletion features/write_examples_for_executing_commands.feature
@@ -1,3 +1,4 @@
@not_implemented_minitest
Feature: Write examples for executing commands

chef_run.should execute_command "whoami"
Expand All @@ -6,4 +7,4 @@ Feature: Write examples for executing commands
Given a Chef cookbook with a recipe that declares an execute resource
And the recipe has a spec example that expects the command to be executed
When the recipe example is successfully run
Then the command will not have been executed
Then the command will not have been executed
36 changes: 18 additions & 18 deletions features/write_examples_for_gem_packages.feature
Expand Up @@ -11,37 +11,37 @@ Feature: Write examples for gem packages
Then the gem package will not have been installed

Scenario: Package resource with default action
Given a Chef cookbook with a recipe that declares a package resource with no action specified
And the recipe has a spec example that expects the package to be installed
Given a Chef cookbook with a recipe that declares a gem package resource with no action specified
And the recipe has a spec example that expects the gem package to be installed
When the recipe example is successfully run
Then the package will not have been installed
Then the gem package will not have been installed

Scenario: Package resource with fixed version
Given a Chef cookbook with a recipe that declares a package resource at a fixed version
And the recipe has a spec example that expects the package to be installed at that version
Given a Chef cookbook with a recipe that declares a gem package resource at a fixed version
And the recipe has a spec example that expects the gem package to be installed at that version
When the recipe example is successfully run
Then the package will not have been installed
Then the gem package will not have been installed

Scenario: Package resource with fixed version and default action
Given a Chef cookbook with a recipe that declares a package resource at a fixed version with no action specified
And the recipe has a spec example that expects the package to be installed at that version
Given a Chef cookbook with a recipe that declares a gem package resource at a fixed version with no action specified
And the recipe has a spec example that expects the gem package to be installed at that version
When the recipe example is successfully run
Then the package will not have been installed
Then the gem package will not have been installed

Scenario: Upgrade a package
Given a Chef cookbook with a recipe that upgrades a package
And the recipe has a spec example that expects the package to be upgraded
Given a Chef cookbook with a recipe that upgrades a gem package
And the recipe has a spec example that expects the gem package to be upgraded
When the recipe example is successfully run
Then the package will not have been upgraded
Then the gem package will not have been upgraded

Scenario: Remove a package
Given a Chef cookbook with a recipe that removes a package
And the recipe has a spec example that expects the package to be removed
Given a Chef cookbook with a recipe that removes a gem package
And the recipe has a spec example that expects the gem package to be removed
When the recipe example is successfully run
Then the package will not have been removed
Then the gem package will not have been removed

Scenario: Purge a package
Given a Chef cookbook with a recipe that purges a package
And the recipe has a spec example that expects the package to be purged
Given a Chef cookbook with a recipe that purges a gem package
And the recipe has a spec example that expects the gem package to be purged
When the recipe example is successfully run
Then the package will not have been purged
Then the gem package will not have been purged
1 change: 1 addition & 0 deletions features/write_examples_for_packages.feature
Expand Up @@ -28,6 +28,7 @@ Feature: Write examples for packages
When the recipe example is successfully run
Then the package will not have been installed

@not_implemented_minitest
Scenario: Upgrade a package
Given a Chef cookbook with a recipe that upgrades a package
And the recipe has a spec example that expects the package to be upgraded
Expand Down
20 changes: 11 additions & 9 deletions lib/chefspec.rb
@@ -1,14 +1,16 @@
require 'chef'
require 'rspec'
require 'chefspec/chef_runner'
require 'chefspec/version'
require 'chefspec/matchers/execute'
require 'chefspec/matchers/file'
require 'chefspec/matchers/link'
require 'chefspec/matchers/log'
require 'chefspec/matchers/package'
require 'chefspec/matchers/service'
require 'chefspec/matchers/shared'
require 'chefspec/matchers/file_content'
if defined?(RSpec)
require 'chefspec/matchers/execute'
require 'chefspec/matchers/file'
require 'chefspec/matchers/link'
require 'chefspec/matchers/log'
require 'chefspec/matchers/package'
require 'chefspec/matchers/service'
require 'chefspec/matchers/shared'
require 'chefspec/matchers/file_content'
end
require 'chefspec/minitest'
require 'chefspec/monkey_patches/hash'
require 'chefspec/monkey_patches/provider'
7 changes: 4 additions & 3 deletions lib/chefspec/chef_runner.rb
Expand Up @@ -14,6 +14,7 @@ class ChefRunner
@resources = []

attr_accessor :resources
attr_reader :run_context
attr_reader :node

# Instantiate a new runner to run examples with.
Expand Down Expand Up @@ -85,11 +86,11 @@ def converge(*recipe_names)

@resources = []
if @client.respond_to?(:setup_run_context) # 0.10.x
run_context = @client.setup_run_context
@run_context = @client.setup_run_context
else
run_context = Chef::RunContext.new(@client.node, Chef::CookbookCollection.new(Chef::CookbookLoader.new)) # 0.9.x
@run_context = Chef::RunContext.new(@client.node, Chef::CookbookCollection.new(Chef::CookbookLoader.new)) # 0.9.x
end
runner = Chef::Runner.new(run_context)
runner = Chef::Runner.new(@run_context)
runner.converge
self
end
Expand Down

0 comments on commit 1e5939a

Please sign in to comment.