public
Last active

Minispec, the mini bdd test framework example

  • Download Gist
README.md
Markdown

Minispec

minispec is a mini bdd test framework example

# npm install git://gist.github.com/4033566.git

# require('minispec') in your project
require('./minispec')

# use expect.js for assertion (http://n37.co/aemDq)
expect = require('expect.js')

user = ""
describe "Minispec", ->
  before ->
    user = name: "Jimmy"

  it 'can success', ->
    expect(true).to.be.ok()

  it 'can fail', ->
    expect().fail ->

  it 'have before', ->
    expect(user.name).to.equal "Jimmy"

  describe 'after', ->

    after ->
      throw new Error('in after')

    it 'will be executed', ->
      expect(true).to.be.ok()

  describe 'nested describe', ->
    before ->
      user.password = '123'

    it 'with nested before', ->
      expect(user.password).to.be '123'

    it 'with nested after', ->
      expect(user.password).to.be '123'

    it 'can also have error', ->
      expect().fail ->

    describe 'nested in nested', ->
      it 'is nested', ->
        expect(1).to.be.ok()

  describe 'async function', ->

    it 'have callback', (done)->
      expect(1).to.be.ok()
      done()
index.js
JavaScript
1 2
require('coffee-script');
module.exports = minispec = require('./minispec');
minispec.coffee
CoffeeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
{EventEmitter} = require 'events'
async = require 'async'
 
#utils
color = (code)-> (text = "")-> code + text + '\u001b[0m'
red = color('\u001b[31m')
green = color('\u001b[32m')
yellow = color('\u001b[33m')
pluralize = (count, noun)-> if count > 1 then noun + 's' else noun
indent = (level)-> (' ' for i in [0...level]).join('')
 
class Suite extends EventEmitter
constructor: (@title, @parent)->
@errors = 0
@tests = []
@childs = []
@parent?.childs.push @
@level = @parent?.level + 1 or 0
 
@on 'start', => @report yellow @title
@delegate ['before', 'after'] if @parent?
@on 'result', @reportResult
@on 'end', @reportSummary
 
delegate: (events)->
events.forEach (event)=>
@on event, ()=> @parent?.emit event
 
run: ->
@emit 'start'
async.forEachSeries @tests, (test, next)=>
callback = =>
@emit('after')
@emit('result', test)
next()
 
try
@emit('before')
if test.isAsync
test.fn callback
else
test.fn()
callback()
catch err
@emit('result', test, err)
next()
, =>
@childs.forEach (spec)-> spec.run()
@emit 'end' unless @parent?
 
report: (text)-> console.log indent(@level) + text
 
reportResult: (test, err)=>
if err?
@errors += 1
@report red " ✗ #{test.title} (#{err})"
else
@report green " ✓ #{test.title}"
 
reportSummary: =>
count = @tests.length
errors = @errors
 
(reduce = (suites)->
suites.forEach (suite)->
count += suite.tests.length
errors += suite.errors
reduce suite.childs if suite.childs?
)(@childs)
 
console.log yellow "run #{count} #{pluralize(count, 'test') } , #{count - errors} success, #{errors} failed"
 
class Runner
constructor: (context)->
suites = []
context.it = (desc, fn)->
suites[0].tests.push title: desc, fn: fn, isAsync: !!fn.length
context.before = (fn)->
suites[0].on 'before', fn
context.after = (fn)->
suites[0].on 'after', fn
context.describe = (title, block)->
suite = new Suite(title, suites[0])
suites.unshift(suite)
block()
suites.shift()
suite.run() if suites.length is 0
 
new Runner(global)
package.json
JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{
"name": "minispec",
"version": "0.0.1",
"description": "mini bdd in coffee",
"main": "./index.js",
"scripts": {
"test": "coffee README.md"
},
"repository": "git://gist.github.com/4033566.git",
"dependencies": {
"coffee-script": "*",
"async": "*"
},
"devDependencies": {
"expect.js": "*"
},
"author": "Jimmy Chao",
"license": "MIT"
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.