Skip to content

Instantly share code, notes, and snippets.

@Rafe
Last active October 12, 2015 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rafe/4033566 to your computer and use it in GitHub Desktop.
Save Rafe/4033566 to your computer and use it in GitHub Desktop.
Minispec, the mini bdd test framework example

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/5gpfa)
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()
require('coffee-script');
module.exports = minispec = require('./minispec');
{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)
{
"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"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment