-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.coffee
124 lines (110 loc) · 3.68 KB
/
index.coffee
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Copyright 2015 Artillery Games, Inc. All rights reserved.
#
# This code, and all derivative work, is the exclusive property of Artillery
# Games, Inc. and may not be used without Artillery Games, Inc.'s authorization.
#
# Author: Mark Logan
path = require 'path'
fs = require 'fs'
child_process = require 'child_process'
temp = require 'temp'
# TestDataFiles makes it easy to do data-file driven regtests.
#
# First, put your input files (if any) in a `test-data` directory,
# within the directory that contains your test, e.g.:
#
# something/something/lib/test
# \_ regtest.coffee
# \_ test-data
# \_ myinputfile
#
# Next, write your test:
#
# exports.setUp = (cb) ->
# @testData = new common.testlib.TestDataFiles(__filename)
# @testData.makeTmpDir()
# cb()
#
# exports.testRegtest = (test) ->
# @testData.testFile test, 'myinputfile', (testHandle) ->
# results = processFile testHandle.inputPath
# testHandle.writeObservedOutput results
#
# Now, generate your expected output:
#
# $ UPDATE_REGTEST_DATA=1 nodeunit regtest.coffee
#
# The expected output is stored in the test-data directory:
#
# something/something/lib/test
# \_ regtest.coffee
# \_ test-data
# \_ myinputfile
# \_ myinputfile.expected
#
# Run the test again, it should pass:
#
# $ nodeunit regtest.coffee
#
# If you like, change `myinputfile.expected`, and verify that the test fails.
#
# Add all the new files to git, and you're done!
class TestDataFiles
constructor: (@testPath) ->
extension = path.extname @testPath
@dirname = path.dirname @testPath
@basename = path.basename @testPath, extension
@tmpdir = temp.mkdirSync()
testFileExpect: (test, inputFile, expected, cb) ->
test.expect expected
testHandle = new RegTestHandle(this, inputFile)
cb testHandle
if not testHandle.compareFiles()
testHandle.printFailureReport ->
test.fail "File contents differed"
test.done()
else
test.ok "No regressions in output"
test.done()
testFileExpectAsync: (test, inputFile, expected, cb) ->
test.expect expected
testHandle = new RegTestHandle(this, inputFile)
cb testHandle, ->
if not testHandle.compareFiles()
testHandle.printFailureReport ->
test.fail "File contents differed"
test.done()
else
test.ok "No regressions in output"
test.done()
testFile: (test, inputFile, cb) ->
@testFileExpect test, inputFile, 1, cb
testFileAsync: (test, inputFile, cb) ->
@testFileExpectAsync test, inputFile, 1, cb
class RegTestHandle
constructor: (@testData, @inputFile) ->
@inputPath = path.join @testData.dirname, 'test-data', @inputFile
@observedOutputPath = path.join @testData.tmpdir, @inputFile
fs.writeFileSync @observedOutputPath, ''
@expectedOutputPath = path.join @testData.dirname, 'test-data', "#{ @inputFile }.expected"
writeObservedOutput: (output) ->
if output.charAt(output.length - 1) != '\n'
output += '\n'
fs.writeFileSync @observedOutputPath, output
if process.env.UPDATE_REGTEST_DATA
fs.writeFileSync @expectedOutputPath, output
compareFiles: ->
observed = fs.readFileSync @observedOutputPath, 'utf8'
expected = fs.readFileSync @expectedOutputPath, 'utf8'
return observed == expected
printFailureReport: (cb) ->
cmd = "diff #{ @observedOutputPath } #{ @expectedOutputPath } || true"
child_process.exec cmd, { maxBuffer: 5 * 1024*1024 }, (error, stdout, stderr) =>
if error
console.error "Error running #{ cmd }:", error
console.error stderr
else
console.log "Diff report for #{ @inputFile }"
console.log stdout
cb()
exports.TestDataFiles = TestDataFiles