ecomdev-chefspec 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/lib/ecomdev/chefspec/api.rb +5 -1
- data/lib/ecomdev/chefspec/api/helpers/runner.rb +143 -0
- data/lib/ecomdev/chefspec/api/matchers/multiline_string.rb +38 -0
- data/lib/ecomdev/chefspec/api/stubs/file_system.rb +16 -0
- data/lib/ecomdev/chefspec/api/{include_recipe.rb → stubs/include_recipe.rb} +3 -5
- data/lib/ecomdev/chefspec/stub/file_system.rb +75 -0
- data/lib/ecomdev/chefspec/stub/include_recipe.rb +3 -3
- data/lib/ecomdev/chefspec/version.rb +1 -1
- data/spec/unit/api/helpers/runner/proxy_spec.rb +208 -0
- data/spec/unit/api/helpers/runner_spec.rb +7 -0
- data/spec/unit/api/matchers/multiline_string_spec.rb +69 -0
- data/spec/unit/api/stubs/file_system_spec.rb +36 -0
- data/spec/unit/{stub/include_recipe/test_spec.rb → api/stubs/include_recipe_spec.rb} +1 -0
- data/spec/unit/stub/file_system_spec.rb +80 -0
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c58f9d004b789d825cc778750855a9aa2e71a661
|
4
|
+
data.tar.gz: 8fd41e808e4df754f1ca203d8cde61e03bf7b669
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 161d79a0c32946662eb7114c18b0fdbf0d90433da2a333c527130fc2139e3744ae0dcf8e83744649d3f975753629144f9d26e0ec6ad113aa5d31d917d4baacb3
|
7
|
+
data.tar.gz: 7ccf603f119bad18cbf7d04232b76724277358ac7873c6b8dbde822a24923a9e05c3cf4f866271ef9e86fa2e58c594a0cccc90bd3bc59ba41f70cb8c4909b7f2
|
data/lib/ecomdev/chefspec/api.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
1
|
require 'chefspec/api'
|
2
2
|
|
3
|
-
|
3
|
+
# Api include stubs
|
4
|
+
require_relative 'api/stubs/include_recipe'
|
5
|
+
require_relative 'api/stubs/file_system'
|
6
|
+
require_relative 'api/matchers/multiline_string'
|
7
|
+
require_relative 'api/helpers/runner'
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
module EcomDevHelpersRunner
|
3
|
+
def chef_run_proxy
|
4
|
+
RunnerProxy
|
5
|
+
end
|
6
|
+
|
7
|
+
class RunnerProxy
|
8
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^instance_variable_get|^initialize|^__|^send$|^object_id$)/ }
|
9
|
+
|
10
|
+
def initialize(*args, &before_initialize)
|
11
|
+
@args = args
|
12
|
+
@constructor_block = before_initialize
|
13
|
+
@target = nil
|
14
|
+
@blocks = {
|
15
|
+
:before => {},
|
16
|
+
:block => {},
|
17
|
+
:after => {}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def options(options = {}, override = false)
|
22
|
+
if @args.length == 0
|
23
|
+
@args << options
|
24
|
+
return @args[0]
|
25
|
+
end
|
26
|
+
if override
|
27
|
+
@args[0] = options
|
28
|
+
else
|
29
|
+
@args[0] = options.merge(@args[0])
|
30
|
+
end
|
31
|
+
@args[0]
|
32
|
+
end
|
33
|
+
|
34
|
+
def before(method, instance_eval = true, &block)
|
35
|
+
define_proxy_block(method, :before, instance_eval, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def after(method, instance_eval = true, &block)
|
39
|
+
define_proxy_block(method, :after, instance_eval, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def block(method, instance_eval = true, &block)
|
43
|
+
define_proxy_block(method, :block, instance_eval, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def proxy_blocks
|
47
|
+
@blocks
|
48
|
+
end
|
49
|
+
|
50
|
+
def runner
|
51
|
+
target
|
52
|
+
end
|
53
|
+
|
54
|
+
# Proxied chef runner
|
55
|
+
protected
|
56
|
+
def define_proxy_block(method, type, instance_eval = true, &block)
|
57
|
+
if block_given?
|
58
|
+
@blocks[type][method] ||= Array.new
|
59
|
+
@blocks[type][method] << {block: block, instance_eval: instance_eval}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def block_for?(method, type)
|
64
|
+
@blocks.key?(type) && @blocks[type].key?(method) && @blocks[type][method].is_a?(Array)
|
65
|
+
end
|
66
|
+
|
67
|
+
def invoke_blocks(method, type, *args, &block)
|
68
|
+
blocks_to_exec = []
|
69
|
+
if block_given?
|
70
|
+
blocks_to_exec << {block: block, instance_eval: false, caller_block: true}
|
71
|
+
end
|
72
|
+
|
73
|
+
if block_for?(method, type)
|
74
|
+
blocks_to_exec.push(@blocks[type][method]).flatten!
|
75
|
+
end
|
76
|
+
|
77
|
+
blocks_to_exec.each do |info|
|
78
|
+
if info[:instance_eval]
|
79
|
+
target.instance_exec(*args, &info[:block])
|
80
|
+
else
|
81
|
+
calling_args = args.clone
|
82
|
+
unless info.key?(:caller_block) && info[:caller_block]
|
83
|
+
calling_args.unshift(target)
|
84
|
+
end
|
85
|
+
info[:block].call(*calling_args)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def method_missing(name, *args, &block)
|
91
|
+
invoke_blocks(name, :before, *args)
|
92
|
+
result = target.send(name, *args) do |*block_args|
|
93
|
+
invoke_blocks(name, :block, *block_args, &block)
|
94
|
+
end
|
95
|
+
args.unshift(result)
|
96
|
+
invoke_blocks(name, :after, *args)
|
97
|
+
result
|
98
|
+
end
|
99
|
+
|
100
|
+
def target
|
101
|
+
unless @target.nil?
|
102
|
+
return @target
|
103
|
+
end
|
104
|
+
block_args = nil
|
105
|
+
@target = ChefSpec::Runner.new(*@args) do |*args|
|
106
|
+
block_args = args
|
107
|
+
end
|
108
|
+
invoke_blocks(:initialize, :block, *block_args, &@constructor_block)
|
109
|
+
@target
|
110
|
+
end
|
111
|
+
|
112
|
+
class << self
|
113
|
+
def instance(*args, &block)
|
114
|
+
proxy = self.new(*args, &block)
|
115
|
+
proxy_calls.each do |call|
|
116
|
+
proxy.send(call[:method], *call[:args], &call[:block])
|
117
|
+
end
|
118
|
+
reset
|
119
|
+
proxy
|
120
|
+
end
|
121
|
+
|
122
|
+
def reset
|
123
|
+
proxy_calls([])
|
124
|
+
self
|
125
|
+
end
|
126
|
+
|
127
|
+
def method_missing(method, *args, &block)
|
128
|
+
proxy_calls.push({method: method, args: args, block: block})
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
def proxy_calls(calls=nil)
|
134
|
+
@calls ||= []
|
135
|
+
unless calls.nil?
|
136
|
+
@calls = calls
|
137
|
+
end
|
138
|
+
@calls
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
module EcomDevMatcherMultilineString
|
3
|
+
|
4
|
+
module Matcher
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def matcher(expected)
|
8
|
+
RSpec::Matchers::BuiltIn::Match.new(expected)
|
9
|
+
end
|
10
|
+
|
11
|
+
def regexp(match, before ='', after = '')
|
12
|
+
unless match.is_a?(Regexp)
|
13
|
+
match = ::Regexp.escape(match).tr_s('\\ ', '\\s')
|
14
|
+
else
|
15
|
+
match = match.source
|
16
|
+
end
|
17
|
+
|
18
|
+
::Regexp.new(before + match + after, Regexp::MULTILINE)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def start_line_with(match)
|
23
|
+
Matcher::matcher(Matcher::regexp(match, '^'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def end_line_with(match)
|
27
|
+
Matcher::matcher(Matcher::regexp(match, '', '$'))
|
28
|
+
end
|
29
|
+
|
30
|
+
def contain_line(match)
|
31
|
+
Matcher::matcher(Matcher::regexp(match, '^.*', '.*$'))
|
32
|
+
end
|
33
|
+
|
34
|
+
def contain_full_line(match)
|
35
|
+
Matcher::matcher(Matcher::regexp(match, '^\s*', '\s*$'))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../../stub/file_system'
|
2
|
+
|
3
|
+
module ChefSpec::API::EcomDevStubsFileSystem
|
4
|
+
def stub_file_exists(file, exists = true)
|
5
|
+
EcomDev::ChefSpec::Stub::FileSystem.instance.file_exists(file, exists)
|
6
|
+
end
|
7
|
+
|
8
|
+
def stub_dir_glob(path, result = [])
|
9
|
+
EcomDev::ChefSpec::Stub::FileSystem.instance.dir_glob(path, result)
|
10
|
+
end
|
11
|
+
|
12
|
+
def stub_file_read(file, content, *additional_args)
|
13
|
+
EcomDev::ChefSpec::Stub::FileSystem.instance.file_read(file, content, *additional_args)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -1,13 +1,11 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../../stub/include_recipe'
|
2
2
|
|
3
3
|
module ChefSpec::API
|
4
|
-
module
|
4
|
+
module EcomDevStubsIncludeRecipe
|
5
5
|
def allow_recipe(*recipe_name)
|
6
6
|
recipe_name.flatten.each do |recipe|
|
7
7
|
EcomDev::ChefSpec::Stub::IncludeRecipe.allow_recipe(recipe)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
11
|
-
end
|
12
|
-
|
13
|
-
EcomDev::ChefSpec::Configuration.callback(EcomDev::ChefSpec::Stub::IncludeRecipe)
|
11
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module EcomDev::ChefSpec::Stub
|
2
|
+
class FileSystem
|
3
|
+
class << self
|
4
|
+
extend Forwardable
|
5
|
+
def_delegators :instance, :allow_recipe, :reset
|
6
|
+
end
|
7
|
+
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@current_example = nil
|
12
|
+
@stubs = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_example(example)
|
16
|
+
@current_example = example
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_example
|
20
|
+
@current_example
|
21
|
+
end
|
22
|
+
|
23
|
+
def after_example
|
24
|
+
@current_example = nil
|
25
|
+
@stubs.clear
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [RSpec::Mocks::Matchers::Receive]
|
29
|
+
def stub(klass, method, static=false)
|
30
|
+
@stubs[static.to_s] ||= {}
|
31
|
+
@stubs[static.to_s][klass.to_s] ||= []
|
32
|
+
stub_method = static ? :allow : :allow_any_instance_of
|
33
|
+
method = method.to_sym
|
34
|
+
unless @stubs[static.to_s][klass.to_s].include?(method)
|
35
|
+
@stubs[static.to_s][klass.to_s] << method
|
36
|
+
current_example.send(stub_method, klass).to current_example.receive(method).and_call_original
|
37
|
+
end
|
38
|
+
|
39
|
+
allowance = current_example.receive(method)
|
40
|
+
if block_given?
|
41
|
+
yield allowance
|
42
|
+
end
|
43
|
+
|
44
|
+
current_example.send(stub_method, klass).to allowance
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_exists(file, exists = true)
|
48
|
+
stub(File, :exists?, true) do |stub|
|
49
|
+
stub.with(file).and_return(exists)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def file_read(file, content, *additional_args)
|
54
|
+
stub(File, :read, true) do |stub|
|
55
|
+
stub.with(file, *additional_args).and_return(content)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def dir_glob(path, result = [])
|
60
|
+
stub(Dir, :glob, true) do |stub|
|
61
|
+
stub.with(path).and_return(result)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
RSpec.configure do |c|
|
68
|
+
c.before(:each) do
|
69
|
+
EcomDev::ChefSpec::Stub::FileSystem.instance.before_example(self)
|
70
|
+
end
|
71
|
+
|
72
|
+
c.after(:each) do
|
73
|
+
EcomDev::ChefSpec::Stub::FileSystem.instance.after_example
|
74
|
+
end
|
75
|
+
end
|
@@ -2,7 +2,7 @@ module EcomDev::ChefSpec::Stub
|
|
2
2
|
class IncludeRecipe
|
3
3
|
class << self
|
4
4
|
extend Forwardable
|
5
|
-
def_delegators :instance, :
|
5
|
+
def_delegators :instance, :allow_recipe, :reset
|
6
6
|
end
|
7
7
|
|
8
8
|
include Singleton
|
@@ -51,7 +51,7 @@ module EcomDev::ChefSpec::Stub
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def after_example(
|
54
|
+
def after_example(*)
|
55
55
|
reset
|
56
56
|
end
|
57
57
|
end
|
@@ -68,4 +68,4 @@ RSpec.configure do |c|
|
|
68
68
|
c.after(:each) do
|
69
69
|
EcomDev::ChefSpec::Stub::IncludeRecipe.instance.after_example(self)
|
70
70
|
end
|
71
|
-
end
|
71
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefSpec::API::EcomDevHelpersRunner::RunnerProxy do
|
4
|
+
it 'does not create any method unless method of runner is executed' do
|
5
|
+
runner_proxy = described_class.new
|
6
|
+
expect(runner_proxy.instance_variable_get('@target')).to be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'passes constructor options to original constructor' do
|
10
|
+
runner_proxy = described_class.new(platform: 'ubuntu')
|
11
|
+
|
12
|
+
expect_any_instance_of(ChefSpec::Runner).to receive(:initialize).with({platform: 'ubuntu'}).and_call_original
|
13
|
+
allow_any_instance_of(ChefSpec::Runner).to receive(:node).and_return('fake')
|
14
|
+
|
15
|
+
# Call node method of proxied object
|
16
|
+
expect(runner_proxy.node).to eq('fake')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'allows specifying options for constructor later' do
|
20
|
+
runner_proxy = described_class.new
|
21
|
+
runner_proxy.options(platform: 'ubuntu')
|
22
|
+
expect(runner_proxy.instance_variable_get('@args')).to contain_exactly(platform: 'ubuntu')
|
23
|
+
expect(runner_proxy.instance_variable_get('@target')).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'allows overriding options for constructor later' do
|
27
|
+
runner_proxy = described_class.new(version: '14.0')
|
28
|
+
runner_proxy.options({platform: 'ubuntu'}, true)
|
29
|
+
expect(runner_proxy.instance_variable_get('@args')).to contain_exactly(platform: 'ubuntu')
|
30
|
+
expect(runner_proxy.instance_variable_get('@target')).to be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'adds a before method wrapper' do
|
34
|
+
runner_proxy = described_class.new
|
35
|
+
block = Proc.new { 'test' }
|
36
|
+
runner_proxy.before(:method_name, &block)
|
37
|
+
runner_proxy.before(:method_name, false, &block)
|
38
|
+
expect(runner_proxy.proxy_blocks[:before]).to eq(method_name: [
|
39
|
+
{block: block, instance_eval: true},
|
40
|
+
{block: block, instance_eval: false}
|
41
|
+
])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'adds a after method wrapper' do
|
45
|
+
runner_proxy = described_class.new
|
46
|
+
block = Proc.new { 'test' }
|
47
|
+
runner_proxy.after(:method_name, &block)
|
48
|
+
runner_proxy.after(:method_name, false, &block)
|
49
|
+
expect(runner_proxy.proxy_blocks[:after]).to eq(method_name: [
|
50
|
+
{block: block, instance_eval: true},
|
51
|
+
{block: block, instance_eval: false}
|
52
|
+
])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'adds a block as call in method' do
|
56
|
+
runner_proxy = described_class.new
|
57
|
+
block = Proc.new { 'test' }
|
58
|
+
runner_proxy.block(:method_name, &block)
|
59
|
+
runner_proxy.block(:method_name, false, &block)
|
60
|
+
expect(runner_proxy.proxy_blocks[:block]).to eq(method_name: [
|
61
|
+
{block: block, instance_eval: true},
|
62
|
+
{block: block, instance_eval: false}
|
63
|
+
])
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'runs added before block in scope of the target class' do
|
67
|
+
runner_proxy = described_class.new
|
68
|
+
checker = double('test')
|
69
|
+
|
70
|
+
block = Proc.new {
|
71
|
+
checker.called(self)
|
72
|
+
}
|
73
|
+
|
74
|
+
expect(checker).to receive(:called).with(instance_of(ChefSpec::Runner)).exactly(1).times
|
75
|
+
|
76
|
+
runner_proxy.before(:node, &block)
|
77
|
+
runner_proxy.node
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'runs added after block in scope of the target class and should recieve as an argument an instance of ' do
|
81
|
+
runner_proxy = described_class.new
|
82
|
+
checker = double('test')
|
83
|
+
|
84
|
+
block = Proc.new { |node, *args|
|
85
|
+
checker.called(self)
|
86
|
+
checker.node(node)
|
87
|
+
checker.args(args)
|
88
|
+
}
|
89
|
+
|
90
|
+
expect(checker).to receive(:node).with(instance_of(Chef::Node)).exactly(1).times
|
91
|
+
expect(checker).to receive(:args).with(Array.new).exactly(1).times
|
92
|
+
expect(checker).to receive(:called).with(instance_of(ChefSpec::Runner)).exactly(1).times
|
93
|
+
|
94
|
+
runner_proxy.after(:node, &block)
|
95
|
+
runner_proxy.node
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'runs added callee block in scope of the target class with initialize method' do
|
99
|
+
checker = double('test')
|
100
|
+
|
101
|
+
block = Proc.new { |node|
|
102
|
+
checker.called(self, node)
|
103
|
+
}
|
104
|
+
|
105
|
+
block_constructor = Proc.new { |node|
|
106
|
+
checker.called_constructor(self, node)
|
107
|
+
}
|
108
|
+
|
109
|
+
runner_proxy = described_class.new(&block_constructor)
|
110
|
+
|
111
|
+
expect(checker).to receive(:called).with(
|
112
|
+
instance_of(ChefSpec::Runner),
|
113
|
+
instance_of(Chef::Node)
|
114
|
+
).exactly(1).times
|
115
|
+
expect(checker).to receive(:called_constructor).with(
|
116
|
+
instance_of(self.class),
|
117
|
+
instance_of(Chef::Node)
|
118
|
+
).exactly(1).times
|
119
|
+
|
120
|
+
runner_proxy.block(:initialize, &block)
|
121
|
+
runner_proxy.node
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'runs added callee block in scope of the target class with converge method' do
|
125
|
+
checker = double('test')
|
126
|
+
|
127
|
+
block = Proc.new {
|
128
|
+
checker.called(self)
|
129
|
+
}
|
130
|
+
|
131
|
+
block_converge = Proc.new {
|
132
|
+
checker.called_converege(self)
|
133
|
+
}
|
134
|
+
|
135
|
+
runner_proxy = described_class.new
|
136
|
+
|
137
|
+
expect(checker).to receive(:called).with(
|
138
|
+
instance_of(ChefSpec::Runner)
|
139
|
+
).exactly(1).times
|
140
|
+
expect(checker).to receive(:called_converege).with(
|
141
|
+
instance_of(self.class)
|
142
|
+
).exactly(1).times
|
143
|
+
|
144
|
+
allow_any_instance_of(ChefSpec::Runner).to receive(:converge).and_yield
|
145
|
+
runner_proxy.block(:initialize, &block)
|
146
|
+
runner_proxy.converge(&block_converge)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'allows to execute any block outside of the target scope' do
|
150
|
+
checker = double('test')
|
151
|
+
|
152
|
+
block = Proc.new { |runner|
|
153
|
+
checker.called(self, runner)
|
154
|
+
}
|
155
|
+
|
156
|
+
runner_proxy = described_class.new
|
157
|
+
|
158
|
+
expect(checker).to receive(:called).with(
|
159
|
+
instance_of(self.class),
|
160
|
+
instance_of(ChefSpec::Runner)
|
161
|
+
).exactly(1).times
|
162
|
+
|
163
|
+
allow_any_instance_of(ChefSpec::Runner).to receive(:converge).and_yield
|
164
|
+
runner_proxy.block(:initialize, false, &block)
|
165
|
+
runner_proxy.converge
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'when in singleton mode' do
|
169
|
+
before (:each) { described_class.reset }
|
170
|
+
|
171
|
+
it 'records any method call into @calls property' do
|
172
|
+
block = Proc.new { 'test' }
|
173
|
+
|
174
|
+
described_class.some_method('arg1', 'arg2')
|
175
|
+
described_class.some_method2('arg1', 'arg2', &block)
|
176
|
+
described_class.some_method3('arg1', 'arg2', 'arg3')
|
177
|
+
|
178
|
+
expect(described_class.instance_variable_get(:@calls)).to contain_exactly(
|
179
|
+
{method: :some_method, args: %w(arg1 arg2), block: nil},
|
180
|
+
{method: :some_method2, args: %w(arg1 arg2), block: block},
|
181
|
+
{method: :some_method3, args: %w(arg1 arg2 arg3), block: nil}
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'calls recorded methods on instantiation of the chef runner' do
|
186
|
+
expect_any_instance_of(described_class).to receive(:some_method).with(*%w(arg1 arg2))
|
187
|
+
expect_any_instance_of(described_class).to receive(:some_method2).with(*%w(arg1 arg2)).and_yield
|
188
|
+
expect_any_instance_of(described_class).to receive(:some_method3).with(*%w(arg1 arg2 arg3))
|
189
|
+
|
190
|
+
block = Proc.new { 'test' }
|
191
|
+
|
192
|
+
described_class.some_method('arg1', 'arg2')
|
193
|
+
described_class.some_method2('arg1', 'arg2', &block)
|
194
|
+
described_class.some_method3('arg1', 'arg2', 'arg3')
|
195
|
+
|
196
|
+
expect(described_class.instance(option: 1).options).to eq(option: 1)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'clears method calls after instantiating proxy' do
|
200
|
+
expect_any_instance_of(described_class).to receive(:some_method).with(*%w(arg1 arg2))
|
201
|
+
described_class.some_method('arg1', 'arg2')
|
202
|
+
|
203
|
+
expect(described_class.instance(option: 1).options).to eq(option: 1)
|
204
|
+
expect(described_class.instance_variable_get(:@calls)).to be_empty
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefSpec::API::EcomDevMatcherMultilineString do
|
4
|
+
it 'should allow match line starts with' do
|
5
|
+
matcher = start_line_with('My Custom Text')
|
6
|
+
expect(matcher).to be_instance_of(RSpec::Matchers::BuiltIn::Match)
|
7
|
+
expect(matcher.expected).to eq(/^My\sCustom\sText/m)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should allow match line ends with' do
|
11
|
+
matcher = end_line_with('My Custom Text')
|
12
|
+
expect(matcher).to be_instance_of(RSpec::Matchers::BuiltIn::Match)
|
13
|
+
expect(matcher.expected).to eq(/My\sCustom\sText$/m)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should allow match any part of a line with expected content' do
|
17
|
+
matcher = contain_line('My Custom Text')
|
18
|
+
expect(matcher).to be_instance_of(RSpec::Matchers::BuiltIn::Match)
|
19
|
+
expect(matcher.expected).to eq(/^.*My\sCustom\sText.*$/m)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should allow match whole line with expected content' do
|
23
|
+
matcher = contain_full_line('My Custom Text')
|
24
|
+
expect(matcher).to be_instance_of(RSpec::Matchers::BuiltIn::Match)
|
25
|
+
expect(matcher.expected).to eq(/^\s*My\sCustom\sText\s*$/m)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when line text is provided it ' do
|
29
|
+
let (:some_text) do
|
30
|
+
<<-EOF.gsub /^( |\t)+/, ''
|
31
|
+
1 Left 1 Middle Right 1
|
32
|
+
2 Left 2 Middle Right 2
|
33
|
+
3 Left 3 Middle Right 3
|
34
|
+
4 Left 4 Middle Right 4
|
35
|
+
5 Left 5 Middle Right 5
|
36
|
+
EOF
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'matches beginning of line correctly' do
|
40
|
+
expect(some_text).to start_line_with('1 Left')
|
41
|
+
expect(some_text).to start_line_with('2 Left')
|
42
|
+
expect(some_text).not_to start_line_with('Right 1')
|
43
|
+
expect(some_text).not_to start_line_with('Right 2')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'matches end of line correctly' do
|
47
|
+
expect(some_text).to end_line_with('Right 1')
|
48
|
+
expect(some_text).to end_line_with('Right 2')
|
49
|
+
|
50
|
+
expect(some_text).not_to end_line_with('1 Left')
|
51
|
+
expect(some_text).not_to end_line_with('2 Left')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'matches any part of line correctly' do
|
55
|
+
expect(some_text).to contain_line('1 Middle')
|
56
|
+
expect(some_text).to contain_line('2 Middle')
|
57
|
+
expect(some_text).not_to contain_line('Left Middle 1')
|
58
|
+
expect(some_text).not_to contain_line('Left Middle 2')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'matches full line correctly' do
|
62
|
+
expect(some_text).to contain_full_line('1 Left 1 Middle Right 1')
|
63
|
+
expect(some_text).to contain_full_line('2 Left 2 Middle Right 2')
|
64
|
+
expect(some_text).not_to contain_line('1 Left Middle 1 Right 1')
|
65
|
+
expect(some_text).not_to contain_line('2 Left Middle 2 Right 2')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefSpec::API::EcomDevStubsFileSystem do
|
4
|
+
describe '#file_exists' do
|
5
|
+
it 'stubs File.exists method' do
|
6
|
+
stub_file_exists('test-file-non-exists-in-real-system')
|
7
|
+
stub_file_exists(__FILE__, false)
|
8
|
+
|
9
|
+
expect(File.exists?(__FILE__)).to eq(false)
|
10
|
+
expect(File.exists?('test-file-non-exists-in-real-system')).to eq(true)
|
11
|
+
expect(File.exists?(File.dirname(__FILE__))).to eq(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#dir_glob' do
|
16
|
+
it 'stubs Dir.glob method' do
|
17
|
+
stub_dir_glob('test.rb')
|
18
|
+
stub_dir_glob('test/match*.rb', %w(test/match-file.rb))
|
19
|
+
|
20
|
+
expect(Dir.glob('test/match*.rb')).to contain_exactly('test/match-file.rb')
|
21
|
+
expect(Dir.glob('test.rb')).to be_instance_of(Array).and be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#file_read' do
|
26
|
+
it 'stubs File.read method' do
|
27
|
+
stub_file_read('test.rb', 'test content')
|
28
|
+
expect(File.read('test.rb')).to eq('test content')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'allows to pass additional arguments for File.read' do
|
32
|
+
stub_file_read('test.rb', 'est c', 1, 5, 'r')
|
33
|
+
expect(File.read('test.rb', 1, 5, 'r')).to eq('est c')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EcomDev::ChefSpec::Stub::FileSystem do
|
4
|
+
describe '#before_example' do
|
5
|
+
it 'sets current example before' do
|
6
|
+
expect(described_class.instance.instance_variable_get('@current_example')).to eq(self)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#current_example' do
|
11
|
+
it 'returns current example' do
|
12
|
+
expect(described_class.instance.current_example).to eq(self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#after_example' do
|
17
|
+
it 'clears example on after callback' do
|
18
|
+
described_class.instance.after_example
|
19
|
+
expect(described_class.instance.current_example).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'clears stubs array on after callback' do
|
23
|
+
described_class.instance.stub(Dir, :glob, true)
|
24
|
+
described_class.instance.after_example
|
25
|
+
expect(described_class.instance.instance_variable_get(:@stubs)).to be_instance_of(Hash).and be_empty
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#stub' do
|
30
|
+
it 'returns a receiver matcher for object' do
|
31
|
+
described_class.instance.stub(Dir, :glob, true) do |stub|
|
32
|
+
expect(stub).to be_instance_of(RSpec::Mocks::Matchers::Receive)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'stubs glob calls only with required parameters and the rest are calling original' do
|
37
|
+
described_class.instance.stub(Dir, :glob, true) do |stub|
|
38
|
+
stub.with('test_dir/*.rb').and_return(%w(test_dir/file.rb))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Default behaviour
|
42
|
+
expect(Dir.glob(__FILE__)).to contain_exactly(__FILE__)
|
43
|
+
# Stubbed behaviour
|
44
|
+
expect(Dir.glob('test_dir/*.rb')).to contain_exactly('test_dir/file.rb')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#file_exists' do
|
49
|
+
it 'stubs File.exists method' do
|
50
|
+
described_class.instance.file_exists('test-file-non-exists-in-real-system')
|
51
|
+
described_class.instance.file_exists(__FILE__, false)
|
52
|
+
|
53
|
+
expect(File.exists?(__FILE__)).to eq(false)
|
54
|
+
expect(File.exists?('test-file-non-exists-in-real-system')).to eq(true)
|
55
|
+
expect(File.exists?(File.dirname(__FILE__))).to eq(true)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#dir_glob' do
|
60
|
+
it 'stubs Dir.glob method' do
|
61
|
+
described_class.instance.dir_glob('test/match*.rb', %w(test/match-file.rb))
|
62
|
+
described_class.instance.dir_glob('test.rb')
|
63
|
+
|
64
|
+
expect(Dir.glob('test/match*.rb')).to contain_exactly('test/match-file.rb')
|
65
|
+
expect(Dir.glob('test.rb')).to be_instance_of(Array).and be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#file_read' do
|
70
|
+
it 'stubs File.read method' do
|
71
|
+
described_class.instance.file_read('test.rb', 'test content')
|
72
|
+
expect(File.read('test.rb')).to eq('test content')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'allows to pass additional arguments for File.read' do
|
76
|
+
described_class.instance.file_read('test.rb', 'est c', 1, 5, 'r')
|
77
|
+
expect(File.read('test.rb', 1, 5, 'r')).to eq('est c')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecomdev-chefspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Chepurnyi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chefspec
|
@@ -70,19 +70,28 @@ files:
|
|
70
70
|
- lib/ecomdev-chefspec.rb
|
71
71
|
- lib/ecomdev/chefspec.rb
|
72
72
|
- lib/ecomdev/chefspec/api.rb
|
73
|
-
- lib/ecomdev/chefspec/api/
|
73
|
+
- lib/ecomdev/chefspec/api/helpers/runner.rb
|
74
|
+
- lib/ecomdev/chefspec/api/matchers/multiline_string.rb
|
75
|
+
- lib/ecomdev/chefspec/api/stubs/file_system.rb
|
76
|
+
- lib/ecomdev/chefspec/api/stubs/include_recipe.rb
|
74
77
|
- lib/ecomdev/chefspec/configuration.rb
|
75
78
|
- lib/ecomdev/chefspec/resource/matcher.rb
|
76
79
|
- lib/ecomdev/chefspec/resource/matcher/dsl.rb
|
77
80
|
- lib/ecomdev/chefspec/resource/matcher/helper.rb
|
81
|
+
- lib/ecomdev/chefspec/stub/file_system.rb
|
78
82
|
- lib/ecomdev/chefspec/stub/include_recipe.rb
|
79
83
|
- lib/ecomdev/chefspec/version.rb
|
80
84
|
- spec/spec_helper.rb
|
85
|
+
- spec/unit/api/helpers/runner/proxy_spec.rb
|
86
|
+
- spec/unit/api/helpers/runner_spec.rb
|
87
|
+
- spec/unit/api/matchers/multiline_string_spec.rb
|
88
|
+
- spec/unit/api/stubs/file_system_spec.rb
|
89
|
+
- spec/unit/api/stubs/include_recipe_spec.rb
|
81
90
|
- spec/unit/configuration_spec.rb
|
82
91
|
- spec/unit/matcher/dsl_spec.rb
|
83
92
|
- spec/unit/matcher/helper_spec.rb
|
84
93
|
- spec/unit/matcher_spec.rb
|
85
|
-
- spec/unit/stub/
|
94
|
+
- spec/unit/stub/file_system_spec.rb
|
86
95
|
- spec/unit/stub/include_recipe_spec.rb
|
87
96
|
homepage: https://github.com/IvanChepurnyi/ecomdev-chefspec
|
88
97
|
licenses:
|
@@ -110,10 +119,15 @@ specification_version: 4
|
|
110
119
|
summary: A collection of helpers for chef spec, to make easier writing recipe specs
|
111
120
|
test_files:
|
112
121
|
- spec/spec_helper.rb
|
122
|
+
- spec/unit/api/helpers/runner/proxy_spec.rb
|
123
|
+
- spec/unit/api/helpers/runner_spec.rb
|
124
|
+
- spec/unit/api/matchers/multiline_string_spec.rb
|
125
|
+
- spec/unit/api/stubs/file_system_spec.rb
|
126
|
+
- spec/unit/api/stubs/include_recipe_spec.rb
|
113
127
|
- spec/unit/configuration_spec.rb
|
114
128
|
- spec/unit/matcher/dsl_spec.rb
|
115
129
|
- spec/unit/matcher/helper_spec.rb
|
116
130
|
- spec/unit/matcher_spec.rb
|
117
|
-
- spec/unit/stub/
|
131
|
+
- spec/unit/stub/file_system_spec.rb
|
118
132
|
- spec/unit/stub/include_recipe_spec.rb
|
119
133
|
has_rdoc:
|