diddy 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/diddy.gemspec +2 -2
- data/lib/diddy/context.rb +9 -0
- data/lib/diddy/run_result.rb +119 -0
- data/lib/diddy/run_result_printer.rb +74 -0
- data/lib/diddy/scenario.rb +113 -0
- data/lib/diddy/script.rb +67 -164
- data/lib/diddy/shared_scope.rb +1 -2
- data/lib/diddy/step.rb +53 -2
- data/lib/diddy/steps.rb +41 -0
- data/lib/diddy.rb +4 -0
- metadata +7 -3
data/diddy.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "diddy"
|
7
|
-
gem.version = '0.
|
7
|
+
gem.version = '0.8.0'
|
8
8
|
gem.authors = ["Diederick Lawson", "Marcel de Graaf"]
|
9
9
|
gem.email = ["diederick@altovista.nl", "mail@marceldegraaf.net"]
|
10
10
|
gem.description = %q{Diddy script runner}
|
@@ -16,5 +16,5 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
|
19
|
-
gem.add_development_dependency "term/
|
19
|
+
gem.add_development_dependency "term/ansicolor"
|
20
20
|
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Diddy
|
2
|
+
class RunResult
|
3
|
+
attr_accessor :scripts
|
4
|
+
|
5
|
+
#
|
6
|
+
# Starts the run of a script. Call this before running a scenario.
|
7
|
+
#
|
8
|
+
def run_script(description)
|
9
|
+
@scripts ||= []
|
10
|
+
@current_script = Script.new(description)
|
11
|
+
@scripts << @current_script
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Start the run of an entire scenario.
|
16
|
+
#
|
17
|
+
def run_scenario(description)
|
18
|
+
@current_scenario = Scenario.new(description)
|
19
|
+
@current_scenario.script = @current_script
|
20
|
+
|
21
|
+
@current_script.scenarios << @current_scenario
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Starts run of a step
|
26
|
+
#
|
27
|
+
def run_step(description)
|
28
|
+
@current_step = Step.new(description)
|
29
|
+
@current_step.scenario = @current_scenario
|
30
|
+
|
31
|
+
@current_scenario.steps << @current_step
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Starts run of a sub step
|
36
|
+
#
|
37
|
+
def run_sub_step(description)
|
38
|
+
@current_sub_step = SubStep.new(description)
|
39
|
+
@current_sub_step.step = @current_step
|
40
|
+
|
41
|
+
@current_step.sub_steps << @current_sub_step
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Sets the result of the current step
|
46
|
+
#
|
47
|
+
def set_step_result(result)
|
48
|
+
@current_step.result = result
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Sets the result to false and logs the exception of the step
|
53
|
+
#
|
54
|
+
def set_step_exception(exception)
|
55
|
+
@current_step.result = false
|
56
|
+
@current_step.exception = exception
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Sets the result of the sub step
|
61
|
+
#
|
62
|
+
def set_sub_step_result(result)
|
63
|
+
@current_sub_step.result = result
|
64
|
+
end
|
65
|
+
|
66
|
+
# helper classes
|
67
|
+
class Script
|
68
|
+
attr_accessor :scenarios, :description
|
69
|
+
|
70
|
+
def initialize(description)
|
71
|
+
self.description = description
|
72
|
+
end
|
73
|
+
|
74
|
+
def scenarios
|
75
|
+
@scenarios ||= []
|
76
|
+
end
|
77
|
+
|
78
|
+
def result
|
79
|
+
scenarios.all? { |scenario| scenario.result }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Scenario
|
84
|
+
attr_accessor :steps, :description, :script
|
85
|
+
|
86
|
+
def initialize(description)
|
87
|
+
self.description = description
|
88
|
+
end
|
89
|
+
|
90
|
+
def steps
|
91
|
+
@steps ||= []
|
92
|
+
end
|
93
|
+
|
94
|
+
def result
|
95
|
+
steps.all? { |step| step.result }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Step
|
100
|
+
attr_accessor :description, :sub_steps, :result, :scenario, :exception
|
101
|
+
|
102
|
+
def initialize(description)
|
103
|
+
self.description = description
|
104
|
+
end
|
105
|
+
|
106
|
+
def sub_steps
|
107
|
+
@sub_steps ||= []
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class SubStep
|
112
|
+
attr_accessor :description, :result, :step
|
113
|
+
|
114
|
+
def initialize(description)
|
115
|
+
self.description = description
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Diddy
|
2
|
+
class RunResultPrinter
|
3
|
+
attr_accessor :run_result
|
4
|
+
|
5
|
+
def initialize(run_result)
|
6
|
+
self.run_result = run_result
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Converts the result to HTML
|
11
|
+
#
|
12
|
+
# @TODO needs to be refactored to a templating language. Quick hack for now.
|
13
|
+
#
|
14
|
+
def to_html
|
15
|
+
html = "<html><head><style type='text/css'>.error { color: red }; pre { display: block; margin: 1em; };</style><title>Run results</title></head><body>"
|
16
|
+
|
17
|
+
# walk over all scripts
|
18
|
+
run_result.scripts.each do |script|
|
19
|
+
html << "<h2>#{script.description}</h2>"
|
20
|
+
|
21
|
+
# walk of the scenarios
|
22
|
+
script.scenarios.each do |scenario|
|
23
|
+
# result was ok? than only log the scenario itself
|
24
|
+
if scenario.result
|
25
|
+
html << "<h3>#{scenario.description}</h3>"
|
26
|
+
else
|
27
|
+
# log the error and it's steps
|
28
|
+
html << "<h3 class='error'>#{scenario.description}</h3>"
|
29
|
+
html << "<ul>"
|
30
|
+
|
31
|
+
# walk over the steps
|
32
|
+
scenario.steps.each do |step|
|
33
|
+
# output step
|
34
|
+
if step.result
|
35
|
+
html << "<li>#{step.description}"
|
36
|
+
else
|
37
|
+
html << "<li class='error'>#{step.description}"
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# was there an exception?
|
42
|
+
if step.exception
|
43
|
+
html << "<pre>#{step.exception.message}\n\n#{step.exception.backtrace.join("\n")}</pre>"
|
44
|
+
end
|
45
|
+
|
46
|
+
# are there any sub steps?
|
47
|
+
if step.sub_steps.any?
|
48
|
+
html << "<ul>"
|
49
|
+
|
50
|
+
# walk over sub steps
|
51
|
+
step.sub_steps.each do |sub_step|
|
52
|
+
if sub_step.result
|
53
|
+
html << "<li>#{sub_step.description}</li>"
|
54
|
+
else
|
55
|
+
html << "<li class='error'>#{sub_step.description}</li>"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
html << "</ul></li>"
|
60
|
+
else
|
61
|
+
html << "</li>"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
html << "</ul>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
html << "</body>"
|
71
|
+
html
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Diddy
|
2
|
+
#
|
3
|
+
# A scenario contains several steps. This is where the real work is done.
|
4
|
+
#
|
5
|
+
class Scenario
|
6
|
+
attr_accessor :script, :context, :description, :steps, :run_result
|
7
|
+
|
8
|
+
#
|
9
|
+
# Creates a scenario
|
10
|
+
#
|
11
|
+
def initialize(options = {})
|
12
|
+
options.each { |k,v| send("#{k}=", v) }
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Determines which step classes should be used
|
17
|
+
#
|
18
|
+
def uses(klass)
|
19
|
+
@steps_instances ||= []
|
20
|
+
@steps_instances << klass.new(shared_scope)
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Describes which step should be run
|
25
|
+
#
|
26
|
+
def step(description)
|
27
|
+
@steps ||= []
|
28
|
+
|
29
|
+
# find step klass
|
30
|
+
steps_instance = find_steps_instance_for(description)
|
31
|
+
|
32
|
+
# check if step exists
|
33
|
+
if steps_instance && steps_instance.class.has_step?(description)
|
34
|
+
@steps << Diddy::Step.new(
|
35
|
+
description: description,
|
36
|
+
steps_instance: steps_instance,
|
37
|
+
definition: steps_instance.class.definition(description)
|
38
|
+
)
|
39
|
+
else
|
40
|
+
raise "Step '#{description}' not defined"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Runs all the steps in the script
|
46
|
+
#
|
47
|
+
def run
|
48
|
+
begin
|
49
|
+
@steps.each do |step|
|
50
|
+
run_step(step)
|
51
|
+
end
|
52
|
+
|
53
|
+
true
|
54
|
+
|
55
|
+
rescue ScenarioAborted
|
56
|
+
false
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Runs one step
|
63
|
+
#
|
64
|
+
def run_step(step)
|
65
|
+
# run proc on this instance as scope
|
66
|
+
begin
|
67
|
+
step.run_result = run_result
|
68
|
+
result = step.run
|
69
|
+
|
70
|
+
rescue Exception => exception
|
71
|
+
print_exception(exception)
|
72
|
+
run_result.set_step_exception(exception)
|
73
|
+
|
74
|
+
raise ScenarioAborted.new
|
75
|
+
end
|
76
|
+
|
77
|
+
unless result
|
78
|
+
raise ScenarioAborted.new
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Prints exception thrown by step, on screen
|
84
|
+
#
|
85
|
+
def print_exception(exception)
|
86
|
+
print("\n")
|
87
|
+
|
88
|
+
# print backtrace
|
89
|
+
puts("- #{exception.message}")
|
90
|
+
puts(" #{exception.backtrace.join("\n ")}")
|
91
|
+
puts("\n")
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Finds the instance of the steps definition by step name
|
96
|
+
#
|
97
|
+
def find_steps_instance_for(description)
|
98
|
+
@steps_instances.each do |instance|
|
99
|
+
if instance.class.steps && instance.class.steps.has_key?(description)
|
100
|
+
return instance
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def shared_scope
|
108
|
+
@shared_scope ||= SharedScope.new
|
109
|
+
end
|
110
|
+
|
111
|
+
class ScenarioAborted < Exception; end
|
112
|
+
end
|
113
|
+
end
|
data/lib/diddy/script.rb
CHANGED
@@ -1,216 +1,119 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Diddy
|
3
|
+
#
|
4
|
+
# A script contains several scenarios. A script can be a recipe, an application etc.
|
5
|
+
#
|
3
6
|
class Script
|
4
|
-
|
5
|
-
STATE_FAILED = 2
|
6
|
-
STATE_EXCEPTION = 3
|
7
|
+
attr_accessor :scenarios, :description, :context, :run_result
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
# Creates a script
|
12
|
-
#
|
13
|
-
def initialize(scenario)
|
14
|
-
@scenario = scenario
|
9
|
+
def initialize(description)
|
10
|
+
self.description = description
|
15
11
|
end
|
16
12
|
|
17
13
|
#
|
18
|
-
#
|
14
|
+
# Defines a new scenario
|
19
15
|
#
|
20
|
-
|
21
|
-
|
22
|
-
@steps_instances << klass.new(shared_scope)
|
23
|
-
end
|
24
|
-
|
16
|
+
# scenario('Do something') do
|
17
|
+
# uses SomeSteps
|
25
18
|
#
|
26
|
-
#
|
19
|
+
# step 'Do this'
|
20
|
+
# step 'Do that'
|
21
|
+
# end
|
27
22
|
#
|
28
|
-
def
|
29
|
-
@
|
30
|
-
end
|
23
|
+
def scenario(description, &block)
|
24
|
+
@scenarios ||= []
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
steps_instance: steps_instance,
|
46
|
-
definition: steps_instance.class.definition(description)
|
47
|
-
)
|
48
|
-
else
|
49
|
-
raise "Step '#{description}' not defined"
|
50
|
-
end
|
26
|
+
# instantiate scenario
|
27
|
+
scenario = Scenario.new(
|
28
|
+
script: self,
|
29
|
+
context: context,
|
30
|
+
description: description,
|
31
|
+
run_result: run_result
|
32
|
+
)
|
33
|
+
|
34
|
+
# run the DSL
|
35
|
+
scenario.instance_eval(&block)
|
36
|
+
|
37
|
+
# add to our collection of scenarios
|
38
|
+
@scenarios << scenario
|
51
39
|
end
|
52
40
|
|
53
41
|
#
|
54
|
-
#
|
42
|
+
# Run the script
|
55
43
|
#
|
56
44
|
def run
|
57
|
-
|
58
|
-
|
45
|
+
scenarios.each_with_index do |scenario, index|
|
46
|
+
# print on screen
|
47
|
+
puts("Scenario #{index + 1}: #{scenario.description}")
|
59
48
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
return true
|
49
|
+
# also log
|
50
|
+
run_result.run_scenario("Scenario #{index + 1}: #{scenario.description}")
|
64
51
|
|
65
|
-
|
66
|
-
|
67
|
-
|
52
|
+
# run all the steps within the scenario
|
53
|
+
scenario.run_result = run_result
|
54
|
+
scenario.run
|
68
55
|
|
56
|
+
puts("\n")
|
69
57
|
end
|
70
58
|
end
|
71
59
|
|
72
60
|
#
|
73
|
-
#
|
61
|
+
# Defines a new script
|
74
62
|
#
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
#
|
63
|
+
# Diddy::Script.define('Some recipe') do
|
64
|
+
# scenario('Putting stuff in a bowl') do
|
65
|
+
# step 'Put milk in it'
|
66
|
+
# step 'Drink from bowl'
|
67
|
+
# end
|
68
|
+
# end
|
81
69
|
#
|
82
|
-
|
83
|
-
# uses ApiSteps
|
84
|
-
# uses LoginSteps
|
85
|
-
#
|
86
|
-
# step 'Do something'
|
87
|
-
# step 'Do something else'
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
def self.define(scenario, &block)
|
70
|
+
def self.define(description, &block)
|
91
71
|
@scripts ||= []
|
92
72
|
|
93
|
-
script = self.new(
|
73
|
+
script = self.new(description)
|
94
74
|
script.instance_eval(&block)
|
95
75
|
|
96
76
|
@scripts << script
|
97
|
-
end
|
98
|
-
|
99
|
-
#
|
100
|
-
# Runs all defined scripts. Returns true if and only if all indivudial
|
101
|
-
# scripts returned true. Otherwise returns false.
|
102
|
-
#
|
103
|
-
def self.run_all
|
104
|
-
# empty log
|
105
|
-
@last_log = ""
|
106
|
-
|
107
|
-
write_log("[#{Time.now}] Diddy starting to run #{@scripts.size} scripts")
|
108
|
-
|
109
|
-
# Run all scripts and remember their return status
|
110
|
-
status = @scripts.map do |script|
|
111
|
-
# run the script
|
112
|
-
result = script.run
|
113
|
-
|
114
|
-
# concat log of script to general log
|
115
|
-
write_log(script.log)
|
116
77
|
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
write_log("[#{Time.now}] Diddy finished running #{@scripts.size} scripts")
|
121
|
-
|
122
|
-
# If one of the scripts returned with "false"; make the entire run
|
123
|
-
# return false as well
|
124
|
-
status.include?(false) ? false : true
|
78
|
+
script
|
125
79
|
end
|
126
80
|
|
127
81
|
#
|
128
|
-
#
|
82
|
+
# Returns all the defined scripts
|
129
83
|
#
|
130
|
-
def self.only_run(scenario)
|
131
|
-
@scripts.select { |script| script.scenario == scenario }.first.run
|
132
|
-
end
|
133
|
-
|
134
84
|
def self.scripts
|
135
85
|
@scripts
|
136
86
|
end
|
137
87
|
|
138
|
-
private
|
139
|
-
|
140
|
-
def self.write_log(message, print = true)
|
141
|
-
puts(message) if print
|
142
|
-
self.last_log << "#{message}\n"
|
143
|
-
end
|
144
|
-
|
145
88
|
#
|
146
|
-
# Runs
|
89
|
+
# Runs a given script
|
147
90
|
#
|
148
|
-
def
|
149
|
-
#
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
rescue Exception => exception
|
154
|
-
log_step(step, STATE_EXCEPTION)
|
155
|
-
print_exception(step, exception)
|
156
|
-
raise ScriptAborted.new
|
157
|
-
end
|
158
|
-
|
159
|
-
if result
|
160
|
-
log_step(step, STATE_OK)
|
161
|
-
else
|
162
|
-
log_step(step, STATE_FAILED)
|
163
|
-
raise ScriptAborted.new
|
164
|
-
end
|
165
|
-
end
|
91
|
+
def self.run(run_result, description, options = {})
|
92
|
+
# find script
|
93
|
+
script = scripts.find { |script| script.description == description }
|
94
|
+
raise CannotFindScriptError.new("Cannot find script #{description}") unless script
|
166
95
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
def log_step(step, state)
|
171
|
-
if state == STATE_FAILED || state == STATE_EXCEPTION
|
172
|
-
print(red(bold("✕ #{step.description}")))
|
173
|
-
self.class.write_log("✕ #{step.description}", false)
|
174
|
-
|
175
|
-
if state == STATE_EXCEPTION
|
176
|
-
print(" [EXCEPTION]")
|
177
|
-
print("\n\n")
|
178
|
-
self.class.write_log("[EXCEPTION]", false)
|
179
|
-
end
|
96
|
+
# output and run
|
97
|
+
if options.any?
|
98
|
+
vars = " (" + options.map { |k, v| "#{k}=#{v}" }.join(', ') + ")"
|
180
99
|
else
|
181
|
-
|
182
|
-
self.class.write_log("✓ #{step.description}", false)
|
100
|
+
vars = ""
|
183
101
|
end
|
184
|
-
end
|
185
102
|
|
186
|
-
|
187
|
-
|
188
|
-
#
|
189
|
-
def print_exception(current_step, exception)
|
190
|
-
# print backtrace
|
191
|
-
self.class.write_log("- #{exception.message}")
|
192
|
-
self.class.write_log(" #{exception.backtrace.join("\n ")}")
|
193
|
-
self.class.write_log("\n")
|
194
|
-
end
|
103
|
+
# print to screen what we are doing
|
104
|
+
puts(bold("Running #{description}#{vars}"))
|
195
105
|
|
196
|
-
|
197
|
-
|
198
|
-
#
|
199
|
-
def find_steps_instance_for(description)
|
200
|
-
@steps_instances.each do |instance|
|
201
|
-
if instance.class.steps && instance.class.steps.has_key?(description)
|
202
|
-
return instance
|
203
|
-
end
|
204
|
-
end
|
106
|
+
# also log to result logger
|
107
|
+
run_result.run_script("Running #{description}#{vars}")
|
205
108
|
|
206
|
-
|
207
|
-
|
109
|
+
# apply the context and run result
|
110
|
+
script.context = Context.new(options)
|
111
|
+
script.run_result = run_result
|
208
112
|
|
209
|
-
|
210
|
-
|
113
|
+
# run the entire script
|
114
|
+
script.run
|
211
115
|
end
|
212
116
|
|
213
|
-
class
|
214
|
-
|
117
|
+
class CannotFindScriptError < StandardError; end
|
215
118
|
end
|
216
119
|
end
|
data/lib/diddy/shared_scope.rb
CHANGED
data/lib/diddy/step.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Diddy
|
3
3
|
class Step
|
4
|
-
|
4
|
+
STATE_OK = 1
|
5
|
+
STATE_FAILED = 2
|
6
|
+
STATE_EXCEPTION = 3
|
7
|
+
STATE_PENDING = 4
|
8
|
+
|
9
|
+
attr_accessor :description, :definition, :steps_instance, :run_result
|
5
10
|
|
6
11
|
#
|
7
12
|
# Initializes step
|
@@ -14,7 +19,53 @@ module Diddy
|
|
14
19
|
# Runs the step
|
15
20
|
#
|
16
21
|
def run
|
17
|
-
|
22
|
+
# set the sub steps to 0
|
23
|
+
steps_instance.sub_steps = []
|
24
|
+
|
25
|
+
# write to screen
|
26
|
+
print(blue(". #{description}"))
|
27
|
+
|
28
|
+
# and to log
|
29
|
+
run_result.run_step(description)
|
30
|
+
|
31
|
+
# eval the step
|
32
|
+
steps_instance.current_step = self
|
33
|
+
|
34
|
+
# run the step itself
|
35
|
+
result = steps_instance.instance_eval(&definition)
|
36
|
+
|
37
|
+
# check if there were any sub steps
|
38
|
+
# if so, the result is dependent of those substeps
|
39
|
+
if steps_instance.sub_steps.size > 0
|
40
|
+
# check result of all sub_steps
|
41
|
+
result = steps_instance.sub_steps.all? { |step| step[:valid] }
|
42
|
+
|
43
|
+
# also log
|
44
|
+
steps_instance.sub_steps.each do |sub_step|
|
45
|
+
run_result.run_sub_step(sub_step[:description])
|
46
|
+
run_result.set_sub_step_result(sub_step[:valid])
|
47
|
+
end
|
48
|
+
|
49
|
+
# faulty
|
50
|
+
print("\n")
|
51
|
+
else
|
52
|
+
print("\r")
|
53
|
+
|
54
|
+
if result
|
55
|
+
print(green("✓ #{description}"))
|
56
|
+
else
|
57
|
+
print(red(bold("✕ #{description}")))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# log result of step
|
62
|
+
run_result.set_step_result(result)
|
63
|
+
|
64
|
+
# next line
|
65
|
+
print("\n")
|
66
|
+
|
67
|
+
# return the result
|
68
|
+
result
|
18
69
|
end
|
19
70
|
end
|
20
71
|
end
|
data/lib/diddy/steps.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Diddy
|
2
3
|
class Steps
|
3
4
|
include Helpers
|
4
5
|
|
6
|
+
attr_accessor :sub_steps, :current_step
|
7
|
+
|
5
8
|
def initialize(shared_scope)
|
6
9
|
@shared_scope = shared_scope
|
7
10
|
end
|
@@ -17,6 +20,20 @@ module Diddy
|
|
17
20
|
# Steps must return TRUE to keep the script running.
|
18
21
|
# When a step returns a FALSE, it will stop the script.
|
19
22
|
#
|
23
|
+
# It is also to use sub_steps (not to confuse with dubstep).
|
24
|
+
#
|
25
|
+
# step('Do something crazy') do
|
26
|
+
# sub_step('Eat brains') do
|
27
|
+
# a == true
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# sub_step('Go insane') do
|
31
|
+
# b == true
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# In the case above, every sub_step needs to return true.
|
36
|
+
#
|
20
37
|
def self.step(description, &block)
|
21
38
|
@steps ||= {}
|
22
39
|
@steps[description] = block
|
@@ -49,5 +66,29 @@ module Diddy
|
|
49
66
|
def shared
|
50
67
|
@shared_scope
|
51
68
|
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Adds a sub_step
|
72
|
+
#
|
73
|
+
def sub_step(description, &block)
|
74
|
+
# print pending to screen
|
75
|
+
print("\n")
|
76
|
+
print(blue(" . #{description}"))
|
77
|
+
|
78
|
+
# yield the block
|
79
|
+
valid = yield(block)
|
80
|
+
|
81
|
+
# jump back to beginning of line
|
82
|
+
print("\r")
|
83
|
+
|
84
|
+
# print out success or failure
|
85
|
+
if valid
|
86
|
+
print(green(" ✓ #{description}"))
|
87
|
+
else
|
88
|
+
print(red(bold(" ✕ #{description}")))
|
89
|
+
end
|
90
|
+
|
91
|
+
self.sub_steps << { description: description, valid: valid }
|
92
|
+
end
|
52
93
|
end
|
53
94
|
end
|
data/lib/diddy.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diddy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,10 +10,10 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name: term/
|
16
|
+
name: term/ansicolor
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
@@ -43,7 +43,11 @@ files:
|
|
43
43
|
- diddy-0.1.0.gem
|
44
44
|
- diddy.gemspec
|
45
45
|
- lib/diddy.rb
|
46
|
+
- lib/diddy/context.rb
|
46
47
|
- lib/diddy/helpers.rb
|
48
|
+
- lib/diddy/run_result.rb
|
49
|
+
- lib/diddy/run_result_printer.rb
|
50
|
+
- lib/diddy/scenario.rb
|
47
51
|
- lib/diddy/script.rb
|
48
52
|
- lib/diddy/shared_scope.rb
|
49
53
|
- lib/diddy/step.rb
|