rspec-command 1.0.0
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 +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/Gemfile +19 -0
- data/LICENSE +202 -0
- data/README.md +181 -0
- data/Rakefile +32 -0
- data/lib/rspec-command.rb +17 -0
- data/lib/rspec_command.rb +361 -0
- data/lib/rspec_command/match_fixture.rb +165 -0
- data/lib/rspec_command/rake.rb +120 -0
- data/lib/rspec_command/version.rb +21 -0
- data/rspec-command.gemspec +48 -0
- data/spec/command_spec.rb +301 -0
- data/spec/file_list_spec.rb +106 -0
- data/spec/fixtures/data.txt +1 -0
- data/spec/fixtures/sub/sub1.txt +1 -0
- data/spec/fixtures/sub/sub2.txt +1 -0
- data/spec/fixtures/sub_nested/sub_inner/sub_inner1.txt +1 -0
- data/spec/fixtures/sub_nested/sub_inner/sub_inner2.txt +1 -0
- data/spec/fixtures/sub_nested/sub_nested.txt +1 -0
- data/spec/match_fixture_spec.rb +186 -0
- data/spec/rake_spec.rb +117 -0
- data/spec/spec_helper.rb +58 -0
- metadata +240 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'rake'
|
18
|
+
require 'rspec'
|
19
|
+
|
20
|
+
require 'rspec_command'
|
21
|
+
|
22
|
+
|
23
|
+
module RSpecCommand
|
24
|
+
# An RSpec helper module for testing Rake tasks without running them in a
|
25
|
+
# full subprocess. This improves test speed while still giving you most of
|
26
|
+
# the benefits of integration testing.
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
# @since 1.0.0
|
30
|
+
# @example
|
31
|
+
# RSpec.configure do |config|
|
32
|
+
# config.include RSpecCommand::Rake
|
33
|
+
# end
|
34
|
+
# @example Enable for a single example group
|
35
|
+
# describe 'mytask' do
|
36
|
+
# rakefile <<-EOH
|
37
|
+
# ...
|
38
|
+
# EOH
|
39
|
+
# rake_task 'mytask'
|
40
|
+
# its(:stdout) { it_expected.to include('1.0.0') }
|
41
|
+
# end
|
42
|
+
module Rake
|
43
|
+
# @!classmethods
|
44
|
+
module ClassMethods
|
45
|
+
# Run a Rake task as the subject of this example group. The subject will
|
46
|
+
# be a string returned by {#capture_output}.
|
47
|
+
#
|
48
|
+
# @param name [String] Name of the task to execute.
|
49
|
+
# @param args [Array<Object>] Arguments to pass to the task.
|
50
|
+
# @return [void]
|
51
|
+
# @example
|
52
|
+
# describe 'mytask' do
|
53
|
+
# rakefile 'require "myapp/rake_tasks"'
|
54
|
+
# rake_task 'mytask'
|
55
|
+
# its(:stdout) { is_expected.to include 'Complete!' }
|
56
|
+
# end
|
57
|
+
def rake_task(name, *args)
|
58
|
+
metadata[:rake] = true
|
59
|
+
subject do
|
60
|
+
exitstatus = []
|
61
|
+
capture_output do
|
62
|
+
Process.waitpid fork {
|
63
|
+
# This has to be nocov because simplecov doesn't track across fork.
|
64
|
+
# :nocov:
|
65
|
+
# Defang SimpleCov so it doesn't print its stuff. Can be removed
|
66
|
+
# when https://github.com/colszowka/simplecov/pull/377 is in a
|
67
|
+
# released version.
|
68
|
+
if defined?(SimpleCov)
|
69
|
+
SimpleCov.at_exit { SimpleCov.instance_variable_set(:@result, nil) }
|
70
|
+
end
|
71
|
+
# Because #init reads from ARGV and will try to parse rspec's flags.
|
72
|
+
ARGV.replace([])
|
73
|
+
Dir.chdir(temp_path)
|
74
|
+
ENV.update(_environment)
|
75
|
+
rake = ::Rake::Application.new.tap do |rake|
|
76
|
+
::Rake.application = rake
|
77
|
+
rake.init
|
78
|
+
rake.load_rakefile
|
79
|
+
end
|
80
|
+
rake[name].invoke(*args)
|
81
|
+
}
|
82
|
+
exitstatus << $?.exitstatus
|
83
|
+
# :nocov:
|
84
|
+
end.tap do |output|
|
85
|
+
output.define_singleton_method(:exitstatus) { exitstatus.first }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Write out a Rakefile to the temporary directory for this example group.
|
91
|
+
# Content can be passed as either a string or a block.
|
92
|
+
#
|
93
|
+
# @param content [String] Rakefile content.
|
94
|
+
# @param block [Proc] Optional block to return the Rakefile content.
|
95
|
+
# @return [void]
|
96
|
+
# @example
|
97
|
+
# describe 'mytask' do
|
98
|
+
# rakefile <<-EOH
|
99
|
+
# task 'mytask' do
|
100
|
+
# ...
|
101
|
+
# end
|
102
|
+
# EOH
|
103
|
+
# rake_task 'mytask'
|
104
|
+
# its(:stdout) { is_expected.to include 'Complete!' }
|
105
|
+
# end
|
106
|
+
def rakefile(content=nil, &block)
|
107
|
+
file('Rakefile', content, &block)
|
108
|
+
end
|
109
|
+
|
110
|
+
def included(klass)
|
111
|
+
super
|
112
|
+
# Pull this in as a dependency.
|
113
|
+
klass.send(:include, RSpecCommand)
|
114
|
+
klass.extend ClassMethods
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
extend ClassMethods
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module RSpecCommand
|
19
|
+
# RSpec-command gem version.
|
20
|
+
VERSION = '1.0.0'
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
lib = File.expand_path('../lib', __FILE__)
|
18
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
19
|
+
require 'rspec_command/version'
|
20
|
+
|
21
|
+
Gem::Specification.new do |spec|
|
22
|
+
spec.name = 'rspec-command'
|
23
|
+
spec.version = RSpecCommand::VERSION
|
24
|
+
spec.authors = ['Noah Kantrowitz']
|
25
|
+
spec.email = %w{noah@coderanger.net}
|
26
|
+
spec.description = 'An RSpec helper module for testing command-line tools.'
|
27
|
+
spec.summary = spec.description
|
28
|
+
spec.homepage = 'https://github.com/coderanger/rspec-command'
|
29
|
+
spec.license = 'Apache 2.0'
|
30
|
+
|
31
|
+
spec.files = `git ls-files`.split($/)
|
32
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
33
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
34
|
+
spec.require_paths = %w{lib}
|
35
|
+
|
36
|
+
spec.add_dependency 'rspec', '~> 3.2'
|
37
|
+
spec.add_dependency 'rspec-its', '~> 1.2'
|
38
|
+
spec.add_dependency 'mixlib-shellout', '~> 2.0'
|
39
|
+
|
40
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
41
|
+
spec.add_development_dependency 'fuubar', '~> 2.0'
|
42
|
+
spec.add_development_dependency 'simplecov', '~> 0.9'
|
43
|
+
spec.add_development_dependency 'yard', '~> 0.8'
|
44
|
+
spec.add_development_dependency 'yard-classmethods', '~> 1.0'
|
45
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.4'
|
46
|
+
spec.add_development_dependency 'codecov', '~> 0.0', '>= 0.0.2'
|
47
|
+
spec.add_development_dependency 'pry'
|
48
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
describe RSpecCommand do
|
20
|
+
def read_temp(path)
|
21
|
+
IO.read(File.join(temp_path, path))
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#command' do
|
25
|
+
context 'true' do
|
26
|
+
command 'true'
|
27
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
28
|
+
end # /context true
|
29
|
+
|
30
|
+
context 'false' do
|
31
|
+
command 'false'
|
32
|
+
it { expect { subject }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) }
|
33
|
+
end # /context false
|
34
|
+
|
35
|
+
context 'with a block' do
|
36
|
+
command { 'true' }
|
37
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
38
|
+
end # /context with a block
|
39
|
+
|
40
|
+
context 'with allow_error' do
|
41
|
+
command 'false', allow_error: true
|
42
|
+
its(:exitstatus) { is_expected.to eq 1 }
|
43
|
+
end # /context with allow_error
|
44
|
+
|
45
|
+
context 'with input' do
|
46
|
+
command 'cat', input: "I'm a little teapot"
|
47
|
+
its(:stdout) { is_expected.to eq "I'm a little teapot" }
|
48
|
+
end # /context with input
|
49
|
+
|
50
|
+
context 'check gemfile' do
|
51
|
+
command 'env'
|
52
|
+
its(:stdout) { is_expected.to include("BUNDLE_GEMFILE=#{File.expand_path('../../Gemfile', __FILE__)}") }
|
53
|
+
end # /context check gemfile
|
54
|
+
|
55
|
+
context 'echo * with shell' do
|
56
|
+
command 'echo *'
|
57
|
+
before { IO.write(File.join(temp_path, 'file'), '') }
|
58
|
+
its(:stdout) { is_expected.to eq "file\n" }
|
59
|
+
end # /context echo * with shell
|
60
|
+
|
61
|
+
context 'echo * without shell' do
|
62
|
+
command %w{echo *}
|
63
|
+
before { IO.write(File.join(temp_path, 'file'), '') }
|
64
|
+
its(:stdout) { is_expected.to eq "*\n" }
|
65
|
+
end # /context echo * without shell
|
66
|
+
|
67
|
+
context 'without a Gemfile' do
|
68
|
+
command 'env'
|
69
|
+
before { allow(self).to receive(:find_file).and_return(nil) }
|
70
|
+
around do |example|
|
71
|
+
begin
|
72
|
+
old_gemfile = ENV.delete('BUNDLE_GEMFILE')
|
73
|
+
example.run
|
74
|
+
ensure
|
75
|
+
ENV['BUNDLE_GEMFILE'] = old_gemfile if old_gemfile
|
76
|
+
end
|
77
|
+
end
|
78
|
+
its(:stdout) { is_expected.to_not include('BUNDLE_GEMFILE') }
|
79
|
+
end # /context without a Gemfile
|
80
|
+
end # /describe #command
|
81
|
+
|
82
|
+
describe '#file' do
|
83
|
+
context 'with a simple file' do
|
84
|
+
file 'data', 'Short and stout'
|
85
|
+
subject { read_temp('data') }
|
86
|
+
it { is_expected.to eq 'Short and stout' }
|
87
|
+
end # /context with a simple file
|
88
|
+
|
89
|
+
context 'with a block' do
|
90
|
+
file 'data' do
|
91
|
+
'Here is my handle'
|
92
|
+
end
|
93
|
+
subject { read_temp('data') }
|
94
|
+
it { is_expected.to eq 'Here is my handle' }
|
95
|
+
end # /context with a block
|
96
|
+
|
97
|
+
context 'with a subfolder' do
|
98
|
+
file 'sub/data', 'Here is my spout'
|
99
|
+
subject { read_temp('sub/data') }
|
100
|
+
it { is_expected.to eq 'Here is my spout' }
|
101
|
+
end # /context with a subfolder
|
102
|
+
|
103
|
+
context 'with an absolute path' do
|
104
|
+
it { expect { self.class.file('/data', '') }.to raise_error }
|
105
|
+
end # /context with an absolute path
|
106
|
+
end # /describe #file
|
107
|
+
|
108
|
+
describe '#fixture_file' do
|
109
|
+
context 'with a single file fixture' do
|
110
|
+
fixture_file 'data.txt'
|
111
|
+
subject { read_temp('data.txt') }
|
112
|
+
it { is_expected.to eq "Fixture data.\n" }
|
113
|
+
end # /context with a single file fixture
|
114
|
+
|
115
|
+
context 'with a directory fixture' do
|
116
|
+
fixture_file 'sub'
|
117
|
+
it { expect(read_temp('sub1.txt')).to eq "Subfixture 1.\n" }
|
118
|
+
it { expect(read_temp('sub2.txt')).to eq "Subfixture 2.\n" }
|
119
|
+
end # /context with a directory fixture
|
120
|
+
|
121
|
+
context 'with a different dest' do
|
122
|
+
fixture_file 'sub', 'other'
|
123
|
+
it { expect(read_temp('other/sub1.txt')).to eq "Subfixture 1.\n" }
|
124
|
+
it { expect(read_temp('other/sub2.txt')).to eq "Subfixture 2.\n" }
|
125
|
+
end # /context with a different dest
|
126
|
+
|
127
|
+
context 'with an absolute path' do
|
128
|
+
it { expect { self.class.fixture_file('/data', '') }.to raise_error }
|
129
|
+
end # /context with an absolute path
|
130
|
+
|
131
|
+
context 'with a nested directory fixture' do
|
132
|
+
fixture_file 'sub_nested'
|
133
|
+
it { expect(read_temp('sub_nested.txt')).to eq "Subfixture nested.\n" }
|
134
|
+
it { expect(read_temp('sub_inner/sub_inner1.txt')).to eq "Subfixture inner 1.\n" }
|
135
|
+
it { expect(read_temp('sub_inner/sub_inner2.txt')).to eq "Subfixture inner 2.\n" }
|
136
|
+
end # /context with a nested directory fixture
|
137
|
+
end # /describe #fixture_file
|
138
|
+
|
139
|
+
describe '#environment' do
|
140
|
+
context 'with a single variable' do
|
141
|
+
environment MY_KEY: 'true'
|
142
|
+
command 'env'
|
143
|
+
its(:stdout) { is_expected.to include("MY_KEY=true") }
|
144
|
+
end # /context with a single variable
|
145
|
+
|
146
|
+
context 'with a two variables' do
|
147
|
+
environment MY_KEY: 'true'
|
148
|
+
environment OTHER_KEY: '1'
|
149
|
+
command 'env'
|
150
|
+
its(:stdout) { is_expected.to include("MY_KEY=true") }
|
151
|
+
its(:stdout) { is_expected.to include("OTHER_KEY=1") }
|
152
|
+
end # /context with a two variables
|
153
|
+
end # /describe #environment
|
154
|
+
|
155
|
+
describe '#temp_path' do
|
156
|
+
subject { temp_path }
|
157
|
+
it { is_expected.to be_a(String) }
|
158
|
+
end # /describe #temp_path
|
159
|
+
|
160
|
+
describe '#fixture_root' do
|
161
|
+
let(:fixture_root) { 'fixtures/sub' }
|
162
|
+
fixture_file 'sub1.txt'
|
163
|
+
subject { read_temp('sub1.txt') }
|
164
|
+
it { is_expected.to eq "Subfixture 1.\n" }
|
165
|
+
end # /describe #fixture_root
|
166
|
+
|
167
|
+
describe '#find_file' do
|
168
|
+
context 'with Gemfile' do
|
169
|
+
subject { find_file(__FILE__, 'Gemfile') }
|
170
|
+
it { is_expected.to eq File.expand_path('../../Gemfile', __FILE__) }
|
171
|
+
end # /context with Gemfile
|
172
|
+
|
173
|
+
context 'with a block' do
|
174
|
+
subject { find_file(__FILE__) {|p| p } }
|
175
|
+
it { is_expected.to eq File.dirname(__FILE__) }
|
176
|
+
end # /context with a block
|
177
|
+
|
178
|
+
context 'with a non-existant file' do
|
179
|
+
subject { find_file(__FILE__, 'NOPE.GIF') }
|
180
|
+
it { is_expected.to be_nil }
|
181
|
+
end # /context with a non-existant file
|
182
|
+
|
183
|
+
# This is important to check because otherwise the backstop test might be a
|
184
|
+
# false negative.
|
185
|
+
context 'with the gem root' do
|
186
|
+
subject { find_file(__FILE__, 'rspec-command') }
|
187
|
+
it { is_expected.to eq File.expand_path('../..', __FILE__) }
|
188
|
+
end # /context with the gem root
|
189
|
+
|
190
|
+
context 'with a backstop' do
|
191
|
+
subject { find_file(__FILE__, 'rspec-command', File.expand_path('..', __FILE__)) }
|
192
|
+
it { is_expected.to be_nil }
|
193
|
+
end # /context with a backstop
|
194
|
+
end # /describe #find_file
|
195
|
+
|
196
|
+
describe '#find_gem_base' do
|
197
|
+
subject { find_gem_base(__FILE__) }
|
198
|
+
it { is_expected.to eq File.expand_path('../..', __FILE__) }
|
199
|
+
end # /describe #find_gem_base
|
200
|
+
|
201
|
+
describe '#find_fixture' do
|
202
|
+
context 'with a fixture file' do
|
203
|
+
subject { find_fixture(__FILE__, 'data.txt') }
|
204
|
+
it { is_expected.to eq File.expand_path('../fixtures/data.txt', __FILE__) }
|
205
|
+
end # /context with a fixture file
|
206
|
+
|
207
|
+
context 'with no fixture path' do
|
208
|
+
subject { find_fixture(__FILE__) }
|
209
|
+
it { is_expected.to eq File.expand_path('../fixtures', __FILE__) }
|
210
|
+
end # /context with no fixture path
|
211
|
+
end # /describe #find_fixture
|
212
|
+
|
213
|
+
describe '#capture_output' do
|
214
|
+
context 'with puts' do
|
215
|
+
subject do
|
216
|
+
capture_output { puts 'test' }
|
217
|
+
end
|
218
|
+
it { is_expected.to eq "test\n" }
|
219
|
+
its(:stdout) { is_expected.to eq "test\n" }
|
220
|
+
its(:stderr) { is_expected.to eq '' }
|
221
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
222
|
+
end # /context with puts
|
223
|
+
|
224
|
+
context 'with STDERR.puts' do
|
225
|
+
subject do
|
226
|
+
capture_output { STDERR.puts 'test' }
|
227
|
+
end
|
228
|
+
it { is_expected.to eq '' }
|
229
|
+
its(:stdout) { is_expected.to eq '' }
|
230
|
+
its(:stderr) { is_expected.to eq "test\n" }
|
231
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
232
|
+
end # /context with STDERR.puts
|
233
|
+
|
234
|
+
context 'with $stderr.puts' do
|
235
|
+
subject do
|
236
|
+
capture_output { $stderr.puts 'test' }
|
237
|
+
end
|
238
|
+
it { is_expected.to eq '' }
|
239
|
+
its(:stdout) { is_expected.to eq '' }
|
240
|
+
its(:stderr) { is_expected.to eq "test\n" }
|
241
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
242
|
+
end # /context with $stderr.puts
|
243
|
+
|
244
|
+
context 'with a subproc' do
|
245
|
+
subject do
|
246
|
+
capture_output do
|
247
|
+
# Can't use `` because that already captures stdout
|
248
|
+
if pid = Process.fork
|
249
|
+
Process.waitpid(pid)
|
250
|
+
else
|
251
|
+
exec('echo test')
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
it { is_expected.to eq "test\n" }
|
256
|
+
its(:stdout) { is_expected.to eq "test\n" }
|
257
|
+
its(:stderr) { is_expected.to eq '' }
|
258
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
259
|
+
end # /context with a subproc
|
260
|
+
|
261
|
+
context 'with a subproc to stderr' do
|
262
|
+
subject do
|
263
|
+
capture_output { `echo test >&2` }
|
264
|
+
end
|
265
|
+
it { is_expected.to eq '' }
|
266
|
+
its(:stdout) { is_expected.to eq '' }
|
267
|
+
its(:stderr) { is_expected.to eq "test\n" }
|
268
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
269
|
+
end # /context with a subproc
|
270
|
+
|
271
|
+
context 'with a block that raises an exception' do
|
272
|
+
subject do
|
273
|
+
capture_output do
|
274
|
+
puts 'before'
|
275
|
+
raise 'OMG'
|
276
|
+
puts 'after'
|
277
|
+
end
|
278
|
+
end
|
279
|
+
it { expect { subject }.to raise_error }
|
280
|
+
it do
|
281
|
+
begin
|
282
|
+
subject
|
283
|
+
rescue Exception => e
|
284
|
+
expect(e).to respond_to(:output_so_far)
|
285
|
+
expect(e.output_so_far).to eq "before\n"
|
286
|
+
else
|
287
|
+
raise 'Subject did not raise exception'
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end # /context with a block that raises an exception
|
291
|
+
end # /describe #capture_output
|
292
|
+
|
293
|
+
describe RSpecCommand::OutputString do
|
294
|
+
subject { described_class.new('testout', 'testerr') }
|
295
|
+
it { is_expected.to be_a String }
|
296
|
+
it { is_expected.to eq 'testout' }
|
297
|
+
its(:stdout) { is_expected.to eq 'testout' }
|
298
|
+
its(:stderr) { is_expected.to eq 'testerr' }
|
299
|
+
its(:exitstatus) { is_expected.to eq 0 }
|
300
|
+
end # /describe RSpecCommand::OutputString
|
301
|
+
end
|