Skip to content

Commit

Permalink
expose expected test output to headless test runner
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchambers committed Dec 9, 2012
1 parent 92dc561 commit 0c0a48d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 82 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.PHONY: compile clean setup test

PORT := 3000
coffee = node_modules/.bin/coffee

compile:
Expand All @@ -13,4 +14,6 @@ setup:
@npm install

test:
@$(coffee) test/cli
@sleep 0.1 && test/open http://localhost:$(PORT) &
@$(coffee) test/server
2 changes: 1 addition & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ MyApp.utils.bar = function() {
make setup
make test

Visit [localhost:3000](http://localhost:3000/).
This runs doctest's test suite: first headless, then in a browser.


[1]: http://docs.python.org/library/doctest.html
Expand Down
12 changes: 12 additions & 0 deletions test/browser.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
jQuery ($) ->

doctest.complete = (results) ->
for message, expected of tests
deepEqual results.shift(), expected, message
start()

asyncTest 'JavaScript doctests', ->
doctest './test.js'

asyncTest 'CoffeeScript doctests', ->
doctest './test.coffee'
27 changes: 27 additions & 0 deletions test/cli.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{isEqual} = require 'underscore'

doctest = require '../src/doctest'
tests = require './tests'


gray = green = red = reset = ''
unless process.env.NODE_DISABLE_COLORS or process.platform is 'win32'
gray = '\x1B[0;37m'
green = '\x1B[0;32m'
red = '\x1B[0;31m'
reset = '\x1B[0m'

queue = ['test/test.js', 'test/test.coffee']
next = -> doctest queue.shift() if queue.length

doctest.complete = (results) ->
for message, expected of tests
actual = results.shift()
if isEqual actual, expected
console.log "#{green} \u2714 #{gray} #{message}#{reset}"
else
console.warn "#{red} \u2718 #{gray} #{message}#{reset}"
console.log "#{gray} expected: #{green}#{expected}#{reset}"
console.log "#{gray} received: #{red}#{actual}#{reset}"
next()
next()
11 changes: 11 additions & 0 deletions test/open
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

for program in open xdg-open ; do
command -v $program >/dev/null 2>&1
if [[ $? == 0 ]] ; then
$program "$@"
exit 0
fi
done

exit 1
6 changes: 6 additions & 0 deletions test/server.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@ app.get '/doctest.js', (req, res) ->
res.contentType 'js'
res.send CoffeeScript.compile text

['browser', 'tests'].forEach (name) ->
app.get "/#{name}.js", (req, res) ->
fs.readFile path.resolve('test', "#{name}.coffee"), 'utf8', (err, text) ->
res.contentType 'js'
res.send CoffeeScript.compile text

port = process.env.PORT ? 3000
app.listen port, -> console.log "listening on port #{port}"
83 changes: 2 additions & 81 deletions test/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,90 +6,11 @@
<script src="http://coffeescript.org/extras/coffee-script.js"></script>
<script src="https://raw.github.com/documentcloud/underscore/master/underscore.js"></script>
<script src="/doctest.js"></script>
<script src="/tests.js"></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://code.jquery.com/qunit/git/qunit.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" />
<script>
jQuery(function($) {

doctest.complete = function(results) {
var idx = 0
var t = function(message, expected) {
if (expected[0]) expected[2] = expected[1]
deepEqual(results[idx++], expected, message)
}

t('global variable accessible in outer scope',
[true, '"global"', , 3])

t('global variable accessible in inner scope',
[true, '"global"', , 10])

t('local variable referenced, not shadowed global',
[true, '"shadowed"', , 14])

t('local variable accessible before declaration',
[true, 2, , 20])

t('assignment is an expression',
[true, 3, , 25])

t('variable declared in doctest remains accessible',
[true, [1, 2, 3], , 28])

t('arithmetic error reported',
[false, 5, 4, 31])

t('TypeError captured and reported',
[true, 'TypeError', , 35])

t('TypeError expected but not reported',
[false, 'TypeError', 0, 38])

t('function accessible before declaration',
[true, 12, , 42])

t('NaN can be used as expected result',
[true, NaN, , 45])

t('function accessible after declaration',
[true, 4, , 53])

t('multiline input',
[true, [1, 2, 3, 4, 5, 6, 7, 8, 9], , 65])

t('multiline assignment',
[true, '"input may span many lines"', , 71])

t('spaces following "//" and ">" are optional',
[true, '"no spaces"', , 75])

t('indented doctest',
[true, '"Docco-compatible whitespace"', , 78])

t('">" in doctest',
[true, true, , 81])

t('comment on input line',
[true, '"foobar"', , 85])

t('comment on output line',
[true, 25, , 88])

t('variable in creation context is not accessible',
[true, '"undefined"', , 92])

start()
}
asyncTest('JavaScript doctests', function() {
doctest('./test.js')
})
asyncTest('CoffeeScript doctests', function() {
doctest('./test.coffee')
})

})
</script>
<script src="/browser.js"></script>
</head>
<body>
<h1 id="qunit-header">doctest test suite</h1>
Expand Down
67 changes: 67 additions & 0 deletions test/tests.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
tests =

'global variable accessible in outer scope':
[yes, '"global"', '"global"', 3]

'global variable accessible in inner scope':
[yes, '"global"', '"global"', 10]

'local variable referenced, not shadowed global':
[yes, '"shadowed"', '"shadowed"', 14]

'local variable accessible before declaration':
[yes, 2, 2, 20]

'assignment is an expression':
[yes, 3, 3, 25]

'variable declared in doctest remains accessible':
[yes, [1, 2, 3], [1, 2, 3], 28]

'arithmetic error reported':
[no, 5, 4, 31]

'TypeError captured and reported':
[yes, 'TypeError', 'TypeError', 35]

'TypeError expected but not reported':
[no, 'TypeError', 0, 38]

'function accessible before declaration':
[yes, 12, 12, 42]

'NaN can be used as expected result':
[yes, NaN, NaN, 45]

'function accessible after declaration':
[yes, 4, 4, 53]

'multiline input':
[yes, [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], 65]

'multiline assignment':
[yes, '"input may span many lines"', '"input may span many lines"', 71]

'spaces following "//" and ">" are optional':
[yes, '"no spaces"', '"no spaces"', 75]

'indented doctest':
[yes, '"Docco-compatible whitespace"', '"Docco-compatible whitespace"', 78]

'">" in doctest':
[yes, yes, yes, 81]

'comment on input line':
[yes, '"foobar"', '"foobar"', 85]

'comment on output line':
[yes, 25, 25, 88]

'variable in creation context is not accessible':
[yes, '"undefined"', '"undefined"', 92]


if typeof window isnt 'undefined'
window.tests = tests
else
module.exports = tests

0 comments on commit 0c0a48d

Please sign in to comment.