kosmas58-cucumber 0.1.16.6 → 0.1.99.21

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.
Files changed (248) hide show
  1. data/History.txt +126 -2
  2. data/License.txt +1 -1
  3. data/Manifest.txt +0 -270
  4. data/Rakefile +1 -1
  5. data/bin/cucumber +2 -2
  6. data/config/hoe.rb +7 -2
  7. data/examples/cs/features/step_definitons/calculator_steps.rb +1 -1
  8. data/examples/i18n/README.textile +1 -1
  9. data/examples/i18n/Rakefile +3 -3
  10. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -6
  11. data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -1
  12. data/examples/i18n/de/features/addition.feature +6 -6
  13. data/examples/i18n/de/features/step_definitons/calculator_steps.rb +2 -2
  14. data/examples/i18n/en/features/addition.feature +6 -6
  15. data/examples/i18n/en/features/step_definitons/calculator_steps.rb +2 -2
  16. data/examples/i18n/es/features/adicion.feature +11 -12
  17. data/examples/i18n/es/features/step_definitons/calculador_steps.rb +7 -10
  18. data/examples/i18n/es/lib/calculador.rb +4 -1
  19. data/examples/i18n/et/features/liitmine.feature +7 -6
  20. data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -1
  21. data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +1 -1
  22. data/examples/i18n/fi/features/yhteenlasku.feature +2 -2
  23. data/examples/i18n/fr/features/addition.feature +2 -2
  24. data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +1 -1
  25. data/examples/i18n/id/features/addition.feature +6 -6
  26. data/examples/i18n/id/features/step_definitons/calculator_steps.rb +2 -2
  27. data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -1
  28. data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +2 -3
  29. data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
  30. data/examples/i18n/lt/features/addition.feature +7 -6
  31. data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +2 -2
  32. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +7 -7
  33. data/examples/i18n/no/features/summering.feature +1 -0
  34. data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -1
  35. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -1
  36. data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -1
  37. data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +2 -2
  38. data/examples/java/src/cucumber/demo/Hello.java +16 -0
  39. data/examples/jbehave/README.textile +17 -0
  40. data/examples/jbehave/features/support/env.rb +7 -0
  41. data/examples/jbehave/features/trading.feature +24 -0
  42. data/examples/jbehave/pom.xml +48 -0
  43. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +32 -0
  44. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +42 -0
  45. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +29 -0
  46. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +22 -0
  47. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +65 -0
  48. data/examples/self_test/README.textile +4 -1
  49. data/examples/{calculator_ruby_features → self_test}/Rakefile +3 -3
  50. data/examples/self_test/features/background/failing_background.feature +10 -0
  51. data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
  52. data/examples/self_test/features/background/multiline_args_background.feature +32 -0
  53. data/examples/self_test/features/background/passing_background.feature +10 -0
  54. data/examples/self_test/features/background/pending_background.feature +10 -0
  55. data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  56. data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  57. data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
  58. data/examples/self_test/features/lots_of_undefined.feature +8 -0
  59. data/examples/self_test/features/outline_sample.feature +11 -5
  60. data/examples/self_test/features/sample.feature +8 -3
  61. data/examples/self_test/features/step_definitions/sample_steps.rb +53 -4
  62. data/examples/self_test/features/support/env.rb +1 -0
  63. data/examples/self_test/features/support/tag_count_formatter.rb +25 -0
  64. data/examples/tickets/features/172.feature +28 -0
  65. data/examples/tickets/features/177/1.feature +29 -0
  66. data/examples/tickets/features/177/2.feature +21 -0
  67. data/examples/tickets/features/177/3.feature +18 -0
  68. data/examples/tickets/features/180.feature +7 -0
  69. data/examples/tickets/features/scenario_outline.feature +6 -1
  70. data/examples/tickets/features/step_definitons/tickets_steps.rb +27 -3
  71. data/examples/tickets/features/tickets.feature +4 -0
  72. data/features/background.feature +223 -0
  73. data/features/cucumber_cli.feature +218 -98
  74. data/features/cucumber_cli_outlines.feature +54 -37
  75. data/features/custom_formatter.feature +11 -0
  76. data/features/report_called_undefined_steps.feature +32 -0
  77. data/features/step_definitions/cucumber_steps.rb +7 -3
  78. data/features/step_definitions/extra_steps.rb +1 -1
  79. data/features/support/env.rb +2 -1
  80. data/gem_tasks/flog.rake +1 -1
  81. data/gem_tasks/gemspec.rake +2 -2
  82. data/gem_tasks/jar.rake +67 -0
  83. data/lib/autotest/cucumber_mixin.rb +17 -23
  84. data/lib/cucumber.rb +63 -11
  85. data/lib/cucumber/ast.rb +29 -0
  86. data/lib/cucumber/ast/background.rb +88 -0
  87. data/lib/cucumber/ast/comment.rb +26 -0
  88. data/lib/cucumber/ast/examples.rb +26 -0
  89. data/lib/cucumber/ast/feature.rb +66 -0
  90. data/lib/cucumber/ast/features.rb +39 -0
  91. data/lib/cucumber/ast/filter.rb +22 -0
  92. data/lib/cucumber/ast/outline_table.rb +49 -0
  93. data/lib/cucumber/ast/py_string.rb +52 -0
  94. data/lib/cucumber/ast/scenario.rb +103 -0
  95. data/lib/cucumber/ast/scenario_outline.rb +92 -0
  96. data/lib/cucumber/ast/step.rb +161 -0
  97. data/lib/cucumber/ast/steps.rb +13 -0
  98. data/lib/cucumber/ast/table.rb +218 -0
  99. data/lib/cucumber/ast/tags.rb +40 -0
  100. data/lib/cucumber/ast/visitor.rb +109 -0
  101. data/lib/cucumber/broadcaster.rb +1 -6
  102. data/lib/cucumber/cli/configuration.rb +339 -0
  103. data/lib/cucumber/cli/language_help_formatter.rb +59 -0
  104. data/lib/cucumber/cli/main.rb +100 -0
  105. data/lib/cucumber/core_ext/exception.rb +41 -8
  106. data/lib/cucumber/core_ext/instance_exec.rb +54 -0
  107. data/lib/cucumber/core_ext/proc.rb +29 -65
  108. data/lib/cucumber/core_ext/string.rb +19 -0
  109. data/lib/cucumber/formatter.rb +1 -0
  110. data/lib/cucumber/{formatters → formatter}/ansicolor.rb +14 -16
  111. data/lib/cucumber/formatter/color_io.rb +17 -0
  112. data/lib/cucumber/formatter/console.rb +119 -0
  113. data/lib/cucumber/formatter/cucumber.css +55 -0
  114. data/lib/cucumber/formatter/cucumber.sass +49 -0
  115. data/lib/cucumber/formatter/html.rb +121 -0
  116. data/lib/cucumber/formatter/pretty.rb +167 -0
  117. data/lib/cucumber/formatter/profile.rb +77 -0
  118. data/lib/cucumber/formatter/progress.rb +68 -0
  119. data/lib/cucumber/formatter/rerun.rb +35 -0
  120. data/lib/cucumber/formatter/unicode.rb +35 -0
  121. data/lib/cucumber/formatters/unicode.rb +2 -35
  122. data/lib/cucumber/jbehave.rb +102 -0
  123. data/lib/cucumber/languages.yml +128 -75
  124. data/lib/cucumber/parser.rb +43 -0
  125. data/lib/cucumber/parser/basic.rb +0 -0
  126. data/lib/cucumber/parser/feature.rb +1490 -0
  127. data/lib/cucumber/parser/feature.tt +188 -0
  128. data/lib/cucumber/parser/i18n.tt +31 -0
  129. data/lib/cucumber/parser/table.rb +402 -0
  130. data/lib/cucumber/parser/table.tt +59 -0
  131. data/lib/cucumber/parser/treetop_ext.rb +75 -0
  132. data/lib/cucumber/platform.rb +3 -17
  133. data/lib/cucumber/rails/rspec.rb +5 -2
  134. data/lib/cucumber/step_definition.rb +87 -0
  135. data/lib/cucumber/step_mother.rb +151 -66
  136. data/lib/cucumber/version.rb +2 -2
  137. data/rails_generators/cucumber/USAGE +3 -2
  138. data/rails_generators/cucumber/cucumber_generator.rb +33 -23
  139. data/rails_generators/cucumber/templates/cucumber +2 -1
  140. data/rails_generators/cucumber/templates/cucumber.rake +6 -1
  141. data/rails_generators/cucumber/templates/env.rb +1 -1
  142. data/rails_generators/feature/USAGE +3 -0
  143. data/rails_generators/feature/feature_generator.rb +30 -6
  144. data/spec/cucumber/ast/background_spec.rb +58 -0
  145. data/spec/cucumber/ast/feature_factory.rb +54 -0
  146. data/spec/cucumber/ast/feature_spec.rb +60 -0
  147. data/spec/cucumber/ast/py_string_spec.rb +40 -0
  148. data/spec/cucumber/ast/scenario_outline_spec.rb +64 -0
  149. data/spec/cucumber/ast/scenario_spec.rb +82 -0
  150. data/spec/cucumber/ast/step_spec.rb +45 -0
  151. data/spec/cucumber/ast/table_spec.rb +81 -0
  152. data/spec/cucumber/ast/tags_spec.rb +23 -0
  153. data/spec/cucumber/broadcaster_spec.rb +4 -17
  154. data/spec/cucumber/cli/configuration_spec.rb +239 -0
  155. data/spec/cucumber/cli/main_spec.rb +164 -0
  156. data/spec/cucumber/core_ext/proc_spec.rb +27 -35
  157. data/spec/cucumber/core_ext/string_spec.rb +8 -0
  158. data/spec/cucumber/{formatters → formatter}/ansicolor_spec.rb +2 -2
  159. data/spec/cucumber/formatter/html/cucumber.css +37 -0
  160. data/spec/cucumber/formatter/html/cucumber.js +13 -0
  161. data/spec/cucumber/formatter/html/index.html +45 -0
  162. data/spec/cucumber/formatter/html/jquery-1.3.min.js +19 -0
  163. data/spec/cucumber/formatter/html/jquery.uitableedit.js +100 -0
  164. data/spec/cucumber/formatters/profile_formatter_spec.rb +17 -16
  165. data/spec/cucumber/parser/feature_parser_spec.rb +281 -0
  166. data/spec/cucumber/parser/table_parser_spec.rb +48 -0
  167. data/spec/cucumber/step_definition_spec.rb +62 -0
  168. data/spec/cucumber/step_mother_spec.rb +50 -51
  169. data/spec/cucumber/treetop_parser/empty_feature.feature +1 -1
  170. data/spec/cucumber/treetop_parser/scenario_outline.feature +1 -1
  171. data/spec/cucumber/treetop_parser/spaces.feature +3 -1
  172. data/spec/cucumber/treetop_parser/with_comments.feature +1 -1
  173. data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
  174. data/spec/cucumber/world/pending_spec.rb +13 -12
  175. data/spec/spec_helper.rb +1 -1
  176. metadata +107 -79
  177. data/examples/calculator_ruby_features/features/addition.rb +0 -39
  178. data/examples/calculator_ruby_features/features/step_definitons/calculator_steps.rb +0 -43
  179. data/gem_tasks/treetop.rake +0 -41
  180. data/lib/cucumber/cli.rb +0 -355
  181. data/lib/cucumber/executor.rb +0 -205
  182. data/lib/cucumber/formatters.rb +0 -1
  183. data/lib/cucumber/formatters/autotest_formatter.rb +0 -23
  184. data/lib/cucumber/formatters/cucumber.css +0 -132
  185. data/lib/cucumber/formatters/cucumber.js +0 -11
  186. data/lib/cucumber/formatters/html_formatter.rb +0 -152
  187. data/lib/cucumber/formatters/jquery.js +0 -32
  188. data/lib/cucumber/formatters/pretty_formatter.rb +0 -285
  189. data/lib/cucumber/formatters/profile_formatter.rb +0 -92
  190. data/lib/cucumber/formatters/progress_formatter.rb +0 -61
  191. data/lib/cucumber/model.rb +0 -1
  192. data/lib/cucumber/model/table.rb +0 -32
  193. data/lib/cucumber/step_methods.rb +0 -49
  194. data/lib/cucumber/tree.rb +0 -16
  195. data/lib/cucumber/tree/feature.rb +0 -105
  196. data/lib/cucumber/tree/features.rb +0 -21
  197. data/lib/cucumber/tree/given_scenario.rb +0 -13
  198. data/lib/cucumber/tree/scenario.rb +0 -240
  199. data/lib/cucumber/tree/step.rb +0 -173
  200. data/lib/cucumber/tree/table.rb +0 -26
  201. data/lib/cucumber/tree/top_down_visitor.rb +0 -23
  202. data/lib/cucumber/treetop_parser/feature.treetop.erb +0 -254
  203. data/lib/cucumber/treetop_parser/feature_ar.rb +0 -1951
  204. data/lib/cucumber/treetop_parser/feature_cy.rb +0 -1951
  205. data/lib/cucumber/treetop_parser/feature_da.rb +0 -1951
  206. data/lib/cucumber/treetop_parser/feature_de.rb +0 -1951
  207. data/lib/cucumber/treetop_parser/feature_en-lol.rb +0 -1951
  208. data/lib/cucumber/treetop_parser/feature_en-tx.rb +0 -1951
  209. data/lib/cucumber/treetop_parser/feature_en.rb +0 -1951
  210. data/lib/cucumber/treetop_parser/feature_es.rb +0 -1951
  211. data/lib/cucumber/treetop_parser/feature_et.rb +0 -1951
  212. data/lib/cucumber/treetop_parser/feature_fi.rb +0 -1951
  213. data/lib/cucumber/treetop_parser/feature_fr.rb +0 -1951
  214. data/lib/cucumber/treetop_parser/feature_id.rb +0 -1951
  215. data/lib/cucumber/treetop_parser/feature_it.rb +0 -1951
  216. data/lib/cucumber/treetop_parser/feature_ja.rb +0 -1951
  217. data/lib/cucumber/treetop_parser/feature_ko.rb +0 -1951
  218. data/lib/cucumber/treetop_parser/feature_lt.rb +0 -1951
  219. data/lib/cucumber/treetop_parser/feature_nl.rb +0 -1951
  220. data/lib/cucumber/treetop_parser/feature_no.rb +0 -1951
  221. data/lib/cucumber/treetop_parser/feature_parser.rb +0 -36
  222. data/lib/cucumber/treetop_parser/feature_pl.rb +0 -1951
  223. data/lib/cucumber/treetop_parser/feature_pt.rb +0 -1951
  224. data/lib/cucumber/treetop_parser/feature_ro.rb +0 -1951
  225. data/lib/cucumber/treetop_parser/feature_ro2.rb +0 -1951
  226. data/lib/cucumber/treetop_parser/feature_ru.rb +0 -1951
  227. data/lib/cucumber/treetop_parser/feature_se.rb +0 -1951
  228. data/lib/cucumber/treetop_parser/feature_zh-CN.rb +0 -1951
  229. data/lib/cucumber/world.rb +0 -1
  230. data/lib/cucumber/world/pending.rb +0 -22
  231. data/setup.rb +0 -1585
  232. data/spec/cucumber/cli_spec.rb +0 -521
  233. data/spec/cucumber/executor_spec.rb +0 -382
  234. data/spec/cucumber/formatters/autotest_formatter_spec.rb +0 -26
  235. data/spec/cucumber/formatters/features.html +0 -269
  236. data/spec/cucumber/formatters/html_formatter_spec.rb +0 -110
  237. data/spec/cucumber/formatters/pretty_formatter_spec.rb +0 -410
  238. data/spec/cucumber/formatters/progress_formatter_spec.rb +0 -81
  239. data/spec/cucumber/model/table_spec.rb +0 -32
  240. data/spec/cucumber/tree/feature_spec.rb +0 -122
  241. data/spec/cucumber/tree/row_scenario_outline_spec.rb +0 -73
  242. data/spec/cucumber/tree/row_scenario_spec.rb +0 -55
  243. data/spec/cucumber/tree/row_step_outline_spec.rb +0 -38
  244. data/spec/cucumber/tree/scenario_outline_spec.rb +0 -50
  245. data/spec/cucumber/tree/scenario_spec.rb +0 -134
  246. data/spec/cucumber/tree/step_outline_spec.rb +0 -17
  247. data/spec/cucumber/tree/step_spec.rb +0 -59
  248. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +0 -120
@@ -1,20 +1,53 @@
1
+ # Exception extension that tweaks Exception backtraces:
2
+ #
3
+ # * The line of the failing .feature line is appended to the backtrace
4
+ # * The line that calls #cucumber_instance_exec is replaced with the StepDefinition's regexp
5
+ # * Non intersting lines are stripped out
6
+ #
7
+ # The result is that backtraces look like this:
8
+ #
9
+ # features/step_definitions/the_step_definition.rb:in `/some step/'
10
+ # features/the_feature_file.feature:41:in `Given some step'
11
+ #
12
+ # or if the exception is raised in the tested code:
13
+ #
14
+ # lib/myapp/some_file.rb:in `/some_method/'
15
+ # lib/myapp/some_other_file.rb:in `/some_other_method/'
16
+ # features/step_definitions/the_step_definition.rb:in `/some step/'
17
+ # features/the_feature_file.feature:41:in `Given some step'
18
+ #
19
+ # All backtrace munging can be turned off with the <tt>--backtrace</tt> switch
20
+ #
1
21
  class Exception
2
22
  CUCUMBER_FILTER_PATTERNS = [
3
- /vendor\/rails/,
4
- /vendor\/plugins\/cucumber/,
5
- /vendor\/plugins\/rspec/,
6
- /gems\/rspec/
23
+ /vendor\/rails|lib\/cucumber|lib\/rspec|gems\//
7
24
  ]
8
25
 
26
+ INSTANCE_EXEC_OFFSET = (Cucumber::RUBY_1_9 || Cucumber::JRUBY) ? -3 : -4
27
+
9
28
  def self.cucumber_full_backtrace=(v)
10
29
  @@cucumber_full_backtrace = v
11
30
  end
12
31
  self.cucumber_full_backtrace = false
13
32
 
14
- def cucumber_backtrace
15
- return (backtrace || []) if @@cucumber_full_backtrace
16
- (backtrace || []).map {|b| b.split("\n") }.flatten.reject do |line|
33
+ # Strips the backtrace from +line+ and down
34
+ def self.cucumber_strip_backtrace!(backtrace, instance_exec_invocation_line, pseudo_method)
35
+ return if @@cucumber_full_backtrace
36
+
37
+ instance_exec_pos = backtrace.index(instance_exec_invocation_line)
38
+ if instance_exec_pos
39
+ replacement_line = instance_exec_pos + INSTANCE_EXEC_OFFSET
40
+ backtrace[replacement_line].gsub!(/`.*'/, "`#{pseudo_method}'") if pseudo_method
41
+ backtrace[replacement_line+1..-1] = nil
42
+
43
+ backtrace.compact!
44
+ else
45
+ # This happens with rails, because they screw up the backtrace
46
+ # before we get here (injecting erb stacktrace and such)
47
+ end
48
+
49
+ backtrace.reject! do |line|
17
50
  CUCUMBER_FILTER_PATTERNS.detect{|p| line =~ p}
18
- end.map { |line| line.strip }
51
+ end
19
52
  end
20
53
  end
@@ -0,0 +1,54 @@
1
+ require 'cucumber/platform'
2
+
3
+ module Cucumber
4
+ class ArityMismatchError < StandardError
5
+ end
6
+ end
7
+
8
+ class Object
9
+ def cucumber_instance_exec(check_arity, pseudo_method, *args, &block)
10
+ arity = block.arity
11
+ arity = 0 if arity == -1
12
+ cucumber_run_with_backtrace_filtering(pseudo_method) do
13
+ if check_arity && args.length != arity
14
+ instance_exec do
15
+ raise Cucumber::ArityMismatchError.new("expected #{arity} block argument(s), got #{args.length}")
16
+ end
17
+ else
18
+ instance_exec(*args, &block)
19
+ end
20
+ end
21
+ end
22
+
23
+ def cucumber_run_with_backtrace_filtering(pseudo_method)
24
+ begin
25
+ yield
26
+ rescue Exception => e
27
+ instance_exec_invocation_line = "#{__FILE__}:#{__LINE__ - 2}:in `cucumber_run_with_backtrace_filtering'"
28
+ Exception.cucumber_strip_backtrace!((e.backtrace || []), instance_exec_invocation_line, pseudo_method)
29
+ raise e
30
+ end
31
+ end
32
+
33
+ unless defined? instance_exec # 1.9
34
+ # http://eigenclass.org/hiki/bounded+space+instance_exec
35
+ module InstanceExecHelper; end
36
+ include InstanceExecHelper
37
+ def instance_exec(*args, &block)
38
+ begin
39
+ old_critical, Thread.critical = Thread.critical, true
40
+ n = 0
41
+ n += 1 while respond_to?(mname="__instance_exec#{n}")
42
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
43
+ ensure
44
+ Thread.critical = old_critical
45
+ end
46
+ begin
47
+ ret = send(mname, *args)
48
+ ensure
49
+ InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
50
+ end
51
+ ret
52
+ end
53
+ end
54
+ end
@@ -1,69 +1,33 @@
1
- module Cucumber
2
- class ArityMismatchError < StandardError
3
- end
4
-
5
- module CoreExt
6
- # Proc extension that allows a proc to be called in the context of any object.
7
- # Also makes it possible to tack a name onto a Proc.
8
- module CallIn
9
- PROC_PATTERN = /[\d\w]+@(.*):(.*)>/
10
-
11
- if Proc.new{}.to_s =~ PROC_PATTERN
12
- def to_backtrace_line
13
- "#{file_colon_line}:in `#{name}'"
14
- end
15
-
16
- def to_comment_line
17
- "# #{file_colon_line}"
18
- end
19
-
20
- def file_colon_line
21
- path, line = *to_s.match(PROC_PATTERN)[1..2]
22
- path = File.expand_path(path)
23
- pwd = Dir.pwd
24
- path = path[pwd.length+1..-1]
25
- "#{path}:#{line}"
26
- end
27
- else
28
- # This Ruby implementation doesn't implement Proc#to_s correctly
29
- STDERR.puts "*** THIS RUBY IMPLEMENTATION DOESN'T REPORT FILE AND LINE FOR PROCS ***"
30
-
31
- def to_backtrace_line
32
- nil
33
- end
34
-
35
- def to_comment_line
36
- ""
37
- end
38
- end
39
-
40
- attr_accessor :name
41
-
42
- def call_in(obj, *args)
43
- obj.extend(mod)
44
- if self != StepMother::PENDING && args.length != arity2
45
- # We have to manually raise when the block has arity -1 (no pipes)
46
- raise ArityMismatchError.new("expected #{arity2} block argument(s), got #{args.length}")
47
- else
48
- obj.__send__(meth, *args)
49
- end
50
- end
1
+ # Proc extension to get more location info out of a proc
2
+ class Proc
3
+ PROC_PATTERN = /[\d\w]+@(.*):(.*)>/
4
+
5
+ if Proc.new{}.to_s =~ PROC_PATTERN
6
+ def to_backtrace_line(name)
7
+ "#{file_colon_line}:in `#{name}'"
8
+ end
51
9
 
52
- def arity2
53
- arity == -1 ? 0 : arity
54
- end
10
+ def to_comment_line
11
+ "# #{file_colon_line}"
12
+ end
55
13
 
56
- def meth
57
- @meth ||= "__cucumber_#{object_id}"
58
- end
14
+ def file_colon_line
15
+ path, line = *to_s.match(PROC_PATTERN)[1..2]
16
+ path = File.expand_path(path)
17
+ pwd = Dir.pwd
18
+ path = path[pwd.length+1..-1]
19
+ "#{path}:#{line}"
20
+ end
21
+ else
22
+ # This Ruby implementation doesn't implement Proc#to_s correctly
23
+ STDERR.puts "*** THIS RUBY IMPLEMENTATION DOESN'T REPORT FILE AND LINE FOR PROCS ***"
24
+
25
+ def to_backtrace_line
26
+ nil
27
+ end
59
28
 
60
- def mod
61
- p = self
62
- m = meth
63
- @mod ||= Module.new do
64
- define_method(m, &p)
65
- end
66
- end
67
- end
29
+ def to_comment_line
30
+ ""
31
+ end
68
32
  end
69
- end
33
+ end
@@ -1,4 +1,21 @@
1
1
  class String
2
+ def indent(n)
3
+ if n >= 0
4
+ gsub(/^/, ' ' * n)
5
+ else
6
+ gsub(/^ {0,#{-n}}/, "")
7
+ end
8
+ end
9
+
10
+ # re.source.gsub(/\([^)]*\)/, '$var')
11
+ # Cumulative #sub
12
+ def subs(re, *args)
13
+ args.inject(self) do |s,arg|
14
+ s.sub(re, arg)
15
+ end
16
+ end
17
+
18
+ # TODO: Use subs instead...
2
19
  def gzub(regexp, format=nil, &proc)
3
20
  md = match(regexp)
4
21
  raise "#{self.inspect} doesn't match #{regexp.inspect}" if md.nil?
@@ -8,6 +25,8 @@ class String
8
25
  md.captures.each_with_index do |m, n|
9
26
  replacement = if block_given?
10
27
  proc.call(m)
28
+ elsif Proc === format
29
+ format.call(m)
11
30
  else
12
31
  format % m
13
32
  end
@@ -0,0 +1 @@
1
+ %w{color_io pretty progress profile rerun html}.each{|n| require "cucumber/formatter/#{n}"}
@@ -1,15 +1,12 @@
1
- # Hack to work around Win32/Console, which bundles a licence-violating, outdated
2
- # copy of term/ansicolor that doesn't implement Term::ANSIColor#coloring=.
3
- # We want the official one!
4
1
  gem 'term-ansicolor'
5
- $LOAD_PATH.each{|path| $LOAD_PATH.unshift($LOAD_PATH.delete(path)) if path =~ /term-ansicolor/}
6
2
  require 'term/ansicolor'
7
3
 
8
4
  if Cucumber::WINDOWS_MRI
9
5
  begin
6
+ gem 'win32console', '>= 1.2.0'
10
7
  require 'Win32/Console/ANSI'
11
8
  rescue LoadError
12
- STDERR.puts "You must gem install win32console to get coloured output on MRI/Windows"
9
+ STDERR.puts "*** WARNING: You must gem install win32console (1.2.0 or higher) to get coloured output on MRI/Windows"
13
10
  Term::ANSIColor.coloring = false
14
11
  end
15
12
  end
@@ -17,7 +14,7 @@ end
17
14
  Term::ANSIColor.coloring = false if !STDOUT.tty? || (Cucumber::WINDOWS && !Cucumber::WINDOWS_MRI)
18
15
 
19
16
  module Cucumber
20
- module Formatters
17
+ module Formatter
21
18
  # Defines aliases for coloured output. You can tweak the colours by defining
22
19
  # a <tt>CUCUMBER_COLORS</tt> variable in your shell, very much like you can
23
20
  # tweak the familiar POSIX command <tt>ls</tt> with
@@ -25,7 +22,7 @@ module Cucumber
25
22
  #
26
23
  # The colours that you can change are:
27
24
  #
28
- # * <tt>missing</tt> - defaults to <tt>yellow</tt>
25
+ # * <tt>undefined</tt> - defaults to <tt>yellow</tt>
29
26
  # * <tt>pending</tt> - defaults to <tt>yellow</tt>
30
27
  # * <tt>pending_param</tt> - defaults to <tt>yellow,bold</tt>
31
28
  # * <tt>failed</tt> - defaults to <tt>red</tt>
@@ -37,7 +34,7 @@ module Cucumber
37
34
  # * <tt>skipped</tt> - defaults to <tt>cyan</tt>
38
35
  # * <tt>skipped_param</tt> - defaults to <tt>cyan,bold</tt>
39
36
  # * <tt>comment</tt> - defaults to <tt>grey</tt>
40
- # * <tt>tag</tt> - defaults to <tt>blue</tt>
37
+ # * <tt>tag</tt> - defaults to <tt>cyan</tt>
41
38
  #
42
39
  # For instance, if your shell has a black background and a green font (like the
43
40
  # "Homebrew" settings for OS X' Terminal.app), you may want to override passed
@@ -69,14 +66,15 @@ module Cucumber
69
66
  h[$1] + ',bold'
70
67
  end
71
68
  end.merge({
72
- 'missing' => 'yellow',
73
- 'pending' => 'yellow',
74
- 'failed' => 'red',
75
- 'passed' => 'green',
76
- 'outline' => 'cyan',
77
- 'skipped' => 'cyan',
78
- 'comment' => 'grey',
79
- 'tag' => 'blue'
69
+ 'undefined' => 'yellow',
70
+ 'pending' => 'yellow',
71
+ 'failed' => 'red',
72
+ 'passed' => 'green',
73
+ 'thead' => 'cyan',
74
+ 'outline' => 'cyan',
75
+ 'skipped' => 'cyan',
76
+ 'comment' => 'grey',
77
+ 'tag' => 'cyan'
80
78
  })
81
79
 
82
80
  if ENV['CUCUMBER_COLORS'] # Example: export CUCUMBER_COLORS="passed=red:failed=yellow"
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ # Adapter to make #puts/#print/#flush work with colours on Windows
6
+ class ColorIO
7
+ extend Forwardable
8
+ def_delegators :@kernel, :puts, :print # win32console colours only work when sent to Kernel
9
+ def_delegators :@stdout, :flush, :tty?
10
+
11
+ def initialize
12
+ @kernel = Kernel
13
+ @stdout = STDOUT
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,119 @@
1
+ require 'cucumber/formatter/ansicolor'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Console
6
+ extend ANSIColor
7
+ FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}
8
+
9
+ def format_step(keyword, step_name, status, step_definition, source_indent)
10
+ comment = if source_indent && step_definition
11
+ c = (' # ' + step_definition.file_colon_line).indent(source_indent)
12
+ format_string(c, :comment)
13
+ else
14
+ ''
15
+ end
16
+
17
+ begin
18
+ line = keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment
19
+ rescue
20
+ # It didn't match. This often happens for :outline steps
21
+ line = keyword + " " + step_name + comment
22
+ end
23
+
24
+ format_string(line, status)
25
+ end
26
+
27
+ def format_string(string, status)
28
+ fmt = format_for(status)
29
+ if Proc === fmt
30
+ fmt.call(string)
31
+ else
32
+ fmt % string
33
+ end
34
+ end
35
+
36
+ def print_undefined_scenarios(features)
37
+ elements = features.scenarios.select{|scenario| scenario.undefined?}
38
+ print_elements(elements, :undefined, 'scenarios')
39
+ end
40
+
41
+ def print_steps(features, status)
42
+ print_elements(features.steps[status], status, 'steps')
43
+ end
44
+
45
+ def print_elements(elements, status, kind)
46
+ if elements.any?
47
+ @io.puts(format_string("(::) #{status} #{kind} (::)", status))
48
+ @io.puts
49
+ @io.flush
50
+ end
51
+
52
+ elements.each_with_index do |element, i|
53
+ if status == :failed
54
+ print_exception(element.exception, 0)
55
+ else
56
+ @io.puts(format_string(element.backtrace_line, status))
57
+ end
58
+ @io.puts
59
+ @io.flush
60
+ end
61
+ end
62
+
63
+ def print_counts(features)
64
+ @io.puts dump_count(features.scenarios.length, "scenario")
65
+
66
+ [:failed, :skipped, :undefined, :pending, :passed].each do |status|
67
+ if features.steps[status].any?
68
+ count_string = dump_count(features.steps[status].length, "step", status.to_s)
69
+ @io.puts format_string(count_string, status)
70
+ @io.flush
71
+ end
72
+ end
73
+ end
74
+
75
+ def print_exception(e, indent)
76
+ status = Cucumber::EXCEPTION_STATUS[e.class]
77
+ @io.puts(format_string("#{e.message} (#{e.class})\n#{e.backtrace.join("\n")}".indent(indent), status))
78
+ end
79
+
80
+ def print_snippets(features, options)
81
+ return unless options[:snippets]
82
+ undefined = features.steps[:undefined]
83
+ return if undefined.empty?
84
+ snippets = undefined.map do |step|
85
+ step_name = Undefined === step.exception ? step.exception.step_name : step.name
86
+ snippet = @step_mother.snippet_text(step.actual_keyword, step_name)
87
+ snippet
88
+ end.compact.uniq
89
+
90
+ text = "\nYou can implement step definitions for missing steps with these snippets:\n\n"
91
+ text += snippets.join("\n\n")
92
+
93
+ @io.puts format_string(text, :undefined)
94
+ @io.puts
95
+ @io.flush
96
+ end
97
+
98
+ private
99
+
100
+ def with_color
101
+ c = Term::ANSIColor.coloring?
102
+ Term::ANSIColor.coloring = @io.tty?
103
+ yield
104
+ Term::ANSIColor.coloring = c
105
+ end
106
+
107
+ def dump_count(count, what, state=nil)
108
+ [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(" ")
109
+ end
110
+
111
+ def format_for(*keys)
112
+ key = keys.join('_').to_sym
113
+ fmt = FORMATS[key]
114
+ raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?
115
+ fmt
116
+ end
117
+ end
118
+ end
119
+ end