oojspec 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8744b2c6b9c6be58bbd8eb3b566c54bae6dda38e
4
+ data.tar.gz: 9e6d34de2357feeb77a41663e8024dc16bf389fe
5
+ SHA512:
6
+ metadata.gz: b93bcf5981587f22cf10e3fbd2a901c869c965804e34d6f05c69c620a48b0e28b904c760c5b1b134f275eb4dfc6052ae24f602995e2c6a428cc68b05edf5e4ae
7
+ data.tar.gz: e02c4ded0fce6d1b47b649bded82d9190ab38b553beb5ddcecec975e8b737f8c0863e2c5be66686fa827869b3197b37513fe7dc0778641227a181f438b2a4d9c
data/README.md CHANGED
@@ -194,3 +194,7 @@ I'd love to hear your opinions on the API and design of `oojspec` and of course
194
194
  will be very welcome if they're aligned with this project goals.
195
195
 
196
196
  Enjoy! :)
197
+
198
+
199
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rosenfeld/oojspec/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
200
+
@@ -1,303 +1,10 @@
1
- # =require buster/all
2
1
  # =require_self
3
- # =require ./progress
2
+ # =require_tree ./oojspec
4
3
 
5
- window.oojspec = new class OojspecRunner
6
- constructor: ->
7
- @timeout = 1000 # 1s - default timeout
8
- @runner = buster.create buster.eventEmitter
9
- @descriptions = []
10
- @assertions = buster.assertions
11
- (logFormatter = buster.create buster.format).quoteStrings = false
12
- @assertions.format = buster.bind logFormatter, "ascii"
13
- @assertions.on 'pass', => @stats.assertions++
14
- @assertions.on 'failure', => @stats.failures++
15
- #@runner.on 'context:start', => @stats.contexts++
16
- @runner.on 'test:timeout', => @stats.timeouts++; @assertions.emit 'failure'
17
- @runner.on 'test:error', => @stats.errors++
18
- @runner.on 'test:deferred', => @stats.deferred++
19
- @runner.on 'oojspec:examples:add', (count)=> @stats.tests += count
4
+ # avoid polluting the global namespace
5
+ # namespace for allowing us to split code in multiple files
6
+ # internal classes and functions declared in separate units should be exported to _
7
+ @oojspec = _: {}
20
8
 
21
- @stats =
22
- contexts: 0
23
- tests: 0
24
- assertions: 0
25
- errors: 0
26
- failures: 0
27
- timeouts: 0
28
- deferred: 0
29
-
30
- exposeAll: -> window.describe = @describe
31
- autorun: -> @runSpecs() unless @disableAutorun
32
-
33
- runSpecs: ->
34
- @reporter = buster.reporters.html.create detectCssPath: false
35
- @reporter.listen @runner
36
- d.processDsl @runner for d in @descriptions
37
- @runner.emit 'suite:start', name: "Specs"
38
- @runNextDescription()
39
-
40
- runNextDescription: =>
41
- (@runner.emit 'suite:end', @stats; return) unless @descriptions.length
42
- @descriptions.shift().run @assertions, @runNextDescription
43
-
44
- describe: (description, block)=>
45
- @stats.contexts++ # only root descriptions will be count
46
- @descriptions.push new Description(description, block)
47
-
48
- RESERVED_FOR_DESCRIPTION_DSL = ['beforeAll', 'before', 'after', 'afterAll', 'describe', 'context',
49
- 'example', 'it', 'specify', 'pending', 'xit']
50
- RESERVED_FOR_EXAMPLE_DSL = ['assert', 'expect', 'fail', 'refute', 'waitsFor', 'runs']
51
- class Description
52
- RESERVED = RESERVED_FOR_DESCRIPTION_DSL.concat RESERVED_FOR_EXAMPLE_DSL
53
-
54
- constructor: (@description, @block)->
55
- if @description.runSpecs or @description.prototype?.runSpecs
56
- @block = @description
57
- @description = @block.description or @block.name
58
-
59
- processDsl: (@runner, @binding, @bare)->
60
- @dsl = new DescribeDsl
61
- (@block.runSpecs or @block.prototype?.runSpecs) and @detectBindingError()
62
-
63
- @binding or= {}
64
- @injectDsl() unless @bare
65
- if @block.runSpecs or @block.prototype?.runSpecs
66
- @binding.runSpecs @dsl
67
- else
68
- @block.call @binding, @dsl
69
- @runner.emit 'oojspec:examples:add', @dsl._examplesCount_
70
- @removeDsl() unless @bare
71
- @bare or= @binding.bare
72
-
73
- d.processDsl @runner, @binding, @bare for d in @dsl._examples_ when d instanceof Description
74
-
75
- detectBindingError: ->
76
- try
77
- @binding = if @block.prototype then new @block else @block
78
- if @binding and not (@bare = @block.bare)
79
- for reserved in RESERVED when @binding[reserved]
80
- throw new Error("'#{reserved}' method is reserved for oojspec usage only")
81
- catch e
82
- e.name = "syntax error"
83
- @bindingError = e
84
-
85
- injectDsl: -> @binding[p] = v for p, v of @dsl; return
86
-
87
- removeDsl: -> delete @binding[p] for p in RESERVED_FOR_DESCRIPTION_DSL; return
88
-
89
- run: (@assertions, @onFinish, @beforeBlocks = [], @afterBlocks = [])->
90
- @runner.emit 'context:start', name: @description
91
- if @bindingError
92
- @runner.emit 'test:error', name: @description, error: @bindingError
93
- @onDescriptionFinished @bindingError
94
- else
95
- @doRun()
96
-
97
- doRun: -> @runAround @beforeBlocks, @afterBlocks, @onDescriptionFinished, @processDescriptionBlock
98
-
99
- onDescriptionFinished: (error)=>
100
- if error and not error.handled
101
- error.handled = true
102
- @runner.emit 'test:error', { name: 'Error running describe statements', error }
103
- @runner.emit 'context:end'
104
- @onFinish error
105
-
106
- runAround: (befores, afters, onFinish, block)->
107
- new AroundBlock(befores, afters, block).run @runner, @assertions, @binding, @bare, onFinish
108
-
109
- processDescriptionBlock: (onFinish)=>
110
- @runAround @dsl._beforeAllBlocks_, @dsl._afterAllBlocks_, onFinish, (@onExamplesFinished)=>
111
- @runNextStep()
112
-
113
- runNextStep: =>
114
- (@onExamplesFinished(); return) unless @dsl._examples_.length
115
- nextStep = @dsl._examples_.shift()
116
- (@reportDeferred(nextStep.description); @runNextStep(); return) if nextStep.pending
117
- nextTick =
118
- if nextStep instanceof Description then =>
119
- nextStep.run @assertions, @runNextStep, @dsl._beforeBlocks_, @dsl._afterBlocks_
120
- else => # ExampleWithHooks
121
- nextStep.run @runner, @assertions, @binding, @bare, @onExampleFinished
122
- setTimeout nextTick, 0
123
-
124
- onExampleFinished: (error)=>
125
- (@runNextStep(); return) unless error and not error.handled
126
- error.handled = true
127
- console.log error
128
- name = @description
129
- name += " in #{error.source}" if error.source
130
- @runner.emit 'test:error', { name, error }
131
- @onFinish(error)
132
-
133
- reportDeferred: (description)-> @runner.emit 'test:deferred', name: description
134
-
135
- class DescribeDsl
136
- addHook = (description, block, container)->
137
- if typeof description is 'string'
138
- return unless block # pending hook
139
- block.description = description
140
- else
141
- block = description
142
- throw new Error("block missing") unless block
143
- container.push block
144
-
145
- constructor: ->
146
- @_beforeAllBlocks_ = []
147
- @_beforeBlocks_ = []
148
- @_afterBlocks_ = []
149
- @_afterAllBlocks_ = []
150
- @_examples_ = []
151
- @_examplesCount_ = 0 # only examples, not describes
152
- # aliases:
153
- @it = @specify = @example
154
- @context = @describe
155
- @xit = @pending
156
-
157
- beforeAll: (description, block)=> addHook description, block, @_beforeAllBlocks_
158
- before: (description, block)=> addHook description, block, @_beforeBlocks_
159
- after: (description, block)=> addHook description, block, @_afterBlocks_
160
- afterAll: (description, block)=> addHook description, block, @_afterAllBlocks_
161
- describe: (description, block)=>
162
- @_examples_.push new Description(description, block, @_beforeBlocks_, @_afterBlocks_)
163
- example: (description, block)=>
164
- throw new Error("Examples must have a description and a block") unless description and block
165
- @_examplesCount_++
166
- @_examples_.push new ExampleWithHooks(description, @_beforeBlocks_, @_afterBlocks_, block)
167
- pending: (description)=>
168
- @_examplesCount_++
169
- @_examples_.push {description, pending: true}
170
-
171
- class AroundBlock
172
- constructor: (@beforeBlocks, @afterBlocks, @block)->
173
-
174
- run: (@runner, @assertions, @binding, @bare, @onFinish)->
175
- @runGroup @beforeBlocks, ((e)=> @onBeforeError e), (wasSuccessful)=>
176
- if wasSuccessful
177
- @runMainBlock @block, (error)=>
178
- @registerError error if error
179
- @runAfterGroup()
180
- else @runAfterGroup()
181
-
182
- registerError: (error)->
183
- @runner.emit 'oojspec:log:error', error
184
- @error or= error
185
-
186
- runMainBlock: (block, onFinish)->
187
- try
188
- block onFinish
189
- catch error
190
- error = new Error(error) if typeof error is 'string'
191
- @registerError error
192
- onFinish error
193
-
194
- runGroup: (group, onError, onFinish)->
195
- new ExampleGroupWithoutHooks(@assertions, @binding, @bare, group, onFinish, onError).run()
196
-
197
- onBeforeError: (error)-> error.source = "before hook"; @registerError error
198
- onAfterError: (error)-> error.source = "after hook"; @registerError error
199
- runAfterGroup: -> @runGroup @afterBlocks, ((e)=> @onAfterError e), (=> @onAfterHooks())
200
- onAfterHooks: -> @onFinish @error
201
-
202
- class ExampleWithHooks extends AroundBlock
203
- constructor: (@description, @beforeBlocks, @afterBlocks, @block)->
204
- runMainBlock: (block, onFinish)-> new Example(block).run @assertions, @binding, @bare, onFinish
205
- onAfterHooks: ->
206
- @handleResult()
207
- super
208
-
209
- handleResult: ->
210
- (@runner.emit 'test:success', name: @description; return) unless @error
211
- @error.handled = true
212
- if @error.name is 'AssertionError'
213
- @runner.emit 'test:failure', name: @description, error: @error
214
- return
215
-
216
- if @error.timeout
217
- @error.source or= 'example'
218
- @runner.emit 'test:timeout', name: @description, error: @error
219
- return
220
- @error.name = 'Exception'
221
- @error.name += " in #{@error.source}" if @error.source
222
- @runner.emit 'test:error', name: @description, error: @error
223
-
224
- class ExampleGroupWithoutHooks
225
- constructor: (@assertions, @binding, @bare, @blocks, @onFinish, @onError)-> @nextIndex = 0
226
-
227
- run: ->
228
- @wasSuccessful = true
229
- setTimeout @nextTick, 0
230
-
231
- nextTick: =>
232
- (@onFinish(@wasSuccessful); return) unless @nextIndex < @blocks.length
233
- block = @blocks[@nextIndex++]
234
- new Example(block).run @assertions, @binding, @bare, (error)=>
235
- (@wasSuccessful = false; @onError error) if error
236
- setTimeout @nextTick, 0
237
-
238
- class Example
239
- TICK = 10 # ms
240
- constructor: (@exampleBlock)-> @describeDsl = {}
241
-
242
- run: (@assertions, @binding, @bare, @onFinish)->
243
- @dsl = new ExampleDsl(@assertions.assert, @assertions.expect, @assertions.fail, \
244
- @assertions.refute)
245
- if @binding and not @bare
246
- for m in RESERVED_FOR_DESCRIPTION_DSL
247
- @describeDsl[m] = b if b = @binding[m]
248
- delete @binding[m]
249
- (@binding[m] = b if b = @dsl[m]) for m in RESERVED_FOR_EXAMPLE_DSL
250
- @tryBlock @exampleBlock, ->
251
- if @binding and not @bare
252
- delete @binding.runs
253
- delete @binding.waitsFor
254
- (@finish(); return) unless (@steps = @dsl._asyncQueue_).length
255
- @runNextAsyncStep()
256
-
257
- tryBlock: (block, onSuccess)->
258
- try
259
- binding = @binding or @dsl
260
- onSuccess.call this, block.call(binding, @dsl)
261
- catch error
262
- error = new Error(error) if typeof error is 'string'
263
- error.message = "'#{error.message}' in '#{block.description}'" if block?.description
264
- @finish error
265
-
266
- runNextAsyncStep: ->
267
- (@finish(); return) unless @steps.length
268
- step = @steps.shift()
269
- if step instanceof Function
270
- @tryBlock step, @runNextAsyncStep
271
- else
272
- @waitsFor step...
273
-
274
- waitsFor: (@condition, timeout = @binding?.timeout or oojspec.timeout, @description)->
275
- @deadline = timeout + new Date().getTime()
276
- @keepTryingCondition()
277
-
278
- keepTryingCondition: =>
279
- @tryBlock @condition, (result)->
280
- (@runNextAsyncStep(); return) if result
281
- (@finish {timeout: true, @description}; return) if new Date().getTime() > @deadline
282
- setTimeout @keepTryingCondition, TICK
283
-
284
- finish: ->
285
- if @binding and not @bare
286
- (@binding[m] = b if b = @describeDsl[m]) for m in RESERVED_FOR_DESCRIPTION_DSL
287
- delete @binding[m] for m in RESERVED_FOR_EXAMPLE_DSL
288
- @onFinish.apply null, arguments
289
-
290
- class ExampleDsl
291
- constructor: (@assert, @expect, @fail, @refute)-> @_asyncQueue_ = []
292
-
293
- runs: (step)=> @_asyncQueue_.push step
294
-
295
- waitsFor: =>
296
- for a in arguments
297
- (condition = a; continue) if typeof a is "function"
298
- (timeout = a; continue) if typeof a is "number"
299
- (description = a; continue) if typeof a is "string"
300
- @_asyncQueue_.push [condition, timeout, description]
301
-
302
- class StepContext
303
- constructor: (@assert, @expect, @fail)->
9
+ (_ = @oojspec._).extend = (extended, extender)->
10
+ extended[p] = v for p, v of extender when p[0] isnt '_'
@@ -1,5 +1,7 @@
1
+ # =require ./runner
2
+
1
3
  new class ProgressStats
2
- constructor: (@eh = oojspec.runner)->
4
+ constructor: (@eh = oojspec.events)->
3
5
  @total = @count = 0
4
6
  @eh.on 'suite:start', @createElements
5
7
  @eh.on 'oojspec:examples:add', (count)=> @total += count
@@ -0,0 +1,316 @@
1
+ # =require buster/all
2
+ # =require ./utils
3
+
4
+ _ = oojspec._
5
+
6
+ _.extend oojspec, new class OojspecRunner
7
+ constructor: ->
8
+ @timeout = 1000 # 1s - default timeout
9
+ @events = buster.create buster.eventEmitter
10
+ @descriptions = []
11
+ @_registerEventHandlers()
12
+ @_initializeStats()
13
+ @params = _.parseParams()
14
+ # avoid too much parameters between methods, acts like a context:
15
+ @params.events = @events
16
+ @params.assertions = @assertions
17
+
18
+ _registerEventHandlers: ->
19
+ @assertions = buster.assertions
20
+ (logFormatter = buster.create buster.format).quoteStrings = false
21
+ @assertions.format = buster.bind logFormatter, "ascii"
22
+ @assertions.on 'pass', => @stats.assertions++
23
+ @assertions.on 'failure', => @stats.failures++
24
+ #@events.on 'context:start', => @stats.contexts++
25
+ @events.on 'test:timeout', => @stats.timeouts++; @assertions.emit 'failure'
26
+ @events.on 'test:error', => @stats.errors++
27
+ @events.on 'test:deferred', => @stats.deferred++
28
+ @events.on 'oojspec:examples:add', (count)=> @stats.tests += count
29
+
30
+ _initializeStats: ->
31
+ @stats =
32
+ contexts: 0
33
+ tests: 0
34
+ assertions: 0
35
+ errors: 0
36
+ failures: 0
37
+ timeouts: 0
38
+ deferred: 0
39
+
40
+ exposeAll: => window.describe = @describe
41
+ autorun: => @runSpecs() unless @disableAutorun
42
+
43
+ runSpecs: =>
44
+ @reporter = buster.reporters.html.create detectCssPath: false
45
+ @reporter.listen @events
46
+ d.processDsl @params for d in @descriptions
47
+ @events.emit 'suite:start', name: "Specs"
48
+ @_runNextDescription()
49
+
50
+ _runNextDescription: =>
51
+ (@events.emit 'suite:end', @stats; return) unless @descriptions.length
52
+ @descriptions.shift().run @params, @_runNextDescription
53
+
54
+ describe: (description, block)=>
55
+ @stats.contexts++ # only root descriptions will be count
56
+ @descriptions.push new Description(description, block)
57
+
58
+ RESERVED_FOR_DESCRIPTION_DSL = ['beforeAll', 'before', 'after', 'afterAll', 'describe', 'context',
59
+ 'example', 'it', 'specify', 'pending', 'xit']
60
+ RESERVED_FOR_EXAMPLE_DSL = ['assert', 'expect', 'fail', 'refute', 'waitsFor', 'runs']
61
+ class Description
62
+ RESERVED = RESERVED_FOR_DESCRIPTION_DSL.concat RESERVED_FOR_EXAMPLE_DSL
63
+
64
+ constructor: (@description, @block)->
65
+ if @description.runSpecs or @description.prototype?.runSpecs
66
+ @block = @description
67
+ @description = @block.description or @block.name
68
+
69
+ processDsl: (@params, @binding, @bare)->
70
+ @events = params.events
71
+ @dsl = new DescribeDsl
72
+ (@block.runSpecs or @block.prototype?.runSpecs) and @detectBindingError()
73
+
74
+ @binding or= {}
75
+ @injectDsl() unless @bare
76
+ if @block.runSpecs or @block.prototype?.runSpecs
77
+ @binding.runSpecs @dsl
78
+ else
79
+ @block.call @binding, @dsl
80
+ @events.emit 'oojspec:examples:add', @dsl._examplesCount_
81
+ @removeDsl() unless @bare
82
+ @bare or= @binding.bare
83
+
84
+ d.processDsl @params, @binding, @bare for d in @dsl._examples_ when d instanceof Description
85
+
86
+ detectBindingError: ->
87
+ try
88
+ @binding = if @block.prototype then new @block else @block
89
+ if @binding and not (@bare = @block.bare)
90
+ for reserved in RESERVED when @binding[reserved]
91
+ throw new Error("'#{reserved}' method is reserved for oojspec usage only")
92
+ catch e
93
+ e.name = "syntax error"
94
+ @bindingError = e
95
+
96
+ injectDsl: -> @binding[p] = v for p, v of @dsl; return
97
+
98
+ removeDsl: -> delete @binding[p] for p in RESERVED_FOR_DESCRIPTION_DSL; return
99
+
100
+ run: (@params, @onFinish, @beforeBlocks = [], @afterBlocks = [])->
101
+ @events.emit 'context:start', name: @description
102
+ if @bindingError
103
+ @events.emit 'test:error', name: @description, error: @bindingError
104
+ @onDescriptionFinished @bindingError
105
+ else
106
+ @doRun()
107
+
108
+ doRun: -> @runAround @beforeBlocks, @afterBlocks, @onDescriptionFinished, @processDescriptionBlock
109
+
110
+ onDescriptionFinished: (error)=>
111
+ if error and not error.handled
112
+ error.handled = true
113
+ @events.emit 'test:error', { name: 'Error running describe statements', error }
114
+ @events.emit 'context:end'
115
+ @onFinish error
116
+
117
+ runAround: (befores, afters, onFinish, block)->
118
+ new AroundBlock(befores, afters, block).run @params, @binding, @bare, onFinish
119
+
120
+ processDescriptionBlock: (onFinish)=>
121
+ @runAround @dsl._beforeAllBlocks_, @dsl._afterAllBlocks_, onFinish, (@onExamplesFinished)=>
122
+ @runNextStep()
123
+
124
+ runNextStep: =>
125
+ (@onExamplesFinished(); return) unless @dsl._examples_.length
126
+ nextStep = @dsl._examples_.shift()
127
+ (@reportDeferred(nextStep.description); @runNextStep(); return) if nextStep.pending
128
+ nextTick =
129
+ if nextStep instanceof Description then =>
130
+ nextStep.run @params, @runNextStep, @dsl._beforeBlocks_, @dsl._afterBlocks_
131
+ else => # ExampleWithHooks
132
+ nextStep.run @params, @binding, @bare, @onExampleFinished
133
+ setTimeout nextTick, 0
134
+
135
+ onExampleFinished: (error)=>
136
+ (@runNextStep(); return) unless error and not error.handled
137
+ error.handled = true
138
+ console.log error
139
+ name = @description
140
+ name += " in #{error.source}" if error.source
141
+ @events.emit 'test:error', { name, error }
142
+ @onFinish(error)
143
+
144
+ reportDeferred: (description)-> @events.emit 'test:deferred', name: description
145
+
146
+ class DescribeDsl
147
+ addHook = (description, block, container)->
148
+ if typeof description is 'string'
149
+ return unless block # pending hook
150
+ block.description = description
151
+ else
152
+ block = description
153
+ throw new Error("block missing") unless block
154
+ container.push block
155
+
156
+ constructor: ->
157
+ @_beforeAllBlocks_ = []
158
+ @_beforeBlocks_ = []
159
+ @_afterBlocks_ = []
160
+ @_afterAllBlocks_ = []
161
+ @_examples_ = []
162
+ @_examplesCount_ = 0 # only examples, not describes
163
+ # aliases:
164
+ @it = @specify = @example
165
+ @context = @describe
166
+ @xit = @pending
167
+
168
+ beforeAll: (description, block)=> addHook description, block, @_beforeAllBlocks_
169
+ before: (description, block)=> addHook description, block, @_beforeBlocks_
170
+ after: (description, block)=> addHook description, block, @_afterBlocks_
171
+ afterAll: (description, block)=> addHook description, block, @_afterAllBlocks_
172
+ describe: (description, block)=>
173
+ @_examples_.push new Description(description, block, @_beforeBlocks_, @_afterBlocks_)
174
+ example: (description, block)=>
175
+ throw new Error("Examples must have a description and a block") unless description and block
176
+ @_examplesCount_++
177
+ @_examples_.push new ExampleWithHooks(description, @_beforeBlocks_, @_afterBlocks_, block)
178
+ pending: (description)=>
179
+ @_examplesCount_++
180
+ @_examples_.push {description, pending: true}
181
+
182
+ class AroundBlock
183
+ constructor: (@beforeBlocks, @afterBlocks, @block)->
184
+
185
+ run: (@params, @binding, @bare, @onFinish)->
186
+ @events = @params.events
187
+ @runGroup @beforeBlocks, ((e)=> @onBeforeError e), (wasSuccessful)=>
188
+ if wasSuccessful
189
+ @runMainBlock @block, (error)=>
190
+ @registerError error if error
191
+ @runAfterGroup()
192
+ else @runAfterGroup()
193
+
194
+ registerError: (error)->
195
+ @events.emit 'oojspec:log:error', error
196
+ @error or= error
197
+
198
+ runMainBlock: (block, onFinish)->
199
+ try
200
+ block onFinish
201
+ catch error
202
+ error = new Error(error) if typeof error is 'string'
203
+ @registerError error
204
+ onFinish error
205
+
206
+ runGroup: (group, onError, onFinish)->
207
+ new ExampleGroupWithoutHooks(@params, @binding, @bare, group, onFinish, onError).run()
208
+
209
+ onBeforeError: (error)-> error.source = "before hook"; @registerError error
210
+ onAfterError: (error)-> error.source = "after hook"; @registerError error
211
+ runAfterGroup: -> @runGroup @afterBlocks, ((e)=> @onAfterError e), (=> @onAfterHooks())
212
+ onAfterHooks: -> @onFinish @error
213
+
214
+ class ExampleWithHooks extends AroundBlock
215
+ constructor: (@description, @beforeBlocks, @afterBlocks, @block)->
216
+ runMainBlock: (block, onFinish)-> new Example(block).run @params, @binding, @bare, onFinish
217
+ onAfterHooks: ->
218
+ @handleResult()
219
+ super
220
+
221
+ handleResult: ->
222
+ (@events.emit 'test:success', name: @description; return) unless @error
223
+ @error.handled = true
224
+ if @error.name is 'AssertionError'
225
+ @events.emit 'test:failure', name: @description, error: @error
226
+ return
227
+
228
+ if @error.timeout
229
+ @error.source or= 'example'
230
+ @events.emit 'test:timeout', name: @description, error: @error
231
+ return
232
+ @error.name = 'Exception'
233
+ @error.name += " in #{@error.source}" if @error.source
234
+ @events.emit 'test:error', name: @description, error: @error
235
+
236
+ class ExampleGroupWithoutHooks
237
+ constructor: (@params, @binding, @bare, @blocks, @onFinish, @onError)->
238
+ @nextIndex = 0
239
+
240
+ run: ->
241
+ @wasSuccessful = true
242
+ setTimeout @nextTick, 0
243
+
244
+ nextTick: =>
245
+ (@onFinish(@wasSuccessful); return) unless @nextIndex < @blocks.length
246
+ block = @blocks[@nextIndex++]
247
+ new Example(block).run @params, @binding, @bare, (error)=>
248
+ (@wasSuccessful = false; @onError error) if error
249
+ setTimeout @nextTick, 0
250
+
251
+ class Example
252
+ TICK = 10 # ms
253
+ constructor: (@exampleBlock)-> @describeDsl = {}
254
+
255
+ run: (@params, @binding, @bare, @onFinish)->
256
+ a = @params.assertions
257
+ @dsl = new ExampleDsl(a.assert, a.expect, a.fail, a.refute)
258
+ if @binding and not @bare
259
+ for m in RESERVED_FOR_DESCRIPTION_DSL
260
+ @describeDsl[m] = b if b = @binding[m]
261
+ delete @binding[m]
262
+ (@binding[m] = b if b = @dsl[m]) for m in RESERVED_FOR_EXAMPLE_DSL
263
+ @tryBlock @exampleBlock, ->
264
+ if @binding and not @bare
265
+ delete @binding.runs
266
+ delete @binding.waitsFor
267
+ (@finish(); return) unless (@steps = @dsl._asyncQueue_).length
268
+ @runNextAsyncStep()
269
+
270
+ tryBlock: (block, onSuccess)->
271
+ try
272
+ binding = @binding or @dsl
273
+ onSuccess.call this, block.call(binding, @dsl)
274
+ catch error
275
+ error = new Error(error) if typeof error is 'string'
276
+ error.message = "'#{error.message}' in '#{block.description}'" if block?.description
277
+ @finish error
278
+
279
+ runNextAsyncStep: ->
280
+ (@finish(); return) unless @steps.length
281
+ step = @steps.shift()
282
+ if typeof step is 'function'
283
+ @tryBlock step, @runNextAsyncStep
284
+ else
285
+ @waitsFor step...
286
+
287
+ waitsFor: (@condition, timeout = @binding?.timeout or oojspec.timeout, @description)->
288
+ @deadline = timeout + new Date().getTime()
289
+ @keepTryingCondition()
290
+
291
+ keepTryingCondition: =>
292
+ @tryBlock @condition, (result)->
293
+ (@runNextAsyncStep(); return) if result
294
+ (@finish {timeout: true, @description}; return) if new Date().getTime() > @deadline
295
+ setTimeout @keepTryingCondition, TICK
296
+
297
+ finish: ->
298
+ if @binding and not @bare
299
+ (@binding[m] = b if b = @describeDsl[m]) for m in RESERVED_FOR_DESCRIPTION_DSL
300
+ delete @binding[m] for m in RESERVED_FOR_EXAMPLE_DSL
301
+ @onFinish.apply null, arguments
302
+
303
+ class ExampleDsl
304
+ constructor: (@assert, @expect, @fail, @refute)-> @_asyncQueue_ = []
305
+
306
+ runs: (step)=> @_asyncQueue_.push step
307
+
308
+ waitsFor: =>
309
+ for a in arguments
310
+ (condition = a; continue) if typeof a is "function"
311
+ (timeout = a; continue) if typeof a is "number"
312
+ (description = a; continue) if typeof a is "string"
313
+ @_asyncQueue_.push [condition, timeout, description]
314
+
315
+ class StepContext
316
+ constructor: (@assert, @expect, @fail)->
@@ -0,0 +1,7 @@
1
+ oojspec._.parseParams = (search = window.location.search)->
2
+ d = (str)-> decodeURIComponent str.replace /\+/g, ' '
3
+ query = search.substring 1
4
+ regex = /(.*?)=([^\&]*)&?/g
5
+ params = {}
6
+ params[d(m[1])] = d(m[2]) while m = regex.exec query
7
+ params
@@ -1,3 +1,3 @@
1
1
  module Oojspec
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
metadata CHANGED
@@ -1,50 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oojspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
5
- prerelease:
4
+ version: 0.0.9
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rodrigo Rosenfeld Rosas
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-01 00:00:00.000000000 Z
11
+ date: 2014-01-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: coffee-rails
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rails-sandbox-assets
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
- description: ! " A test runner similar to RSpec for client-side code built\n on
47
- top of Buster.js that is more suited for integration tests."
41
+ description: |2-
42
+ A test runner similar to RSpec for client-side code built
43
+ on top of Buster.js that is more suited for integration tests.
48
44
  email:
49
45
  - rr.rosas@gmail.com
50
46
  executables: []
@@ -52,7 +48,9 @@ extensions: []
52
48
  extra_rdoc_files: []
53
49
  files:
54
50
  - app/views/oojspec/runner.html.erb
55
- - lib/assets/javascripts/progress.js.coffee
51
+ - lib/assets/javascripts/oojspec/utils.js.coffee
52
+ - lib/assets/javascripts/oojspec/runner.js.coffee
53
+ - lib/assets/javascripts/oojspec/progress.js.coffee
56
54
  - lib/assets/javascripts/oojspec.js.coffee
57
55
  - lib/assets/stylesheets/oojspec.css.erb
58
56
  - lib/assets/stylesheets/oojspec/progress.css
@@ -75,32 +73,25 @@ files:
75
73
  - README.md
76
74
  homepage: http://github.com/rosenfeld/oojspec
77
75
  licenses: []
76
+ metadata: {}
78
77
  post_install_message:
79
78
  rdoc_options: []
80
79
  require_paths:
81
80
  - lib
82
81
  required_ruby_version: !ruby/object:Gem::Requirement
83
- none: false
84
82
  requirements:
85
- - - ! '>='
83
+ - - '>='
86
84
  - !ruby/object:Gem::Version
87
85
  version: '0'
88
- segments:
89
- - 0
90
- hash: -2878099860768326426
91
86
  required_rubygems_version: !ruby/object:Gem::Requirement
92
- none: false
93
87
  requirements:
94
- - - ! '>='
88
+ - - '>='
95
89
  - !ruby/object:Gem::Version
96
90
  version: '0'
97
- segments:
98
- - 0
99
- hash: -2878099860768326426
100
91
  requirements: []
101
92
  rubyforge_project:
102
- rubygems_version: 1.8.24
93
+ rubygems_version: 2.0.14
103
94
  signing_key:
104
- specification_version: 3
95
+ specification_version: 4
105
96
  summary: Object-oriented client-side testing
106
97
  test_files: []