cucumber 0.1.6

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 (153) hide show
  1. data/History.txt +3 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +152 -0
  4. data/README.txt +42 -0
  5. data/Rakefile +4 -0
  6. data/TODO.txt +26 -0
  7. data/bin/cucumber +4 -0
  8. data/config/hoe.rb +69 -0
  9. data/config/requirements.rb +15 -0
  10. data/cucumber.yml +1 -0
  11. data/examples/calculator/Rakefile +6 -0
  12. data/examples/calculator/cucumber.yml +1 -0
  13. data/examples/calculator/features/addition.feature +16 -0
  14. data/examples/calculator/features/division.feature +10 -0
  15. data/examples/calculator/features/steps/calculator_steps.rb +31 -0
  16. data/examples/calculator/lib/calculator.rb +16 -0
  17. data/examples/calculator_ruby_features/Rakefile +6 -0
  18. data/examples/calculator_ruby_features/features/addition.rb +23 -0
  19. data/examples/calculator_ruby_features/features/steps/calculator_steps.rb +43 -0
  20. data/examples/calculatrice_francaise_avec_soit_scenario/Rakefile +6 -0
  21. data/examples/calculatrice_francaise_avec_soit_scenario/features/addition.feature +13 -0
  22. data/examples/calculatrice_francaise_avec_soit_scenario/features/calculatrice_steps.rb +31 -0
  23. data/examples/cs/README.textile +22 -0
  24. data/examples/cs/Rakefile +12 -0
  25. data/examples/cs/features/hello.feature +11 -0
  26. data/examples/cs/features/steps/hello_steps.rb +25 -0
  27. data/examples/cs/features/steps/tree_steps.rb +14 -0
  28. data/examples/cs/features/tree.feature +9 -0
  29. data/examples/cs/src/Hello.cs +18 -0
  30. data/examples/danish_calculator/Rakefile +6 -0
  31. data/examples/danish_calculator/features/steps/kalkulator_steps.rb +22 -0
  32. data/examples/danish_calculator/features/summering.feature +17 -0
  33. data/examples/danish_calculator/lib/kalkulator.rb +11 -0
  34. data/examples/estonian_calculator/Rakefile +6 -0
  35. data/examples/estonian_calculator/features/kalkulaator_steps.rb +35 -0
  36. data/examples/estonian_calculator/features/liitmine.feature +16 -0
  37. data/examples/java/README.textile +22 -0
  38. data/examples/java/Rakefile +12 -0
  39. data/examples/java/features/hello.feature +11 -0
  40. data/examples/java/features/steps/hello_steps.rb +25 -0
  41. data/examples/java/features/steps/tree_steps.rb +14 -0
  42. data/examples/java/features/tree.feature +9 -0
  43. data/examples/java/src/cucumber/demo/Hello.java +16 -0
  44. data/examples/norwegian_calculator/Rakefile +6 -0
  45. data/examples/norwegian_calculator/features/steps/kalkulator_steps.rb +22 -0
  46. data/examples/norwegian_calculator/features/summering.feature +17 -0
  47. data/examples/norwegian_calculator/lib/kalkulator.rb +11 -0
  48. data/examples/portuguese_calculator/Rakefile +6 -0
  49. data/examples/portuguese_calculator/features/adicao.feature +10 -0
  50. data/examples/portuguese_calculator/features/calculadora_steps.rb +31 -0
  51. data/examples/selenium/Rakefile +6 -0
  52. data/examples/selenium/features/search.feature +9 -0
  53. data/examples/selenium/features/steps/stories_steps.rb +41 -0
  54. data/examples/spanish_calculator/Rakefile +6 -0
  55. data/examples/spanish_calculator/features/adicion.feature +17 -0
  56. data/examples/spanish_calculator/features/steps/calculador_steps.rb +22 -0
  57. data/examples/spanish_calculator/lib/Calculador.rb +11 -0
  58. data/examples/tickets/Rakefile +4 -0
  59. data/examples/tickets/features/steps/tickets_steps.rb +5 -0
  60. data/examples/tickets/features/tickets.feature +7 -0
  61. data/examples/watir/Rakefile +6 -0
  62. data/examples/watir/features/search.feature +9 -0
  63. data/examples/watir/features/steps/stories_steps.rb +51 -0
  64. data/features/see_features.feature +8 -0
  65. data/features/steps/features_steps.rb +9 -0
  66. data/gem_tasks/deployment.rake +34 -0
  67. data/gem_tasks/environment.rake +7 -0
  68. data/gem_tasks/features.rake +6 -0
  69. data/gem_tasks/fix_cr_lf.rake +10 -0
  70. data/gem_tasks/flog.rake +4 -0
  71. data/gem_tasks/gemspec.rake +6 -0
  72. data/gem_tasks/rspec.rake +21 -0
  73. data/gem_tasks/treetop.rake +27 -0
  74. data/generators/cucumber/cucumber_generator.rb +27 -0
  75. data/generators/cucumber/templates/common_webrat.rb +51 -0
  76. data/generators/cucumber/templates/cucumber +2 -0
  77. data/generators/cucumber/templates/cucumber.rake +7 -0
  78. data/generators/cucumber/templates/env.rb +8 -0
  79. data/generators/feature/feature_generator.rb +17 -0
  80. data/generators/feature/templates/feature.erb +27 -0
  81. data/generators/feature/templates/steps.erb +22 -0
  82. data/lib/cucumber.rb +32 -0
  83. data/lib/cucumber/cli.rb +163 -0
  84. data/lib/cucumber/core_ext/proc.rb +43 -0
  85. data/lib/cucumber/core_ext/string.rb +22 -0
  86. data/lib/cucumber/executor.rb +120 -0
  87. data/lib/cucumber/formatters.rb +1 -0
  88. data/lib/cucumber/formatters/ansicolor.rb +90 -0
  89. data/lib/cucumber/formatters/cucumber.css +132 -0
  90. data/lib/cucumber/formatters/cucumber.js +11 -0
  91. data/lib/cucumber/formatters/html_formatter.rb +125 -0
  92. data/lib/cucumber/formatters/jquery.js +32 -0
  93. data/lib/cucumber/formatters/pretty_formatter.rb +126 -0
  94. data/lib/cucumber/formatters/progress_formatter.rb +42 -0
  95. data/lib/cucumber/languages.yml +83 -0
  96. data/lib/cucumber/rails/rspec.rb +12 -0
  97. data/lib/cucumber/rails/world.rb +75 -0
  98. data/lib/cucumber/rake/task.rb +75 -0
  99. data/lib/cucumber/step_methods.rb +45 -0
  100. data/lib/cucumber/step_mother.rb +82 -0
  101. data/lib/cucumber/tree.rb +18 -0
  102. data/lib/cucumber/tree/feature.rb +53 -0
  103. data/lib/cucumber/tree/features.rb +21 -0
  104. data/lib/cucumber/tree/given_scenario.rb +13 -0
  105. data/lib/cucumber/tree/scenario.rb +110 -0
  106. data/lib/cucumber/tree/step.rb +123 -0
  107. data/lib/cucumber/tree/table.rb +26 -0
  108. data/lib/cucumber/tree/top_down_visitor.rb +23 -0
  109. data/lib/cucumber/treetop_parser/feature.treetop.erb +159 -0
  110. data/lib/cucumber/treetop_parser/feature_da.rb +1214 -0
  111. data/lib/cucumber/treetop_parser/feature_de.rb +1214 -0
  112. data/lib/cucumber/treetop_parser/feature_en.rb +1214 -0
  113. data/lib/cucumber/treetop_parser/feature_es.rb +1214 -0
  114. data/lib/cucumber/treetop_parser/feature_et.rb +1214 -0
  115. data/lib/cucumber/treetop_parser/feature_fr.rb +1214 -0
  116. data/lib/cucumber/treetop_parser/feature_no.rb +1214 -0
  117. data/lib/cucumber/treetop_parser/feature_parser.rb +32 -0
  118. data/lib/cucumber/treetop_parser/feature_pt.rb +1214 -0
  119. data/lib/cucumber/treetop_parser/feature_ru.rb +1214 -0
  120. data/lib/cucumber/treetop_parser/feature_se.rb +1214 -0
  121. data/lib/cucumber/version.rb +9 -0
  122. data/script/console +10 -0
  123. data/script/console.cmd +1 -0
  124. data/script/destroy +14 -0
  125. data/script/destroy.cmd +1 -0
  126. data/script/generate +14 -0
  127. data/script/generate.cmd +1 -0
  128. data/script/txt2html +74 -0
  129. data/script/txt2html.cmd +1 -0
  130. data/setup.rb +1585 -0
  131. data/spec/cucumber/cli_spec.rb +36 -0
  132. data/spec/cucumber/core_ext/proc_spec.rb +39 -0
  133. data/spec/cucumber/core_ext/string_spec.rb +34 -0
  134. data/spec/cucumber/executor_spec.rb +131 -0
  135. data/spec/cucumber/formatters/ansicolor_spec.rb +23 -0
  136. data/spec/cucumber/formatters/features.html +269 -0
  137. data/spec/cucumber/formatters/html_formatter_spec.rb +59 -0
  138. data/spec/cucumber/formatters/pretty_formatter_spec.rb +17 -0
  139. data/spec/cucumber/formatters/progress_formatter_spec.rb +44 -0
  140. data/spec/cucumber/sell_cucumbers.feature +9 -0
  141. data/spec/cucumber/step_mother_spec.rb +53 -0
  142. data/spec/cucumber/tree/scenario_spec.rb +15 -0
  143. data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
  144. data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
  145. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +73 -0
  146. data/spec/cucumber/treetop_parser/fit_scenario.feature +7 -0
  147. data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
  148. data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
  149. data/spec/cucumber/treetop_parser/spaces.feature +10 -0
  150. data/spec/cucumber/treetop_parser/with_comments.feature +6 -0
  151. data/spec/spec.opts +2 -0
  152. data/spec/spec_helper.rb +23 -0
  153. metadata +259 -0
@@ -0,0 +1,43 @@
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
+ attr_accessor :name
10
+
11
+ def call_in(obj, *args)
12
+ obj.extend(mod)
13
+ a = arity == -1 ? 0 : arity
14
+ if self != StepMother::PENDING && args.length != a
15
+ # We have to manually raise when the block has arity -1 (no pipes)
16
+ raise ArityMismatchError.new("expected #{arity == -1 ? 0 : arity} block argument(s), got #{args.length}")
17
+ else
18
+ obj.__send__(meth, *args)
19
+ end
20
+ end
21
+
22
+ def arity2
23
+ arity == -1 ? 0 : arity
24
+ end
25
+
26
+ def backtrace_line
27
+ to_s.match(/[\d\w]+@(.*)>/)[1] + ":in `#{name}'"
28
+ end
29
+
30
+ def meth
31
+ @meth ||= "__cucumber_#{object_id}"
32
+ end
33
+
34
+ def mod
35
+ p = self
36
+ m = meth
37
+ @mod ||= Module.new do
38
+ define_method(m, &p)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ class String
2
+ def gzub(regexp, format=nil, &proc)
3
+ md = match(regexp)
4
+ raise "#{self.inspect} doesn't match #{regexp.inspect}" if md.nil?
5
+
6
+ s = dup
7
+ pos = 0
8
+ md.captures.each_with_index do |m, n|
9
+ replacement = if block_given?
10
+ proc.call(m)
11
+ else
12
+ format % m
13
+ end
14
+
15
+ if md.offset(n+1)[0]
16
+ s[md.offset(n+1)[0] + pos, m.length] = replacement
17
+ pos += replacement.length - m.length
18
+ end
19
+ end
20
+ s
21
+ end
22
+ end
@@ -0,0 +1,120 @@
1
+ require 'cucumber/core_ext/proc'
2
+
3
+ module Cucumber
4
+ class Executor
5
+ attr_reader :failed
6
+
7
+ def line=(line)
8
+ @line = line
9
+ end
10
+
11
+ def initialize(formatter, step_mother)
12
+ @formatter = formatter
13
+ @world_proc = lambda do
14
+ world = Object.new
15
+ world.extend(Spec::Matchers) if defined?(Spec::Matchers)
16
+ world
17
+ end
18
+ @before_scenario_procs = []
19
+ @after_scenario_procs = []
20
+ @after_step_procs = []
21
+ @step_mother = step_mother
22
+ end
23
+
24
+ def register_world_proc(&proc)
25
+ @world_proc = proc
26
+ end
27
+
28
+ def register_before_scenario_proc(&proc)
29
+ proc.extend(CoreExt::CallIn)
30
+ @before_scenario_procs << proc
31
+ end
32
+
33
+ def register_after_scenario_proc(&proc)
34
+ proc.extend(CoreExt::CallIn)
35
+ @after_scenario_procs << proc
36
+ end
37
+
38
+ def register_after_step_proc(&proc)
39
+ proc.extend(CoreExt::CallIn)
40
+ @after_step_procs << proc
41
+ end
42
+
43
+ def visit_features(features)
44
+ raise "Line number can only be specified when there is 1 feature. There were #{features.length}." if @line && features.length != 1
45
+ @formatter.visit_features(features) if @formatter.respond_to?(:visit_features)
46
+ features.accept(self)
47
+ @formatter.dump
48
+ end
49
+
50
+ def visit_feature(feature)
51
+ feature.accept(self)
52
+ end
53
+
54
+ def visit_header(header)
55
+ @formatter.header_executing(header) if @formatter.respond_to?(:header_executing)
56
+ end
57
+
58
+ def visit_row_scenario(scenario)
59
+ visit_scenario(scenario)
60
+ end
61
+
62
+ def visit_regular_scenario(scenario)
63
+ visit_scenario(scenario)
64
+ end
65
+
66
+ def visit_scenario(scenario)
67
+ if @line.nil? || scenario.at_line?(@line)
68
+ @error = nil
69
+ @pending = nil
70
+ @world = @world_proc.call
71
+ @formatter.scenario_executing(scenario) if @formatter.respond_to?(:scenario_executing)
72
+ @before_scenario_procs.each{|p| p.call_in(@world, *[])}
73
+ scenario.accept(self)
74
+ @after_scenario_procs.each{|p| p.call_in(@world, *[])}
75
+ @formatter.scenario_executed(scenario) if @formatter.respond_to?(:scenario_executed)
76
+ end
77
+ end
78
+
79
+ def visit_row_step(step)
80
+ visit_step(step)
81
+ end
82
+
83
+ def visit_regular_step(step)
84
+ visit_step(step)
85
+ end
86
+
87
+ def visit_step(step)
88
+ unless @pending || @error
89
+ begin
90
+ regexp, args, proc = step.regexp_args_proc(@step_mother)
91
+ step.execute_in(@world, regexp, args, proc)
92
+ @after_step_procs.each{|p| p.call_in(@world, *[])}
93
+ @formatter.step_passed(step, regexp, args)
94
+ rescue Pending
95
+ record_pending_step(step, regexp, args)
96
+ rescue => e
97
+ @failed = true
98
+ @error = step.error = e
99
+ @formatter.step_failed(step, regexp, args)
100
+ end
101
+ else
102
+ begin
103
+ regexp, args, proc = step.regexp_args_proc(@step_mother)
104
+ step.execute_in(@world, regexp, args, proc)
105
+ @formatter.step_skipped(step, regexp, args)
106
+ rescue Pending
107
+ record_pending_step(step, regexp, args)
108
+ rescue Exception
109
+ @formatter.step_skipped(step, regexp, args)
110
+ end
111
+ end
112
+ end
113
+
114
+ def record_pending_step(step, regexp, args)
115
+ @pending = true
116
+ @formatter.step_pending(step, regexp, args)
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1 @@
1
+ %w{html pretty progress}.each{|n| require "cucumber/formatters/#{n}_formatter"}
@@ -0,0 +1,90 @@
1
+ require 'term/ansicolor'
2
+ begin
3
+ require 'Win32/Console/ANSI' if PLATFORM =~ /mswin|mingw/
4
+ rescue LoadError
5
+ STDERR.puts "You must gem install win32console to get coloured output on this ruby platform (#{PLATFORM})"
6
+ ::Term::ANSIColor.coloring = false
7
+ end
8
+ ::Term::ANSIColor.coloring = false if !STDOUT.tty?
9
+
10
+ module Cucumber
11
+ module Formatters
12
+ # Adds ANSI color support to formatters.
13
+ # You can define your own colours by defining CUCUMBER_COLORS in your shell. Example:
14
+ #
15
+ # CUCUMBER_COLORS=pending=black,on_yellow:failed=dark,magenta:failed_param=bold,red
16
+ #
17
+ # The string must be a series of key=value pairs where:
18
+ #
19
+ # * Each key=value pair is separated by a colon (:)
20
+ # * Each key must be one of:
21
+ # ** passed
22
+ # ** passed_param
23
+ # ** failed
24
+ # ** failed_param
25
+ # ** skipped
26
+ # ** skipped_param
27
+ # ** pending
28
+ # * Each value must be a comma-separated string composed of:
29
+ # ** bold
30
+ # ** dark
31
+ # ** italic
32
+ # ** underline
33
+ # ** underscore
34
+ # ** blink
35
+ # ** rapid_blink
36
+ # ** negative
37
+ # ** concealed
38
+ # ** strikethrough
39
+ # ** black
40
+ # ** red
41
+ # ** green
42
+ # ** yellow
43
+ # ** blue
44
+ # ** magenta
45
+ # ** cyan
46
+ # ** white
47
+ # ** on_black
48
+ # ** on_red
49
+ # ** on_green
50
+ # ** on_yellow
51
+ # ** on_blue
52
+ # ** on_magenta
53
+ # ** on_cyan
54
+ # ** on_white
55
+ #
56
+ module ANSIColor
57
+ include ::Term::ANSIColor
58
+
59
+ # Params are underlined bold, except in windows, which doesn't support underline. Use non-bold colour.
60
+ param = PLATFORM =~ /mswin|mingw/ ? '' : 'underline,bold,'
61
+
62
+ # Default aliases
63
+ ALIASES = {
64
+ :passed => 'bold,green',
65
+ :passed_param => "#{param}green",
66
+ :failed => 'bold,red',
67
+ :failed_param => "#{param}red",
68
+ :skipped => 'bold,cyan',
69
+ :skipped_param => "#{param}cyan",
70
+ :pending => 'bold,yellow' # No pending_param
71
+ }
72
+ if ENV['CUCUMBER_COLORS']
73
+ ENV['CUCUMBER_COLORS'].split(':').each do |pair|
74
+ a = pair.split('=')
75
+ ALIASES[a[0].to_sym] = a[1]
76
+ end
77
+ end
78
+
79
+ ALIASES.each do |m, color_string|
80
+ colors = color_string.split(",").reverse
81
+ define_method(m) do |*s|
82
+ ::Term::ANSIColor.coloring = false if ENV['CUCUMBER_COLORS_DISABLED'] == '1'
83
+ clear + colors.inject(s[0]) do |memo, color|
84
+ s[0].nil? ? __send__(color) + memo.to_s : __send__(color, memo.to_s)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,132 @@
1
+ body {
2
+ background: #fff;
3
+ font-size: 80%;
4
+ margin:0pt;
5
+ padding:0pt;
6
+ }
7
+
8
+ #container {
9
+ background:white none repeat scroll 0%;
10
+ font-family:Helvetica,Arial,sans-serif;
11
+ margin:0pt auto;
12
+ position:relative;
13
+ text-align:left;
14
+ top:1.0em;
15
+ width:78em;
16
+ }
17
+
18
+ span {
19
+ font-weight: bold;
20
+ text-decoration: underline;
21
+ }
22
+
23
+ dl {
24
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
25
+ margin-left: 5px;
26
+ }
27
+
28
+ dl.new {
29
+ border-left: 5px solid #444444;
30
+ }
31
+
32
+ dl.pending {
33
+ border-left: 5px solid #FAF834;
34
+ }
35
+
36
+ dl.failed {
37
+ border-left: 5px solid #C20000;
38
+ }
39
+
40
+ dl.passed {
41
+ border-left: 5px solid #65C400;
42
+ }
43
+
44
+ dt {
45
+ color: #fff;
46
+ padding: 3px;
47
+ font-weight: bold;
48
+ }
49
+
50
+ dl.new > dt {
51
+ background: #444444;
52
+ }
53
+
54
+ dl.pending > dt {
55
+ color: #131313;
56
+ background: #FAF834;
57
+ }
58
+
59
+ dl.failed > dt {
60
+ background: #C20000;
61
+ }
62
+
63
+ dl.passed > dt {
64
+ background: #65C400;
65
+ }
66
+
67
+ dd {
68
+ margin: 0px 0px 0px 0px;
69
+ }
70
+
71
+ dd p, pre {
72
+ padding: 5px;
73
+ margin-top: 0;
74
+ margin-bottom: 5px;
75
+ }
76
+
77
+ dl.passed > dd > p, li.passed {
78
+ background: #DBFFB4; color: #3D7700;
79
+ border-bottom: 1px solid #65C400;
80
+ }
81
+
82
+ dl.failed > dd > p, li.failed {
83
+ color: #C20000; background: #FFFBD3;
84
+ border-bottom: 1px solid #C20000;
85
+ }
86
+
87
+ dl.pending > dd > p, li.pending {
88
+ color: #131313; background: #FCFB98;
89
+ border-bottom: 1px solid #FAF834;
90
+ }
91
+
92
+ dl.new > dd > p, li.new {
93
+ color: #444444; background: #DDDDDD;
94
+ border-bottom: 1px solid #444444;
95
+ }
96
+
97
+ span.param, span.param_editor {
98
+ font-weight: bold;
99
+ }
100
+
101
+ input {
102
+ width: 100%;
103
+ }
104
+
105
+ ul {
106
+ padding: 0px;
107
+ list-style: none;
108
+ }
109
+
110
+ ul > li {
111
+ margin: 5px 0px 5px 5px;
112
+ padding: 3px 3px 3px 5px;
113
+ }
114
+
115
+ div.auto_complete ul {
116
+ list-style-type: none;
117
+ border: 2px solid #F0F0F0;
118
+ margin: 0px;
119
+ padding: 0px;
120
+ }
121
+
122
+ div.auto_complete ul li {
123
+ background-color: white;
124
+ list-style-type: none;
125
+ display: block;
126
+ margin: 0;
127
+ padding: 2px;
128
+ }
129
+
130
+ div.auto_complete ul li.selected {
131
+ color: #444444; background: #DDDDDD;
132
+ }
@@ -0,0 +1,11 @@
1
+ function stepPassed(id) {
2
+ $("#"+id).removeClass("new").addClass("passed");
3
+ }
4
+
5
+ function stepPending(id) {
6
+ $("#"+id).removeClass("new").addClass("pending");
7
+ }
8
+
9
+ function stepFailed(id, message, backtrace) {
10
+ $("#"+id).removeClass("new").addClass("failed").append("<div>" + message + "</div>").append("<pre>" + backtrace + "</pre>");
11
+ }
@@ -0,0 +1,125 @@
1
+ module Cucumber
2
+ module Formatters
3
+ class HtmlFormatter
4
+ def initialize(io, step_mother)
5
+ @io = io
6
+ @step_mother = step_mother
7
+ @errors = []
8
+ end
9
+
10
+ def visit_features(features)
11
+ # IMPORTANT NOTICE ABOUT JQUERY BELOW. THE ORIGINAL BACKSLASHES (\) HAVE
12
+ # BEEN REPLACED BY DOUBLE BACKSLASHES (\\) IN THIS FILE TO MAKE SURE THEY
13
+ # ARE PRINTED PROPERLY WITH ONLY ONE BACKSLASH (\).
14
+ @io.puts(<<-HTML)
15
+ <?xml version="1.0" encoding="UTF-8"?>
16
+ <!DOCTYPE html
17
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
18
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
19
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
20
+ <head>
21
+ <title>#{Cucumber.language['feature']}</title>
22
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
23
+ <meta http-equiv="Expires" content="-1" />
24
+ <meta http-equiv="Pragma" content="no-cache" />
25
+ <script type="text/javascript">
26
+ #{IO.read(File.dirname(__FILE__) + '/jquery.js')}
27
+ #{IO.read(File.dirname(__FILE__) + '/cucumber.js')}
28
+ </script>
29
+ <style>
30
+ #{IO.read(File.dirname(__FILE__) + '/cucumber.css')}
31
+ </style>
32
+ </head>
33
+ <body>
34
+ <div id="container">
35
+ HTML
36
+ features.accept(self)
37
+ @io.puts %{ </div>}
38
+ end
39
+
40
+ def visit_feature(feature)
41
+ @io.puts %{ <dl class="feature new">}
42
+ feature.accept(self)
43
+ @io.puts %{ </dd>}
44
+ @io.puts %{ </dl>}
45
+ end
46
+
47
+ def visit_header(header)
48
+ header = header.gsub(/\n/, "<br />\n")
49
+ @io.puts %{ <dt>#{header}}
50
+ @io.puts %{ </dt>}
51
+ @io.puts %{ <dd>}
52
+ end
53
+
54
+ def visit_regular_scenario(scenario)
55
+ @io.puts %{ <dl class="new">}
56
+ @io.puts %{ <dt>#{Cucumber.language['scenario']}: #{scenario.name}</dt>}
57
+ @io.puts %{ <dd>}
58
+ @io.puts %{ <ul>}
59
+ scenario.accept(self)
60
+ @io.puts %{ </ul>}
61
+ @io.puts %{ </dd>}
62
+ @io.puts %{ </dl>}
63
+ end
64
+
65
+ def visit_row_scenario(scenario)
66
+ @io.puts %{ <dl class="new">}
67
+ @io.puts %{ <dt>#{Cucumber.language['scenario']}: #{scenario.name}</dt>}
68
+ @io.puts %{ <dd>}
69
+ @io.puts %{ <table>}
70
+ @io.puts %{ <thead>}
71
+ @io.puts %{ <tr>}
72
+ @io.puts %{ <th>COL 1</th>}
73
+ @io.puts %{ <th>COL 2</th>}
74
+ @io.puts %{ </tr>}
75
+ @io.puts %{ </thead>}
76
+ @io.puts %{ <tbody>}
77
+ scenario.accept(self)
78
+ @io.puts %{ </tbody>}
79
+ @io.puts %{ </table>}
80
+ @io.puts %{ </dd>}
81
+ @io.puts %{ </dl>}
82
+ end
83
+
84
+ def visit_row_step(step)
85
+ _, args, _ = step.regexp_args_proc(@step_mother)
86
+ args.each do |arg|
87
+ @io.puts %{ <td id="#{step.id}"><span>#{arg}</span></td>}
88
+ end
89
+ end
90
+
91
+ def visit_regular_step(step)
92
+ regexp, _, _ = step.regexp_args_proc(@step_mother)
93
+ @io.puts %{ <li class="new" id="#{step.id}">#{step.keyword} #{step.format(regexp, '<span>%s</span>')}</li>}
94
+ end
95
+
96
+ def step_passed(step, regexp, args)
97
+ print_javascript_tag("stepPassed(#{step.id})")
98
+ end
99
+
100
+ def step_failed(step, regexp, args)
101
+ @errors << step.error
102
+ print_javascript_tag("stepFailed(#{step.id}, #{step.error.message.inspect}, #{step.error.backtrace.join("\n").inspect})")
103
+ end
104
+
105
+ def step_pending(step, regexp, args)
106
+ print_javascript_tag("stepPending(#{step.id})")
107
+ end
108
+
109
+ def step_skipped(step, regexp, args)
110
+ # noop
111
+ end
112
+
113
+ def print_javascript_tag(js)
114
+ @io.puts %{ <script type="text/javascript">#{js}</script>}
115
+ end
116
+
117
+ def dump
118
+ @io.puts <<-HTML
119
+ </body>
120
+ </html>
121
+ HTML
122
+ end
123
+ end
124
+ end
125
+ end