producer-core 0.1.12 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Guardfile +4 -3
  3. data/features/actions/file_replace_content.feature +31 -0
  4. data/features/recipes/registry.feature +21 -0
  5. data/features/steps/remote_steps.rb +8 -0
  6. data/features/tasks/registry.feature +13 -0
  7. data/features/tests/file_contains.feature +28 -0
  8. data/lib/producer/core/action.rb +0 -2
  9. data/lib/producer/core/actions/file_replace_content.rb +27 -0
  10. data/lib/producer/core/condition/dsl.rb +4 -3
  11. data/lib/producer/core/env.rb +15 -5
  12. data/lib/producer/core/recipe/dsl.rb +8 -0
  13. data/lib/producer/core/remote/environment.rb +0 -2
  14. data/lib/producer/core/remote/fs.rb +9 -9
  15. data/lib/producer/core/remote.rb +1 -4
  16. data/lib/producer/core/task/dsl.rb +7 -2
  17. data/lib/producer/core/test.rb +0 -2
  18. data/lib/producer/core/testing/mock_remote.rb +25 -0
  19. data/lib/producer/core/testing.rb +1 -0
  20. data/lib/producer/core/tests/file_contains.rb +18 -0
  21. data/lib/producer/core/version.rb +1 -1
  22. data/lib/producer/core.rb +9 -0
  23. data/producer-core.gemspec +2 -2
  24. data/spec/producer/core/action_spec.rb +1 -42
  25. data/spec/producer/core/actions/echo_spec.rb +11 -8
  26. data/spec/producer/core/actions/file_replace_content_spec.rb +49 -0
  27. data/spec/producer/core/actions/file_writer_spec.rb +20 -17
  28. data/spec/producer/core/actions/mkdir_spec.rb +15 -13
  29. data/spec/producer/core/actions/shell_command_spec.rb +16 -14
  30. data/spec/producer/core/condition/dsl_spec.rb +53 -51
  31. data/spec/producer/core/env_spec.rb +30 -2
  32. data/spec/producer/core/prompter_spec.rb +0 -1
  33. data/spec/producer/core/recipe/dsl_spec.rb +82 -66
  34. data/spec/producer/core/remote/environment_spec.rb +32 -30
  35. data/spec/producer/core/remote/fs_spec.rb +100 -104
  36. data/spec/producer/core/remote_spec.rb +4 -13
  37. data/spec/producer/core/task/dsl_spec.rb +82 -72
  38. data/spec/producer/core/task_spec.rb +1 -1
  39. data/spec/producer/core/test_spec.rb +1 -77
  40. data/spec/producer/core/testing/mock_remote_spec.rb +46 -0
  41. data/spec/producer/core/tests/file_contains_spec.rb +46 -0
  42. data/spec/producer/core/tests/has_dir_spec.rb +15 -18
  43. data/spec/producer/core/tests/has_env_spec.rb +34 -34
  44. data/spec/producer/core/tests/has_file_spec.rb +15 -18
  45. data/spec/spec_helper.rb +3 -3
  46. data/spec/support/shared_action.rb +44 -0
  47. data/spec/support/shared_test.rb +82 -0
  48. data/spec/support/test_env_helpers.rb +34 -0
  49. metadata +33 -9
@@ -1,97 +1,88 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Producer::Core
4
- describe Remote::FS do
5
- let(:remote) { Remote.new('some_host.example') }
6
- subject(:fs) { Remote::FS.new(remote) }
7
-
8
- describe '#new' do
9
- it 'assigns the remote given as argument' do
10
- expect(fs.remote).to be remote
4
+ class Remote
5
+ describe FS do
6
+ let(:sftp_file) { double 'sftp_file' }
7
+ let(:sftp) { double('sftp', file: sftp_file) }
8
+ subject(:fs) { FS.new(sftp) }
9
+
10
+ describe '#initialize' do
11
+ it 'assigns the sftp session' do
12
+ expect(fs.sftp).to be sftp
13
+ end
11
14
  end
12
- end
13
15
 
14
- describe '#sftp', :ssh do
15
- before { sftp_story }
16
+ describe '#dir?' do
17
+ let(:path) { 'some_directory_path' }
18
+ let(:stat) { double 'stat' }
16
19
 
17
- it 'builds a new SFTP session' do
18
- expect(remote.session.sftp).to receive :connect
19
- fs.sftp
20
- end
20
+ before { allow(sftp).to receive(:stat!).with(path) { stat } }
21
21
 
22
- it 'returns the new SFTP session' do
23
- session = double 'session'
24
- allow(remote.session.sftp).to receive(:connect) { session }
25
- expect(fs.sftp).to be session
26
- end
22
+ context 'when path given as argument is a directory' do
23
+ before { allow(stat).to receive(:directory?) { true } }
27
24
 
28
- it 'memoizes the FS' do
29
- allow(remote.session.sftp).to receive(:connect) { Object.new }
30
- expect(fs.sftp).to be fs.sftp
31
- end
32
- end
33
-
34
- describe '#dir?' do
35
- let(:sftp) { double('sftp').as_null_object }
36
- let(:path) { 'some_directory_path' }
37
- let(:stat) { double 'stat' }
38
-
39
- before do
40
- allow(fs).to receive(:sftp) { sftp }
41
- allow(sftp).to receive(:stat!).with(path) { stat }
42
- end
25
+ it 'returns true' do
26
+ expect(fs.dir? path).to be true
27
+ end
28
+ end
43
29
 
44
- context 'when path given as argument is a directory' do
45
- before { allow(stat).to receive(:directory?) { true } }
30
+ context 'when path given as argument is not a directory' do
31
+ before { allow(stat).to receive(:directory?) { false } }
46
32
 
47
- it 'returns true' do
48
- expect(fs.dir? path).to be true
33
+ it 'returns false' do
34
+ expect(fs.dir? path).to be false
35
+ end
49
36
  end
50
- end
51
37
 
52
- context 'when path given as argument is not a directory' do
53
- before { allow(stat).to receive(:directory?) { false } }
38
+ context 'when querying the path raises a Net::SFTP::StatusException' do
39
+ before do
40
+ response = double 'response', code: '42', message: 'some message'
41
+ ex = Net::SFTP::StatusException.new(response)
42
+ allow(sftp).to receive(:stat!).with(path).and_raise(ex)
43
+ end
54
44
 
55
- it 'returns false' do
56
- expect(fs.dir? path).to be false
45
+ it 'returns false' do
46
+ expect(fs.dir? path).to be false
47
+ end
57
48
  end
58
49
  end
59
50
 
60
- context 'when querying the path raises a Net::SFTP::StatusException' do
51
+ # FIXME: We rely a lot on mocking net-sftp heavily, while we already use a
52
+ # part of net-ssh story helpers, which are more close to integration tests.
53
+ describe '#file?', :ssh do
54
+ let(:file_path) { 'some_file_path' }
55
+ let(:stat) { double 'stat' }
56
+
61
57
  before do
62
- response = double 'response', code: '42', message: 'some message'
63
- ex = Net::SFTP::StatusException.new(response)
64
- allow(sftp).to receive(:stat!).with(path).and_raise(ex)
58
+ sftp_story
59
+ allow(fs.sftp).to receive(:stat!) { stat }
65
60
  end
66
61
 
67
- it 'returns false' do
68
- expect(fs.dir? path).to be false
69
- end
70
- end
71
- end
72
-
73
- # FIXME: We rely a lot on mocking net-sftp heavily, while we already use a
74
- # part of net-ssh story helpers, which are more close to integration tests.
75
- describe '#file?', :ssh do
76
- let(:file_path) { 'some_file_path' }
77
- let(:stat) { double 'stat' }
62
+ context 'when path given as argument exists' do
63
+ context 'when path is a file' do
64
+ before { allow(stat).to receive(:file?) { true } }
78
65
 
79
- before do
80
- sftp_story
81
- allow(fs.sftp).to receive(:stat!) { stat }
82
- end
66
+ it 'returns true' do
67
+ expect(fs.file? file_path).to be true
68
+ end
69
+ end
83
70
 
84
- context 'when path given as argument exists' do
85
- context 'when path is a file' do
86
- before { allow(stat).to receive(:file?) { true } }
71
+ context 'when path is not a file' do
72
+ before { allow(stat).to receive(:file?) { false } }
87
73
 
88
- it 'returns true' do
89
- expect(fs.file? file_path).to be true
74
+ it 'returns false' do
75
+ expect(fs.file? file_path).to be false
76
+ end
90
77
  end
91
78
  end
92
79
 
93
- context 'when path is not a file' do
94
- before { allow(stat).to receive(:file?) { false } }
80
+ context 'when querying the path raises a Net::SFTP::StatusException' do
81
+ before do
82
+ response = double 'response', code: '42', message: 'some message'
83
+ ex = Net::SFTP::StatusException.new(response)
84
+ allow(stat).to receive(:file?).and_raise(ex)
85
+ end
95
86
 
96
87
  it 'returns false' do
97
88
  expect(fs.file? file_path).to be false
@@ -99,53 +90,58 @@ module Producer::Core
99
90
  end
100
91
  end
101
92
 
102
- context 'when querying the path raises a Net::SFTP::StatusException' do
103
- before do
104
- response = double 'response', code: '42', message: 'some message'
105
- ex = Net::SFTP::StatusException.new(response)
106
- allow(stat).to receive(:file?).and_raise(ex)
107
- end
93
+ describe '#mkdir' do
94
+ let(:path) { 'some_directory_path' }
108
95
 
109
- it 'returns false' do
110
- expect(fs.file? file_path).to be false
96
+ it 'creates the directory' do
97
+ expect(sftp).to receive(:mkdir!).with(path)
98
+ fs.mkdir path
111
99
  end
112
100
  end
113
- end
114
101
 
115
- describe '#mkdir' do
116
- let(:sftp) { double 'sftp' }
117
- let(:path) { 'some_directory_path' }
102
+ describe '#file_read' do
103
+ let(:f) { double 'f' }
104
+ let(:path) { 'some_file_path' }
105
+ let(:content) { 'some_content' }
118
106
 
119
- before { allow(fs).to receive(:sftp) { sftp } }
107
+ before do
108
+ allow(sftp_file).to receive(:open).and_yield(f)
109
+ allow(f).to receive(:read) { content }
110
+ end
120
111
 
121
- it 'creates the directory' do
122
- expect(sftp).to receive(:mkdir!).with(path)
123
- fs.mkdir path
124
- end
125
- end
112
+ it 'returns the file content' do
113
+ expect(fs.file_read(path)).to eq content
114
+ end
126
115
 
127
- describe '#file_write' do
128
- let(:sftp) { double('sftp').as_null_object }
129
- let(:file) { double('sftp').as_null_object }
130
- let(:path) { 'some_file_path' }
131
- let(:content) { 'some_content' }
116
+ context 'when opening the file raises a Net::SFTP::StatusException' do
117
+ before do
118
+ response = double 'response', code: '42', message: 'some message'
119
+ ex = Net::SFTP::StatusException.new(response)
120
+ allow(sftp_file).to receive(:open).and_raise(ex)
121
+ end
132
122
 
133
- before do
134
- allow(fs).to receive(:sftp) { sftp }
135
- allow(sftp).to receive(:file) { file }
123
+ it 'returns nil' do
124
+ expect(fs.file_read(path)).to be nil
125
+ end
126
+ end
136
127
  end
137
128
 
138
- it 'opens the file' do
139
- expect(file).to receive(:open).with(path, 'w')
140
- fs.file_write path, content
141
- end
129
+ describe '#file_write' do
130
+ let(:path) { 'some_file_path' }
131
+ let(:content) { 'some_content' }
142
132
 
143
- it 'writes the content' do
144
- expect(file).to receive(:open).with(any_args) do |&b|
145
- expect(file).to receive(:write).with(content)
146
- b.call file
133
+ it 'opens the file' do
134
+ expect(sftp_file).to receive(:open).with(path, 'w')
135
+ fs.file_write path, content
136
+ end
137
+
138
+ it 'writes the content' do
139
+ expect(sftp_file).to receive(:open).with(any_args) do |&b|
140
+ expect(sftp_file).to receive(:write).with(content)
141
+ b.call sftp_file
142
+ end
143
+ fs.file_write path, content
147
144
  end
148
- fs.file_write path, content
149
145
  end
150
146
  end
151
147
  end
@@ -68,20 +68,11 @@ module Producer::Core
68
68
  end
69
69
 
70
70
  describe '#fs' do
71
- it 'builds a new FS' do
72
- expect(Remote::FS).to receive :new
73
- remote.fs
74
- end
75
-
76
- it 'returns the new FS instance' do
77
- fs = double 'fs'
78
- allow(Remote::FS).to receive(:new) { fs }
79
- expect(remote.fs).to be fs
80
- end
71
+ let(:sftp_session) { double 'sftp session' }
81
72
 
82
- it 'memoizes the FS' do
83
- allow(Remote::FS).to receive(:new) { Object.new }
84
- expect(remote.fs).to be remote.fs
73
+ it 'returns an FS instance built with a new sftp session' do
74
+ remote.stub_chain(:session, :sftp, :connect) { sftp_session }
75
+ expect(remote.fs.sftp).to be sftp_session
85
76
  end
86
77
  end
87
78
 
@@ -1,105 +1,115 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Producer::Core
4
- describe Task::DSL do
5
- let(:block) { proc {} }
6
- let(:env) { Env.new }
7
- subject(:dsl) { Task::DSL.new(env, &block) }
8
-
9
- %w[echo sh mkdir file_write].each do |action|
10
- it "has `#{action}' action defined" do
11
- expect(dsl).to respond_to action.to_sym
4
+ class Task
5
+ describe DSL do
6
+ let(:block) { proc {} }
7
+ let(:env) { Env.new }
8
+ subject(:dsl) { DSL.new(env, &block) }
9
+
10
+ %w[echo sh mkdir file_write file_replace_content].each do |action|
11
+ it "has `#{action}' action defined" do
12
+ expect(dsl).to respond_to action.to_sym
13
+ end
12
14
  end
13
- end
14
-
15
- describe '.define_action' do
16
- let(:some_action_class) { Class.new(Action) }
17
15
 
18
- before { described_class.define_action(:some_action, some_action_class) }
16
+ describe '.define_action' do
17
+ let(:some_action_class) { Class.new(Action) }
19
18
 
20
- it 'defines a new action keyword' do
21
- expect(dsl).to respond_to :some_action
22
- end
19
+ before { described_class.define_action(:some_action, some_action_class) }
23
20
 
24
- context 'when an action keyword is called' do
25
- it 'registers the action' do
26
- expect { dsl.some_action }.to change { dsl.actions.count }.by 1
21
+ it 'defines a new action keyword' do
22
+ expect(dsl).to respond_to :some_action
27
23
  end
28
24
 
29
- it 'registers the action with current env' do
30
- dsl.some_action
31
- expect(dsl.actions.first.env).to be env
32
- end
25
+ context 'when an action keyword is called' do
26
+ it 'registers the action' do
27
+ expect { dsl.some_action }.to change { dsl.actions.count }.by 1
28
+ end
29
+
30
+ it 'registers the action with current env' do
31
+ dsl.some_action
32
+ expect(dsl.actions.first.env).to be env
33
+ end
33
34
 
34
- it 'registers the action with given arguments' do
35
- dsl.some_action :some, :args
36
- expect(dsl.actions.first.arguments).to eq [:some, :args]
35
+ it 'registers the action with given arguments' do
36
+ dsl.some_action :some, :args
37
+ expect(dsl.actions.first.arguments).to eq [:some, :args]
38
+ end
37
39
  end
38
40
  end
39
- end
40
41
 
41
- describe '#initialize' do
42
- it 'assigns the given env' do
43
- expect(dsl.env).to be env
44
- end
42
+ describe '#initialize' do
43
+ it 'assigns the given env' do
44
+ expect(dsl.env).to be env
45
+ end
45
46
 
46
- it 'assigns the given block' do
47
- expect(dsl.block).to be block
48
- end
47
+ it 'assigns the given block' do
48
+ expect(dsl.block).to be block
49
+ end
49
50
 
50
- it 'assigns no action' do
51
- expect(dsl.actions).to be_empty
52
- end
51
+ it 'assigns no action' do
52
+ expect(dsl.actions).to be_empty
53
+ end
53
54
 
54
- it 'assigns true as the condition' do
55
- expect(dsl.condition).to be true
55
+ it 'assigns true as the condition' do
56
+ expect(dsl.condition).to be true
57
+ end
56
58
  end
57
- end
58
59
 
59
- describe '#evaluate' do
60
- let(:block) { proc { throw :task_code } }
60
+ describe '#evaluate' do
61
+ let(:block) { proc { throw :task_code } }
61
62
 
62
- it 'evaluates its code' do
63
- expect { dsl.evaluate }
64
- .to throw_symbol :task_code
65
- end
63
+ it 'evaluates its code' do
64
+ expect { dsl.evaluate }
65
+ .to throw_symbol :task_code
66
+ end
66
67
 
67
- context 'when arguments are given' do
68
- let(:block) { proc { |e| throw e } }
68
+ context 'when arguments are given' do
69
+ let(:block) { proc { |e| throw e } }
69
70
 
70
- it 'passes arguments as block parameters' do
71
- expect { dsl.evaluate :some_argument }
72
- .to throw_symbol :some_argument
71
+ it 'passes arguments as block parameters' do
72
+ expect { dsl.evaluate :some_argument }
73
+ .to throw_symbol :some_argument
74
+ end
73
75
  end
74
76
  end
75
- end
76
77
 
77
- describe '#condition' do
78
- context 'when a block is given' do
79
- it 'assigns a new evaluated condition' do
80
- dsl.condition { :some_return_value }
81
- expect(dsl.condition.return_value).to eq :some_return_value
78
+ describe '#condition' do
79
+ context 'when a block is given' do
80
+ it 'assigns a new evaluated condition' do
81
+ dsl.condition { :some_return_value }
82
+ expect(dsl.condition.return_value).to eq :some_return_value
83
+ end
82
84
  end
83
85
  end
84
- end
85
86
 
86
- describe '#ask' do
87
- let(:question) { 'Which letter?' }
88
- let(:choices) { [[:a, ?A], [:b, ?B]] }
89
- let(:prompter_class) { double('prompter class').as_null_object }
90
- subject(:ask) { dsl.ask question, choices,
91
- prompter: prompter_class }
87
+ describe '#ask' do
88
+ let(:question) { 'Which letter?' }
89
+ let(:choices) { [[:a, ?A], [:b, ?B]] }
90
+ let(:prompter_class) { double('prompter class').as_null_object }
91
+ subject(:ask) { dsl.ask question, choices,
92
+ prompter: prompter_class }
93
+
94
+ it 'builds a prompter' do
95
+ expect(prompter_class).to receive(:new).with(env.input, env.output)
96
+ ask
97
+ end
92
98
 
93
- it 'builds a prompter' do
94
- expect(prompter_class).to receive(:new).with(env.input, env.output)
95
- ask
99
+ it 'prompts and returns the choice' do
100
+ prompter = double 'prompter'
101
+ allow(prompter_class).to receive(:new) { prompter }
102
+ allow(prompter).to receive(:prompt) { :choice }
103
+ expect(ask).to eq :choice
104
+ end
96
105
  end
97
106
 
98
- it 'prompts and returns the choice' do
99
- prompter = double 'prompter'
100
- allow(prompter_class).to receive(:new) { prompter }
101
- allow(prompter).to receive(:prompt) { :choice }
102
- expect(ask).to eq :choice
107
+ describe '#get' do
108
+ let(:env) { Env.new(registry: { some_key: :some_value }) }
109
+
110
+ it 'fetches a value from the registry at given index' do
111
+ expect(dsl.get :some_key).to eq :some_value
112
+ end
103
113
  end
104
114
  end
105
115
  end
@@ -49,7 +49,7 @@ module Producer::Core
49
49
  end
50
50
 
51
51
  context 'when only the name is given as argument' do
52
- subject(:task) { Task.new(name) }
52
+ subject(:task) { described_class.new(name) }
53
53
 
54
54
  it 'assigns no action' do
55
55
  expect(task.actions).to be_empty
@@ -2,82 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Producer::Core
4
4
  describe Test do
5
- let(:env) { Env.new }
6
- let(:arguments) { [:some, :arguments] }
7
- subject(:test) { Test.new(env, *arguments) }
8
-
9
- describe '#initialize' do
10
- it 'assigns the env' do
11
- expect(test.env).to be env
12
- end
13
-
14
- it 'assigns the arguments' do
15
- expect(test.arguments).to eq arguments
16
- end
17
-
18
- it 'assigns negated as false by default' do
19
- expect(test).to_not be_negated
20
- end
21
-
22
- context 'when negated option is true' do
23
- subject(:test) { described_class.new(env, *arguments, negated: true) }
24
-
25
- it 'assigns negated as true' do
26
- expect(test).to be_negated
27
- end
28
- end
29
- end
30
-
31
- describe '#remote' do
32
- it 'returns env remote' do
33
- expect(test.remote).to be test.env.remote
34
- end
35
- end
36
-
37
- describe '#fs' do
38
- it 'returns env remote fs' do
39
- expect(test.fs).to be test.env.remote.fs
40
- end
41
- end
42
-
43
- describe '#negated?' do
44
- it 'returns false' do
45
- expect(test.negated?).to be false
46
- end
47
-
48
- context 'when test is negated' do
49
- subject(:test) { described_class.new(env, *arguments, negated: true) }
50
-
51
- it 'returns true' do
52
- expect(test.negated?).to be true
53
- end
54
- end
55
- end
56
-
57
- describe '#pass?' do
58
- it 'returns true when #verify is true' do
59
- allow(test).to receive(:verify) { true }
60
- expect(test.pass?).to be true
61
- end
62
-
63
- it 'returns false when #verify is false' do
64
- allow(test).to receive(:verify) { false }
65
- expect(test.pass?).to be false
66
- end
67
-
68
- context 'when test is negated' do
69
- subject(:test) { described_class.new(env, *arguments, negated: true) }
70
-
71
- it 'returns false when #verify is true' do
72
- allow(test).to receive(:verify) { true }
73
- expect(test.pass?).to be false
74
- end
75
-
76
- it 'returns true when #verify is false' do
77
- allow(test).to receive(:verify) { false }
78
- expect(test.pass?).to be true
79
- end
80
- end
81
- end
5
+ it_behaves_like 'test'
82
6
  end
83
7
  end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'producer/core/testing'
3
+
4
+ module Producer::Core
5
+ module Testing
6
+ describe MockRemote do
7
+ subject(:remote) { MockRemote.new('some_host.example') }
8
+
9
+ it 'is a remote' do
10
+ expect(remote).to be_a Remote
11
+ end
12
+
13
+ describe '#session' do
14
+ it 'raises an error to prevent real session usage' do
15
+ expect { remote.session }.to raise_error
16
+ end
17
+ end
18
+
19
+ describe '#execute' do
20
+ context 'dummy echo command' do
21
+ let(:command) { 'echo some arguments' }
22
+
23
+ it 'returns command arguments' do
24
+ expect(remote.execute(command)).to eq 'some arguments'
25
+ end
26
+ end
27
+
28
+ context 'dummy true command' do
29
+ let(:command) { 'true' }
30
+
31
+ it 'returns an empty string' do
32
+ expect(remote.execute(command)).to eq ''
33
+ end
34
+ end
35
+
36
+ context 'dummy false command' do
37
+ let(:command) { 'false' }
38
+
39
+ it 'raises a RemoteCommandExecutionError' do
40
+ expect { remote.execute(command) }.to raise_error(RemoteCommandExecutionError)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Producer::Core
4
+ module Tests
5
+ describe FileContains, :env do
6
+ let(:filepath) { 'some_file' }
7
+ let(:content) { 'some_content' }
8
+ subject(:test) { FileContains.new(env, filepath, content) }
9
+
10
+ it_behaves_like 'test'
11
+
12
+ describe '#verify' do
13
+ context 'when file contains the content' do
14
+ before do
15
+ allow(remote_fs)
16
+ .to receive(:file_read).with(filepath) { "foo#{content}bar" }
17
+ end
18
+
19
+ it 'returns true' do
20
+ expect(test.verify).to be true
21
+ end
22
+ end
23
+
24
+ context 'when file does not contain the content' do
25
+ before do
26
+ allow(remote_fs).to receive(:file_read).with(filepath) { 'foo bar' }
27
+ end
28
+
29
+ it 'returns false' do
30
+ expect(test.verify).to be false
31
+ end
32
+ end
33
+
34
+ context 'when file does not exist' do
35
+ before do
36
+ allow(remote_fs).to receive(:file_read).with(filepath) { nil }
37
+ end
38
+
39
+ it 'returns false' do
40
+ expect(test.verify).to be false
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end