unstoppable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.md
3
+ LICENSE.txt
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+ .idea
20
+ unstoppable.log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1 @@
1
+ --markup markdown --title "unstoppable Documentation" --protected
@@ -0,0 +1,4 @@
1
+ ### 0.1.0 / 2013-12-06
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'kramdown'
7
+ end
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ unstoppable (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ kramdown (1.2.0)
11
+ rake (0.9.6)
12
+ rspec (2.14.1)
13
+ rspec-core (~> 2.14.0)
14
+ rspec-expectations (~> 2.14.0)
15
+ rspec-mocks (~> 2.14.0)
16
+ rspec-core (2.14.7)
17
+ rspec-expectations (2.14.4)
18
+ diff-lcs (>= 1.1.3, < 2.0)
19
+ rspec-mocks (2.14.4)
20
+ rubygems-tasks (0.2.4)
21
+ yard (0.8.7.3)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0)
28
+ kramdown
29
+ rake (~> 0.8)
30
+ rspec (~> 2.4)
31
+ rubygems-tasks (~> 0.2)
32
+ unstoppable!
33
+ yard (~> 0.8)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Steven Holloway
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Steven Holloway
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ unstoppable
2
+ ===========
3
+
4
+ * [Homepage](https://rubygems.org/gems/unstoppable)
5
+ * [Documentation](http://rubydoc.info/gems/unstoppable/frames)
6
+ Cucumber extension that ensures all tests run to completion, catching failures and errors along the way and reporting them at completion.
7
+
8
+ This concept may seem ludicrous to some. It is however serving my purposes.
9
+
10
+ ## Description
11
+ Problem:
12
+
13
+ While Cucumber is an awesome tool, for some kinds of tests it's default behaviour becomes an obstacle.
14
+ Testing large batches of input against a slow error prone system is the source of much frustration.
15
+ Cucumber will skip remaining steps on failure or error. This is especially problematic if the test input is
16
+ a dynamic collection, *(e.g. results of a database query).
17
+ This is opposed to a static collection testing which is solved by a Scenario Outline.
18
+
19
+ Solution:
20
+
21
+ We need to step putside Cucumber's default pass/fail/error handling.
22
+ Capture all failures and errors in collections.
23
+ Log errors and failures.
24
+ Generate a pass/fail manifest against the test inputs.
25
+
26
+ Do not use this for normal BDD style testing, Cucumber's default behaviour is perfect for that.
27
+
28
+ Public Interface:
29
+
30
+ This is a works in progress so I expect changes as usage reveals more.
31
+
32
+ In your cucumber env.rb
33
+
34
+
35
+ Before do |scenario|
36
+ setup_unstoppable
37
+ end
38
+
39
+ After do |scenario|
40
+ print unstoppable_failures(scenario)
41
+ print unstoppable_errors(scenario)
42
+ end
43
+
44
+ In a step definition wrap any operation that you do not wish to stop execution like so
45
+
46
+ unstoppable do
47
+ expect(thing).to be(exected_thing)
48
+ end
49
+
50
+ This helper method does the following:
51
+ 1. runs executes the block
52
+ 2. catches any exception
53
+ 2a. adds error to errors collection if an error
54
+ 2b. adds expectation failure to failures collection if error is an RSpec::Expectations::ExpectationNotMetError
55
+ 3. logs error/failure
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'rubygems/tasks'
24
+ Gem::Tasks.new
25
+
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new
28
+
29
+ task :test => :spec
30
+ task :default => :spec
31
+
32
+ require 'yard'
33
+ YARD::Rake::YardocTask.new
34
+ task :doc => :yard
@@ -0,0 +1,2 @@
1
+ require 'unstoppable/version'
2
+ require 'unstoppable/helpers'
@@ -0,0 +1,56 @@
1
+ module Unstoppable
2
+ module Helpers
3
+ attr_accessor :failures, :errors
4
+
5
+ def setup_unstoppable
6
+ @failures ||=[]
7
+ @errors ||=[]
8
+ end
9
+
10
+ def unstoppable
11
+ begin
12
+ yield
13
+ rescue => error
14
+ handle_error(error)
15
+ end
16
+ end
17
+
18
+ def unstoppable_failures(scenario)
19
+ output = 'No Failures'
20
+ unless failures.empty?
21
+ output = failures.reduce("Failures for scenario: #{scenario.name}\n") do |memo, failure|
22
+ memo << "#{failure}\n"
23
+ memo
24
+ end
25
+ end
26
+ output
27
+ end
28
+
29
+ def unstoppable_errors(scenario)
30
+ output = 'No Errors'
31
+ unless errors.empty?
32
+ output = errors.reduce("Errors for scenario: #{scenario.name}\n") do |memo, error|
33
+ memo << "#{error}\n"
34
+ memo
35
+ end
36
+ end
37
+ output
38
+ end
39
+
40
+ private
41
+ def handle_error(error)
42
+ log_error(error)
43
+ if error.class == RSpec::Expectations::ExpectationNotMetError
44
+ failures.push(error)
45
+ else
46
+ errors.push(error)
47
+ end
48
+ end
49
+
50
+ def log_error(error)
51
+ File.open("#{Dir.pwd}/unstoppable.log", 'a') do |f|
52
+ f.write("#{error}\n")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,4 @@
1
+ module Unstoppable
2
+ # unstoppable version
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+ require 'unstoppable'
3
+
4
+ include Unstoppable
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ include Unstoppable::Helpers
4
+
5
+ describe Unstoppable::Helpers do
6
+
7
+ context '#setup_unstoppable' do
8
+
9
+ before do
10
+ setup_unstoppable
11
+ end
12
+
13
+ it 'should create an empty failures collection' do
14
+ expect(failures).to eq []
15
+ end
16
+
17
+ it 'should create an empty errors collection' do
18
+ expect(errors).to eq []
19
+ end
20
+
21
+ end
22
+
23
+ context '#unstoppable' do
24
+
25
+ before do
26
+ setup_unstoppable
27
+ end
28
+
29
+ it 'does not raise an error' do
30
+ expect {
31
+ unstoppable do
32
+ raise('hell')
33
+ end
34
+ }.to_not raise_error
35
+ end
36
+
37
+ it 'captures errors in the errors collection' do
38
+ unstoppable do
39
+ raise('hell')
40
+ end
41
+ expect(errors.first.message).to eq(RuntimeError.new('hell').message)
42
+ end
43
+
44
+ it 'captures failures in the failures collection' do
45
+ unstoppable do
46
+ expect('foo').to eq('bar')
47
+ end
48
+ expect(failures.count).to eq(1)
49
+ end
50
+
51
+ end
52
+
53
+ let(:scenario) { double('Scenario') }
54
+
55
+ context '#unstoppable_failures' do
56
+
57
+ before do
58
+ allow(scenario).to receive(:name) { 'My awesome scenario' }
59
+ setup_unstoppable
60
+ unstoppable do
61
+ expect('foo').to eq('bar')
62
+ end
63
+ end
64
+
65
+ it 'returns a string of all test failures' do
66
+
67
+ expected = <<-EXPECTED
68
+ Failures for scenario: My awesome scenario
69
+
70
+ expected: "bar"
71
+ got: "foo"
72
+
73
+ (compared using ==)
74
+
75
+ EXPECTED
76
+
77
+ expect(unstoppable_failures(scenario)).to eq(expected)
78
+ end
79
+ end
80
+
81
+ context '#unstoppable_errors' do
82
+
83
+ before do
84
+ allow(scenario).to receive(:name) { 'My awesome scenario' }
85
+ setup_unstoppable
86
+ unstoppable do
87
+ raise('hell')
88
+ end
89
+ end
90
+
91
+ it 'returns a string of all test errors' do
92
+ expected = <<-EXPECTED
93
+ Errors for scenario: My awesome scenario
94
+ hell
95
+ EXPECTED
96
+ expect(unstoppable_errors(scenario)).to eq(expected)
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Unstoppable do
4
+ it "should have a VERSION constant" do
5
+ subject.const_get('VERSION').should_not be_empty
6
+ end
7
+ end
@@ -0,0 +1,51 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/unstoppable/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "unstoppable"
7
+ gem.version = Unstoppable::VERSION
8
+ gem.summary = %q{Cucumber extension that ensures all tests run to completion, catching failures and errors along the way and reporting them at completion.}
9
+ gem.description = %q{Problem:
10
+ While Cucumber is an awesome tool, for some kinds of tests it's default behaviour becomes an obstacle. Testing large batches of input against a slow error prone system is the source of much frustration. Cucumber will skip remaining steps on failure or error. This is especially problematic if the test input is a dynamic collection, *(e.g. results of a database query). This is opposed to a static collection testing which is solved by a Scenario Outline.
11
+
12
+ Solution:
13
+
14
+ We need to step putside Cucumber's default pass/fail/error handling. Capture all failures and errors in collections. Log errors and failures. Generate a pass/fail manifest against the test inputs.
15
+
16
+ Do not use this for normal BDD style testing, Cucumber's default behaviour is perfect for that.
17
+
18
+ Public Interface:
19
+
20
+ This is a works in progress so I expect changes as usage reveals more.
21
+
22
+ In your cucumber env.rb
23
+
24
+ Before do |scenario| setup_unstoppable end
25
+
26
+ After do |scenario| print unstoppable_failures(scenario) print unstoppable_errors(scenario) end
27
+
28
+ In a step definition wrap any operation that you do not wish to stop execution like so
29
+
30
+ unstoppable do expect(thing).to be(exected_thing) end
31
+
32
+ This helper method does the following:
33
+
34
+ runs executes the block
35
+ catches any exception 2a. adds error to errors collection if an error 2b. adds expectation failure to failures collection if error is an RSpec::Expectations::ExpectationNotMetError
36
+ logs error/failure}
37
+ gem.license = "MIT"
38
+ gem.authors = ["Steven Holloway"]
39
+ gem.email = "impurist@gmail.com"
40
+ gem.homepage = "https://rubygems.org/gems/unstoppable"
41
+
42
+ gem.files = `git ls-files`.split($/)
43
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
44
+ gem.require_paths = ['lib']
45
+
46
+ gem.add_development_dependency 'bundler', '~> 1.0'
47
+ gem.add_development_dependency 'rake', '~> 0.8'
48
+ gem.add_development_dependency 'rspec', '~> 2.4'
49
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
50
+ gem.add_development_dependency 'yard', '~> 0.8'
51
+ end
metadata ADDED
@@ -0,0 +1,206 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: unstoppable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Steven Holloway
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.8'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '0.8'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.4'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.4'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rubygems-tasks
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.2'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.2'
78
+ - !ruby/object:Gem::Dependency
79
+ name: yard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.8'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.8'
94
+ description: ! 'Problem:
95
+
96
+ While Cucumber is an awesome tool, for some kinds of tests it''s default behaviour
97
+ becomes an obstacle. Testing large batches of input against a slow error prone system
98
+ is the source of much frustration. Cucumber will skip remaining steps on failure
99
+ or error. This is especially problematic if the test input is a dynamic collection,
100
+ *(e.g. results of a database query). This is opposed to a static collection testing
101
+ which is solved by a Scenario Outline.
102
+
103
+
104
+ Solution:
105
+
106
+
107
+ We need to step putside Cucumber''s default pass/fail/error handling. Capture all
108
+ failures and errors in collections. Log errors and failures. Generate a pass/fail
109
+ manifest against the test inputs.
110
+
111
+
112
+ Do not use this for normal BDD style testing, Cucumber''s default behaviour is perfect
113
+ for that.
114
+
115
+
116
+ Public Interface:
117
+
118
+
119
+ This is a works in progress so I expect changes as usage reveals more.
120
+
121
+
122
+ In your cucumber env.rb
123
+
124
+
125
+ Before do |scenario| setup_unstoppable end
126
+
127
+
128
+ After do |scenario| print unstoppable_failures(scenario) print unstoppable_errors(scenario)
129
+ end
130
+
131
+
132
+ In a step definition wrap any operation that you do not wish to stop execution like
133
+ so
134
+
135
+
136
+ unstoppable do expect(thing).to be(exected_thing) end
137
+
138
+
139
+ This helper method does the following:
140
+
141
+
142
+ runs executes the block
143
+
144
+ catches any exception 2a. adds error to errors collection if an error 2b. adds expectation
145
+ failure to failures collection if error is an RSpec::Expectations::ExpectationNotMetError
146
+
147
+ logs error/failure'
148
+ email: impurist@gmail.com
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - .document
154
+ - .gitignore
155
+ - .rspec
156
+ - .yardopts
157
+ - ChangeLog.md
158
+ - Gemfile
159
+ - Gemfile.lock
160
+ - LICENSE
161
+ - LICENSE.txt
162
+ - README.md
163
+ - Rakefile
164
+ - lib/unstoppable.rb
165
+ - lib/unstoppable/helpers.rb
166
+ - lib/unstoppable/version.rb
167
+ - spec/spec_helper.rb
168
+ - spec/unstoppable/helpers_spec.rb
169
+ - spec/unstoppable_spec.rb
170
+ - unstoppable.gemspec
171
+ homepage: https://rubygems.org/gems/unstoppable
172
+ licenses:
173
+ - MIT
174
+ post_install_message:
175
+ rdoc_options: []
176
+ require_paths:
177
+ - lib
178
+ required_ruby_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ! '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ segments:
185
+ - 0
186
+ hash: 1285484951952155202
187
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ! '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ segments:
194
+ - 0
195
+ hash: 1285484951952155202
196
+ requirements: []
197
+ rubyforge_project:
198
+ rubygems_version: 1.8.23
199
+ signing_key:
200
+ specification_version: 3
201
+ summary: Cucumber extension that ensures all tests run to completion, catching failures
202
+ and errors along the way and reporting them at completion.
203
+ test_files:
204
+ - spec/spec_helper.rb
205
+ - spec/unstoppable/helpers_spec.rb
206
+ - spec/unstoppable_spec.rb