oojspec 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -23,10 +23,24 @@ I'd rather prefer to write:
23
23
  assert(seats.length)
24
24
  ```
25
25
 
26
+ # Examples
27
+
26
28
  [Here is how it looks like](http://oojspec.herokuapp.com/)
27
29
  (yeah, I know it is failing - it is on purpose so that you can see
28
30
  how the report looks like).
29
31
 
32
+ Feel free to explore it in jsfiddle:
33
+
34
+ - [JavaScript example with test runner](http://jsfiddle.net/rosenfeld/FWtaZ/)
35
+ - [JavaScript example without test runner](http://jsfiddle.net/rosenfeld/W3BCJ/)
36
+ - [CoffeeScript example with test runner](http://jsfiddle.net/rosenfeld/qJSyz/)
37
+ - [CoffeeScript example without test runner](http://jsfiddle.net/rosenfeld/37Qdn/)
38
+
39
+ And finally [a more complete suite](http://jsfiddle.net/rosenfeld/wgBJg/)
40
+ demonstrating lots of the features available. This was extracted from the test
41
+ application and is expected to fail. The result should be the same as the first
42
+ example of this section, hosted on Heroku.
43
+
30
44
  # Is it production ready?
31
45
 
32
46
  It should be, but its API is certainly going to change a lot before it becomes stable.
@@ -27,7 +27,7 @@ window.oojspec = new class OojspecRunner
27
27
  autorun: -> @runSpecs() unless @disableAutorun
28
28
 
29
29
  runSpecs: ->
30
- @reporter = buster.reporters.html.create()
30
+ @reporter = buster.reporters.html.create detectCssPath: false
31
31
  @reporter.listen @runner
32
32
  @runner.emit 'suite:start', name: "Specs"
33
33
  @runNextDescription()
@@ -35,30 +35,46 @@ window.oojspec = new class OojspecRunner
35
35
  runNextDescription: =>
36
36
  (@runner.emit 'suite:end', @stats; return) unless @descriptions.length
37
37
  # TODO: think about non null contexts usage
38
- @descriptions.shift().run @runner, @assertions, null, @runNextDescription
38
+ @descriptions.shift().run @runner, @assertions, null, false, @runNextDescription
39
39
 
40
40
  describe: (description, block)=>
41
41
  @stats.contexts++ # only root descriptions will be count
42
42
  @descriptions.push new Description(description, block)
43
43
 
44
+ RESERVED_FOR_DESCRIPTION_DSL = ['beforeAll', 'before', 'after', 'afterAll', 'describe', 'context',
45
+ 'example', 'it', 'specify', 'pending', 'xit']
46
+ RESERVED_FOR_EXAMPLE_DSL = ['assert', 'expect', 'fail', 'refute', 'waitsFor', 'runs']
44
47
  class Description
45
- RESERVED = ['beforeAll', 'before', 'after', 'afterAll', 'describe', 'context',
46
- 'example', 'it', 'specify', 'pending', 'xit']
48
+ RESERVED = RESERVED_FOR_DESCRIPTION_DSL.concat RESERVED_FOR_EXAMPLE_DSL
49
+
47
50
  constructor: (@description, @block)->
51
+ if @description.runSpecs or @description.prototype?.runSpecs
52
+ @block = @description
53
+ @description = @block.description or @block.name
48
54
 
49
- run: (@runner, @assertions, @context, @onFinish, @beforeBlocks = [], @afterBlocks = [])->
55
+ run: (@runner, @assertions, @binding, @bare, @onFinish, @beforeBlocks = [], @afterBlocks = [])->
50
56
  @runner.emit 'context:start', name: @description
51
57
  @dsl = new DescribeDsl
52
- if c = @context
53
- for reserved in RESERVED
54
- try
55
- throw new Error("'#{reserved}' method is reserved for oojspec usage only") if c[reserved]
56
- catch e
57
- e.name = "syntax error"
58
- @runner.emit 'test:error', name: @description, error: e
59
- @onDescriptionFinished(e)
60
- c[reserved] = @dsl[reserved]
61
- @runAround @beforeBlocks, @afterBlocks, @onDescriptionFinished, @processDescriptionBlock
58
+ if @block.runSpecs or @block.prototype?.runSpecs
59
+ @runWithContext()
60
+ else
61
+ @doRun()
62
+
63
+ doRun: -> @runAround @beforeBlocks, @afterBlocks, @onDescriptionFinished, @processDescriptionBlock
64
+
65
+ runWithContext: ->
66
+ try
67
+ @binding = if @block.prototype then new @block else @block
68
+ if @binding and not (@bare = @block.bare)
69
+ for reserved in RESERVED
70
+ if @binding[reserved]
71
+ throw new Error("'#{reserved}' method is reserved for oojspec usage only")
72
+ @binding[reserved] = @dsl[reserved]
73
+ @doRun()
74
+ catch e
75
+ e.name = "syntax error"
76
+ @runner.emit 'test:error', name: @description, error: e
77
+ @onDescriptionFinished(e)
62
78
 
63
79
  onDescriptionFinished: (error)=>
64
80
  if error and not error.handled
@@ -68,11 +84,14 @@ class Description
68
84
  @onFinish error
69
85
 
70
86
  runAround: (befores, afters, onFinish, block)->
71
- new AroundBlock(befores, afters, block).run @runner, @assertions, @context, onFinish
87
+ new AroundBlock(befores, afters, block).run @runner, @assertions, @binding, @bare, onFinish
72
88
 
73
89
  processDescriptionBlock: (onFinish)=>
74
- context = @context or @dsl
75
- @block.call context, context
90
+ if @block.runSpecs or @block.prototype?.runSpecs
91
+ @binding.runSpecs @dsl
92
+ else
93
+ binding = @binding or @dsl
94
+ @block.call binding, @dsl
76
95
  @runAround @dsl._beforeAllBlocks_, @dsl._afterAllBlocks_, onFinish, (@onExamplesFinished)=>
77
96
  @runNextStep()
78
97
 
@@ -81,10 +100,11 @@ class Description
81
100
  nextStep = @dsl._examples_.shift()
82
101
  (@reportDeferred(nextStep.description); @runNextStep(); return) if nextStep.pending
83
102
  nextTick =
84
- if nextStep instanceof Description then => nextStep
85
- .run @runner, @assertions, @context, @runNextStep, @dsl._beforeBlocks_, @dsl._afterBlocks_
103
+ if nextStep instanceof Description then =>
104
+ nextStep.run @runner, @assertions, @binding, @bare, @runNextStep, \
105
+ @dsl._beforeBlocks_, @dsl._afterBlocks_
86
106
  else => # ExampleWithHooks
87
- nextStep.run @runner, @assertions, @context, @onExampleFinished
107
+ nextStep.run @runner, @assertions, @binding, @bare, @onExampleFinished
88
108
  setTimeout nextTick, 0
89
109
 
90
110
  onExampleFinished: (error)=>
@@ -105,6 +125,7 @@ class DescribeDsl
105
125
  block.description = description
106
126
  else
107
127
  block = description
128
+ throw new Error("block missing") unless block
108
129
  container.push block
109
130
 
110
131
  constructor: ->
@@ -125,17 +146,18 @@ class DescribeDsl
125
146
  describe: (description, block)=>
126
147
  @_examples_.push new Description(description, block, @_beforeBlocks_, @_afterBlocks_)
127
148
  example: (description, block)=>
149
+ throw new Error("Examples must have a description and a block") unless description and block
128
150
  @_examples_.push new ExampleWithHooks(description, @_beforeBlocks_, @_afterBlocks_, block)
129
151
  pending: (description)=> @_examples_.push {description, pending: true}
130
152
 
131
153
  class AroundBlock
132
154
  constructor: (@beforeBlocks, @afterBlocks, @block)->
133
155
 
134
- run: (@runner, @assertions, @context, @onFinish)->
156
+ run: (@runner, @assertions, @binding, @bare, @onFinish)->
135
157
  @runGroup @beforeBlocks, ((e)=> @onBeforeError e), (wasSuccessful)=>
136
158
  if wasSuccessful
137
159
  @runMainBlock @block, (error)=>
138
- @registerError error
160
+ @registerError error if error
139
161
  @runAfterGroup()
140
162
  else @runAfterGroup()
141
163
 
@@ -152,7 +174,7 @@ class AroundBlock
152
174
  onFinish error
153
175
 
154
176
  runGroup: (group, onError, onFinish)->
155
- new ExampleGroupWithoutHooks(@assertions, @context, group, onFinish, onError).run()
177
+ new ExampleGroupWithoutHooks(@assertions, @binding, @bare, group, onFinish, onError).run()
156
178
 
157
179
  onBeforeError: (error)-> error.source = "before hook"; @registerError error
158
180
  onAfterError: (error)-> error.source = "after hook"; @registerError error
@@ -161,7 +183,7 @@ class AroundBlock
161
183
 
162
184
  class ExampleWithHooks extends AroundBlock
163
185
  constructor: (@description, @beforeBlocks, @afterBlocks, @block)->
164
- runMainBlock: (block, onFinish)-> new Example(block).run @assertions, @context, onFinish
186
+ runMainBlock: (block, onFinish)-> new Example(block).run @assertions, @binding, @bare, onFinish
165
187
  onAfterHooks: ->
166
188
  @handleResult()
167
189
  super
@@ -182,7 +204,7 @@ class ExampleWithHooks extends AroundBlock
182
204
  @runner.emit 'test:error', name: @description, error: @error
183
205
 
184
206
  class ExampleGroupWithoutHooks
185
- constructor: (@assertions, @context, @blocks, @onFinish, @onError)-> @nextIndex = 0
207
+ constructor: (@assertions, @binding, @bare, @blocks, @onFinish, @onError)-> @nextIndex = 0
186
208
 
187
209
  run: ->
188
210
  @wasSuccessful = true
@@ -191,39 +213,40 @@ class ExampleGroupWithoutHooks
191
213
  nextTick: =>
192
214
  (@onFinish(@wasSuccessful); return) unless @nextIndex < @blocks.length
193
215
  block = @blocks[@nextIndex++]
194
- new Example(block).run @assertions, @context, (error)=>
216
+ new Example(block).run @assertions, @binding, @bare, (error)=>
195
217
  (@wasSuccessful = false; @onError error) if error
196
218
  setTimeout @nextTick, 0
197
219
 
198
220
  class Example
199
221
  TICK = 10 # ms
200
- constructor: (@exampleBlock)->
222
+ constructor: (@exampleBlock)-> @describeDsl = {}
201
223
 
202
- run: (@assertions, @context, @onFinish)->
224
+ run: (@assertions, @binding, @bare, @onFinish)->
203
225
  @dsl = new ExampleDsl(@assertions.assert, @assertions.expect, @assertions.fail, \
204
226
  @assertions.refute)
205
- if @context
206
- throw "runs and waitsFor are reserved attributes" if @context.runs or @context.waitsFor
207
- @context.runs = @dsl.runs
208
- @context.waitsFor = @dsl.waitsFor
227
+ if @binding and not @bare
228
+ for m in RESERVED_FOR_DESCRIPTION_DSL
229
+ @describeDsl[m] = b if b = @binding[m]
230
+ delete @binding[m]
231
+ (@binding[m] = b if b = @dsl[m]) for m in RESERVED_FOR_EXAMPLE_DSL
209
232
  @tryBlock @exampleBlock, ->
210
- if @context
211
- delete @context.runs
212
- delete @context.waitsFor
213
- (@onFinish(); return) unless (@steps = @dsl._asyncQueue_).length
233
+ if @binding and not @bare
234
+ delete @binding.runs
235
+ delete @binding.waitsFor
236
+ (@finish(); return) unless (@steps = @dsl._asyncQueue_).length
214
237
  @runNextAsyncStep()
215
238
 
216
239
  tryBlock: (block, onSuccess)->
217
240
  try
218
- context = @context or @dsl
219
- onSuccess.call this, block.call context, context
241
+ binding = @binding or @dsl
242
+ onSuccess.call this, block.call(binding, @dsl)
220
243
  catch error
221
244
  error = new Error(error) if typeof error is 'string'
222
- error.message = "'#{error.message}' in '#{block.description}'" if block.description
223
- @onFinish error
245
+ error.message = "'#{error.message}' in '#{block.description}'" if block?.description
246
+ @finish error
224
247
 
225
248
  runNextAsyncStep: ->
226
- (@onFinish(); return) unless @steps.length
249
+ (@finish(); return) unless @steps.length
227
250
  step = @steps.shift()
228
251
  if step instanceof Function
229
252
  @tryBlock step, @runNextAsyncStep
@@ -237,9 +260,15 @@ class Example
237
260
  keepTryingCondition: =>
238
261
  @tryBlock @condition, (result)->
239
262
  (@runNextAsyncStep(); return) if result
240
- (@onFinish {timeout: true, @description}; return) if new Date().getTime() > @deadline
263
+ (@finish {timeout: true, @description}; return) if new Date().getTime() > @deadline
241
264
  setTimeout @keepTryingCondition, TICK
242
265
 
266
+ finish: ->
267
+ if @binding and not @bare
268
+ (@binding[m] = b if b = @describeDsl[m]) for m in RESERVED_FOR_DESCRIPTION_DSL
269
+ delete @binding[m] for m in RESERVED_FOR_EXAMPLE_DSL
270
+ @onFinish.apply null, arguments
271
+
243
272
  class ExampleDsl
244
273
  constructor: (@assert, @expect, @fail, @refute)-> @_asyncQueue_ = []
245
274
 
@@ -1,3 +1,3 @@
1
1
  module Oojspec
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -21,7 +21,9 @@
21
21
  reporter.contexts = [];
22
22
  reporter.doc = getDoc(opt);
23
23
  var cssPath = opt.cssPath;
24
- if (!cssPath && opt.detectCssPath) cssPath = busterTestPath(reporter.doc) + "buster-test.css";
24
+ if (!cssPath && opt.detectCssPath !== false) {
25
+ cssPath = busterTestPath(reporter.doc) + "buster-test.css";
26
+ }
25
27
  reporter.setRoot(opt.root || reporter.doc.body, cssPath);
26
28
  reporter.io = opt.io || (isNodeJS && require("util"));
27
29
 
@@ -205,7 +207,9 @@
205
207
 
206
208
  head.appendChild(el(head.ownerDocument, "style", {
207
209
  type: "text/css",
208
- innerHTML: fs.readFileSync(path.join(__dirname, "../../../resources/buster-test.css"))
210
+ innerHTML: fs.readFileSync(
211
+ path.join(__dirname, "../../../resources/buster-test.css")
212
+ )
209
213
  }));
210
214
  } else {
211
215
  head.appendChild(el(document, "link", {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oojspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-15 00:00:00.000000000 Z
12
+ date: 2012-07-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: coffee-rails
@@ -85,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
85
  version: '0'
86
86
  segments:
87
87
  - 0
88
- hash: -240007266511017517
88
+ hash: -1275332504698129146
89
89
  required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  none: false
91
91
  requirements:
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  version: '0'
95
95
  segments:
96
96
  - 0
97
- hash: -240007266511017517
97
+ hash: -1275332504698129146
98
98
  requirements: []
99
99
  rubyforge_project:
100
100
  rubygems_version: 1.8.24