turnip_formatter 0.0.1
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/.gitignore +20 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/lib/rspec/core/formatters/turnip_formatter.rb +61 -0
- data/lib/turnip_formatter/ext/turnip/builder.rb +46 -0
- data/lib/turnip_formatter/ext/turnip/rspec.rb +73 -0
- data/lib/turnip_formatter/formatter.css +159 -0
- data/lib/turnip_formatter/formatter.scss +225 -0
- data/lib/turnip_formatter/scenario/failure.rb +47 -0
- data/lib/turnip_formatter/scenario/pass.rb +19 -0
- data/lib/turnip_formatter/scenario/pending.rb +37 -0
- data/lib/turnip_formatter/scenario.rb +63 -0
- data/lib/turnip_formatter/step/failure.rb +21 -0
- data/lib/turnip_formatter/step/pending.rb +21 -0
- data/lib/turnip_formatter/step.rb +18 -0
- data/lib/turnip_formatter/template.rb +243 -0
- data/lib/turnip_formatter/version.rb +5 -0
- data/lib/turnip_formatter.rb +14 -0
- data/spec/examples/README.md +124 -0
- data/spec/examples/features/battle.feature +36 -0
- data/spec/examples/features/battle2.feature +17 -0
- data/spec/examples/features/battle3.feature +16 -0
- data/spec/examples/features/songs.feature +10 -0
- data/spec/examples/images/background.png +0 -0
- data/spec/examples/images/basic_step.png +0 -0
- data/spec/examples/images/failed_step.png +0 -0
- data/spec/examples/images/multiline.png +0 -0
- data/spec/examples/images/outline.png +0 -0
- data/spec/examples/images/pending_and_tagged_step.png +0 -0
- data/spec/examples/spec_helper.rb +8 -0
- data/spec/examples/steps/spell_steps.rb +5 -0
- data/spec/examples/steps/steps.rb +50 -0
- data/spec/rspec/core/formatters/turnip_formatter_spec.rb +101 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/passed.feature +4 -0
- data/spec/support/shared_context_examples.rb +17 -0
- data/spec/turnip_formatter/scenario/failure_spec.rb +55 -0
- data/spec/turnip_formatter/scenario/pass_spec.rb +73 -0
- data/spec/turnip_formatter/scenario/pending_spec.rb +60 -0
- data/spec/turnip_formatter/step/failure_spec.rb +41 -0
- data/spec/turnip_formatter/step/pending_spec.rb +28 -0
- data/spec/turnip_formatter/step_spec.rb +32 -0
- data/spec/turnip_formatter/template_spec.rb +161 -0
- data/turnip_formatter.gemspec +26 -0
- metadata +206 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'turnip_formatter/scenario'
|
4
|
+
require 'turnip_formatter/step/failure'
|
5
|
+
require 'rspec/core/formatters/helpers'
|
6
|
+
|
7
|
+
module TurnipFormatter
|
8
|
+
module Scenario
|
9
|
+
class NotFailedScenarioError < ::StandardError; end
|
10
|
+
class NoExistFailedStepInformationError < ::StandardError; end
|
11
|
+
|
12
|
+
class Failure
|
13
|
+
include TurnipFormatter::Scenario
|
14
|
+
include RSpec::Core::BacktraceFormatter
|
15
|
+
|
16
|
+
def steps
|
17
|
+
steps = super
|
18
|
+
steps[offending_line].tap do |step|
|
19
|
+
step.extend TurnipFormatter::Step::Failure
|
20
|
+
step.attention(exception, backtrace)
|
21
|
+
end
|
22
|
+
steps
|
23
|
+
end
|
24
|
+
|
25
|
+
def validation
|
26
|
+
raise NotFailedScenarioError if (status != 'failed')
|
27
|
+
offending_line
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def offending_line
|
34
|
+
unless backtrace.last =~ /:in step:(?<stepno>\d+) `/
|
35
|
+
raise NoExistFailedStepInformationError
|
36
|
+
end
|
37
|
+
$~[:stepno].to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
def backtrace
|
41
|
+
@backtrace ||= format_backtrace(exception.backtrace, scenario.metadata).map do |b|
|
42
|
+
backtrace_line(b)
|
43
|
+
end.compact
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'turnip_formatter/scenario'
|
4
|
+
require 'turnip_formatter/step/pending'
|
5
|
+
|
6
|
+
module TurnipFormatter
|
7
|
+
module Scenario
|
8
|
+
class NotPassedScenarioError < ::StandardError; end
|
9
|
+
|
10
|
+
class Pass
|
11
|
+
include TurnipFormatter::Scenario
|
12
|
+
|
13
|
+
def validation
|
14
|
+
raise NotPassedScenarioError if status != 'passed'
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'turnip_formatter/scenario'
|
4
|
+
require 'turnip_formatter/step/pending'
|
5
|
+
|
6
|
+
module TurnipFormatter
|
7
|
+
module Scenario
|
8
|
+
class NotPendingScenarioError < ::StandardError; end
|
9
|
+
class NoExistPendingStepInformationError < ::StandardError; end
|
10
|
+
|
11
|
+
class Pending
|
12
|
+
include TurnipFormatter::Scenario
|
13
|
+
|
14
|
+
def steps
|
15
|
+
steps = super
|
16
|
+
steps[offending_line].tap do |step|
|
17
|
+
step.extend TurnipFormatter::Step::Pending
|
18
|
+
step.attention(pending_message, scenario.location)
|
19
|
+
end
|
20
|
+
steps
|
21
|
+
end
|
22
|
+
|
23
|
+
def validation
|
24
|
+
raise NotPendingScenarioError if status != 'pending'
|
25
|
+
offending_line
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def offending_line
|
32
|
+
raise NoExistPendingStepInformationError unless pending_message =~ /^No such step\((?<stepno>\d+)\): /
|
33
|
+
$~[:stepno].to_i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'turnip_formatter/step'
|
4
|
+
|
5
|
+
module TurnipFormatter
|
6
|
+
module Scenario
|
7
|
+
class NotExistStepsInformationError < ::StandardError; end
|
8
|
+
class NoFeatureFileError < ::StandardError; end
|
9
|
+
|
10
|
+
#
|
11
|
+
# @param [RSpec::Core::Example] example
|
12
|
+
#
|
13
|
+
def initialize(example)
|
14
|
+
@scenario = example
|
15
|
+
end
|
16
|
+
|
17
|
+
def validation
|
18
|
+
raise NotExistStepsInformationError unless scenario.metadata.member?(:steps)
|
19
|
+
raise NoFeatureFileError unless feature_file_path.end_with?('.feature')
|
20
|
+
end
|
21
|
+
|
22
|
+
def steps
|
23
|
+
descriptions.map { |desc| TurnipFormatter::Step.new(desc) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(name, *args, &block)
|
27
|
+
if scenario.execution_result.member?(name.to_sym)
|
28
|
+
scenario.execution_result[name.to_sym]
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def name
|
35
|
+
scenario.example_group.description
|
36
|
+
end
|
37
|
+
|
38
|
+
def feature_name
|
39
|
+
@scenario.example_group.metadata[:example_group][:example_group][:description]
|
40
|
+
end
|
41
|
+
|
42
|
+
def feature_file_path
|
43
|
+
scenario.metadata[:file_path]
|
44
|
+
end
|
45
|
+
|
46
|
+
def tags
|
47
|
+
scenario.metadata[:steps][:tags]
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def scenario
|
53
|
+
@scenario
|
54
|
+
end
|
55
|
+
|
56
|
+
def descriptions
|
57
|
+
descriptions = scenario.metadata[:steps][:descriptions]
|
58
|
+
keywords = scenario.metadata[:steps][:keywords]
|
59
|
+
docstrings = scenario.metadata[:steps][:docstrings]
|
60
|
+
descriptions.zip(keywords, docstrings)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module TurnipFormatter
|
4
|
+
class Step
|
5
|
+
module Failure
|
6
|
+
def attention?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def attention(exception, backtrace)
|
11
|
+
exception.set_backtrace(backtrace)
|
12
|
+
docs[:source] = backtrace.first
|
13
|
+
docs[:exception] = exception
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
'failure'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module TurnipFormatter
|
4
|
+
class Step
|
5
|
+
module Pending
|
6
|
+
def attention?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def attention(message, location)
|
11
|
+
exception = RSpec::Core::Pending::PendingDeclaredInExample.new(message)
|
12
|
+
exception.set_backtrace(location)
|
13
|
+
docs[:exception] = exception
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
'pending'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module TurnipFormatter
|
4
|
+
class Step
|
5
|
+
attr_reader :name, :docs
|
6
|
+
|
7
|
+
def initialize(description)
|
8
|
+
step_name, keyword, docstring = description
|
9
|
+
@name = keyword + step_name
|
10
|
+
@docs = {}
|
11
|
+
@docs[:extra_args] = docstring unless docstring.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def attention?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'rspec/core/formatters/snippet_extractor'
|
5
|
+
|
6
|
+
module TurnipFormatter
|
7
|
+
class Template
|
8
|
+
include ERB::Util
|
9
|
+
include RSpec::Core::BacktraceFormatter
|
10
|
+
|
11
|
+
def print_header
|
12
|
+
<<-EOS
|
13
|
+
<!DOCTYPE html>
|
14
|
+
<head>
|
15
|
+
<meta charset="UTF-8">
|
16
|
+
<style>
|
17
|
+
#{File.read(File.dirname(__FILE__) + '/formatter.css')}
|
18
|
+
</style>
|
19
|
+
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
20
|
+
<script>
|
21
|
+
$(function() {
|
22
|
+
["passed", "failed", "pending"].forEach(function(status) {
|
23
|
+
$('#' + status + '_check').click(function() {
|
24
|
+
if (this.checked) {
|
25
|
+
$('.scenario.' + status).show();
|
26
|
+
} else {
|
27
|
+
$('.scenario.' + status).hide();
|
28
|
+
}
|
29
|
+
});
|
30
|
+
});
|
31
|
+
});
|
32
|
+
</script>
|
33
|
+
</head>
|
34
|
+
<body>
|
35
|
+
#{report_area}
|
36
|
+
<div id="main" role="main">
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
def print_footer(total_count, failed_count, pending_count, total_time)
|
41
|
+
update_report_js_tmp = '<script type="text/javascript">document.getElementById("%s").innerHTML = "%s";</script>'
|
42
|
+
update_report_js = ''
|
43
|
+
|
44
|
+
|
45
|
+
%w{ total_count failed_count pending_count total_time }.each do |key|
|
46
|
+
update_report_js += update_report_js_tmp % [key, eval(key)]
|
47
|
+
end
|
48
|
+
|
49
|
+
<<-EOS
|
50
|
+
</div>
|
51
|
+
#{update_report_js}
|
52
|
+
</body>
|
53
|
+
</html>
|
54
|
+
EOS
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_scenario(scenario)
|
58
|
+
template_scenario.result(binding)
|
59
|
+
end
|
60
|
+
|
61
|
+
def print_runtime_error(example, exception)
|
62
|
+
|
63
|
+
if example.exception
|
64
|
+
example_backtrace = format_backtrace(example.exception.backtrace[0..14], example.metadata).map do |l|
|
65
|
+
RSpec::Core::Metadata::relative_path(l)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
template_exception.result(binding)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def feature_name(scenario)
|
75
|
+
path = RSpec::Core::Metadata::relative_path(scenario.feature_file_path)
|
76
|
+
name = scenario.feature_name
|
77
|
+
"\"#{name}\" in #{path}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def scenario_tags(scenario)
|
81
|
+
return '' if scenario.tags.empty?
|
82
|
+
template_scenario_tags.result(binding)
|
83
|
+
end
|
84
|
+
|
85
|
+
def step_attr(step)
|
86
|
+
attr = 'step'
|
87
|
+
attr += " #{step.status}" if step.attention?
|
88
|
+
"class=\"#{h(attr)}\""
|
89
|
+
end
|
90
|
+
|
91
|
+
def step_args(step)
|
92
|
+
args = []
|
93
|
+
[:extra_args, :source, :exception].each do |k|
|
94
|
+
args << send("step_#{k}", step.docs[k]) unless step.docs[k].nil?
|
95
|
+
end
|
96
|
+
args.join("\n")
|
97
|
+
end
|
98
|
+
|
99
|
+
def step_extra_args(extra_args)
|
100
|
+
extra_args.map do |arg|
|
101
|
+
if arg.instance_of?(Turnip::Table)
|
102
|
+
step_outline(arg)
|
103
|
+
else
|
104
|
+
step_multiline(arg)
|
105
|
+
end
|
106
|
+
end.join("\n")
|
107
|
+
end
|
108
|
+
|
109
|
+
def step_outline(table)
|
110
|
+
template_step_outline.result(binding)
|
111
|
+
end
|
112
|
+
|
113
|
+
def step_multiline(lines)
|
114
|
+
'<pre class="multiline">' + h(lines) + '</pre>'
|
115
|
+
end
|
116
|
+
|
117
|
+
def step_source(location)
|
118
|
+
@snippet_extractor ||= ::RSpec::Core::Formatters::SnippetExtractor.new
|
119
|
+
'<pre class="source"><code class="ruby">' + @snippet_extractor.snippet([location]) + '</code></pre>'
|
120
|
+
end
|
121
|
+
|
122
|
+
def step_exception(exception)
|
123
|
+
template_step_exception.result(binding)
|
124
|
+
end
|
125
|
+
|
126
|
+
def report_area
|
127
|
+
<<-EOS
|
128
|
+
<div id="report">
|
129
|
+
<h1>Turnip Report</h1>
|
130
|
+
<section class="checkbox">
|
131
|
+
<label for="passed_check">Passed</label><input type="checkbox" checked id="passed_check">
|
132
|
+
<label for="failed_check">Failed</label><input type="checkbox" checked id="failed_check">
|
133
|
+
<label for="pending_check">Pending</label><input type="checkbox" checked id="pending_check">
|
134
|
+
</section>
|
135
|
+
|
136
|
+
<section class="result">
|
137
|
+
<p>
|
138
|
+
<span id="total_count"></span> Scenario (<span id="failed_count"></span> failed <span id="pending_count"></span> pending).
|
139
|
+
</p>
|
140
|
+
<p>Finished in <span id="total_time"></span></p>
|
141
|
+
</section>
|
142
|
+
</div>
|
143
|
+
EOS
|
144
|
+
end
|
145
|
+
|
146
|
+
def template_scenario
|
147
|
+
@template_scenario ||= ERB.new(<<-EOS)
|
148
|
+
<section class="scenario <%= h(scenario.status) %>">
|
149
|
+
<header>
|
150
|
+
<span class="permalink">
|
151
|
+
<a href="#<%= scenario.object_id %>">¶</a>
|
152
|
+
</span>
|
153
|
+
<span class="scenario_name" id="<%= scenario.object_id %>">
|
154
|
+
Scenario: <%= h(scenario.name) %>
|
155
|
+
</span>
|
156
|
+
<span class="feature_name">(Feature: <%= h(feature_name(scenario)) %>)</span>
|
157
|
+
</header>
|
158
|
+
<%= scenario_tags(scenario) %>
|
159
|
+
<ul class="steps">
|
160
|
+
<% scenario.steps.each do |step| %>
|
161
|
+
<li <%= step_attr(step) %>><span><%= h(step.name) %></span>
|
162
|
+
<div class="args"><%= step_args(step) %></div>
|
163
|
+
</li>
|
164
|
+
<% end %>
|
165
|
+
</ul>
|
166
|
+
</section>
|
167
|
+
EOS
|
168
|
+
end
|
169
|
+
|
170
|
+
def template_scenario_tags
|
171
|
+
@template_scenario_tags ||= ERB.new(<<-EOS)
|
172
|
+
<ul class="tags">
|
173
|
+
<% scenario.tags.each do |tag| %>
|
174
|
+
<li>@<%= h(tag) %></li>
|
175
|
+
<% end %>
|
176
|
+
</ul>
|
177
|
+
EOS
|
178
|
+
end
|
179
|
+
|
180
|
+
def template_step_outline
|
181
|
+
@template_step_outline ||= ERB.new(<<-EOS)
|
182
|
+
<table class="step_outline">
|
183
|
+
<% table.each do |tr| %>
|
184
|
+
<tr>
|
185
|
+
<% tr.each do |td| %>
|
186
|
+
<td><%= h(td) %></td>
|
187
|
+
<% end %>
|
188
|
+
</tr>
|
189
|
+
<% end %>
|
190
|
+
</table>
|
191
|
+
EOS
|
192
|
+
end
|
193
|
+
|
194
|
+
def template_step_exception
|
195
|
+
@template_step_exception ||= ERB.new(<<-EOS)
|
196
|
+
<div class="step_exception">
|
197
|
+
<span>Failure:</span>
|
198
|
+
<pre><%= h(exception.to_s) %></pre>
|
199
|
+
<span>Backtrace:</span>
|
200
|
+
<ol>
|
201
|
+
<% exception.backtrace.each do |line| %>
|
202
|
+
<li><%= h(line) %></li>
|
203
|
+
<% end %>
|
204
|
+
</ol>
|
205
|
+
</div>
|
206
|
+
EOS
|
207
|
+
end
|
208
|
+
|
209
|
+
def template_exception
|
210
|
+
@template_exception ||= ERB.new(<<-EOS)
|
211
|
+
<section class="exception">
|
212
|
+
<h1>TurnipFormatter RuntimeError</h1>
|
213
|
+
<dl>
|
214
|
+
<dt>Exception</dt>
|
215
|
+
<dd><%= h(exception.to_s) %></dd>
|
216
|
+
|
217
|
+
<dt>Example Full Description</dt>
|
218
|
+
<dd><%= h(example.metadata[:full_description]) %></dd>
|
219
|
+
|
220
|
+
<% if example.exception %>
|
221
|
+
<dt>Example Exception</dt>
|
222
|
+
<dd><%= h(example.exception.to_s) %></dd>
|
223
|
+
|
224
|
+
<dt>Backtrace:</dt>
|
225
|
+
<dd>
|
226
|
+
<ol>
|
227
|
+
<% example_backtrace.each do |line| %>
|
228
|
+
<li><%= h(line) %></li>
|
229
|
+
<% end %>
|
230
|
+
</ol>
|
231
|
+
</dd>
|
232
|
+
<% end %>
|
233
|
+
|
234
|
+
<% if example.pending %>
|
235
|
+
<dt>Example Pending description</dt>
|
236
|
+
<dd><%= h(example.metadata[:description]) %></dd>
|
237
|
+
<% end %>
|
238
|
+
</dl>
|
239
|
+
</section>
|
240
|
+
EOS
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "turnip_formatter/version"
|
4
|
+
require 'turnip'
|
5
|
+
|
6
|
+
module TurnipFormatter
|
7
|
+
require 'rspec/core/formatters/turnip_formatter'
|
8
|
+
require 'turnip_formatter/template'
|
9
|
+
require 'turnip_formatter/ext/turnip/rspec'
|
10
|
+
require 'turnip_formatter/ext/turnip/builder'
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpecTurnipFormatter = RSpec::Core::Formatters::TurnipFormatter
|
14
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# TurnipFormatter Demo
|
2
|
+
|
3
|
+
## Usage
|
4
|
+
|
5
|
+
$ cd /path/to/turnip_formatter
|
6
|
+
$ bundle install --path vendor/bundle
|
7
|
+
$ bundle exec rspec -r ./spec/examples/spec_helper spec/examples/features
|
8
|
+
$ open report.html
|
9
|
+
|
10
|
+
## Screenshot
|
11
|
+
|
12
|
+
### Basic step
|
13
|
+
|
14
|
+
```feature
|
15
|
+
Scenario: normal monster
|
16
|
+
Given there is a monster
|
17
|
+
When I attack it
|
18
|
+
Then it should die
|
19
|
+
And Fanfare
|
20
|
+
```
|
21
|
+
|
22
|
+

|
23
|
+
|
24
|
+
### Failed step
|
25
|
+
|
26
|
+
```feature
|
27
|
+
Scenario: strong monster
|
28
|
+
|
29
|
+
This scenario will error
|
30
|
+
So, fanfare is not...oh...
|
31
|
+
|
32
|
+
Given there is a strong monster
|
33
|
+
When I attack it
|
34
|
+
Then it should die
|
35
|
+
And Fanfare
|
36
|
+
```
|
37
|
+
|
38
|
+

|
39
|
+
|
40
|
+
### Pending step and specify tag
|
41
|
+
|
42
|
+
```feature
|
43
|
+
Scenario: spell magic
|
44
|
+
|
45
|
+
This scenario will error because he can't cast spell
|
46
|
+
|
47
|
+
Given there is a strong monster
|
48
|
+
When I cast a spell 'fireball'
|
49
|
+
And I attack it
|
50
|
+
Then it should die
|
51
|
+
And Fanfare
|
52
|
+
|
53
|
+
@magician
|
54
|
+
Scenario: spell magic
|
55
|
+
|
56
|
+
Given there is a strong monster
|
57
|
+
When I cast a spell 'fireball'
|
58
|
+
And I attack it
|
59
|
+
Then it should die
|
60
|
+
And Fanfare
|
61
|
+
```
|
62
|
+
|
63
|
+

|
64
|
+
|
65
|
+
### Background
|
66
|
+
|
67
|
+
```feature
|
68
|
+
Feature: Battle a monster with weapon
|
69
|
+
|
70
|
+
Background:
|
71
|
+
Given I equip a weapon
|
72
|
+
|
73
|
+
Scenario: normal monster
|
74
|
+
Given there is a monster
|
75
|
+
When I attack it
|
76
|
+
Then it should die
|
77
|
+
And Fanfare
|
78
|
+
|
79
|
+
Scenario: strong monster
|
80
|
+
Given there is a strong monster
|
81
|
+
When I attack it
|
82
|
+
Then it should die
|
83
|
+
And Fanfare
|
84
|
+
```
|
85
|
+
|
86
|
+

|
87
|
+
|
88
|
+
### Outline
|
89
|
+
|
90
|
+
```feature
|
91
|
+
Feature: Battle monsters
|
92
|
+
|
93
|
+
Scenario: Escape
|
94
|
+
Given there are monsters:
|
95
|
+
| gargoyle |
|
96
|
+
| Cockatrice |
|
97
|
+
When I escape
|
98
|
+
Then I was able to escape
|
99
|
+
|
100
|
+
Scenario: Inescapable
|
101
|
+
Given there are monsters:
|
102
|
+
| gargoyle |
|
103
|
+
| Cockatrice |
|
104
|
+
| basilisk |
|
105
|
+
When I escape
|
106
|
+
Then I could not escape
|
107
|
+
```
|
108
|
+
|
109
|
+

|
110
|
+
|
111
|
+
### Multiline
|
112
|
+
|
113
|
+
```feature
|
114
|
+
Feature: A feature with multiline strings
|
115
|
+
Scenario: This is a feature with multiline strings
|
116
|
+
When the monster sings the following song
|
117
|
+
"""
|
118
|
+
Oh here be monsters
|
119
|
+
This is cool
|
120
|
+
"""
|
121
|
+
Then the song should have 2 lines
|
122
|
+
```
|
123
|
+
|
124
|
+

|
@@ -0,0 +1,36 @@
|
|
1
|
+
Feature: Battle a monster
|
2
|
+
|
3
|
+
Scenario: normal monster
|
4
|
+
Given there is a monster
|
5
|
+
When I attack it
|
6
|
+
Then it should die
|
7
|
+
And Fanfare
|
8
|
+
|
9
|
+
Scenario: strong monster
|
10
|
+
|
11
|
+
This scenario will error
|
12
|
+
So, fanfare is not...oh...
|
13
|
+
|
14
|
+
Given there is a strong monster
|
15
|
+
When I attack it
|
16
|
+
Then it should die
|
17
|
+
And Fanfare
|
18
|
+
|
19
|
+
Scenario: spell magic
|
20
|
+
|
21
|
+
This scenario will error because he can't cast spell
|
22
|
+
|
23
|
+
Given there is a strong monster
|
24
|
+
When I cast a spell 'fireball'
|
25
|
+
And I attack it
|
26
|
+
Then it should die
|
27
|
+
And Fanfare
|
28
|
+
|
29
|
+
@magician
|
30
|
+
Scenario: spell magic
|
31
|
+
|
32
|
+
Given there is a strong monster
|
33
|
+
When I cast a spell 'fireball'
|
34
|
+
And I attack it
|
35
|
+
Then it should die
|
36
|
+
And Fanfare
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Battle a monster with weapon
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I equip a weapon
|
5
|
+
|
6
|
+
Scenario: normal monster
|
7
|
+
Given there is a monster
|
8
|
+
When I attack it
|
9
|
+
Then it should die
|
10
|
+
And Fanfare
|
11
|
+
|
12
|
+
Scenario: strong monster
|
13
|
+
Given there is a strong monster
|
14
|
+
When I attack it
|
15
|
+
Then it should die
|
16
|
+
And Fanfare
|
17
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Battle monsters
|
2
|
+
|
3
|
+
Scenario: Escape
|
4
|
+
Given there are monsters:
|
5
|
+
| gargoyle |
|
6
|
+
| Cockatrice |
|
7
|
+
When I escape
|
8
|
+
Then I was able to escape
|
9
|
+
|
10
|
+
Scenario: Inescapable
|
11
|
+
Given there are monsters:
|
12
|
+
| gargoyle |
|
13
|
+
| Cockatrice |
|
14
|
+
| basilisk |
|
15
|
+
When I escape
|
16
|
+
Then I could not escape
|