test: add rune-like, restriction, and alternative

This commit is contained in:
Ricardo Arturo Cabral Mejia
2022-08-29 03:44:15 +00:00
parent 0fa6bc7d83
commit 814b489f91
7 changed files with 391 additions and 90 deletions

View File

@@ -1,7 +1,7 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { Alternative } from '../../../src/utils/runes'
import { Alternative } from '../../../../src/utils/runes/alternative'
describe('Alternative', () => {
describe('constructor', () => {

View File

@@ -0,0 +1,132 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { Alternative } from '../../../../src/utils/runes/alternative'
import { Restriction } from '../../../../src/utils/runes/restriction'
describe('Restriction', () => {
describe('constructor', () => {
it('throws if given alternatives list is empty', () => {
expect(() => new Restriction([])).to.throw(Error, 'Restriction must have some alternatives')
})
})
describe('test', () => {
it('returns undefined given 1 true alternative', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns(undefined) },
] as any
expect(new Restriction(alternatives).test(values)).to.be.undefined
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
})
it('returns undefined given 2 true alternative', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns(undefined) },
{ test: sinon.fake.returns(undefined) },
] as any
expect(new Restriction(alternatives).test(values)).to.be.undefined
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
expect(alternatives[1].test).not.to.have.been.called
})
it('returns undefined given 1 true and 1 false alternative', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns(undefined) },
{ test: sinon.fake.returns('reason') },
] as any
expect(new Restriction(alternatives).test(values)).to.be.undefined
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
expect(alternatives[1].test).not.to.have.been.called
})
it('returns reason given 1 false alternative', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns('reason') },
] as any
expect(new Restriction(alternatives).test(values)).to.equal('reason')
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
})
it('returns undefined given 1 false and 1 true alternative', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns('reason') },
{ test: sinon.fake.returns(undefined) },
] as any
expect(new Restriction(alternatives).test(values)).to.be.undefined
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
expect(alternatives[1].test).to.have.been.calledOnceWithExactly(values)
})
it('returns reasons given 2 false alternatives', () => {
const values = { a: 1 }
const alternatives: Alternative[] = [
{ test: sinon.fake.returns('reason 1') },
{ test: sinon.fake.returns('reason 2') },
] as any
expect(new Restriction(alternatives).test(values)).to.equal('reason 1 AND reason 2')
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
expect(alternatives[1].test).to.have.been.calledOnceWithExactly(values)
})
})
describe('encode', () => {
it('returns encoded restriction with 1 alternative', () => {
const alternatives: Alternative[] = [
{ encode: sinon.fake.returns('a=1') },
] as any
expect(new Restriction(alternatives).encode()).to.equal('a=1')
})
it('returns encoded restrictions with 2 alternatives', () => {
const alternatives: Alternative[] = [
{ encode: sinon.fake.returns('a=1') },
{ encode: sinon.fake.returns('b=2') },
] as any
expect(new Restriction(alternatives).encode()).to.equal('a=1|b=2')
})
})
describe('decode', () => {
it('returns encoded restriction given 1 alternative', () => {
const [restriction, remainder] = Restriction.decode('a=1')
expect(restriction.encode()).to.equal('a=1')
expect(remainder).to.be.empty
})
it('returns encoded restriction given 2 alternatives', () => {
const [restriction, remainder] = Restriction.decode('a=1|b=2')
expect(restriction.encode()).to.equal('a=1|b=2')
expect(remainder).to.be.empty
})
it('returns encoded restriction given 2 alternatives and another restriction', () => {
const [restriction, remainder] = Restriction.decode('a=1|b=2&c=1')
expect(restriction.encode()).to.equal('a=1|b=2')
expect(remainder).to.equal('c=1')
})
})
})

View File

@@ -0,0 +1,173 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { Alternative } from '../../../../src/utils/runes/alternative'
import { Restriction } from '../../../../src/utils/runes/restriction'
import { RuneLike } from '../../../../src/utils/runes/rune-like'
describe('RuneLike', () => {
describe('test', () => {
it('returns true if 1 restriction is true', () => {
const values = { a: 1 }
const restrictions: Restriction[] = [
{ test: sinon.fake.returns(undefined) } as any,
]
expect(new RuneLike(restrictions).test(values)).to.deep.equal([true, ''])
expect(restrictions[0].test).to.have.been.calledOnceWithExactly(values)
})
it('returns false and reason if 1 restriction is false', () => {
const values = { a: 1 }
const restrictions: Restriction[] = [
{ test: sinon.fake.returns('reason') } as any,
]
expect(new RuneLike(restrictions).test(values)).to.deep.equal([false, 'reason'])
expect(restrictions[0].test).to.have.been.calledOnceWithExactly(values)
})
it('returns false if 1 restriction is true and 1 is false', () => {
const values = { a: 1 }
const restrictions: Restriction[] = [
{ test: sinon.fake.returns(undefined) } as any,
{ test: sinon.fake.returns('reason 2') } as any,
]
expect(new RuneLike(restrictions).test(values)).to.deep.equal([false, 'reason 2'])
expect(restrictions[0].test).to.have.been.calledOnceWithExactly(values)
expect(restrictions[1].test).to.have.been.calledOnceWithExactly(values)
})
it('returns false if 1 restriction is false and 1 is true', () => {
const values = { a: 1 }
const restrictions: Restriction[] = [
{ test: sinon.fake.returns('reason 1') } as any,
{ test: sinon.fake.returns(undefined) } as any,
]
expect(new RuneLike(restrictions).test(values)).to.deep.equal([false, 'reason 1'])
expect(restrictions[0].test).to.have.been.calledOnceWithExactly(values)
expect(restrictions[1].test).not.to.have.been.called
})
it('returns false if 2 restrictions are false', () => {
const values = { a: 1 }
const restrictions: Restriction[] = [
{ test: sinon.fake.returns('reason 1') } as any,
{ test: sinon.fake.returns('reason 2') } as any,
]
expect(new RuneLike(restrictions).test(values)).to.deep.equal([false, 'reason 1'])
expect(restrictions[0].test).to.have.been.calledOnceWithExactly(values)
expect(restrictions[1].test).not.to.have.been.called
})
})
describe('encode', () => {
it('encodes 1 restriction', () => {
const restrictions: Restriction[] = [
{ encode: sinon.fake.returns('a=1') },
] as any
expect(new RuneLike(restrictions).encode()).to.equal('a=1')
})
it('encodes 2 restrictions', () => {
const restrictions: Restriction[] = [
{ encode: sinon.fake.returns('a=1') },
{ encode: sinon.fake.returns('b=2') },
] as any
expect(new RuneLike(restrictions).encode()).to.equal('a=1&b=2')
})
})
describe('from', () => {
let restrictionDecodeStub: sinon.SinonStub
beforeEach(() => {
restrictionDecodeStub = sinon.stub(Restriction, 'decode')
})
afterEach(() => {
restrictionDecodeStub.restore()
})
it('returns rune-like given restrictions a=1', () => {
restrictionDecodeStub.withArgs('a=1').returns([
new Restriction([
new Alternative('a', '=', '1'),
]),
'',
])
const runeLike = RuneLike.from('a=1')
expect(runeLike).to.be.an.instanceOf(RuneLike)
expect(restrictionDecodeStub.firstCall).to.have.been.calledWithExactly('a=1')
expect(runeLike.encode()).to.equal('a=1')
})
it('returns rune-like given restrictions a=1|b=2', () => {
restrictionDecodeStub.withArgs('a=1|b=2').returns([
new Restriction([
new Alternative('a', '=', '1'),
new Alternative('b', '=', '2'),
]),
'',
])
const runeLike = RuneLike.from('a=1|b=2')
expect(runeLike).to.be.an.instanceOf(RuneLike)
expect(restrictionDecodeStub.firstCall).to.have.been.calledWithExactly('a=1|b=2')
expect(runeLike.encode()).to.equal('a=1|b=2')
})
it('returns rune-like given restrictions a=1|b=2&c=3', () => {
restrictionDecodeStub.withArgs('a=1|b=2&c=3').returns([
new Restriction([
new Alternative('a', '=', '1'),
new Alternative('b', '=', '2'),
]),
'&c=3',
])
restrictionDecodeStub.withArgs('&c=3').returns([
new Restriction([
new Alternative('c', '=', '3'),
]),
'',
])
const runeLike = RuneLike.from('a=1|b=2&c=3')
expect(runeLike).to.be.an.instanceOf(RuneLike)
expect(restrictionDecodeStub.firstCall).to.have.been.calledWithExactly('a=1|b=2&c=3')
expect(restrictionDecodeStub.secondCall).to.have.been.calledWithExactly('&c=3')
expect(runeLike.encode()).to.equal('a=1|b=2&c=3')
})
it('returns rune-like given restrictions with spaces a = 1 | b = 2 & c = 3', () => {
restrictionDecodeStub.withArgs('a=1|b=2&c=3').returns([
new Restriction([
new Alternative('a', '=', '1'),
new Alternative('b', '=', '2'),
]),
'&c=3',
])
restrictionDecodeStub.withArgs('&c=3').returns([
new Restriction([
new Alternative('c', '=', '3'),
]),
'',
])
const runeLike = RuneLike.from('a = 1 | b = 2 & c = 3')
expect(runeLike).to.be.an.instanceOf(RuneLike)
expect(restrictionDecodeStub.firstCall).to.have.been.calledWithExactly('a=1|b=2&c=3')
expect(restrictionDecodeStub.secondCall).to.have.been.calledWithExactly('&c=3')
expect(runeLike.encode()).to.equal('a=1|b=2&c=3')
})
})
})