marso 0.1.15089 → 0.1.29007

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,29 @@
1
+
2
+ module Marso
3
+ module Messages
4
+
5
+ def self.no_component_found(component_type, rootpath)
6
+ component_name = proc {
7
+ case component_type
8
+ when :feature
9
+ "features"
10
+ when :story
11
+ "stories"
12
+ when :scenario
13
+ "scenarios"
14
+ else
15
+ raise ArgumentError, ":#{component_type} is not a valid component_type. " +
16
+ "Valid values are: #{[:feature, :story, :scenario].join(', ')}"
17
+ end
18
+ }
19
+
20
+ "E0000: No #{component_name.call} were found under path '#{rootpath}'.\n" +
21
+ "Browse to a different folder, or use the :rootpath option to define an adequate path"
22
+ end
23
+
24
+ def self.no_component_match(component_type, offenders)
25
+ "E0001: The following selected #{component_type} ids couldn't be found: #{offenders.join(', ')}"
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,207 @@
1
+ require 'eventmachine'
2
+
3
+ module Marso
4
+ class Enumerate
5
+
6
+ STOP_MSG = "End of seed"
7
+ attr_reader :process, :src
8
+
9
+ def self.from(collection)
10
+ _process = lambda {
11
+ collection.each { |x|
12
+ Fiber.yield x
13
+ }
14
+
15
+ raise StopIteration, STOP_MSG
16
+ }
17
+
18
+ Enumerate.new(_process)
19
+ end
20
+
21
+ def initialize(process, source={})
22
+ @src = source
23
+ @process = process
24
+
25
+ @fiber_delegate = Fiber.new do
26
+ process.call
27
+ end
28
+ end
29
+
30
+ def resume
31
+ if @src.is_a?(Marso::Enumerate)
32
+ @fiber_delegate.resume(@src.resume)
33
+ else # case where @src is nil
34
+ @fiber_delegate.resume
35
+ end
36
+ end
37
+
38
+ def source(other_source)
39
+ Enumerate.new(@process, other_source)
40
+ end
41
+
42
+ def clone
43
+ class_name = self.class.to_s
44
+ if @src.is_a?(Marso::Enumerate)
45
+ return Object.const_get(class_name).new(@process, @src.clone)
46
+ else
47
+ return Object.const_get(class_name).new(@process)
48
+ end
49
+ end
50
+
51
+ def |(other_source)
52
+ other_source.source(clone_original_source_to_protect_it)
53
+ end
54
+
55
+ def where(&block)
56
+ FiberFilter.new(block, clone_original_source_to_protect_it)
57
+ end
58
+
59
+ def select(&block)
60
+ FiberProjection.new(block, clone_original_source_to_protect_it)
61
+ end
62
+
63
+ def select_many(&block)
64
+ FiberProjectionMany.new(block, clone_original_source_to_protect_it)
65
+ end
66
+
67
+ def execute(max_iteration=1000000)
68
+ begin
69
+ if max_iteration.zero?
70
+ loop do
71
+ self.resume
72
+ end
73
+ else
74
+ max_iteration.times { self.resume }
75
+ end
76
+ rescue StopIteration => ex
77
+ raise ex unless ex.message == STOP_MSG
78
+ rescue Exception => ex
79
+ raise ex
80
+ end
81
+ end
82
+
83
+ def to_a
84
+ a = []
85
+ begin
86
+ loop do
87
+ a << self.resume
88
+ end
89
+ rescue StopIteration => ex
90
+ raise ex unless ex.message == STOP_MSG
91
+ rescue Exception => ex
92
+ raise ex
93
+ end
94
+
95
+ return a
96
+ end
97
+
98
+ private
99
+ def clone_original_source_to_protect_it
100
+ # prevent the core source to be altered so that we can reuse it
101
+ # to build other queries. Otherwise, after one usage, there'll be
102
+ # a dead fiber exception thrown
103
+ return self.clone
104
+ end
105
+ end
106
+
107
+ class FiberProjection < Enumerate
108
+
109
+ def initialize(process, source={})
110
+ @src = source
111
+ @process = process
112
+
113
+ @fiber_delegate = Fiber.new do
114
+ output = nil
115
+ while input = Fiber.yield(output)
116
+ output = process.call(input)
117
+ end
118
+ end
119
+
120
+ @fiber_delegate.resume
121
+ end
122
+
123
+ def source(other_source)
124
+ FiberProjection.new(@process, other_source)
125
+ end
126
+ end
127
+
128
+ class FiberProjectionMany < Enumerate
129
+
130
+ def initialize(process, source={})
131
+ @src = source
132
+ @process = process
133
+ @is_inside_inner_enumerate = false
134
+
135
+ @fiber_delegate = Fiber.new do
136
+ output = []
137
+ while input = Fiber.yield(output)
138
+ output = process.call(input)
139
+
140
+ @is_inside_inner_enumerate = true
141
+
142
+ output.each { |o|
143
+ Fiber.yield(o)
144
+ }
145
+
146
+ @is_inside_inner_enumerate = false
147
+ end
148
+ end
149
+
150
+ @fiber_delegate.resume
151
+ end
152
+
153
+ def resume
154
+ if @src.is_a?(Marso::Enumerate) && !@is_inside_inner_enumerate
155
+ output = @fiber_delegate.resume(@src.resume)
156
+ output = @fiber_delegate.resume(@src.resume) if output.is_a?(Array) && output.empty?
157
+ return output
158
+ else
159
+ output = @fiber_delegate.resume
160
+ output = @fiber_delegate.resume(@src.resume) unless @is_inside_inner_enumerate
161
+ output = @fiber_delegate.resume(@src.resume) if output.is_a?(Array) && output.empty?
162
+ return output
163
+ end
164
+ end
165
+
166
+ def source(other_source)
167
+ FiberProjectionMany.new(@process, other_source)
168
+ end
169
+
170
+ end
171
+
172
+ class FiberFilter < Enumerate
173
+
174
+ def initialize(process, source={})
175
+ @src = source
176
+ @process = process
177
+
178
+ @fiber_delegate = Fiber.new do
179
+ output = nil
180
+ while input = Fiber.yield(output)
181
+ if process.call(input)
182
+ output = input
183
+ else
184
+ output = :invalid_input
185
+ end
186
+ end
187
+ end
188
+
189
+ @fiber_delegate.resume
190
+ end
191
+
192
+ def resume
193
+ v = nil
194
+ if @src.is_a?(Marso::Enumerate)
195
+ v = @fiber_delegate.resume(@src.resume)
196
+ v = self.resume if v == :invalid_input
197
+ else
198
+ v = @fiber_delegate.resume
199
+ end
200
+ return v
201
+ end
202
+
203
+ def source(other_source)
204
+ FiberFilter.new(@process, other_source)
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,21 @@
1
+
2
+ class NilClass
3
+
4
+ def ensure_valid_sync_mode
5
+ raise ArgumentError, "'sync_mode' cannot be nil" if self == null
6
+ end
7
+ end
8
+
9
+ class Object
10
+
11
+ def ensure_valid_sync_mode
12
+ raise ArgumentError, "'sync_mode' must be a Symbol" unless self.is_a?(Symbol)
13
+ end
14
+ end
15
+
16
+ class Symbol
17
+
18
+ def ensure_valid_sync_mode
19
+ raise ArgumentError, "':#{self}' is an invalid sync_mode value. Valid values are either :sync or :async" unless (self == :sync || self == :async)
20
+ end
21
+ end
data/lib/marso/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Marso
2
- VERSION ="0.1.15089"
2
+ VERSION ="0.1.29007"
3
3
  end
data/marso.gemspec CHANGED
@@ -37,4 +37,5 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "rake", "~> 10.3"
38
38
  spec.add_runtime_dependency "colorize", "~> 0.7"
39
39
  spec.add_runtime_dependency "watir-webdriver", "~> 0.6"
40
+ spec.add_runtime_dependency "eventmachine", "~> 1.0"
40
41
  end
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.15089
4
+ version: 0.1.29007
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-06-07 00:00:00.000000000 Z
11
+ date: 2014-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: eventmachine
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
69
83
  description: Marso is the beginning of a small lightweight BDD project. Currently,
70
84
  this is just a very simple code sample that only displays a custom message in green
71
85
  or in red depending on the value of a predicate.
@@ -82,10 +96,25 @@ files:
82
96
  - README.md
83
97
  - Rakefile
84
98
  - lib/marso.rb
85
- - lib/marso/assert.rb
86
99
  - lib/marso/config.rb
100
+ - lib/marso/domain/feature/feature.rb
101
+ - lib/marso/domain/feature/feature_load.rb
102
+ - lib/marso/domain/feature/feature_publish.rb
103
+ - lib/marso/domain/scenario/scenario.rb
104
+ - lib/marso/domain/scenario/scenario_publish.rb
105
+ - lib/marso/domain/step/step.rb
106
+ - lib/marso/domain/step/step_publish.rb
107
+ - lib/marso/domain/story/story.rb
108
+ - lib/marso/domain/story/story_load.rb
109
+ - lib/marso/domain/story/story_publish.rb
87
110
  - lib/marso/factories.rb
88
- - lib/marso/scenario.rb
111
+ - lib/marso/helpers/componenthelper.rb
112
+ - lib/marso/helpers/statushelper.rb
113
+ - lib/marso/helpers/texthelper.rb
114
+ - lib/marso/launcher.rb
115
+ - lib/marso/messages/errors.rb
116
+ - lib/marso/toolbelt/fiberpiping.rb
117
+ - lib/marso/validation/symbol.rb
89
118
  - lib/marso/version.rb
90
119
  - marso.gemspec
91
120
  homepage: https://github.com/nicolasdao/marso
data/lib/marso/assert.rb DELETED
@@ -1,17 +0,0 @@
1
- require "colorize"
2
-
3
- module Marso
4
- module_function
5
-
6
- def assert(message, &block)
7
- begin
8
- if (block.call)
9
- puts "Assert #{message}: PASSED".green
10
- else
11
- puts "Assert #{message}: FAILED".red
12
- end
13
- rescue Exception => e
14
- puts "Assert #{message} FAILED with exception #{e.message}".red
15
- end
16
- end
17
- end
@@ -1,278 +0,0 @@
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