cucumber-in-the-yard 1.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.
- data/History.txt +3 -0
- data/Manifest +51 -0
- data/README.txt +55 -0
- data/Rakefile +28 -0
- data/cucumber-in-the-yard.gemspec +42 -0
- data/example/example.feature +13 -0
- data/example/example.step.rb +48 -0
- data/example/example.third.feature +30 -0
- data/example/second_example.feature +36 -0
- data/lib/city.rb +23 -0
- data/lib/cucumber/city_builder.rb +130 -0
- data/lib/yard/code_objects/cucumber_location_helper.rb +15 -0
- data/lib/yard/code_objects/feature.rb +24 -0
- data/lib/yard/code_objects/scenario.rb +25 -0
- data/lib/yard/code_objects/step.rb +25 -0
- data/lib/yard/code_objects/tags.rb +63 -0
- data/lib/yard/extensions.rb +38 -0
- data/lib/yard/handlers/base.rb +21 -0
- data/lib/yard/handlers/feature_handler.rb +41 -0
- data/lib/yard/parser/feature.rb +46 -0
- data/lib/yard/rake/city_task.rb +12 -0
- data/lib/yard/rb_extensions.rb +152 -0
- data/lib/yard/templates/default/feature/html/feature.erb +243 -0
- data/lib/yard/templates/default/feature/setup.rb +5 -0
- data/lib/yard/templates/default/fulldoc/html/css/common.css +182 -0
- data/lib/yard/templates/default/fulldoc/html/full_list.erb +34 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_features.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_scenarios.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_stepdefinitions.erb +11 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_steps.erb +13 -0
- data/lib/yard/templates/default/fulldoc/html/full_list_tagusages.erb +10 -0
- data/lib/yard/templates/default/fulldoc/html/index.erb +24 -0
- data/lib/yard/templates/default/fulldoc/html/js/cucumber.js +13 -0
- data/lib/yard/templates/default/fulldoc/html/setup.rb +73 -0
- data/lib/yard/templates/default/layout/html/headers.erb +14 -0
- data/lib/yard/templates/default/layout/html/search.erb +8 -0
- data/lib/yard/templates/default/module/html/step_transforms.erb +23 -0
- data/lib/yard/templates/default/module/setup.rb +5 -0
- data/lib/yard/templates/default/scenario/html/scenario.erb +26 -0
- data/lib/yard/templates/default/scenario/setup.rb +5 -0
- data/lib/yard/templates/default/steptransformers/html/stepdefinition.erb +38 -0
- data/lib/yard/templates/default/steptransformers/setup.rb +5 -0
- data/lib/yard/templates/default/tagusage/html/tagusage.erb +65 -0
- data/lib/yard/templates/default/tagusage/setup.rb +5 -0
- data/spec/city/feature_parser_spec_examples.rb +153 -0
- data/spec/city/gherkin_loader_spec.rb +39 -0
- data/spec/city/test.feature +36 -0
- data/spec/city/yard_handlers_cucumber_spec.rb +24 -0
- data/spec/city/yard_namespace_object_spec.rb +8 -0
- data/spec/city/yard_parser_cucumber_spec.rb +215 -0
- data/spec/city/yard_rb_extensions_spec.rb +128 -0
- data/spec/spec_helper.rb +5 -0
- data.tar.gz.sig +0 -0
- metadata +201 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module YARD::CodeObjects
|
3
|
+
|
4
|
+
NamespaceObject.class_eval do
|
5
|
+
|
6
|
+
attr_accessor :features
|
7
|
+
|
8
|
+
def features(opts = {})
|
9
|
+
children.select {|child| child.type == :feature }
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :scenarios
|
13
|
+
|
14
|
+
def scenarios(opts = {})
|
15
|
+
children.select {|child| child.type == :scenario }
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :steps
|
19
|
+
|
20
|
+
def steps(opts = {})
|
21
|
+
children.select {|child| child.type == :step }
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :step_definitions
|
25
|
+
|
26
|
+
def step_definitions(opts = {})
|
27
|
+
children.select {|child| child.type == :stepdefinition }
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :step_transforms
|
31
|
+
|
32
|
+
def step_transforms(opts = {})
|
33
|
+
children.select {|child| child.type == :steptransform }
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
module Cucumber
|
4
|
+
|
5
|
+
class Base < Handlers::Base
|
6
|
+
class << self
|
7
|
+
include Parser::Cucumber
|
8
|
+
def handles?(node)
|
9
|
+
handlers.any? do |a_handler|
|
10
|
+
log.debug "YARD::Handlers::Cucumber::Base#handles?"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
include Parser::Cucumber
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
Processor.register_handler_namespace :feature, Cucumber
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module YARD
|
2
|
+
module Handlers
|
3
|
+
module Cucumber
|
4
|
+
|
5
|
+
class FeatureHandler < Base
|
6
|
+
|
7
|
+
handles CodeObjects::Cucumber::Feature
|
8
|
+
|
9
|
+
def process
|
10
|
+
|
11
|
+
# For the background and the scenario, find the steps that have definitions
|
12
|
+
process_scenario(statement.background) if statement.background
|
13
|
+
|
14
|
+
statement.scenarios.each do |scenario|
|
15
|
+
process_scenario(scenario)
|
16
|
+
end
|
17
|
+
|
18
|
+
rescue YARD::Handlers::NamespaceMissingError
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def process_scenario(scenario)
|
23
|
+
scenario.steps.each do |step|
|
24
|
+
owner.step_definitions.each do |stepdef|
|
25
|
+
if %r{#{stepdef.compare_value}}.match(step.value)
|
26
|
+
step.definition = stepdef
|
27
|
+
stepdef.steps << step
|
28
|
+
log.info "STEP #{step} has found its definition #{stepdef}"
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module YARD::Parser::Cucumber
|
2
|
+
|
3
|
+
class FeatureParser < YARD::Parser::Base
|
4
|
+
|
5
|
+
def initialize(source, file = '(stdin)')
|
6
|
+
|
7
|
+
@builder = Cucumber::Parser::CityBuilder.new(file)
|
8
|
+
@tag_counts = {}
|
9
|
+
@tag_formatter = Gherkin::Formatter::TagCountFormatter.new(@builder, @tag_counts)
|
10
|
+
@parser = Gherkin::Parser::Parser.new(@tag_formatter, true, "root", false)
|
11
|
+
|
12
|
+
@source = source
|
13
|
+
@file = file
|
14
|
+
|
15
|
+
@feature = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse
|
19
|
+
begin
|
20
|
+
@parser.parse(@source, @file, 0)
|
21
|
+
@feature = @builder.ast
|
22
|
+
return nil if @feature.nil? # Nothing matched
|
23
|
+
@feature.language = @parser.i18n_language
|
24
|
+
rescue Gherkin::Lexer::LexingError, Gherkin::Parser::ParseError => e
|
25
|
+
e.message.insert(0, "#{@file}: ")
|
26
|
+
raise e
|
27
|
+
end
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def tokenize
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def enumerator
|
38
|
+
[@feature]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
YARD::Parser::SourceParser.register_parser_type :feature, FeatureParser, 'feature'
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
|
2
|
+
module YARD::CodeObjects
|
3
|
+
|
4
|
+
|
5
|
+
#
|
6
|
+
# StepDefinitions, as implemented in a ruby file
|
7
|
+
#
|
8
|
+
class StepDefinitionObject < Base
|
9
|
+
|
10
|
+
attr_reader :keyword, :value, :compare_value, :source
|
11
|
+
attr_accessor :constants, :steps
|
12
|
+
|
13
|
+
def value=(value)
|
14
|
+
@value = format_source(value)
|
15
|
+
@constants = {}
|
16
|
+
@steps = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def compare_value
|
20
|
+
base_value = value.gsub(/^\/|\/$/,'')
|
21
|
+
@constants.each do |name,value|
|
22
|
+
base_value.gsub!(/\#\{\s*#{name.to_s}\s*\}/,value.gsub(/^\/|\/$/,''))
|
23
|
+
end
|
24
|
+
base_value
|
25
|
+
end
|
26
|
+
|
27
|
+
def _value_constants(data=@value)
|
28
|
+
#Hash[*data.scan(/\#\{([^\}]+)\}/).flatten.collect {|value| [value.strip,nil]}.flatten]
|
29
|
+
data.scan(/\#\{([^\}]+)\}/).flatten.collect { |value| value.strip }
|
30
|
+
end
|
31
|
+
|
32
|
+
def constants=(value)
|
33
|
+
value.each do |val|
|
34
|
+
@constants[val.name.to_s] = val if val.respond_to?(:name) && val.respond_to?(:value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
class StepTransformersObject < Base
|
41
|
+
|
42
|
+
attr_reader :source
|
43
|
+
attr_accessor :definitions, :transforms
|
44
|
+
|
45
|
+
def push(stepobject)
|
46
|
+
if stepobject.is_a?(StepDefinitionObject)
|
47
|
+
@definitions = [] unless @definitions
|
48
|
+
@definitions << stepobject
|
49
|
+
elsif stepobject.ia_a?(StepTransformObject)
|
50
|
+
@transforms = [] unless @transforms
|
51
|
+
@transforms << stepobject
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :<< , :push
|
56
|
+
|
57
|
+
def filename
|
58
|
+
"#{name}.html"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
#
|
65
|
+
# Transforms
|
66
|
+
#
|
67
|
+
class StepTransformObject < Base
|
68
|
+
attr_reader :value
|
69
|
+
|
70
|
+
def value=(value)
|
71
|
+
@value = format_source(value)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
class StepDefinitionHandler < YARD::Handlers::Ruby::Legacy::Base
|
82
|
+
MATCH = /^((When|Given|And|Then)\s*(\/[^\/]+\/).+)$/
|
83
|
+
handles MATCH
|
84
|
+
|
85
|
+
@@unique_name = 0
|
86
|
+
|
87
|
+
def process
|
88
|
+
|
89
|
+
keyword = statement.tokens.to_s[MATCH,2]
|
90
|
+
step_definition = statement.tokens.to_s[MATCH,3]
|
91
|
+
@@unique_name = @@unique_name + 1
|
92
|
+
|
93
|
+
stepdef_instance = StepDefinitionObject.new(namespace, "StepDefinition_#{@@unique_name}") {|o| o.source = statement.block.to_s ; o.value = step_definition ; o.keyword = keyword}
|
94
|
+
|
95
|
+
begin
|
96
|
+
# Look for all constants within the step definitions
|
97
|
+
stepdef_instance.constants = stepdef_instance._value_constants.each do |stepdef_constant|
|
98
|
+
owner.constants.each do |constant|
|
99
|
+
if stepdef_constant.to_sym == constant.name
|
100
|
+
log.info "Replacing #{constant.name} with its value in the step definition #{stepdef_instance.value}"
|
101
|
+
stepdef_instance.constants[constant.name] = unpack_constants(constant.value)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
rescue Exception => e
|
107
|
+
log.error "Failed to link step definition to constants. This will make step definition to step linking impossible if constants are present. #{e}"
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
obj = register stepdef_instance
|
112
|
+
|
113
|
+
|
114
|
+
parse_block :owner => obj
|
115
|
+
rescue YARD::Handlers::NamespaceMissingError
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def unpack_constants(constant_value)
|
120
|
+
constant_value.scan(/\#\{([^\}]+)\}/).flatten.collect { |value| value.strip }.each do |inner_constant|
|
121
|
+
inner_constant_match = owner.constants.find {|constant| constant.name.to_s == inner_constant }
|
122
|
+
if inner_constant_match
|
123
|
+
constant_value.gsub!(/\#\{#{inner_constant}\}/,unpack_constants(inner_constant_match.value))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
constant_value.gsub!(/^('|"|\/)|('|"|\/)$/,'')
|
128
|
+
constant_value
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
class StepTransformHandler < YARD::Handlers::Ruby::Legacy::Base
|
135
|
+
MATCH = /^Transform\s*(\/[^\/]+\/).+$/
|
136
|
+
handles MATCH
|
137
|
+
|
138
|
+
@@unique_name = 0
|
139
|
+
|
140
|
+
def process
|
141
|
+
transformDefinition = statement.tokens.to_s[MATCH,1]
|
142
|
+
#log.debug "#process - transformDefinition = #{transformDefinition}"
|
143
|
+
@@unique_name = @@unique_name + 1
|
144
|
+
|
145
|
+
obj = register StepTransformObject.new(namespace, "StepTransform_#{@@unique_name}") {|o| o.source = statement.block.to_s ; o.value = transformDefinition }
|
146
|
+
|
147
|
+
parse_block :owner => obj
|
148
|
+
|
149
|
+
rescue YARD::Handlers::NamespaceMissingError
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,243 @@
|
|
1
|
+
<div class="feature">
|
2
|
+
<div class="title">
|
3
|
+
<span class="pre"><%= @feature.keyword %>:</span>
|
4
|
+
<span class="name"><%= @feature.value %></span>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="meta">
|
8
|
+
<div class="file"><%= h(@feature.file) %></div>
|
9
|
+
<div class="tags">
|
10
|
+
<% @feature.tags.each do |tag| %>
|
11
|
+
<a href="tag_<%= tag.value %>.html"><%= tag.value %></a>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div class="description">
|
17
|
+
<%= @feature.description %>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<% if @feature.background %>
|
21
|
+
|
22
|
+
<script type="text/javascript" charset="utf-8">
|
23
|
+
$(function() {
|
24
|
+
$('#background .toggle').click(function() {
|
25
|
+
$("#backgroundSteps").toggle('blind');
|
26
|
+
|
27
|
+
var stateIndicator = $('#background a.toggle')[0]
|
28
|
+
|
29
|
+
stateIndicator.innerHTML = (stateIndicator.innerHTML === '+' ? '-' : '+');
|
30
|
+
return false;
|
31
|
+
});
|
32
|
+
});
|
33
|
+
</script>
|
34
|
+
|
35
|
+
<div id="background">
|
36
|
+
<div class="title">
|
37
|
+
<a class="toggle">-</a>
|
38
|
+
<span class="pre">Background</span>
|
39
|
+
</div>
|
40
|
+
<% unless @feature.background.description.empty? %>
|
41
|
+
<div class="description">
|
42
|
+
<%= h(@feature.background.description.join("\n<br/>")) %>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<!-- Background and scenario should have the same display with some minor changes -->
|
47
|
+
|
48
|
+
<div id="backgroundSteps" class="steps">
|
49
|
+
<% if @feature.background.steps %>
|
50
|
+
<% @feature.background.steps.each_with_index do |step,index| %>
|
51
|
+
<div <%= "id='backgroundStep#{index}'" %> class="step <%= (index + 1) % 2 == 0 ? 'even' : 'odd' %>">
|
52
|
+
<span class="predicate"><%= step.keyword %></span>
|
53
|
+
|
54
|
+
<% if step.definition %>
|
55
|
+
<script type="text/javascript" charset="utf-8">
|
56
|
+
$('<%= "#backgroundStep#{index}" %>').hover(
|
57
|
+
function () { $('<%= "#backgroundStep#{index} div.details" %>').toggle('slide'); },
|
58
|
+
function () { $('<%= "#backgroundStep#{index} div.details" %>').toggle('slide'); }
|
59
|
+
);
|
60
|
+
|
61
|
+
$('<%= "#backgroundStep#{index} div.details" %>').show();
|
62
|
+
|
63
|
+
</script>
|
64
|
+
<span class="defined">
|
65
|
+
<a href="steptransformers.html#<%= step.definition.name %>"><%= h(step.value) %></a>
|
66
|
+
<div class="details" style="display: none;">
|
67
|
+
(<%= h("#{step.definition.files.first.first}:#{step.definition.files.first.last}") %>)
|
68
|
+
</div>
|
69
|
+
</span>
|
70
|
+
<% else %>
|
71
|
+
<span class="undefined"><%= h(step.value) %></span>
|
72
|
+
<% end %>
|
73
|
+
|
74
|
+
<% if step.has_text? %>
|
75
|
+
<div class="text">
|
76
|
+
<%= h(step.text) %>
|
77
|
+
</div>
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
<% if step.has_table? %>
|
81
|
+
<div class="multiline">
|
82
|
+
<table style="">
|
83
|
+
|
84
|
+
<thead>
|
85
|
+
<tr>
|
86
|
+
<% step.table.each_with_index do |column,column_index| %>
|
87
|
+
<th class="<%= (column_index + 1) % 2 == 0 ? 'even' : 'odd' %>"><%= h(column.to_s.strip) %></td>
|
88
|
+
<% end %>
|
89
|
+
</tr>
|
90
|
+
</thead>
|
91
|
+
|
92
|
+
<% step.table[1..-1].each do |row| %>
|
93
|
+
<tr>
|
94
|
+
<% row.split("|").each_with_index do |column,column_index| %>
|
95
|
+
<td class="<%= (column_index + 1) % 2 == 0 ? 'even' : 'odd' %>"><%= h(column.to_s.strip) %></td>
|
96
|
+
<% end %>
|
97
|
+
</tr>
|
98
|
+
<% end %>
|
99
|
+
</table>
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<% end %>
|
103
|
+
|
104
|
+
</div>
|
105
|
+
|
106
|
+
<% end %>
|
107
|
+
<% else %>
|
108
|
+
<span>No Steps Defined</span>
|
109
|
+
<% end %>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</div>
|
113
|
+
<% end %>
|
114
|
+
|
115
|
+
<% if @feature.scenarios %>
|
116
|
+
<% @feature.scenarios.each_with_index do |scenario,scenario_index| %>
|
117
|
+
|
118
|
+
<script type="text/javascript" charset="utf-8">
|
119
|
+
$(function() {
|
120
|
+
$('#scenario<%=scenario_index%> .toggle').click(function() {
|
121
|
+
$("#scenario<%=scenario_index%>Steps").toggle('blind');
|
122
|
+
|
123
|
+
var stateIndicator = $('#scenario<%=scenario_index%> a.toggle')[0]
|
124
|
+
|
125
|
+
stateIndicator.innerHTML = (stateIndicator.innerHTML === '+' ? '-' : '+');
|
126
|
+
return false;
|
127
|
+
});
|
128
|
+
});
|
129
|
+
</script>
|
130
|
+
|
131
|
+
<div <%= "id='scenario#{scenario_index}'" %> class="scenario">
|
132
|
+
<div class="title">
|
133
|
+
<a class="toggle">-</a>
|
134
|
+
<span class="pre">Scenario<%= !scenario.examples.empty? ? " Outline" : "" %>:</span>
|
135
|
+
<span class="name"><%= h(scenario.value) %></span>
|
136
|
+
</div>
|
137
|
+
<div class="meta">
|
138
|
+
<div class="file">Line: <%= scenario.files.first.last %></div>
|
139
|
+
<% unless scenario.tags.empty? %>
|
140
|
+
<div class="tags">
|
141
|
+
<% scenario.tags.each do |tag| %>
|
142
|
+
<a href="tag_<%= tag.value %>.html"><%= tag.value %></a>
|
143
|
+
<% end %>
|
144
|
+
</div>
|
145
|
+
<% end%>
|
146
|
+
</div>
|
147
|
+
<% unless scenario.description.empty? %>
|
148
|
+
<div class="description">
|
149
|
+
<%= h(scenario.description.join("\n<br/>")) %>
|
150
|
+
</div>
|
151
|
+
<% end %>
|
152
|
+
|
153
|
+
<div <%= "id='scenario#{scenario_index}Steps'" %> class="steps">
|
154
|
+
<% if scenario.steps %>
|
155
|
+
<% scenario.steps.each_with_index do |step,index| %>
|
156
|
+
<div <%= "id='scenario#{scenario_index}Step#{index}'" %> class="step <%= (index + 1) % 2 == 0 ? 'even' : 'odd' %>">
|
157
|
+
<span class="predicate"><%= step.keyword %></span>
|
158
|
+
|
159
|
+
<% if step.definition %>
|
160
|
+
<script type="text/javascript" charset="utf-8">
|
161
|
+
$('<%= "#scenario#{scenario_index}Step#{index}" %>').hover(
|
162
|
+
function () { $('<%= "#scenario#{scenario_index}Step#{index} div.details" %>').toggle('slide'); },
|
163
|
+
function () { $('<%= "#scenario#{scenario_index}Step#{index} div.details" %>').toggle('slide'); }
|
164
|
+
);
|
165
|
+
|
166
|
+
$('<%= "#scenario#{scenario_index}Step#{index} div.details" %>').show();
|
167
|
+
|
168
|
+
</script>
|
169
|
+
<span class="defined">
|
170
|
+
<a href="steptransformers.html#<%= step.definition.name %>"><%= h(step.value) %></a>
|
171
|
+
<div class="details" style="display: none;">
|
172
|
+
(<%= h("#{step.definition.files.first.first}:#{step.definition.files.first.last}") %>)
|
173
|
+
</div>
|
174
|
+
</span>
|
175
|
+
<% else %>
|
176
|
+
<span class="undefined"><%= h(step.value) %></span>
|
177
|
+
<% end %>
|
178
|
+
|
179
|
+
<% if step.has_text? %>
|
180
|
+
<div class="text">
|
181
|
+
<%= h(step.text) %>
|
182
|
+
</div>
|
183
|
+
<% end %>
|
184
|
+
|
185
|
+
<% if step.has_table? %>
|
186
|
+
<div class="multiline">
|
187
|
+
<table style="">
|
188
|
+
|
189
|
+
<thead>
|
190
|
+
<tr>
|
191
|
+
<% step.table.first.each_with_index do |column,column_index| %>
|
192
|
+
<th class="<%= (column_index + 1) % 2 == 0 ? 'even' : 'odd' %>"><%= h(column.strip) %></td>
|
193
|
+
<% end %>
|
194
|
+
</tr>
|
195
|
+
</thead>
|
196
|
+
|
197
|
+
<% step.table[1..-1].each do |row| %>
|
198
|
+
<tr>
|
199
|
+
<% row.each_with_index do |column,column_index| %>
|
200
|
+
<td class="<%= (column_index + 1) % 2 == 0 ? 'even' : 'odd' %>"><%= h(column.strip) %></td>
|
201
|
+
<% end %>
|
202
|
+
</tr>
|
203
|
+
<% end %>
|
204
|
+
</table>
|
205
|
+
</div>
|
206
|
+
|
207
|
+
<% end %>
|
208
|
+
|
209
|
+
|
210
|
+
</div>
|
211
|
+
|
212
|
+
<% end %>
|
213
|
+
<% else %>
|
214
|
+
<span>No Steps Defined</span>
|
215
|
+
<% end %>
|
216
|
+
</div>
|
217
|
+
|
218
|
+
<% if scenario.examples && !scenario.examples.empty? %>
|
219
|
+
<div class="outline">
|
220
|
+
<table>
|
221
|
+
<thead>
|
222
|
+
<tr>
|
223
|
+
<th class="odd" colspan="10"><%= h(scenario.examples.first.first.to_s.strip) %></td>
|
224
|
+
</tr>
|
225
|
+
</thead>
|
226
|
+
<% scenario.examples.first.find {|example| example.is_a?(Array) }.each_with_index do |row,row_index| %>
|
227
|
+
<tr>
|
228
|
+
<% row.each do |column| %>
|
229
|
+
<td class="<%= (row_index + 1) % 2 == 0 ? 'even' : 'odd' %>"><%= h(column.to_s.strip) %></td>
|
230
|
+
<% end %>
|
231
|
+
</tr>
|
232
|
+
<% end %>
|
233
|
+
</table>
|
234
|
+
</div>
|
235
|
+
|
236
|
+
<% end %>
|
237
|
+
|
238
|
+
</div>
|
239
|
+
<% end %>
|
240
|
+
<% end %>
|
241
|
+
|
242
|
+
</div>
|
243
|
+
|