chefspec 7.3.3 → 7.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +23 -0
  3. data/Rakefile +77 -0
  4. data/chefspec.gemspec +29 -0
  5. data/lib/chefspec/version.rb +1 -1
  6. data/spec/spec_helper.rb +13 -0
  7. data/spec/support/hash.rb +35 -0
  8. data/spec/unit/cacher_spec.rb +70 -0
  9. data/spec/unit/coverage/filters_spec.rb +60 -0
  10. data/spec/unit/deprecations_spec.rb +53 -0
  11. data/spec/unit/errors_spec.rb +57 -0
  12. data/spec/unit/expect_exception_spec.rb +32 -0
  13. data/spec/unit/macros_spec.rb +119 -0
  14. data/spec/unit/matchers/do_nothing_matcher.rb +5 -0
  15. data/spec/unit/matchers/include_recipe_matcher_spec.rb +38 -0
  16. data/spec/unit/matchers/link_to_matcher_spec.rb +55 -0
  17. data/spec/unit/matchers/notifications_matcher_spec.rb +40 -0
  18. data/spec/unit/matchers/render_file_matcher_spec.rb +68 -0
  19. data/spec/unit/matchers/resource_matcher_spec.rb +5 -0
  20. data/spec/unit/matchers/state_attrs_matcher_spec.rb +68 -0
  21. data/spec/unit/matchers/subscribes_matcher_spec.rb +65 -0
  22. data/spec/unit/renderer_spec.rb +69 -0
  23. data/spec/unit/server_runner_spec.rb +28 -0
  24. data/spec/unit/solo_runner_spec.rb +171 -0
  25. data/spec/unit/stubs/command_registry_spec.rb +27 -0
  26. data/spec/unit/stubs/command_stub_spec.rb +61 -0
  27. data/spec/unit/stubs/data_bag_item_registry_spec.rb +39 -0
  28. data/spec/unit/stubs/data_bag_item_stub_spec.rb +36 -0
  29. data/spec/unit/stubs/data_bag_registry_spec.rb +39 -0
  30. data/spec/unit/stubs/data_bag_stub_spec.rb +35 -0
  31. data/spec/unit/stubs/registry_spec.rb +29 -0
  32. data/spec/unit/stubs/search_registry_spec.rb +39 -0
  33. data/spec/unit/stubs/search_stub_spec.rb +36 -0
  34. data/spec/unit/stubs/stub_spec.rb +64 -0
  35. metadata +34 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7ad20235c511ac776998d932fedf88069c52f6fd935768b345ae182ae583c1a
4
- data.tar.gz: b5c1096a905aaf0b872b8c7b4698bbd55223bc1ab77f772aacaa2da2e13d6e10
3
+ metadata.gz: '087946db9144fc3c278e7b18e1afefd129d6f964f1008114b00ab5bbe5fbb34e'
4
+ data.tar.gz: 47809ae0412a69c75c8e2e0eb8f7109adfe86befc62270aa5e3b4659a0d5737b
5
5
  SHA512:
6
- metadata.gz: a368547ad18bd6d809535741ee89e2547aa4ca94ac69c00b24822032756bc94fdec949b01d2b0361dd9db3efb85d1ca8a0135ec192e15c33cbd8218c79c6325c
7
- data.tar.gz: a97c33254a9927d1a63b14cc9188732bce0bbbfa96c26ecfd2078a0be33d798bbbf26e8590d7551d6b4fde4ece9c6624d5717ab400c39eb1aded67f153c7fe8d
6
+ metadata.gz: 0e988f0d741d4dce1f20c21cf6d8d19eaa6cae90261eaa9e090e99483ef6a249c54a544017fda8aba6bf67d3a7e753c9614c42e75c464733382969eb811ebe67
7
+ data.tar.gz: 7279c57f503a0b662d840608f79a8cd5b445e19fe3a7302043b3162bd044369a61729ea69098ae9e064539d54e8d7c9691a7922659b5ab5eeca027660178ce21
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'redcarpet'
8
+ gem 'yard'
9
+ gem 'pry'
10
+ gem 'pry-byebug'
11
+ end
12
+
13
+ if ENV["GEMFILE_MOD"]
14
+ puts "GEMFILE_MOD: #{ENV['GEMFILE_MOD']}"
15
+ instance_eval(ENV["GEMFILE_MOD"])
16
+ else
17
+ gem 'chef', git: "https://github.com/chef/chef"
18
+ gem 'ohai', git: "https://github.com/chef/ohai"
19
+ end
20
+
21
+ # If you want to load debugging tools into the bundle exec sandbox,
22
+ # add these additional dependencies into Gemfile.local
23
+ eval_gemfile(__FILE__ + ".local") if File.exist?(__FILE__ + ".local")
@@ -0,0 +1,77 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+ require 'yard/rake/yardoc_task'
5
+ require 'tmpdir'
6
+ require 'rspec'
7
+ require 'chefspec'
8
+
9
+ require 'chef/version'
10
+
11
+ YARD::Rake::YardocTask.new
12
+
13
+ RSpec::Core::RakeTask.new(:unit) do |t|
14
+ t.rspec_opts = [].tap do |a|
15
+ a.push('--color')
16
+ a.push('--format progress')
17
+ end.join(' ')
18
+ end
19
+
20
+ failed = []
21
+ start_time = nil
22
+
23
+ namespace :acceptance do |ns|
24
+ begin
25
+ Dir.foreach("examples") do |dir|
26
+ next if dir == '.' or dir == '..'
27
+ desc "#{dir} acceptance tests"
28
+ task dir.to_sym do
29
+ start_time ||= Time.now
30
+ Dir.mktmpdir do |tmp|
31
+ FileUtils.cp_r("examples/#{dir}", tmp)
32
+
33
+ pwd = Dir.pwd
34
+
35
+ Dir.chdir "#{tmp}/#{dir}" do
36
+ puts "rspec examples/#{dir}"
37
+
38
+ #
39
+ # This bit of mildly awful magic below is to load each file into an in-memory
40
+ # RSpec runner while keeping a persistent ChefZero server alive.
41
+ #
42
+ load "#{pwd}/lib/chefspec/rspec.rb"
43
+
44
+ RSpec.configure do |config|
45
+ config.color = true
46
+ config.run_all_when_everything_filtered = true
47
+ config.filter_run(:focus)
48
+ config.before(:suite) do
49
+ ChefSpec::ZeroServer.setup!
50
+ end
51
+ config.after(:each) do
52
+ ChefSpec::ZeroServer.reset!
53
+ end
54
+ end
55
+
56
+ RSpec.clear_examples
57
+ exitstatus = RSpec::Core::Runner.run(["spec"])
58
+ RSpec.reset
59
+ failed << dir unless exitstatus == 0
60
+ end
61
+ end
62
+ end
63
+ end
64
+ rescue Errno::ENOENT # examples dir is probably missing
65
+ puts "The rake acceptance tests require a full git checkout of chefspec including all examples files!"
66
+ end
67
+ end
68
+
69
+ task acceptance: Rake.application.tasks.select { |t| t.name.start_with?("acceptance:") } do
70
+ puts "Acceptance tests took #{Time.now - start_time} seconds"
71
+ raise "some tests failed: #{failed.join(', ')}" unless failed.empty?
72
+ end
73
+
74
+ desc 'Run all tests'
75
+ task :test => [:unit, :acceptance]
76
+
77
+ task :default => [:test]
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+ require 'chefspec/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'chefspec'
7
+ s.version = ChefSpec::VERSION
8
+ s.authors = ['Andrew Crump', 'Seth Vargo']
9
+ s.email = ['andrew.crump@ieee.org', 'sethvargo@gmail.com']
10
+ s.summary = 'Write RSpec examples and generate coverage reports for ' \
11
+ 'Chef recipes!'
12
+ s.description = 'ChefSpec is a unit testing and resource coverage ' \
13
+ '(code coverage) framework for testing Chef cookbooks ' \
14
+ 'ChefSpec makes it easy to write examples and get fast ' \
15
+ 'feedback on cookbook changes without the need for ' \
16
+ 'virtual machines or cloud servers.'
17
+ s.homepage = 'https://github.com/chefspec/chefspec'
18
+ s.license = 'MIT'
19
+
20
+ # Packaging
21
+ s.files = %w{LICENSE Rakefile Gemfile chefspec.gemspec} + Dir.glob("{lib,templates,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
22
+ s.require_paths = ['lib']
23
+
24
+ s.required_ruby_version = '>= 2.2'
25
+
26
+ s.add_dependency 'chef', '>= 12.16.42'
27
+ s.add_dependency 'fauxhai', '>= 4'
28
+ s.add_dependency 'rspec', '~> 3.0'
29
+ end
@@ -1,3 +1,3 @@
1
1
  module ChefSpec
2
- VERSION = '7.3.3'
2
+ VERSION = '7.3.4'
3
3
  end
@@ -0,0 +1,13 @@
1
+ require 'chefspec'
2
+ require 'support/hash'
3
+
4
+
5
+ ChefSpec::Coverage.start! do
6
+ set_template 'table.erb'
7
+ end
8
+
9
+ RSpec.configure do |config|
10
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
11
+ config.filter_run(focus: true)
12
+ config.run_all_when_everything_filtered = true
13
+ end
@@ -0,0 +1,35 @@
1
+ #
2
+ # An extension of a Hash that allows mash-style like lookups.
3
+ #
4
+ # @private
5
+ #
6
+ class Hash
7
+ # Like, seriously Windows?
8
+ undef_method(:timeout)
9
+
10
+ #
11
+ # Monkey-patch to allow mash-style look ups for tests
12
+ #
13
+ def method_missing(m, *args, &block)
14
+ if has_key?(m.to_sym)
15
+ self[m.to_sym]
16
+ elsif has_key?(m.to_s)
17
+ self[m.to_s]
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ #
24
+ # Monkey-patch to stdlib Hash to correspond to Mash-style lookup
25
+ #
26
+ # @see Hash#respond_to?
27
+ #
28
+ def respond_to?(m, include_private = false)
29
+ if has_key?(m.to_sym) || has_key?(m.to_s)
30
+ true
31
+ else
32
+ super
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'chefspec/cacher'
3
+
4
+ describe ChefSpec::Cacher do
5
+ let(:klass) do
6
+ Class.new(RSpec::Core::ExampleGroup) do
7
+ extend ChefSpec::Cacher
8
+
9
+ def self.metadata
10
+ { parent_example_group: { location: 'spec' } }
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:cache) { described_class.class_variable_get(:@@cache) }
16
+ let(:preserve_cache) { false }
17
+
18
+ before(:each) { described_class.class_variable_set(:@@cache, {}) unless preserve_cache }
19
+
20
+ describe 'cached' do
21
+ it 'lazily defines the results for the cache' do
22
+ klass.cached(:chef_run)
23
+ expect(klass).to be_method_defined(:chef_run)
24
+ end
25
+
26
+ it 'adds the item to the cache when called' do
27
+ runner = double(:runner)
28
+ klass.cached(:chef_run) { runner }
29
+ klass.new.chef_run
30
+
31
+ expect(cache[Thread.current.object_id]).to have_key('spec.chef_run')
32
+ expect(cache[Thread.current.object_id]['spec.chef_run']).to eq(runner)
33
+ end
34
+
35
+ context 'when multithreaded environment' do
36
+ it 'is thread safe' do
37
+ (1..2).each do |n|
38
+ Thread.new do
39
+ klass.cached(:chef_run) { n }
40
+ expect(klass.new.chef_run).to eq(n)
41
+ end.join
42
+ end
43
+ end
44
+ end
45
+
46
+ context 'when example groups are defined by looping' do
47
+ let(:preserve_cache) { true }
48
+
49
+ ['first', 'second', 'third'].each do |iteration|
50
+ context "on the #{iteration} iteration" do
51
+ context 'in caching context' do
52
+ cached(:cached_iteration) { iteration }
53
+ it 'caches the iteration for this context' do
54
+ expect(cached_iteration).to eq iteration
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'cached!' do
63
+ it 'loads the value at runtime' do
64
+ expect(klass).to receive(:cached).with(:chef_run).once
65
+ expect(klass).to receive(:before).once
66
+
67
+ klass.cached!(:chef_run) { }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ # Note: These specs don't use Berkshelf code directly as this project doesn't
4
+ # have a direct dependency on Berkshelf and loading it would impact the
5
+ # perfance of these specs. While not ideal, the test doubles provide enough of
6
+ # a standin for Berkshelf to exercise the `#matches?` behavior.
7
+ describe ChefSpec::Coverage::BerkshelfFilter do
8
+ let(:dependencies) do
9
+ [double('Berkshelf::Dependency', metadata?: true, name: "cookbookery")]
10
+ end
11
+ let(:berksfile) { double('Berkshelf::Berksfile', dependencies: dependencies) }
12
+ let(:resource) { Chef::Resource.new('theone') }
13
+ subject { described_class.new(berksfile) }
14
+
15
+ describe '#matches?' do
16
+ it 'returns truthy if resource source_line is nil' do
17
+ expect(subject.matches?(resource)).to be_truthy
18
+ end
19
+
20
+ context 'when resource#source_line is under target cookbook' do
21
+ it 'normal unix path returns truthy' do
22
+ resource.source_line =
23
+ '/path/to/cookbooks/nope/recipes/default.rb:22'
24
+ expect(subject.matches?(resource)).to be_truthy
25
+ end
26
+
27
+ it 'normal windows path returns truthy' do
28
+ resource.source_line =
29
+ 'C:\\path\\to\\cookbooks\\nope\\recipes\\default.rb:22'
30
+ expect(subject.matches?(resource)).to be_truthy
31
+ end
32
+
33
+ it 'mixed windows path returns truthy' do
34
+ resource.source_line =
35
+ 'C:\\path\\to\\cookbooks/nope/recipes/default.rb:22'
36
+ expect(subject.matches?(resource)).to be_truthy
37
+ end
38
+ end
39
+
40
+ context 'when resource#source_line is not under target cookbook' do
41
+ it 'normal unix path returns falsey' do
42
+ resource.source_line =
43
+ '/path/to/cookbooks/cookbookery/recipes/default.rb:22'
44
+ expect(subject.matches?(resource)).to be_falsey
45
+ end
46
+
47
+ it 'normal windows path returns falsey' do
48
+ resource.source_line =
49
+ 'C:\\path\\to\\cookbooks\\cookbookery\\recipes\\default.rb:22'
50
+ expect(subject.matches?(resource)).to be_falsey
51
+ end
52
+
53
+ it 'mixed windows path returns falsey' do
54
+ resource.source_line =
55
+ 'C:\\path\\to\\cookbooks/cookbookery/recipes/default.rb:22'
56
+ expect(subject.matches?(resource)).to be_falsey
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe ChefSpec::Runner do
4
+ before do
5
+ allow_any_instance_of(ChefSpec::SoloRunner)
6
+ .to receive(:dry_run?)
7
+ .and_return(true)
8
+ allow(ChefSpec::Runner).to receive(:deprecated)
9
+ end
10
+
11
+ describe '#define_runner_method' do
12
+ before do
13
+ allow(ChefSpec).to receive(:define_matcher)
14
+ end
15
+
16
+ it 'prints a deprecation' do
17
+ expect(ChefSpec::Runner).to receive(:deprecated)
18
+ .with("`ChefSpec::Runner.define_runner_method' is deprecated."\
19
+ " It is being used in the my_custom_resource resource matcher." \
20
+ " Please use `ChefSpec.define_matcher' instead.")
21
+ ChefSpec::Runner.define_runner_method(:my_custom_resource)
22
+ end
23
+
24
+ it 'calls ChefSpec#define_matcher' do
25
+ expect(ChefSpec).to receive(:define_matcher).with(:my_custom_resource).once
26
+ ChefSpec::Runner.define_runner_method(:my_custom_resource)
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ describe ChefSpec::Server do
33
+ before do
34
+ allow(ChefSpec::Server).to receive(:deprecated)
35
+ end
36
+
37
+ it 'prints a deprecation for any method called' do
38
+ expect(ChefSpec::Server).to receive(:deprecated)
39
+ .with("`ChefSpec::Server.any_method' is deprecated. There is no longer" \
40
+ " a global Chef Server instance. Please use a ChefSpec::SoloRunner" \
41
+ " instead. More documentation can be found in the ChefSpec README."
42
+ )
43
+ expect {
44
+ ChefSpec::Server.any_method
45
+ }.to raise_error(ChefSpec::Error::NoConversionError)
46
+ end
47
+
48
+ it 'raises non-conversion error for any method called' do
49
+ expect{ChefSpec::Server.any_method}
50
+ .to raise_error(ChefSpec::Error::NoConversionError)
51
+ end
52
+
53
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ module ChefSpec::Error
4
+ describe CommandNotStubbed do
5
+ let(:instance) { described_class.new(args: ['cat']) }
6
+
7
+ it 'raises an exception with the correct message' do
8
+ instance
9
+ expect { raise instance }.to raise_error { |error|
10
+ expect(error).to be_a(described_class)
11
+ expect(error.message).to eq <<-EOH.gsub(/^ {10}/, '')
12
+ Executing a real command is disabled. Unregistered command:
13
+
14
+ command("cat")
15
+
16
+ You can stub this command with:
17
+
18
+ stub_command("cat").and_return(...)
19
+ EOH
20
+ }
21
+ end
22
+ end
23
+
24
+ describe CookbookPathNotFound do
25
+ let(:instance) { described_class.new }
26
+
27
+ it 'raises an exception with the correct message' do
28
+ expect { raise instance }.to raise_error { |error|
29
+ expect(error).to be_a(described_class)
30
+ expect(error.message).to eq <<-EOH.gsub(/^ {10}/, '')
31
+ I could not find or infer a cookbook_path from your current working directory.
32
+ Please make sure you put your specs (tests) under a directory named 'spec' or
33
+ manually set the cookbook path in the RSpec configuration.
34
+ EOH
35
+ }
36
+ end
37
+ end
38
+
39
+ describe GemLoadError do
40
+ let(:instance) { described_class.new(gem: 'bacon', name: 'bacon') }
41
+
42
+ it 'raises an exception with the correct message' do
43
+ expect { raise instance }.to raise_error { |error|
44
+ expect(error).to be_a(described_class)
45
+ expect(error.message).to eq <<-EOH.gsub(/^ {10}/, '')
46
+ I could not load the 'bacon' gem! You must have the gem installed
47
+ on your local system before you can use the bacon plugin.
48
+ You can install bacon by running:
49
+
50
+ gem install bacon
51
+
52
+ or add bacon to your Gemfile and run the `bundle` command to install.
53
+ EOH
54
+ }
55
+ end
56
+ end
57
+ end