ecomdev-chefspec 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|