Skip to content

Instantly share code, notes, and snippets.

@FukKwang
Created May 4, 2020 11:30
Show Gist options
  • Save FukKwang/67f03cf5ac0d99e917b786fd9730f0c5 to your computer and use it in GitHub Desktop.
Save FukKwang/67f03cf5ac0d99e917b786fd9730f0c5 to your computer and use it in GitHub Desktop.
Table driven test in javascript
const magicClient = require('./client'); // To get the magic from the universe
const spellRepository = required('./repository'); // List of speel that can be executed
const errors = require('./errors'); // List of error
/**
*
* @param command object
* @param command.spell string
* @param command.target string
* @param who string
*/
async function doSomeMagic(command, who) {
if (!command) {
throw new errors.BadRequest('no command was found');
}
if (!who) {
throw new errors.BadRequest('we don\'t know who cast the spell');
}
const {
spell,
target,
} = command;
if (target === who) {
throw new errors.InvalidRequest('can\'t cass spell to your self');
}
const knownSpell = await spellRepository.getSpell(spell);
if (!knownSpell) {
throw new errors.NotFound('sorry mate don\' know this spell');
}
if (knownSpell.notAllowedTarget.has(target)) {
throw new errors.NotAllowed(`Please don't cast spell to ${target}, have mercy`);
}
const yourMagic = await magicClient.getAvailableMagic(who);
if (!yourMagic || !yourMagic.magic) {
throw new errors.NotFound('your magic wasnot found !!');
}
if (!yourMagic.enabled || yourMagic.isSealed) {
throw new errors.NotAllowed('it seems your magic was not enabled or sealed');
}
if (spell.magic > yourMagic.magic) {
throw new errors.BadRequest(`Your magic ${yourMagic.magic} was not enough to cast this spell (${spell.magic})`);
}
const shoot = await magicClient.fireSpell(knownSpell);
if (shoot.fail) {
throw new errors.InternalError(`something wrong with the flow of magic, err: ${shoot.err}`);
}
return shoot;
}
module.exports = {
doSomeMagic,
};
const sinon = require('sinon');
const chai = require('chai');
const magicClient = require('./client');
const spellRepository = required('./repository');
const errors = require('./errors');
const magic = require('./magic');
chai.use(require('chai-as-promised'));
const { expect } = chai;
describe('magic, () => {
describe('doSomeMagic', () => {
beforeEach(() => {
this.sandbox = sinon.createSandbox();
this.getSpell = this.sandbox.stub(spellRepository, 'getSpell');
this.getAvailableMagic = this.sandbox.stub(magicClient, 'getAvailableMagic');
this.fireSpell = this.sandbox.stub(magicClient, 'fireSpell');
});
afterEach(() => {
this.sandbox.restore();
});
it('no commmand was found', async () => {
await expect(magic.doSomeMagic(
null, 'test',
)).to.be.rejectedWith(errors.BadRequest);
});
it('no who was found', async () => {
await expect(magic.doSomeMagic(
{}, null,
)).to.be.rejectedWith(errors.BadRequest);
});
it('target equal to who', async () => {
await expect(magic.doSomeMagic(
{ target: 'test' }, 'test',
)).to.be.rejectedWith(errors.InvalidRequest);
});
it('no know spell was found', async () => {
this.getSpell.returns(null);
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotFound);
});
it('not allowed target', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test'])});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotAllowed);
});
it('no magic was found', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1'])});
this.getAvailableMagic.returns(null);
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotFound);
});
it('runout magic', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1'])});
this.getAvailableMagic.returns({magic: 0});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotFound);
});
it('magic is not enabled', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1'])});
this.getAvailableMagic.returns({magic: 1, enabled: false});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotAllowed);
});
it('magic is sealed', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1'])});
this.getAvailableMagic.returns({magic: 1, enabled: true, sealed: true});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.NotAllowed);
});
it('spell magic energy is greater than available magic', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1']), magic: 5});
this.getAvailableMagic.returns({magic: 1, enabled: true, sealed: false});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.BadRequest);
});
it('shoot fail', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1']), magic: 5});
this.getAvailableMagic.returns({magic: 6, enabled: true, sealed: false});
this.fireSpell.returns({fail: true});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.rejectedWith(errors.BadRequest);
});
it('success', async () => {
this.getSpell.returns({ notAllowedTarget: new Set(['test1']), magic: 5});
this.getAvailableMagic.returns({magic: 6, enabled: true, sealed: false});
this.fireSpell.returns({fail: false});
await expect(magic.doSomeMagic(
{ spell: { magic: 1 }, target: 'test' }, 'test',
)).to.be.not.rejected;
});
});
});
const sinon = require('sinon');
const chai = require('chai');
const magicClient = require('./client');
const spellRepository = required('./repository');
const errors = require('./errors');
const magic = require('./magic');
chai.use(require('chai-as-promised'));
const { expect } = chai;
describe('magic, () => {
describe('doSomeMagic', () => {
beforeEach(() => {
this.sandbox = sinon.createSandbox();
this.getSpell = this.sandbox.stub(spellRepository, 'getSpell');
this.getAvailableMagic = this.sandbox.stub(magicClient, 'getAvailableMagic');
this.fireSpell = this.sandbox.stub(magicClient, 'fireSpell');
});
afterEach(() => {
this.sandbox.restore();
});
const tests = [
{
name: 'no commmand was found',
param: {
command: null,
who: 'test',
},
hasError: errors.BadRequest,
},
{
name: 'no who was found',
param: {
command: {},
who: null,
},
hasError: errors.BadRequest,
},
{
name: 'target equal to who',
param: {
command: { target: 'test' },
who: 'test',
},
hasError: errors.InvalidRequest,
},
{
name: 'no know spell was found',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotFound,
getSpell: null
},
{
name: 'not allowed target',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotAllowed,
getSpell: { notAllowedTarget: new Set(['test'])}
},
{
name: 'not allowed target',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotAllowed,
getSpell: { notAllowedTarget: new Set(['test'])}
},
{
name: 'no magic was found',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotFound,
getSpell: { notAllowedTarget: new Set(['test1'])},
getAvailableMagic: null,
},
{
name: 'runout magic',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotFound,
getSpell: { notAllowedTarget: new Set(['test1'])},
getAvailableMagic: {magic: 0},
},
{
name: 'magic is not enabled',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotAllowed,
getSpell: { notAllowedTarget: new Set(['test1'])},
getAvailableMagic: {magic: 1, enabled: false},
},
{
name: 'magic is sealed',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.NotAllowed,
getSpell: { notAllowedTarget: new Set(['test1'])},
getAvailableMagic: {magic: 1, enabled: true, sealed: true},
},
{
name: 'spell magic energy is greater than available magic',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.BadRequest,
getSpell: { notAllowedTarget: new Set(['test1'])},
getAvailableMagic: {magic: 1, enabled: true, sealed: false},
},
{
name: 'shoot fail',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: errors.BadRequest,
getSpell: { notAllowedTarget: new Set(['test1']), magic: 5},
getAvailableMagic: {magic: 6, enabled: true, sealed: false},
fireSpell: {fail: true},
},
{
name: 'success',
param: {
command: { spell: { magic: 1 }, target: 'test' },
who: 'test',
},
hasError: null,
getSpell: { notAllowedTarget: new Set(['test1']), magic: 5},
getAvailableMagic: {magic: 6, enabled: true, sealed: false},
fireSpell: {fail: false},
},
];
tests.forEach((test) => {
const testMethod = async () => {
this.getSpell.returns(test.getSpell);
this.getAvailableMagic.returns(test.getAvailableMagic);
this.fireSpell.returns(test.fireSpell);
const process = expect(magic.doSomeMagic(
...Object.values(test.param),
));
if (test.hasError) {
await process.to.be.rejectedWith(test.hasError);
} else {
await process.not.to.be.rejected;
};
};
if (test.focus) {
it.only(test.name, testMethod);
} else {
it(test.name, testMethod);
}
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment