@northscaler/better-enum
Version:
Better enumeration support for TypeScript than its `enum` keyword. This class is modeled after [Java's enumeration pattern](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html), where enums are instances of classes. This library provides a base
131 lines (116 loc) • 4.76 kB
text/typescript
import * as chai from 'chai'
import Bool from './Bool'
import { Enumeration, sortByName, sortByOrdinal } from '../../main'
import {
DuplicateEnumerationDeclarationError,
InvalidEnumerationNameError,
InvalidEnumerationOrdinalError,
UnidentifiableEnumerationValueError,
} from '../../main/errors'
import HelloWorld from './HelloWorld'
import Planet from './Planet'
const expect = chai.expect
describe('unit tests of Enumeration', function () {
it('should work normally with hello world', () => {
expect(HelloWorld.of('HELLO')).to.equal(HelloWorld.HELLO)
expect(HelloWorld.of('WORLD')).to.equal(HelloWorld.WORLD)
expect(HelloWorld.of(0)).to.equal(HelloWorld.HELLO)
expect(HelloWorld.of(1)).to.equal(HelloWorld.WORLD)
expect(HelloWorld.of(HelloWorld.WORLD)).to.equal(HelloWorld.WORLD)
expect(HelloWorld.of(HelloWorld.HELLO)).to.equal(HelloWorld.HELLO)
expect(`${HelloWorld.WORLD}`).to.equal('WORLD')
expect(HelloWorld.WORLD.toFullyQualifiedString()).to.equal(
'HelloWorld:WORLD:1'
)
expect(
HelloWorld.WORLD.equals({
constructor: { name: 'HelloWorld' },
name: () => 'WORLD',
ordinal: () => 1,
} as HelloWorld)
).to.be.true
expect(() => HelloWorld.of('')).to.throw(
UnidentifiableEnumerationValueError
)
expect(() => HelloWorld.of(-42)).to.throw(
UnidentifiableEnumerationValueError
)
expect(JSON.stringify(Bool.TRUE)).to.equal('"TRUE"')
expect(JSON.stringify(Bool.values().sort(sortByName))).to.equal(
'["FALSE","NEITHER","TRUE"]'
)
expect(JSON.stringify(Bool.values().sort(sortByOrdinal))).to.deep.equal(
'["NEITHER","FALSE","TRUE"]'
)
})
it('should work normally', () => {
expect(Bool.of('FALSE')).to.equal(Bool.FALSE)
expect(Bool.of('TRUE')).to.equal(Bool.TRUE)
expect(Bool.of(0)).to.equal(Bool.FALSE)
expect(Bool.of(1)).to.equal(Bool.TRUE)
expect(Bool.of(Bool.TRUE)).to.equal(Bool.TRUE)
expect(Bool.of(Bool.FALSE)).to.equal(Bool.FALSE)
expect(`${Bool.TRUE}`).to.equal('TRUE')
expect(Bool.TRUE.toFullyQualifiedString()).to.equal('Bool:TRUE:1')
expect(
Bool.TRUE.equals({
constructor: { name: 'Bool' },
name: () => 'TRUE',
ordinal: () => 1,
} as Bool)
).to.be.true
expect(Bool.TRUE.definite).to.be.true
expect(Bool.FALSE.definite).to.be.true
expect(Bool.NEITHER.definite).to.be.false
expect(() => Bool.of('')).to.throw(UnidentifiableEnumerationValueError)
expect(() => Bool.of(2)).to.throw(UnidentifiableEnumerationValueError)
expect(Bool.TRUE.toBoolean()).to.be.true
expect(Bool.FALSE.toBoolean()).to.be.false
expect(() => Bool.NEITHER.toBoolean()).to.throw()
})
it('should prevent incorrect enumerations', function () {
expect(() => {
class BoolWithDupOrdinal extends Enumeration<BoolWithDupOrdinal> {
static readonly F = new BoolWithDupOrdinal('FALSE', 0)
static readonly T = new BoolWithDupOrdinal('TRUE', 0) // dup ordinal
private constructor(_name: string, _ordinal: number) {
super(_name, _ordinal, BoolWithDupOrdinal)
}
}
}).to.throw(DuplicateEnumerationDeclarationError)
expect(() => {
class BoolWithDupName extends Enumeration<BoolWithDupName> {
static readonly F = new BoolWithDupName('FALSE', 0)
static readonly T = new BoolWithDupName('FALSE', 1) // dup name
private constructor(_name: string, _ordinal: number) {
super(_name, _ordinal, BoolWithDupName)
}
}
}).to.throw(DuplicateEnumerationDeclarationError)
expect(() => {
class BoolWithFloatOrdinal extends Enumeration<BoolWithFloatOrdinal> {
static readonly F = new BoolWithFloatOrdinal('FALSE', 0)
static readonly T = new BoolWithFloatOrdinal('TRUE', 0.1) // float ordinal
private constructor(_name: string, _ordinal: number) {
super(_name, _ordinal, BoolWithFloatOrdinal)
}
}
}).to.throw(InvalidEnumerationOrdinalError)
expect(() => {
class BoolWithInvalidName extends Enumeration<BoolWithInvalidName> {
static readonly F = new BoolWithInvalidName('FALSE', 0)
static readonly T = new BoolWithInvalidName('1T', 1) // invalid name
private constructor(_name: string, _ordinal: number) {
super(_name, _ordinal, BoolWithInvalidName)
}
}
}).to.throw(InvalidEnumerationNameError)
})
it('should work with Planet', function () {
const earthWeight = 175 // kg
const mass = earthWeight / Planet.EARTH.surfaceGravity
for (const p of Planet.values().sort(sortByOrdinal)) {
console.log(`Your weight on ${p} is ${p.surfaceWeight(mass)}`)
}
})
})