nukumber 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ module Nukumber
2
+
3
+ module Reporter
4
+
5
+ class Mono < Colour
6
+
7
+ protected
8
+
9
+ def puts_colour_indent(text, *)
10
+ out = text
11
+ @indent.times { out = INDENT + out }
12
+ @outstream.puts out
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,237 @@
1
+ module Nukumber
2
+
3
+ class Runtime
4
+
5
+ def initialize(dirs, filenames, filters, reporter)
6
+
7
+ @reporter = reporter
8
+
9
+ builder = Nukumber::GherkinBuilder.new
10
+
11
+ if filters.empty?
12
+ filter_f = builder
13
+ else
14
+ filter_f = Gherkin::Formatter::FilterFormatter.new(builder, filters)
15
+ end
16
+ tag_f = Gherkin::Formatter::TagCountFormatter.new(filter_f, {})
17
+ parser = Gherkin::Parser::Parser.new(tag_f)
18
+
19
+ parse_feature_files(parser, dirs, filenames)
20
+ validate_features(builder.features)
21
+
22
+ $before_hooks = {}
23
+ $after_hooks = {}
24
+ old_methods = Object.private_methods
25
+
26
+ # Load all user-space Ruby files
27
+ Dir[Dir.pwd + "/#{dirs[:features]}/#{dirs[:support]}/env.rb"].each { |f| load f }
28
+ Dir[Dir.pwd + "/#{dirs[:features]}/#{dirs[:support]}/*.rb"].each { |f| load f }
29
+ Dir[Dir.pwd + "/#{dirs[:features]}/#{dirs[:definitions]}/*.rb"].each { |f| load f }
30
+
31
+ user_methods = Object.private_methods - old_methods
32
+
33
+ @expected_steps = []
34
+ @tests_passed = []
35
+ @tests_failed = []
36
+ @tests_pending = []
37
+ @tests_undefined = []
38
+
39
+ # Run all relevant features
40
+ builder.features.each { |feature| run_feature feature }
41
+
42
+ # Report
43
+ @reporter.final_report(@tests_passed, @tests_failed, @tests_pending, @tests_undefined)
44
+
45
+ # Provide code snippets as appropriate
46
+ @reporter.print_skeleton_code @tests_undefined unless @tests_undefined.empty?
47
+
48
+ @reporter.terminate
49
+
50
+ user_methods.each { |method_sym| Object.send(:remove_method, method_sym) }
51
+
52
+ end
53
+
54
+ def pass (step_name)
55
+ raise "Tried to pass without a step name" unless step_name.is_a? String
56
+ if @expected_steps.empty?
57
+ raise "Tried to pass unexpected step \"#{step_name}\" (expected test to be finished)"
58
+ elsif @expected_steps.first.name != step_name
59
+ raise "Tried to pass unexpected step \"#{step_name}\" (expected \"#{@expected_steps.first.name}\")"
60
+ else
61
+ @reporter.print_step(@expected_steps.first, :passed) unless @executing_element.is_a? Nukumber::Model::ScenarioOutline
62
+ @expected_steps.shift
63
+ end
64
+ end
65
+
66
+ def pending (*)
67
+ raise Nukumber::PendingTestError
68
+ end
69
+
70
+ def fail (err_msg = nil)
71
+ err_msg = ": #{err_msg}" unless err_msg.nil?
72
+ if @expected_steps.empty?
73
+ raise "Failed after all steps completed#{err_msg}"
74
+ else
75
+ raise "Failed step \"#{@expected_steps.first.name}\"#{err_msg}"
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def parse_feature_files(parser, dirs, filenames)
82
+ Dir[Dir.pwd + "/#{dirs[:features]}/*.feature"].each do |ff_path|
83
+ unless filenames.empty?
84
+ skip = false
85
+ filenames.each { |f| skip = true unless ff_path.include? f }
86
+ next if skip
87
+ end
88
+ $feature_file_path = ff_path # TODO: this global is crap
89
+ parser.parse(IO.read(ff_path), ff_path, 0)
90
+ end
91
+ end
92
+
93
+ def validate_features(features)
94
+ features.each do |f|
95
+ f.feature_elements.each do |e|
96
+ id = "#{e.name}, #{f.file_path}:#{e.line}"
97
+ if e.is_a? Nukumber::Model::ScenarioOutline and e.examples.nil?
98
+ raise Nukumber::SyntaxError, "Missing examples from element: #{id}"
99
+ end
100
+ if e.is_a? Nukumber::Model::ScenarioOutline and e.examples.table.rows.empty?
101
+ raise Nukumber::SyntaxError, "Example table from element has no rows: #{id}"
102
+ end
103
+ e.steps.each do |s|
104
+ if !s.args.empty? and s.args.rows.empty?
105
+ raise Nukumber::SyntaxError, "Arguments table in element has no rows: #{id}"
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ def check_for_element_method(element)
113
+ raise Nukumber::UndefinedTestError unless respond_to?(element.shortsym, true) or respond_to?(element.longsym, true)
114
+ end
115
+
116
+ def run_feature(feature)
117
+ @reporter.begin_feature feature
118
+
119
+ all_elements = []
120
+ all_elements << feature.background unless feature.background.nil?
121
+ all_elements += feature.feature_elements
122
+
123
+ # find undefined tests
124
+ all_elements.each do |element|
125
+ begin
126
+ check_for_element_method(element)
127
+ rescue Nukumber::UndefinedTestError
128
+ @tests_undefined << element
129
+ end
130
+ end
131
+
132
+ # and attempt to run tests
133
+ @background_undefined = false
134
+ all_elements.each do |element|
135
+ begin
136
+ check_for_element_method element
137
+ @reporter.begin_element element
138
+ @executing_element = element
139
+ run_outline_element(element) if element.is_a? Nukumber::Model::ScenarioOutline
140
+ run_single_element(element) unless element.is_a? Nukumber::Model::ScenarioOutline
141
+ rescue Nukumber::UndefinedTestError
142
+ @reporter.undefined_element(element)
143
+ @background_undefined = true if element.is_a? Nukumber::Model::Background
144
+ next
145
+ rescue
146
+ return if element.is_a? Nukumber::Model::Background
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+ def run_single_element(element)
153
+ if element.is_a? Nukumber::Model::Background
154
+ elements_at_stake = element.feature.feature_elements
155
+ else
156
+ elements_at_stake = [element]
157
+ end
158
+ $example = nil
159
+ status = nil
160
+ begin
161
+ before_hooks(element)
162
+ execute_element(element)
163
+ @tests_passed << element unless element.is_a? Nukumber::Model::Background
164
+ status = :passed
165
+ rescue Nukumber::PendingTestError
166
+ @expected_steps.each { |s| @reporter.print_step(s, :pending) }
167
+ @tests_pending += elements_at_stake
168
+ status = :pending
169
+ raise RuntimeError if element.is_a? Nukumber::Model::Background
170
+ rescue => e
171
+ @reporter.print_step(@expected_steps.first, :failed) unless @expected_steps.empty?
172
+ @expected_steps.shift
173
+ @expected_steps.each { |s| @reporter.print_step(s, :pending) }
174
+ @reporter.error(e, element)
175
+ @tests_failed += elements_at_stake
176
+ status = :failed
177
+ raise RuntimeError if element.is_a? Nukumber::Model::Background
178
+ ensure
179
+ after_hooks(element, status)
180
+ end
181
+ end
182
+
183
+ def run_outline_element(element)
184
+ element.examples.table.rows.size.times do |i|
185
+ $example = element.examples.table.row_hash(i)
186
+ status = nil
187
+ begin
188
+ before_hooks(element)
189
+ execute_element(element)
190
+ @reporter.print_example(element.examples.table, i, :passed)
191
+ @tests_passed << element
192
+ status = :passed
193
+ rescue Nukumber::PendingTestError
194
+ @reporter.print_example(element.examples.table, i, :pending)
195
+ @tests_pending << element
196
+ status = :pending
197
+ rescue => e
198
+ @reporter.print_example(element.examples.table, i, :failed)
199
+ @reporter.error(e, element)
200
+ @tests_failed << element
201
+ status = :failed
202
+ ensure
203
+ after_hooks(element, status)
204
+ end
205
+ end
206
+ end
207
+
208
+ def before_hooks(element)
209
+ $before_hooks[:each].each { |p| self.instance_eval &p } if $before_hooks[:each]
210
+ element.tags.each do |t|
211
+ $before_hooks[t.to_sym].each { |p| self.instance_eval &p } if $before_hooks[t.to_sym]
212
+ end
213
+ end
214
+
215
+ def after_hooks(element, status)
216
+ element.tags.each do |t|
217
+ $after_hooks[t.to_sym].each { |p| instance_exec(element, status, &p) } if $after_hooks[t.to_sym]
218
+ end
219
+ $after_hooks[:each].each { |p| instance_exec(element, status, &p) } if $after_hooks[:each]
220
+ end
221
+
222
+ def execute_element(element)
223
+ @expected_steps = element.steps.clone
224
+ $args = element.step_args
225
+ raise Nukumber::PendingTestError if @background_undefined
226
+
227
+ send(element.shortsym) if respond_to?(element.shortsym, true)
228
+ send(element.longsym) if respond_to?(element.longsym, true)
229
+
230
+ unless @expected_steps.empty?
231
+ raise "Last #{@expected_steps.size > 1 ? "#{@expected_steps.size} steps" : 'step'} not passed"
232
+ end
233
+ end
234
+
235
+ end
236
+
237
+ end
@@ -0,0 +1,7 @@
1
+ module Nukumber
2
+ major = 0
3
+ minor = 4
4
+ release = 1
5
+
6
+ VERSION = "#{major}.#{minor}.#{release}"
7
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nukumber
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ibrahim Sha'ath
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gherkin
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.11.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.11.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.5'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.5'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.2
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: 0.9.2
62
+ description: Specify your tests using Gherkin, but avoid the hassle of step definitions
63
+ email: nukumber@ibrahimshaath.co.uk
64
+ executables:
65
+ - nukumber
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - lib/nukumber/builder.rb
70
+ - lib/nukumber/cli.rb
71
+ - lib/nukumber/errors.rb
72
+ - lib/nukumber/helpers.rb
73
+ - lib/nukumber/hooks.rb
74
+ - lib/nukumber/model/background.rb
75
+ - lib/nukumber/model/examples.rb
76
+ - lib/nukumber/model/feature.rb
77
+ - lib/nukumber/model/feature_element.rb
78
+ - lib/nukumber/model/scenario.rb
79
+ - lib/nukumber/model/scenario_outline.rb
80
+ - lib/nukumber/model/step.rb
81
+ - lib/nukumber/model/table.rb
82
+ - lib/nukumber/model.rb
83
+ - lib/nukumber/reporter/colour.rb
84
+ - lib/nukumber/reporter/html.rb
85
+ - lib/nukumber/reporter/html_css.rb
86
+ - lib/nukumber/reporter/mono.rb
87
+ - lib/nukumber/reporter.rb
88
+ - lib/nukumber/runtime.rb
89
+ - lib/nukumber/version.rb
90
+ - lib/nukumber.rb
91
+ - bin/nukumber
92
+ homepage: https://github.com/ibsh/nukumber
93
+ licenses: []
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.8.24
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Run Gherkin feature files a bit more simply
116
+ test_files: []
117
+ has_rdoc: