-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Really early/basic prototype of a spec-like thing
- Loading branch information
Showing
14 changed files
with
1,487 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const React = require('react') | ||
const {Box, Color} = require('ink') | ||
const importJSX = require('import-jsx') | ||
const AssertCounts = importJSX('../base/assert-counts.js') | ||
const SuiteCounts = importJSX('../base/suite-counts.js') | ||
|
||
module.exports = ({suiteCounts, assertCounts, time}) => ( | ||
<Box flexDirection="column"> | ||
<SuiteCounts {...suiteCounts} /> | ||
<AssertCounts {...assertCounts} /> | ||
</Box> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const React = require('react') | ||
const importJSX = require('import-jsx') | ||
const t = require('tap') | ||
const {render} = require('ink-testing-library') | ||
const Footer = importJSX('./footer.js') | ||
|
||
// not too terribly much to do here! | ||
const [pass, fail, skip, todo, total] = [1,1,1,1,4] | ||
const r = render(<Footer | ||
suiteCounts={{pass,fail,skip,todo,total}} | ||
assertCounts={{pass,fail,skip,todo,total}} | ||
time={123} />) | ||
t.matchSnapshot(r.lastFrame()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
const React = require('react') | ||
const importJSX = require('import-jsx') | ||
const Base = importJSX('../base') | ||
const Footer = importJSX('./footer.js') | ||
const Log = importJSX('./log.js') | ||
const Summary = importJSX('./summary.js') | ||
const chalk = require('chalk') | ||
|
||
const symbols = { | ||
ok: '✓', | ||
err: '✖', | ||
} | ||
|
||
const yaml = require('tap-yaml') | ||
|
||
const getSymbol = r => | ||
r.ok ? chalk.green(symbols.ok) | ||
: chalk.red(symbols.err) | ||
|
||
class Specy extends Base { | ||
tapResume () {} | ||
|
||
constructor ({tap}) { | ||
super({tap}) | ||
this.lastThing = null | ||
this.tap = tap | ||
} | ||
|
||
componentWillMount () { | ||
const tap = this.tap | ||
const onAssert = p => r => { | ||
const c = p.lastChild | ||
p.lastChild = null | ||
if (c && r.name === c.name) | ||
return | ||
|
||
const ind = new Array(p.level + 2).join(' ') | ||
const raw = ind + getSymbol(r) + | ||
' ' + | ||
r.name + ( | ||
r.diag ? '\n' + yaml.stringify(r.diag).replace(/^/gm, ind) : '') | ||
|
||
this.lastThing = 'assert' | ||
this.setState(prevState => ({ | ||
...prevState, | ||
log: prevState.log.concat({raw}), | ||
})) | ||
} | ||
const onParser = p => { | ||
if (p.parent) | ||
p.parent.lastChild = p | ||
p.on('child', onParser) | ||
p.on('assert', onAssert(p)) | ||
const raw = (this.lastThing === 'assert' ? '\n' : '') | ||
+ new Array(p.level + 1).join(' ') + p.name | ||
this.lastThing = 'suite' | ||
this.setState(prevState => ({ | ||
...prevState, | ||
log: prevState.log.concat({raw}), | ||
})) | ||
} | ||
onParser(tap.parser) | ||
tap.resume() | ||
} | ||
|
||
get Log () { | ||
return Log | ||
} | ||
get Footer () { | ||
return Footer | ||
} | ||
get Summary () { | ||
return Summary | ||
} | ||
} | ||
|
||
module.exports = Specy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
const importJSX = require('import-jsx') | ||
const React = require('react') | ||
const Report = importJSX('./index.js') | ||
const t = require('tap') | ||
const {Test} = t | ||
const {render, cleanup} = require('ink-testing-library') | ||
|
||
let tickCount = 1 | ||
Date.now = () => 1000 * tickCount | ||
const tick = () => tickCount += 1 | ||
|
||
t.test('mostly good test run', async t => { | ||
const tap = new Test({ name: 'TAP', jobs: 4, bail: false }) | ||
const r = render(<Report tap={tap} />) | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
const tests = [] | ||
tap.test('zro', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('one', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('two', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('tre', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('for', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('fiv', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('six', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('svn', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('eit', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('nin', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
tap.test('ten', t => tests.push(t)) | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
|
||
tests[0].fail('this is a failure') | ||
tests[1].pass('give this one a pass') | ||
tests[2].pass('give this two a pass') | ||
tests[3].pass('give this tre a pass') | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
// bump the time by a second | ||
tick() | ||
|
||
tests[0].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
|
||
tests[1].pass('give this one a pass') | ||
tests[2].pass('give this two a pass') | ||
tests[3].pass('give this tre a pass') | ||
|
||
tests[1].pass('give this one a pass') | ||
tests[2].pass('give this two a pass') | ||
tests[3].pass('give this tre a pass') | ||
|
||
// bump the time by a second | ||
tick() | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
tests[2].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
tests[1].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
|
||
const opt = {} | ||
tests[4].emit('preprocess', opt) | ||
t.match(opt, { stdio: 'pipe' }) | ||
|
||
const Minipass = require('minipass') | ||
const stderr = new Minipass() | ||
tests[4].emit('process', {stderr}) | ||
stderr.write('this is some raw 2> stuff') | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
tests[3].fail('do this later', { todo: 'at another time' }) | ||
tests[4].options.skip = 'skip this whole thing for now' | ||
tests[4].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
|
||
tests[5].parser.write('this is definitely not tap\n') | ||
tests[5].fail('hop over it', { skip: true }) | ||
tests[5].test('no function, just a todo') | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
tests.forEach(t => t.results || t.pass('still ok')) | ||
tests.forEach(t => t.results || t.end()) | ||
|
||
tests[8].fail('fail but will be todo somehow') | ||
tests[8].options.todo = true | ||
tests[8].end() | ||
|
||
tests[9].pass('this is fine') | ||
tests[9].options.todo = true | ||
|
||
t.matchSnapshot(r.lastFrame()) | ||
t.matchSnapshot(tests.map(t => t.name), 'current tests') | ||
|
||
tap.end() | ||
|
||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
tests.forEach(t => t.results || t.end()) | ||
|
||
t.matchSnapshot(r.lastFrame()) | ||
|
||
t.end() | ||
cleanup() | ||
}) | ||
|
||
t.test('bailout run', async t => { | ||
const tap = new Test({ jobs: 4, name: 'TAP bailer', bail: true }) | ||
|
||
const r = render(<Report tap={tap} />) | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
const tests = [] | ||
tap.test('zro', { bail: true }, t => tests.push(t)) | ||
tap.test('one', { bail: true }, t => tests.push(t)) | ||
tap.test('two', { bail: true }, t => tests.push(t)) | ||
tap.test('tre', { bail: true }, t => tests.push(t)) | ||
tap.test('for', { bail: true }, t => tests.push(t)) | ||
tap.test('fiv', { bail: true }, t => tests.push(t)) | ||
|
||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
// let the counter bouncer bounce | ||
await new Promise(r => setTimeout(r, 200)) | ||
|
||
// bump the time by a second | ||
tick() | ||
t.matchSnapshot(r.lastFrame()) | ||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
await new Promise(r => setTimeout(r, 200)) | ||
tests[2].end() | ||
tests[3].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
tests[0].end() | ||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
await new Promise(r => setTimeout(r, 200)) | ||
|
||
tests[1].fail('not fine') | ||
tests[4].fail('ton enif') | ||
tests[4].end() | ||
|
||
// subsequent bailout does nothing | ||
tap.emit('bailout', 'this should not be shown') | ||
|
||
t.matchSnapshot(r.lastFrame()) | ||
|
||
t.end() | ||
cleanup() | ||
}) | ||
|
||
t.test('weird root bailout', async t => { | ||
const tap = new Test({ jobs: 4, name: 'TAP bailer' }) | ||
|
||
const r = render(<Report tap={tap} />) | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
const tests = [] | ||
tap.test('zro', { bail: false }, t => tests.push(t)) | ||
tap.test('one', { bail: false }, t => tests.push(t)) | ||
tap.test('two', { bail: false }, t => tests.push(t)) | ||
tap.test('tre', { bail: false }, t => tests.push(t)) | ||
tap.test('for', { bail: false }, t => tests.push(t)) | ||
tap.test('fiv', { bail: false }, t => tests.push(t)) | ||
tap.test('six', { bail: false }, t => tests.push(t)) | ||
tap.test('svn', { bail: false }, t => tests.push(t)) | ||
tap.test('eit', { bail: false }, t => tests.push(t)) | ||
tap.test('nin', { bail: false }, t => tests.push(t)) | ||
|
||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
// let the counter bouncer bounce | ||
await new Promise(r => setTimeout(r, 200)) | ||
|
||
// bump the time by a second | ||
tick() | ||
t.matchSnapshot(r.lastFrame()) | ||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
await new Promise(r => setTimeout(r, 200)) | ||
tests[2].end() | ||
tests[3].end() | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
tests[0].end() | ||
tests.forEach(t => t.results || t.pass('this is fine')) | ||
await new Promise(r => setTimeout(r, 200)) | ||
|
||
tests[1].fail('not fine') | ||
tap.bailout('not fine') | ||
tests[4].fail('ton enif') | ||
tests[4].end() | ||
|
||
// subsequent bailout does nothing | ||
tap.emit('bailout', 'this should not be shown') | ||
|
||
t.matchSnapshot(r.lastFrame()) | ||
|
||
t.end() | ||
cleanup() | ||
}) | ||
|
||
t.test('one at a time', async t => { | ||
const tap = new Test({ jobs: 1 }) | ||
|
||
const r = render(<Report tap={tap} />) | ||
t.matchSnapshot(r.lastFrame()) | ||
|
||
const tests = [] | ||
tap.test('zro', { buffered: false }, t => tests.push(t)) | ||
tap.test('one', { buffered: false }, t => tests.push(t)) | ||
tap.test('two', { buffered: false }, t => tests.push(t)) | ||
tap.test('tre', { buffered: false }, t => tests.push(t)) | ||
tap.test('for', { buffered: false }, t => tests.push(t)) | ||
tap.test('fiv', { buffered: false }, t => tests.push(t)) | ||
tap.end() | ||
|
||
for (let i = 1; !tap.results; i++) { | ||
// bump the time by a second | ||
tick() | ||
tests.forEach(t => t.results || t.pass('pass '+i)) | ||
await new Promise(r => setTimeout(r, 200)) | ||
t.matchSnapshot(r.lastFrame()) | ||
// bump the time by a second | ||
tick() | ||
tests.forEach(t => t.results || t.end()) | ||
t.matchSnapshot(r.lastFrame()) | ||
} | ||
|
||
t.end() | ||
cleanup() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const React = require('react') | ||
const importJSX = require('import-jsx') | ||
const {Static} = require('ink') | ||
const {Result} = importJSX('../base') | ||
|
||
module.exports = ({log}) => ( | ||
<Static>{ | ||
log.filter(result => result.hasOwnProperty('raw')) | ||
.map((result, i) => (<Result {...result} key={`${i}`} /> )) | ||
}</Static> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const importJSX = require('import-jsx') | ||
const React = require('react') | ||
const Log = importJSX('./log.js') | ||
const t = require('tap') | ||
const {render} = require('ink-testing-library') | ||
|
||
const r = render(<Log log={[ | ||
{raw: 'hello'}, | ||
{result: {ok: true, name: 'this is fine', testName: 'foo'}}, | ||
{result: {ok: false, name: 'not fine', testName: 'bar'}}, | ||
]} />) | ||
|
||
t.matchSnapshot(r.lastFrame()) |
Oops, something went wrong.