chefspec 7.3.3 → 7.3.4

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.
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