implementation of minimum, maximum, hasAny and hasAll for bitflags
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
import { FlagDefinition, FlagsDictionary } from '~'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { ReusedFlagAliasError, ReusedFlagValueError } from '../../src/errors'
|
||||
|
||||
class TestDefinition implements FlagDefinition<unknown, unknown> {
|
||||
private readonly _value: number
|
||||
|
||||
public constructor(value: number) {
|
||||
this._value = value
|
||||
}
|
||||
|
||||
public get values(): unknown {
|
||||
return this._value
|
||||
}
|
||||
|
||||
public hasSameValue(other: FlagDefinition<unknown, unknown>): boolean {
|
||||
return other instanceof TestDefinition && this._value === other._value
|
||||
}
|
||||
}
|
||||
|
||||
describe(FlagsDictionary, () => {
|
||||
test('define then look up', () => {
|
||||
const dict = new FlagsDictionary()
|
||||
const def = new TestDefinition(1)
|
||||
|
||||
dict.define('test', def)
|
||||
|
||||
expect(dict.findByAlias('test')).toBe(def)
|
||||
expect(dict.findByAlias('undefined')).toBe(undefined)
|
||||
})
|
||||
|
||||
test("can't use the same alias twice", () => {
|
||||
const dict = new FlagsDictionary()
|
||||
|
||||
dict.define('test', new TestDefinition(1))
|
||||
expect(() => dict.define('test', new TestDefinition(2))).toThrow(
|
||||
ReusedFlagAliasError,
|
||||
)
|
||||
})
|
||||
|
||||
test("can't use the same value twice", () => {
|
||||
const dict = new FlagsDictionary()
|
||||
|
||||
dict.define('test A', new TestDefinition(1))
|
||||
expect(() => dict.define('test B', new TestDefinition(1))).toThrow(
|
||||
ReusedFlagValueError,
|
||||
)
|
||||
})
|
||||
})
|
||||
52
node/tests/definitions/graph.test.ts
Normal file
52
node/tests/definitions/graph.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { FlagsGraph } from '~/definitions/graph'
|
||||
|
||||
describe(FlagsGraph, () => {
|
||||
test('put a definition in the graph', () => {
|
||||
const graph = new FlagsGraph<number>()
|
||||
|
||||
const A = graph.put({ alias: 'A', value: 1 })
|
||||
|
||||
expect(graph.definitions).toHaveLength(1)
|
||||
expect(graph.definitions).toContain(A)
|
||||
|
||||
expect(A.isPlaceholder).toBe(false)
|
||||
expect(A.alias).toBe('A')
|
||||
expect(A.value).toBe(1)
|
||||
})
|
||||
|
||||
test('create a definition with a reference to an existing definition', () => {
|
||||
const graph = new FlagsGraph<number>()
|
||||
|
||||
const A = graph.put({ alias: 'A', value: 1 })
|
||||
|
||||
expect(graph.definitions).toHaveLength(1)
|
||||
expect(graph.definitions).toContain(A)
|
||||
|
||||
const B = graph.put({ alias: 'B', value: 2, parents: [{ alias: 'A' }] })
|
||||
|
||||
expect(graph.definitions).toHaveLength(2)
|
||||
expect(graph.definitions).toContain(B)
|
||||
|
||||
expect(B.parents).toContain(A)
|
||||
expect(A.children).toContain(B)
|
||||
})
|
||||
|
||||
test('create a definition with a forward reference', () => {
|
||||
const graph = new FlagsGraph<number>()
|
||||
|
||||
const B = graph.put({ alias: 'B', value: 2, parents: [{ alias: 'A' }] })
|
||||
|
||||
expect(graph.definitions).toHaveLength(1)
|
||||
expect(graph.definitions).toContain(B)
|
||||
|
||||
const A = graph.put({ alias: 'A', value: 1 })
|
||||
|
||||
expect(graph.definitions).toHaveLength(2)
|
||||
expect(graph.definitions).toContain(A)
|
||||
expect(A.value).toBe(1)
|
||||
|
||||
expect(B.parents).toContain(A)
|
||||
expect(A.children).toContain(B)
|
||||
})
|
||||
})
|
||||
@@ -36,10 +36,7 @@ describe(ArrayFlagSet, () => {
|
||||
expect(flags.intersection(['A'], ['B'])).toEqual([])
|
||||
expect(flags.intersection(['A'], ['A', 'B'])).toEqual(['A'])
|
||||
expect(flags.intersection(['A', 'B', 'D'], ['A', 'C'])).toEqual(['A'])
|
||||
expect(flags.intersection(['A', 'B', 'D'], ['A', 'B', 'C'])).toEqual([
|
||||
'A',
|
||||
'B',
|
||||
])
|
||||
expect(flags.intersection(['A', 'B', 'D'], ['A', 'B', 'C'])).toEqual(['A', 'B'])
|
||||
})
|
||||
|
||||
test('isSuperset', () => {
|
||||
|
||||
@@ -19,9 +19,7 @@ describe(CollectionFlagSet, () => {
|
||||
expect(flags.union(set('A'), set())).toEqual(set('A'))
|
||||
expect(flags.union(set(), set('B'))).toEqual(set('B'))
|
||||
expect(flags.union(set('A'), set('B'))).toEqual(set('A', 'B'))
|
||||
expect(flags.union(set('A', 'B'), set('B', 'C'))).toEqual(
|
||||
set('A', 'B', 'C'),
|
||||
)
|
||||
expect(flags.union(set('A', 'B'), set('B', 'C'))).toEqual(set('A', 'B', 'C'))
|
||||
})
|
||||
|
||||
test('difference', () => {
|
||||
@@ -41,12 +39,8 @@ describe(CollectionFlagSet, () => {
|
||||
expect(flags.intersection(set('A'), set())).toEqual(set())
|
||||
expect(flags.intersection(set('A'), set('B'))).toEqual(set())
|
||||
expect(flags.intersection(set('A'), set('A', 'B'))).toEqual(set('A'))
|
||||
expect(flags.intersection(set('A', 'B', 'D'), set('A', 'C'))).toEqual(
|
||||
set('A'),
|
||||
)
|
||||
expect(
|
||||
flags.intersection(set('A', 'B', 'D'), set('A', 'B', 'C')),
|
||||
).toEqual(set('A', 'B'))
|
||||
expect(flags.intersection(set('A', 'B', 'D'), set('A', 'C'))).toEqual(set('A'))
|
||||
expect(flags.intersection(set('A', 'B', 'D'), set('A', 'B', 'C'))).toEqual(set('A', 'B'))
|
||||
})
|
||||
|
||||
test('isSuperset', () => {
|
||||
@@ -65,10 +59,6 @@ describe(CollectionFlagSet, () => {
|
||||
|
||||
expect([...flags.enumerate(set())]).toEqual([])
|
||||
expect([...flags.enumerate(set('A'))]).toEqual(['A'])
|
||||
expect([...flags.enumerate(set('A', 'B', 'C'))]).toEqual([
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
])
|
||||
expect([...flags.enumerate(set('A', 'B', 'C'))]).toEqual(['A', 'B', 'C'])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -75,6 +75,38 @@ describe(BitFlagSet, () => {
|
||||
expect(flags.isSuperset(8, 4)).toBe(false)
|
||||
})
|
||||
|
||||
test('hasAny', () => {
|
||||
const flags = createBitFlagSet([
|
||||
{ value: 1, as: 'A' },
|
||||
{ value: 2, as: 'B', requires: ['A'] },
|
||||
{ value: 4, as: 'C', requires: ['A'] },
|
||||
{ value: 8, as: 'D', requires: ['B', 'C'] },
|
||||
])
|
||||
|
||||
expect(flags.hasAny(15, 0)).toBe(false)
|
||||
expect(flags.hasAny(0, 0)).toBe(false)
|
||||
expect(flags.hasAny(7, 1)).toBe(true)
|
||||
expect(flags.hasAny(1, 7)).toBe(true)
|
||||
expect(flags.hasAny(5, 12)).toBe(false)
|
||||
expect(flags.hasAny(2, 2)).toBe(false)
|
||||
})
|
||||
|
||||
test('hasAll', () => {
|
||||
const flags = createBitFlagSet([
|
||||
{ value: 1, as: 'A' },
|
||||
{ value: 2, as: 'B', requires: ['A'] },
|
||||
{ value: 4, as: 'C', requires: ['A'] },
|
||||
{ value: 8, as: 'D', requires: ['B', 'C'] },
|
||||
])
|
||||
|
||||
expect(flags.hasAll(15, 0)).toBe(true)
|
||||
expect(flags.hasAll(0, 0)).toBe(true)
|
||||
expect(flags.hasAll(7, 2)).toBe(true)
|
||||
expect(flags.hasAll(6, 2)).toBe(false)
|
||||
expect(flags.hasAll(1, 7)).toBe(false)
|
||||
expect(flags.hasAll(5, 12)).toBe(false)
|
||||
})
|
||||
|
||||
test('enumerate', () => {
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
@@ -85,4 +117,36 @@ describe(BitFlagSet, () => {
|
||||
expect([...flags.enumerate(11)]).toEqual([1, 2, 8])
|
||||
expect([...flags.enumerate(100)]).toEqual([4, 32, 64])
|
||||
})
|
||||
|
||||
test('maximum', () => {
|
||||
const flags = createBitFlagSet([
|
||||
{ value: 1, as: 'A' },
|
||||
{ value: 2, as: 'B', requires: ['A'] },
|
||||
{ value: 4, as: 'C', requires: ['A'] },
|
||||
{ value: 8, as: 'D', requires: ['B', 'C'] },
|
||||
])
|
||||
|
||||
expect(flags.maximum(0)).toEqual(0)
|
||||
expect(flags.maximum(1)).toEqual(1)
|
||||
expect(flags.maximum(2)).toEqual(3)
|
||||
expect(flags.maximum(3)).toEqual(3)
|
||||
expect(flags.maximum(4)).toEqual(5)
|
||||
expect(flags.maximum(8)).toEqual(15)
|
||||
})
|
||||
|
||||
test('minimum', () => {
|
||||
const flags = createBitFlagSet([
|
||||
{ value: 1, as: 'A' },
|
||||
{ value: 2, as: 'B', requires: ['A'] },
|
||||
{ value: 4, as: 'C', requires: ['A'] },
|
||||
{ value: 8, as: 'D', requires: ['B', 'C'] },
|
||||
])
|
||||
|
||||
expect(flags.minimum(0)).toEqual(0)
|
||||
expect(flags.minimum(1)).toEqual(1)
|
||||
expect(flags.minimum(2)).toEqual(0)
|
||||
expect(flags.minimum(3)).toEqual(3)
|
||||
expect(flags.minimum(4)).toEqual(0)
|
||||
expect(flags.minimum(13)).toEqual(5)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user