Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e5fc2b4
fix(test): Rewrite run method to better handle function timeouts.. Up…
ElijahKotyluk Apr 14, 2021
3af00c5
test(snapshot): update snapshots.
ElijahKotyluk Apr 14, 2021
008ee7e
chore(merge): pull master.
ElijahKotyluk Apr 14, 2021
9e5440c
style(test): lint fix.
ElijahKotyluk Apr 14, 2021
7471f92
style(interface): remove non-null assertion.
ElijahKotyluk Apr 14, 2021
e42b184
test(suite): update snapshots.
ElijahKotyluk Apr 14, 2021
650bfe0
test(interface): fix possibly null prop.
ElijahKotyluk Apr 14, 2021
94514f4
refactor(suite): clean up suite class. Remove skip from bail test.
ElijahKotyluk Apr 14, 2021
bebf8f1
fix(test): clear timeout in wait promise chain.
ElijahKotyluk Apr 14, 2021
d9f2fb4
style(test): lint fix.
ElijahKotyluk Apr 14, 2021
e6a4ebf
test(suite): split bail tests into two, one for sequential, one for n…
ElijahKotyluk Apr 15, 2021
efa4c18
chore(suite): fix spacing.
ElijahKotyluk May 4, 2021
7175f70
Merge branch 'master' into refactor/core-v1-alpha
ElijahKotyluk May 4, 2021
bcc4f4a
test(test): clear timers at end of timeout test.
ElijahKotyluk May 22, 2021
34d860d
chore(test-spec): update comment for timeout test.
ElijahKotyluk May 22, 2021
bbfa7a0
fix(test): remove await from fn when racing promise against timeout.
ElijahKotyluk May 22, 2021
74f1c54
refactor(runnable): make runnable an abstract class, remove events an…
ElijahKotyluk May 26, 2021
6893b76
test(runnable): start testing abstract class.
ElijahKotyluk May 26, 2021
403cd68
refactor(runnable): update runnable class and tests. Update result ty…
ElijahKotyluk Jun 4, 2021
a3b3c94
refactor(runnable): make doFail always take an error.
ElijahKotyluk Jun 5, 2021
a540717
Merge branch 'master' into refactor/core-v1-alpha
ElijahKotyluk Jan 4, 2022
df63892
chore(core): misc changes.
ElijahKotyluk Jan 4, 2022
7e3b2c4
Merge branch 'refactor/core-v1-alpha' of github.com:onyxjs/onyx into …
ElijahKotyluk Jan 4, 2022
77e357c
chore(configs): update ts and jest.
ElijahKotyluk Jan 10, 2022
fb7e5a0
refactor(test): rewrite test class, runnable class, and tests. Commen…
ElijahKotyluk Jan 10, 2022
a8d7757
test(core): skip files that have not been refactored.
ElijahKotyluk Jan 10, 2022
3bb9ff9
refactor(test): rewrite test class.
ElijahKotyluk Jan 11, 2022
4eda7c3
refactor(suite): rewrite run method.
ElijahKotyluk Jan 11, 2022
097457c
chore(core): remove utils.ts and types.ts.
ElijahKotyluk Jan 11, 2022
554c493
feat(utils): add utils.
ElijahKotyluk Jan 11, 2022
844363c
feat(errors): add internal error classes.
ElijahKotyluk Jan 11, 2022
1abd6bd
feat(types): add types directory.
ElijahKotyluk Jan 11, 2022
3fbd310
chore(snapshots): remove old snapshots.
ElijahKotyluk Jan 11, 2022
384b73b
chore(core): WIP, circular dependencies from core class imports.
ElijahKotyluk Jan 11, 2022
d5fecdc
fix(suite): export isSuite and rootSymbol.
ElijahKotyluk Jan 11, 2022
0200e16
test(Test): fix should fail.
ElijahKotyluk Jan 11, 2022
6085412
feat(runnable): add isStatus method.
ElijahKotyluk Jan 11, 2022
45ec3b3
refactor(result): remove properties, update addErrors method.
ElijahKotyluk Jan 11, 2022
aeff41d
refactor(runnable): add isPending method, update concatenated return …
ElijahKotyluk Jan 12, 2022
da35643
refactor(result): make result type generic based on test type. add cr…
ElijahKotyluk Jan 12, 2022
e4e5e68
test(result): reintroduce result class tests.
ElijahKotyluk Jan 12, 2022
41e63a8
Merge branch 'master' into refactor/core-v1-alpha
ElijahKotyluk Jan 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions packages/core/src/suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ export interface SuiteStats {
}

export class BailError extends Error {
/* istanbul ignore next */
constructor(message: string) {
super(message) /* istanbul ignore next */
super(message)
this.name = 'BailError'
}
}
Expand Down Expand Up @@ -109,9 +110,7 @@ export default class Suite extends Runnable {
this.result.addMessages(...result.messages.map((m) => `${child.description}: ${m}`))
await this.invokeHook('afterEach')

if (result.status === Status.Failed) {
++this.failed
}
if (result.status === Status.Failed) ++this.failed

return result
})())
Expand All @@ -121,8 +120,8 @@ export default class Suite extends Runnable {
for (const promise of promises) {
try {
const result = await promise

if (options.bail && result !== undefined) {
if (options.bail && result) {
throw new BailError(result.messages[0])
}
} catch (error) {
Expand All @@ -135,7 +134,7 @@ export default class Suite extends Runnable {
await Promise.all(promises.map(async (promise) => {
const result = await promise

if (options && options.bail && result !== undefined) {
if (options && options.bail && result) {
throw new BailError(result.messages[0])
}
}))
Expand Down
31 changes: 13 additions & 18 deletions packages/core/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Runnable, { isRunnable, RunnableOptions, RunnableTypes } from './runnable
import { RunOptions } from './runner'
import Suite from './suite'

export type TestFn = () => (void | Promise<any>)
export type TestFn = () => (void | Promise<any>)

/**
* @description Checks if the passed `Runnable` value is a `Test` instance.
Expand Down Expand Up @@ -35,22 +35,17 @@ export default class Test extends Runnable {
this.doStart()

if (options && options.timeout) {
let timeoutID: NodeJS.Timeout
const test: Promise<void> = new Promise(async (resolve, reject) => {
timeoutID = setTimeout(() => {
reject(`${this.getFullDescription()} has timed out: ${options.timeout}ms`)
}, options.timeout as number)

try {
await this.fn()
} catch (error) {
clearTimeout(timeoutID)
reject(error)
}

clearTimeout(timeoutID)
resolve()
})
let timer: NodeJS.Timeout
const wait = (ms: number) => new Promise(resolve => {
timer = setTimeout(resolve, ms)
})
const test = Promise.race([
wait(options.timeout).then(() => {
clearTimeout(timer)
throw new Error(`${this.getFullDescription()} has timed out: ${options.timeout}ms`)
}),
this.fn()
])

try {
await test
Expand All @@ -61,7 +56,7 @@ export default class Test extends Runnable {
return this.doPass()
} else {
try {
this.fn()
await this.fn()
} catch (error) {
return this.doFail(error)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/interface.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('Interface', () => {
})

expect(suite.children[0]).toMatchSnapshot()
expect(suite.children[0].parent!.parent).toBe(root)
expect(suite.parent).toBe(root)
})

it('should create skipped tests inside of suites', () => {
Expand Down
20 changes: 10 additions & 10 deletions packages/core/test/runner.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Status } from '../src/result'
import Runnable from '../src/runnable'
import Runner, { normalizeRunOptions, RunOptions } from '../src/runner'
//import { Status } from '../src/result'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it all commented out?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am rethinking the Runner class entirely. I am aiming for generator + co-routines.

//import Runnable from '../src/runnable'
import Runner, { normalizeRunOptions, /*RunOptions*/ } from '../src/runner'
import Suite, { rootSymbol } from '../src/suite'
import Test from '../src/test'

Expand All @@ -24,7 +24,7 @@ describe('runner', () => {
})

// tslint:disable-next-line:max-classes-per-file
class TimeoutTestRunnable extends Runnable {
/*class TimeoutTestRunnable extends Runnable {
private cb: (options?: RunOptions) => void

constructor(
Expand Down Expand Up @@ -52,10 +52,10 @@ describe('runner', () => {

return this.doPass()
}
}
}*/

it('should pass run options to children', async () => {
const opts = { bail: true, timeout: 1234, sequential: true }
/*it.skip('should pass run options to children', async () => {
const opts = { bail: true, timeout: 1234, sequential: true };

const rootSuite = new Suite('root', {}, null)
const childSuite = new Suite('child', {}, null)
Expand All @@ -74,9 +74,9 @@ describe('runner', () => {

await runner.run()

expect(cb1).toHaveBeenCalledWith(undefined)
expect(cb2).toHaveBeenCalledWith(undefined)
})
expect(cb1).toHaveBeenCalledWith(opts);
expect(cb2).toHaveBeenCalledWith(opts);
}); */

it('should run a suite and children', async () => {
const rootSuite = new Suite('root', {}, null)
Expand Down
100 changes: 52 additions & 48 deletions packages/core/test/suite.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('Suite', () => {
expect(end).toHaveBeenCalledTimes(1)
})

it.skip('should bail out on first failure', async () => {
describe('should bail out on first failure', () => {
jest.useRealTimers()

const fn = () => {
Expand All @@ -99,53 +99,57 @@ describe('Suite', () => {
throw Error()
}

// Non-sequential
const parent = new Suite('parent', defaultOpts, null)
const firstFail = new Test('firstFail', errorFn, defaultOpts, null)
const firstPass = new Test('firstPass', fn, defaultOpts, null)
const secondPass = new Test('secondPass', fn, defaultOpts, null)

parent.addChildren(firstFail, firstPass, secondPass)

const parentFail = jest.fn()
parent.on('fail', parentFail)
const parentPass = jest.fn()
parent.on('pass', parentPass)
const testFail = jest.fn()
firstFail.on('fail', testFail)
const testPass = jest.fn()
firstPass.on('pass', testPass)

expect((await parent.run({ bail: true, sequential: false })).status).toBe(Status.Failed)
expect(parent.getStats().done).toBe(1)
expect(testPass).toHaveBeenCalledTimes(0)
expect(testFail).toHaveBeenCalledTimes(1)
expect(parentPass).toHaveBeenCalledTimes(0)
expect(parentFail).toHaveBeenCalledTimes(1)

// Sequential
const sequentialParent = new Suite('sequentialParent', defaultOpts, null)
const secondFail = new Test('secondFail', errorFn, defaultOpts, null)
const thirdPass = new Test('thirdPass', fn, defaultOpts, null)
const fourthPass = new Test('fourthPass', fn, defaultOpts, null)

const sequentialParentPass = jest.fn()
sequentialParent.on('pass', sequentialParentPass)
const sequentialParentFail = jest.fn()
sequentialParent.on('fail', sequentialParentFail)
const sequentialTestPass = jest.fn()
thirdPass.on('pass', sequentialTestPass)
const sequentialTestFail = jest.fn()
secondFail.on('fail', sequentialTestFail)

sequentialParent.addChildren(thirdPass, secondFail, fourthPass)

expect((await sequentialParent.run({ bail: true, sequential: true })).status).toBe(Status.Failed)
expect(sequentialParent.getStats().done).toBe(2)
expect(sequentialTestPass).toHaveBeenCalledTimes(1)
expect(sequentialTestFail).toHaveBeenCalledTimes(1)
expect(sequentialParentPass).toHaveBeenCalledTimes(0)
expect(sequentialParentFail).toHaveBeenCalledTimes(1)
it ('non-sequential', async () => {
// Non-sequential
const parent = new Suite('parent', defaultOpts, null)
const fail = new Test('firstFail', errorFn, defaultOpts, null)
const pass = new Test('firstPass', fn, defaultOpts, null)
const secondPass = new Test('secondPass', fn, defaultOpts, null)

parent.addChildren(fail, pass, secondPass)

const parentFail = jest.fn()
parent.on('fail', parentFail)
const parentPass = jest.fn()
parent.on('pass', parentPass)
const testFail = jest.fn()
fail.on('fail', testFail)
const testPass = jest.fn()
pass.on('pass', testPass)

expect((await parent.run({ bail: true, sequential: false })).status).toBe(Status.Failed)
expect(parent.getStats().done).toBe(1)
expect(testPass).toHaveBeenCalledTimes(0)
expect(testFail).toHaveBeenCalledTimes(1)
expect(parentPass).toHaveBeenCalledTimes(0)
expect(parentFail).toHaveBeenCalledTimes(1)
})

it('sequential', async () => {
// Sequential
const sequentialParent = new Suite('sequentialParent', defaultOpts, null)
const fail = new Test('fail', errorFn, defaultOpts, null)
const pass = new Test('pass', fn, defaultOpts, null)
const secondPass = new Test('secondPass', fn, defaultOpts, null)

const sequentialParentPass = jest.fn()
sequentialParent.on('pass', sequentialParentPass)
const sequentialParentFail = jest.fn()
sequentialParent.on('fail', sequentialParentFail)
const sequentialTestPass = jest.fn()
pass.on('pass', sequentialTestPass)
const sequentialTestFail = jest.fn()
fail.on('fail', sequentialTestFail)

sequentialParent.addChildren(pass, fail, secondPass)

expect((await sequentialParent.run({ bail: true, sequential: true })).status).toBe(Status.Failed)
expect(sequentialParent.getStats().done).toBe(2)
expect(sequentialTestPass).toHaveBeenCalledTimes(1)
expect(sequentialTestFail).toHaveBeenCalledTimes(1)
expect(sequentialParentPass).toHaveBeenCalledTimes(0)
expect(sequentialParentFail).toHaveBeenCalledTimes(1)
})
})

it('should skip', async () => {
Expand Down
26 changes: 14 additions & 12 deletions packages/core/test/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import Test, { isTest } from '../src/test'
describe('Test', () => {
const defaultOpts = { skip: false, todo: false }

it('should return isDone', () => {
it('should return isDone', async () => {
const fn = jest.fn()
const test = new Test('test', fn, defaultOpts, null)

expect(test.isDone()).toBeFalsy()
test.run()
await test.run()
expect(test.isDone()).toBeTruthy()
})

Expand Down Expand Up @@ -74,29 +74,31 @@ describe('Test', () => {

it('should timeout', async () => {
jest.useRealTimers()
const fn = () => {
return new Promise((resolve) => {
// Test fn should not resolve before the timeout promise
const fn = () => new Promise((resolve) => {
setTimeout(() => {
resolve('Shouldn\'t resolve')
}, 1001)
resolve('Shouldn\'t resolve first')
}, 3000)
})
}

const test = new Test('test', fn, defaultOpts, null)

const start = jest.fn()
test.on('start', start)
const fail = jest.fn()
test.on('fail', fail)
const end = jest.fn()
test.on('end', end)
const fail = jest.fn()
test.on('fail', fail)
const pass = jest.fn()
test.on('pass', pass)
const start = jest.fn()
test.on('start', start)

const result = await test.run({ timeout: 1000 })

expect(result.status).toBe('failed')
expect(result.messages[0]).toBe(`${test.description} has timed out: 1000ms`)
expect(result.messages[0]).toBe(`Error: ${test.description} has timed out: 1000ms`)
expect(start).toHaveBeenCalledTimes(1)
expect(fail).toHaveBeenCalledTimes(1)
expect(end).toHaveBeenCalledTimes(1)
expect(pass).toHaveBeenCalledTimes(0)
})
})