marso 0.1.5297 → 0.1.15089
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/marso.rb +2 -0
- data/lib/marso/assert.rb +2 -2
- data/lib/marso/config.rb +25 -0
- data/lib/marso/scenario.rb +278 -0
- data/lib/marso/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dd68ffdf94aa8dc6c18a66a1be55774e8aa2b4b
|
4
|
+
data.tar.gz: 07415303338d5c40520661aa865a656b171cb148
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1386739d560795b6bcc2e6e74a59030aa46e9eeacfe3951bc3d62fbb58b9b48da18ea7ba2e7cb0374c151e9699e04ccc8595725e2e2ce38115034e529dad03db
|
7
|
+
data.tar.gz: fab73a4f66f4856dc1f2500f0aeeb9693bd9240caa7f0ca12d9a8f6b35812635dff42fc7e7fabd4e88a006392f0277502fbff4917abc9a3c393dc9660b260f66
|
data/lib/marso.rb
CHANGED
data/lib/marso/assert.rb
CHANGED
@@ -3,7 +3,7 @@ require "colorize"
|
|
3
3
|
module Marso
|
4
4
|
module_function
|
5
5
|
|
6
|
-
def assert
|
6
|
+
def assert(message, &block)
|
7
7
|
begin
|
8
8
|
if (block.call)
|
9
9
|
puts "Assert #{message}: PASSED".green
|
@@ -11,7 +11,7 @@ module Marso
|
|
11
11
|
puts "Assert #{message}: FAILED".red
|
12
12
|
end
|
13
13
|
rescue Exception => e
|
14
|
-
puts "Assert #{message} FAILED with exception #{e}".red
|
14
|
+
puts "Assert #{message} FAILED with exception #{e.message}".red
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/marso/config.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Marso
|
2
|
+
class Config
|
3
|
+
@@configuration={
|
4
|
+
# If true, the result of each step is output to the console in realtime.
|
5
|
+
# The consequence os setting that config to true is that steps
|
6
|
+
# may be harder to read together when multiple scenarios are executed
|
7
|
+
# paralell. Steps of different scenarios may indeed be intertwined in the
|
8
|
+
# console
|
9
|
+
:realtime_step_stdout => false,
|
10
|
+
|
11
|
+
# If true, all steps of the same scenario defined after a broken step(i.e.
|
12
|
+
# step in status :failed, :error, or :cancelled) will not be executed, and
|
13
|
+
# will all be set so their status is :cancelled
|
14
|
+
:cancel_steps_upon_issues => true
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.set(config_name, config_value)
|
18
|
+
@@configuration[config_name] = config_value if @@configuration.key?(config_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.get(config_name)
|
22
|
+
@@configuration[config_name]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'securerandom'
|
3
|
+
require_relative 'config'
|
4
|
+
|
5
|
+
module Marso
|
6
|
+
|
7
|
+
class Scenario
|
8
|
+
ISSUES_LIST = [:error, :failed, :cancelled]
|
9
|
+
@@color_options=nil
|
10
|
+
@@color_options_size=0
|
11
|
+
attr_reader :name, :steps, :id, :status, :color_theme, :cancel_steps_upon_issues,
|
12
|
+
:realtime_step_stdout
|
13
|
+
|
14
|
+
# name: Scenario's name
|
15
|
+
# options:
|
16
|
+
# :id => hex string (length 8). Default is randomly generated
|
17
|
+
# :steps => array of Step objects
|
18
|
+
# :color_theme => color from gem 'colorize'(e.g. :blue). That allows
|
19
|
+
# to visually group all steps from the same scenario.
|
20
|
+
# Default is randomly choosen from the available set
|
21
|
+
# :cancel_steps_upon_issues => Boolean. If true, all steps defined after
|
22
|
+
# a broken step(i.e. step in status :failed,
|
23
|
+
# :error, or :cancelled) will not be
|
24
|
+
# executed, and will all be set so their
|
25
|
+
# status is :cancelled. If defined, it
|
26
|
+
# overrides the Config.cancel_steps_upon_issues
|
27
|
+
# setting.
|
28
|
+
def initialize(name, options={})
|
29
|
+
|
30
|
+
if @@color_options.nil?
|
31
|
+
@@color_options = String.colors
|
32
|
+
@@color_options_size = @@color_options.size
|
33
|
+
end
|
34
|
+
|
35
|
+
@name = name
|
36
|
+
@id =
|
37
|
+
options.key?(:id) ?
|
38
|
+
options[:id] :
|
39
|
+
SecureRandom.hex(4)
|
40
|
+
|
41
|
+
@status =
|
42
|
+
options.key?(:status) ?
|
43
|
+
options[:status] :
|
44
|
+
:pending
|
45
|
+
|
46
|
+
@color_theme =
|
47
|
+
options.key?(:color_theme) ?
|
48
|
+
options[:color_theme] :
|
49
|
+
@@color_options[rand(@@color_options_size)]
|
50
|
+
|
51
|
+
@steps =
|
52
|
+
options.key?(:steps) ?
|
53
|
+
options[:steps].map { |s| Step.new(s.text, @id, @color_theme, s.status, &s.block) } :
|
54
|
+
[]
|
55
|
+
|
56
|
+
@cancel_steps_upon_issues =
|
57
|
+
options.key?(:cancel_steps_upon_issues) ?
|
58
|
+
options[:cancel_steps_upon_issues] :
|
59
|
+
Marso::Config.get(:cancel_steps_upon_issues)
|
60
|
+
|
61
|
+
@realtime_step_stdout =
|
62
|
+
options.key?(:realtime_step_stdout) ?
|
63
|
+
options[:realtime_step_stdout] :
|
64
|
+
Marso::Config.get(:realtime_step_stdout)
|
65
|
+
end
|
66
|
+
|
67
|
+
def given(assumption_text, *args, &block)
|
68
|
+
return add_step(:given, assumption_text, *args, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def and(assumption_text, *args, &block)
|
72
|
+
return add_step(:and, assumption_text, *args, &block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def when(assumption_text, *args, &block)
|
76
|
+
return add_step(:when, assumption_text, *args, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def then(assumption_text, *args, &block)
|
80
|
+
return add_step(:then, assumption_text, *args, &block)
|
81
|
+
end
|
82
|
+
|
83
|
+
def but(assumption_text, *args, &block)
|
84
|
+
return add_step(:but, assumption_text, *args, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
def run
|
88
|
+
previous_step_status = nil
|
89
|
+
scenario_status = :passed
|
90
|
+
no_issues = true
|
91
|
+
puts "Scenario #{@id}".colorize(@color_theme) + ": " + "#{name}".blue if @realtime_step_stdout
|
92
|
+
|
93
|
+
processed_steps = @steps.map { |s|
|
94
|
+
executed_step = execute_step(s, previous_step_status)
|
95
|
+
|
96
|
+
print executed_step.print_context if @realtime_step_stdout
|
97
|
+
|
98
|
+
previous_step_status = executed_step.status
|
99
|
+
|
100
|
+
if no_issues
|
101
|
+
case previous_step_status
|
102
|
+
when :error
|
103
|
+
no_issues = false
|
104
|
+
scenario_status = :error
|
105
|
+
when :failed
|
106
|
+
no_issues = false
|
107
|
+
scenario_status = :failed
|
108
|
+
when :cancelled
|
109
|
+
no_issues = false
|
110
|
+
scenario_status = :failed
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
executed_step
|
115
|
+
}
|
116
|
+
|
117
|
+
return Scenario.new(@name, {
|
118
|
+
:id => @id,
|
119
|
+
:steps => processed_steps,
|
120
|
+
:status => scenario_status,
|
121
|
+
:color_theme => @color_theme
|
122
|
+
})
|
123
|
+
end
|
124
|
+
|
125
|
+
def context
|
126
|
+
return
|
127
|
+
"Scenario #{@id}: #{name}\n" +
|
128
|
+
(@steps.any? ? @steps.map { |s| s.context }.join("\n") : "")
|
129
|
+
end
|
130
|
+
|
131
|
+
def print_context
|
132
|
+
puts "Scenario #{@id}".colorize(@color_theme) + ": " + "#{name}".blue
|
133
|
+
@steps.map { |s| s.print_context } if !@steps.nil?
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def add_step(step_type, assumption_text, *args, &block)
|
140
|
+
body_msg = nil
|
141
|
+
status = :pending
|
142
|
+
step_name = step_type.to_s
|
143
|
+
|
144
|
+
begin
|
145
|
+
body_msg = "#{step_name} " + assumption_text % args
|
146
|
+
rescue Exception => e
|
147
|
+
status = :error
|
148
|
+
body_msg =
|
149
|
+
"#{assumption_text}: ERROR\n" +
|
150
|
+
"args: #{args.nil? ? '' : args.join(',')}\n" +
|
151
|
+
"#{e.message}\n" +
|
152
|
+
"#{e.backtrace}"
|
153
|
+
end
|
154
|
+
|
155
|
+
new_step_series = @steps | [Step.new(body_msg, @id, color_theme, status, &block)]
|
156
|
+
|
157
|
+
return Scenario.new(@name, {
|
158
|
+
:id => @id,
|
159
|
+
:steps => new_step_series,
|
160
|
+
:status => @status,
|
161
|
+
:color_theme => @color_theme
|
162
|
+
})
|
163
|
+
end
|
164
|
+
|
165
|
+
def execute_step(step, previous_step_status)
|
166
|
+
if ISSUES_LIST.include?(previous_step_status) && @cancel_steps_upon_issues
|
167
|
+
cancelled_step = Step.new(step.text, @id, @color_theme, :cancelled, &step.block)
|
168
|
+
return cancelled_step.execute
|
169
|
+
else
|
170
|
+
return step.execute
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# A 'Step' is a Scenario's part. It contains
|
176
|
+
# a text that describe what that step does, as well
|
177
|
+
# as a status that indicates whether or not that step
|
178
|
+
# has already been executed. This status can take the
|
179
|
+
# following values:
|
180
|
+
# => :pending
|
181
|
+
# => :passed
|
182
|
+
# => :failed
|
183
|
+
# => :cancelled
|
184
|
+
# => :error
|
185
|
+
class Step
|
186
|
+
attr_reader :text, :status, :color_theme, :scenario_id, :block
|
187
|
+
|
188
|
+
def initialize(text, scenario_id, color_theme, status=:pending, &block)
|
189
|
+
@text=text
|
190
|
+
@status=status
|
191
|
+
@block=block
|
192
|
+
@scenario_id=scenario_id
|
193
|
+
@color_theme = color_theme
|
194
|
+
end
|
195
|
+
|
196
|
+
def execute
|
197
|
+
if @status != :cancelled
|
198
|
+
execute_block
|
199
|
+
else
|
200
|
+
return self
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def context
|
205
|
+
scenario_id = "#{@scenario_id}"
|
206
|
+
body = nil
|
207
|
+
case @status
|
208
|
+
when :pending
|
209
|
+
body = "#{@text}: PENDING"
|
210
|
+
when :passed
|
211
|
+
body = "#{@text}: PASSED"
|
212
|
+
when :failed
|
213
|
+
body = "#{@text}: FAILED"
|
214
|
+
when :cancelled
|
215
|
+
body = "#{@text}: CANCELLED"
|
216
|
+
when :error
|
217
|
+
body = "#{@text}"
|
218
|
+
end
|
219
|
+
|
220
|
+
return "#{scenario_id}: #{body}"
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
def print_context
|
225
|
+
scenario_id = "#{@scenario_id}".colorize(@color_theme)
|
226
|
+
body = nil
|
227
|
+
case @status
|
228
|
+
when :pending
|
229
|
+
body = "#{@text}: PENDING".light_yellow
|
230
|
+
when :passed
|
231
|
+
body = "#{@text}: PASSED".green
|
232
|
+
when :failed
|
233
|
+
body = "#{@text}: FAILED".red
|
234
|
+
when :cancelled
|
235
|
+
body = "#{@text}: CANCELLED".light_black
|
236
|
+
when :error
|
237
|
+
body = "#{@text}".red
|
238
|
+
end
|
239
|
+
|
240
|
+
puts "#{scenario_id}: #{body}"
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
def execute_block
|
246
|
+
operation = lambda { |x|
|
247
|
+
begin
|
248
|
+
result = @block.call
|
249
|
+
result_type = result.class
|
250
|
+
if result_type == TrueClass || result_type == FalseClass
|
251
|
+
if result
|
252
|
+
return :passed, nil
|
253
|
+
else
|
254
|
+
return :failed, nil
|
255
|
+
end
|
256
|
+
else
|
257
|
+
return :passed, nil
|
258
|
+
end
|
259
|
+
rescue Exception => e
|
260
|
+
return :error, e
|
261
|
+
end
|
262
|
+
}
|
263
|
+
|
264
|
+
status, err = operation.call(nil)
|
265
|
+
|
266
|
+
updated_text = @text
|
267
|
+
|
268
|
+
if status==:error
|
269
|
+
updated_text =
|
270
|
+
"#{text}: ERROR\n" +
|
271
|
+
"#{err.message}\n" +
|
272
|
+
"#{err.backtrace}"
|
273
|
+
end
|
274
|
+
|
275
|
+
return Step.new(updated_text, @scenario_id, @color_theme, status, &@block)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
data/lib/marso/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15089
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Dao
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -83,7 +83,9 @@ files:
|
|
83
83
|
- Rakefile
|
84
84
|
- lib/marso.rb
|
85
85
|
- lib/marso/assert.rb
|
86
|
+
- lib/marso/config.rb
|
86
87
|
- lib/marso/factories.rb
|
88
|
+
- lib/marso/scenario.rb
|
87
89
|
- lib/marso/version.rb
|
88
90
|
- marso.gemspec
|
89
91
|
homepage: https://github.com/nicolasdao/marso
|