UNPKG

@herbsjs/aloe

Version:

Scenario description and test runner for Herbs

456 lines (397 loc) 16.9 kB
const { scenario } = require('../src/scenario') const assert = require('assert') const { given } = require('../src/given') const { when } = require('../src/when') const { check } = require('../src/check') const { samples } = require('../src/samples') const { state } = require('../src/runningState') const { Err } = require('@herbsjs/buchu') describe('A scenario', () => { context('before run', () => { const givenTheSimplestScenario = () => { const instance = scenario({ info: 'A simple scenario', 'A Sample data': samples([ { x: 1 }, { x: 2 }, ]), 'Given a input': given(() => ({ user: 'a', })), 'Given another input': given(() => ({ customer: 'x', project: 'w', })), 'When running': when((ctx) => { ctx.user = 'b' }), 'Check output': check((ctx) => { assert.ok(ctx.user === 'b') }), 'Check another output': check((ctx) => { assert.ok(ctx.customer === 'x') }), }) return instance } it('should validate its structure') it('should document its structure', async () => { //given const factory = givenTheSimplestScenario() const instance = factory.create('A "Scenario" description') //when const ret = await instance.doc() //then assert.deepStrictEqual( ret, { type: 'scenario', description: 'A "Scenario" description', info: 'A simple scenario', samples: [ { type: 'samples', description: 'A Sample data', value: [{ x: 1 }, { x: 2 }], isFunction: false }, ], givens: [ { type: 'given', description: 'Given a input', value: { user: 'a' }, isFunction: true }, { type: 'given', description: 'Given another input', value: { customer: 'x', project: 'w' }, isFunction: true } ], whens: [{ type: 'when', description: 'When running' }], checks: [ { type: 'check', description: 'Check output' }, { type: 'check', description: 'Check another output' } ] }, ) }) }) context('passing', () => { const givenTheSimplestScenario = () => { return scenario({ info: 'A simple scenario', 'Given a input': given(() => ({ user: 'a', })), 'Given another input': given(() => ({ customer: 'x', project: 'w', })), 'When running': when((ctx) => { ctx.user = 'b' }), 'Check output': check((ctx) => { assert.ok(ctx.user === 'b') }), 'Check another output': check((ctx) => { assert.ok(ctx.customer === 'x') }), }) } it('should run', async () => { //given const factory = givenTheSimplestScenario() const instance = factory.create('A scenario') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.equal(ret, state.passed) assert.strictEqual(instance.description, 'A scenario') assert.strictEqual(instance.info, 'A simple scenario') assert.strictEqual(instance.samples[0].description, '') assert.strictEqual(instance.samples[0].builtin, true) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'check') assert.strictEqual(instance.samples[0].execution.scenarios[0].state, state.passed) assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].description, 'Given a input') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[1].description, 'Given another input') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[1].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].description, 'When running') assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[0].description, 'Check output') assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[0].state, state.passed) assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[1].description, 'Check another output') assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[1].state, state.passed) }) it('should audit after run', async () => { //given const factory = givenTheSimplestScenario() const instance = factory.create('A scenario') //when const ret = await instance.run() //then assert.deepStrictEqual(instance.auditTrail, { type: "scenario", state: "passed", description: "A scenario", samples: [{ builtin: true, executions: [{ sample: {}, state: "passed", stage: "check", givens: [ { type: "given", state: "done", description: "Given a input" }, { type: "given", state: "done", description: "Given another input" }], whens: [ { type: "when", state: "done", description: "When running" }], checks: [ { type: "check", state: "passed", description: "Check output" }, { type: "check", state: "passed", description: "Check another output" }] }] }] }) }) it('should not be allow to run more than once') }) context('falling', () => { const givenTheSimplestScenario = () => { return scenario({ info: 'A simple scenario', 'Given a input': given(() => ({ user: 'a', })), 'Given another input': given(() => ({ customer: 'x', project: 'w', })), 'When running': when((ctx) => { ctx.user = 'b' }), 'Check output': check((ctx) => { assert.ok(ctx.user === 'a') }), 'Check another output': check((ctx) => { assert.ok(ctx.customer === 'z') }), }) } it('should run', async () => { //given const factory = givenTheSimplestScenario() const instance = factory.create('A failed scenario') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.equal(ret, state.failed) assert.strictEqual(instance.description, 'A failed scenario') assert.strictEqual(instance.info, 'A simple scenario') assert.strictEqual(instance.samples[0].description, '') assert.strictEqual(instance.samples[0].builtin, true) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'check') assert.strictEqual(instance.samples[0].execution.scenarios[0].state, state.failed) assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].description, 'Given a input') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[1].description, 'Given another input') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[1].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].description, 'When running') assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[0].description, 'Check output') assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[0].state, state.failed) assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[1].description, 'Check another output') assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[1].state, state.failed) }) it('should audit after run', async () => { //given const factory = givenTheSimplestScenario() const instance = factory.create('A failed scenario') //when const ret = await instance.run() //then assert.strictEqual(instance.auditTrail.state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[0].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[0].error.message, `The expression evaluated to a falsy value:\n\n assert.ok(ctx.user === 'a')\n`) assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[1].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[1].error.message, `The expression evaluated to a falsy value:\n\n assert.ok(ctx.customer === 'z')\n`) }) it('should not be allow to run more than once') }) context('with exceptions', () => { context('on Given', () => { const givenAScenarioWithException = () => { return scenario({ 'Given a input': given(() => { throw Error('A given error') }), 'When running': when(() => { }), 'Check output': check(() => { }) }) } it('should run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.strictEqual(ret, state.failed) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'given') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].state, state.failed) }) it('should audit after run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then assert.strictEqual(instance.auditTrail.samples[0].executions[0].givens[0].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].givens[0].error.message, `A given error`) }) }) context('on When', () => { const givenAScenarioWithException = () => { return scenario({ 'Given a input': given(() => { }), 'When running': when(() => { throw Error(`A whens error`) }), 'Check output': check(() => { }) }) } it('should run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.strictEqual(ret, state.failed) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'when') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].state, state.failed) }) it('should audit after run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then assert.strictEqual(instance.auditTrail.samples[0].executions[0].whens[0].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].whens[0].error.message, `A whens error`) }) }) context('on Check', () => { const givenAScenarioWithException = () => { return scenario({ 'Given a input': given(() => { }), 'When running': when(() => { }), 'Check output': check(() => { throw Error(`A check error`) }) }) } it('should run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.strictEqual(ret, state.failed) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'check') assert.strictEqual(instance.samples[0].execution.scenarios[0].givens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].whens[0].state, state.done) assert.strictEqual(instance.samples[0].execution.scenarios[0].checks[0].state, state.failed) }) it('should audit after run', async () => { //given const factory = givenAScenarioWithException() const instance = factory.create('A scenario with exception') //when const ret = await instance.run() //then assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[0].state, state.failed) assert.strictEqual(instance.auditTrail.samples[0].executions[0].checks[0].error.message, `A check error`) }) }) }) context('with samples', () => { const givenTheScenarioWithSamples = () => { return scenario({ 'Sample1': samples([ { x: 1, y: 1, result: 2 }, { x: 2, y: 2, result: 4 }, ]), 'Sample2': samples(() => [ { x: 3, y: 3, result: 6 }, { x: 7, y: 7, result: 14 }, ]), 'Given a input': given((ctx) => ({ x: ctx.sample.x, y: ctx.sample.y, })), 'When running': when((ctx) => { ctx.ret = ctx.x + ctx.y }), 'Check output': check((ctx) => { assert.ok(ctx.ret === ctx.sample.result) }), }) } it('should run', async () => { //given const factory = givenTheScenarioWithSamples() const instance = factory.create('A scenario') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.equal(ret, state.passed) assert.strictEqual(instance.samples.length, 2) assert.strictEqual(instance.samples[0].state, state.done) for (const s of [0, 1]) { assert.strictEqual(instance.samples[s].description, `Sample${s + 1}`) for (const sc of [0, 1]) { assert.strictEqual(instance.samples[s].execution.scenarios[sc].stage, 'check') assert.strictEqual(instance.samples[s].execution.scenarios[sc].state, state.passed) assert.strictEqual(instance.samples[s].execution.scenarios[sc].givens[0].state, state.done) assert.strictEqual(instance.samples[s].execution.scenarios[sc].whens[0].state, state.done) assert.strictEqual(instance.samples[s].execution.scenarios[sc].checks[0].state, state.passed) } } }) }) context('with only', () => { const givenTheScenarioWithOnly = () => { return scenario.only({ 'Given a input': given(() => { }), 'When running': when(() => { }), 'Check output': check(() => { }), }) } it('should run', async () => { //given const factory = givenTheScenarioWithOnly() const instance = factory.create('A scenario') //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.equal(ret, state.passed) assert.strictEqual(instance.description, 'A scenario') assert.strictEqual(instance.samples[0].description, '') assert.strictEqual(instance.samples[0].builtin, true) assert.strictEqual(instance.samples[0].execution.scenarios[0].stage, 'check') }) }) context('with ignore flag', () => { const givenTheScenarioWithIgnore = () => { return scenario({ 'Given a input': given(() => { }), 'When running': when(() => { }), 'Check output': check(() => { }), }) } it('should run', async () => { //given const factory = givenTheScenarioWithIgnore() const instance = factory.create('A scenario') instance.ignore = true //when const ret = await instance.run() //then // - firts, it should not throw a exception, then: assert.equal(ret, state.ignored) assert.strictEqual(instance.description, 'A scenario') assert.strictEqual(instance.samples[0].description, '') assert.strictEqual(instance.samples[0].builtin, true) assert.strictEqual(instance.samples[0].state, state.ready) }) }) })