spectacular
Version:
Advanced BDD framework for CoffeeScript and JavaScript
203 lines (163 loc) • 5.89 kB
text/coffeescript
class spectacular.Random
constructor: () ->
get: ->
= ( * 9301 + 49297) % 233280
/ 233280.0
class spectacular.RunnerResults
constructor: () ->
= []
= []
= []
= []
= []
= []
{, } =
= null
= null
hasFailures: -> .some (e) ->
e.result.state in ['skipped', 'failure', 'errored']
class spectacular.Runner
spectacular.EventDispatcher
constructor: (, , ) ->
= []
= []
= []
seed = if .seed?
.seed
else
Math.round(Math.random() * 99999999)
.seed = seed
= new spectacular.Random seed
= => Math.round 1 - .get() * 2
run: () =>
results = new spectacular.RunnerResults this
promise = spectacular.Promise.unit(results)
.then (results) ->
results.specsStartedAt = new Date()
results
.then()
.then()
.then (results) ->
results.specsEndedAt = new Date()
results
.then()
.then (results) ->
if results.hasFailures() then 1 else 0
findSpecFileInStack: (stack) ->
for p in .paths or []
for l,i in stack
return i if l.indexOf(p) isnt -1
-1
registerSpecs: (results) =>
set = .children
set = set.sort() if .random
for example in set
example, .hasExclusiveExamples()
new spectacular.Event 'start', this
results
register: (child, exclusiveOnly=false) ->
if child.children?
if exclusiveOnly
if child.hasExclusiveExamplesWithDependencies()
for c in child.allExclusiveExamplesWithDependecies
c, exclusiveOnly
set = child.allExclusiveExamples
set = set.sort() if .random
c, exclusiveOnly for c in set
else
if child.hasExamplesWithDependencies()
for c in child.allExamplesWithDependecies
c, exclusiveOnly
set = child.allExamples
set = set.sort() if .random
c, exclusiveOnly for c in set
else
return if exclusiveOnly and not child.exclusive
if child.hasDependencies()
child, exclusiveOnly
child, exclusiveOnly
registerDependencies: (child) ->
for dep in child.dependencies
dependency = .identifiedExamplesMap[dep]
if dependency?
child, dependency
dependency
insert: (example) ->
example
.push example unless example in
.push example unless example in
handleDependencies: (example) ->
return if example in
dependencies = []
cascading = null
dependenciesSucceed = null
cascadingSucceed = null
if example.dependencies.length > 0
for dep in example.dependencies
dependency = .identifiedExamplesMap[dep]
if dependency?
dependencies.push dependency
else
msg = "Warning: unmet dependency #{dep} for example #{example}"
msg = msg.yellow if .colors
new spectacular.Event 'message', msg
dependenciesSucceed = -> dependencies.every (e) -> e.succeed
if example.cascading?
s for s in example.cascading.examples
cascadingSucceed = -> example.cascading.examplesSuceed
if dependenciesSucceed?
if cascadingSucceed?
example.dependenciesMet = ->
dependenciesSucceed() and cascadingSucceed()
else
example.dependenciesMet = dependenciesSucceed
else if cascadingSucceed?
example.dependenciesMet = cascadingSucceed
checkDependency: (example, dependency) ->
if dependency in example.ancestors
throw new Error "#{example} can't depends on ancestor #{dependency}"
example, dependency
checkCircularity: (example, dependency) ->
currentParents = example.identifiedAncestors.map (a) -> a.options.id
depParents = dependency.identifiedAncestors.map((a) -> a.options.id).concat(dependency.options.id)
for id in currentParents
if id in depParents
throw new Error(
"circular dependencies between #{example} and #{dependency}"
)
if dependency.dependencies.length > 0
for dep in dependency.dependencies
dependency = .identifiedExamplesMap[dep]
example, dependency if dependency?
return
executeSpecs: (results) =>
promise = new spectacular.Promise
promise, results
promise
nextExample: (defer, results) =>
spectacular.nextTick =>
if .length is 0
defer.resolve(results)
else
nextExample = .shift()
.currentExample = nextExample
nextExample.run()
.then =>
nextExample, results
defer, results
.fail (reason) =>
nextExample, results
defer, results
handleResult: (example, results) ->
results.results.push example.result
results.examples.push example
switch example.result.state
when 'pending' then results.pending.push example
when 'skipped' then results.skipped.push example
when 'errored' then results.errors.push example
when 'failure' then results.failures.push example
new spectacular.Event 'result', example
.currentExample = null
notifyEnd: (results) =>
new spectacular.Event 'end', results
results