implemented of() and named() for CollectionFlagSets
This commit is contained in:
@@ -2,13 +2,23 @@ import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import tseslint from 'typescript-eslint'
|
||||
import { defineConfig } from 'eslint/config'
|
||||
import simpleImportSort from 'eslint-plugin-simple-import-sort'
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
plugins: { js },
|
||||
plugins: { js, 'simple-import-sort': simpleImportSort },
|
||||
extends: ['js/recommended'],
|
||||
languageOptions: { globals: { ...globals.browser, ...globals.node } },
|
||||
languageOptions: {
|
||||
globals: { ...globals.browser, ...globals.node },
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
},
|
||||
tseslint.configs.recommended,
|
||||
},
|
||||
rules: {
|
||||
'simple-import-sort/imports': 'error',
|
||||
'simple-import-sort/exports': 'error',
|
||||
},
|
||||
},
|
||||
tseslint.configs.recommendedTypeChecked,
|
||||
])
|
||||
|
||||
79
node/src/builders/collection.ts
Normal file
79
node/src/builders/collection.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { CollectionFlagSet } from '~/flagsets'
|
||||
import {
|
||||
applyDeclarations,
|
||||
FlagWithValue,
|
||||
FlagWithValueOrOrdinal,
|
||||
ListOfFlagsWithValue,
|
||||
ListOfFlagsWithValueOrOrdinal,
|
||||
NamedFlagWithValue,
|
||||
NamedFlagWithValueOrOrdinal,
|
||||
} from './declarative'
|
||||
import { FlagDefinition } from '~/definitions'
|
||||
import {
|
||||
DefineWithValueOrOrdinal,
|
||||
RequireParentsOrDefineWithValueOrOrdinal,
|
||||
WithValueOrOrdinal,
|
||||
WithValueOrOrdinalOrCompose,
|
||||
} from './syntax'
|
||||
import { FlagSetBuilder } from './generic'
|
||||
import { CollectionFlagDefinitionFactory } from '~/definitions/collection'
|
||||
|
||||
export class CollectionFlagSetBuilder<T>
|
||||
implements
|
||||
WithValueOrOrdinalOrCompose<T, Set<T>, CollectionFlagSet<T>>,
|
||||
RequireParentsOrDefineWithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>>
|
||||
{
|
||||
private readonly _underlying: FlagSetBuilder<T>
|
||||
|
||||
public constructor() {
|
||||
this._underlying = new FlagSetBuilder()
|
||||
}
|
||||
|
||||
public define(): WithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>>
|
||||
public define(alias: string): WithValueOrOrdinalOrCompose<T, Set<T>, CollectionFlagSet<T>>
|
||||
public define(alias?: string): WithValueOrOrdinalOrCompose<T, Set<T>, CollectionFlagSet<T>> {
|
||||
this._underlying.define(alias)
|
||||
return this
|
||||
}
|
||||
|
||||
public compose(...flags: string[]): DefineWithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>> {
|
||||
this._underlying.compose(flags)
|
||||
return this
|
||||
}
|
||||
|
||||
public withValue(
|
||||
value: T,
|
||||
): RequireParentsOrDefineWithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>> {
|
||||
this._underlying.withValue(value)
|
||||
return this
|
||||
}
|
||||
|
||||
public withOrdinal(
|
||||
ordinal: number,
|
||||
): RequireParentsOrDefineWithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
public requires(...flags: string[]): DefineWithValueOrOrdinal<T, Set<T>, CollectionFlagSet<T>> {
|
||||
this._underlying.requires(flags)
|
||||
return this
|
||||
}
|
||||
|
||||
public getResult(): CollectionFlagSet<T> {
|
||||
const graph = this._underlying.finish()
|
||||
const factory = new CollectionFlagDefinitionFactory<T>()
|
||||
return new CollectionFlagSet(graph.intoDictionary(factory))
|
||||
}
|
||||
}
|
||||
|
||||
export function createCollectionFlagSet<T>(declarations: FlagWithValue<T>[]): CollectionFlagSet<T>
|
||||
export function createCollectionFlagSet<T, D extends string>(
|
||||
declarations: Record<D, NamedFlagWithValue<T>>,
|
||||
): CollectionFlagSet<T> & Record<D, FlagDefinition<Set<T>>>
|
||||
export function createCollectionFlagSet<T>(
|
||||
declarations: ListOfFlagsWithValue<T>,
|
||||
): CollectionFlagSet<T> {
|
||||
const builder = new CollectionFlagSetBuilder<T>()
|
||||
applyDeclarations(declarations, builder)
|
||||
return builder.getResult()
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export { BitFlagSetBuilder, createBitFlagSet } from './number'
|
||||
export { createCollectionFlagSet, CollectionFlagSetBuilder } from './collection'
|
||||
|
||||
@@ -57,7 +57,6 @@ export class BitFlagSetBuilder
|
||||
|
||||
public getResult(): BitFlagSet {
|
||||
const graph = this._underlying.finish()
|
||||
const definitions = graph.sortedDefinitions()
|
||||
const factory = new BitFlagDefinitionFactory()
|
||||
return new BitFlagSet(graph.intoDictionary(factory))
|
||||
}
|
||||
@@ -66,7 +65,7 @@ export class BitFlagSetBuilder
|
||||
export function createBitFlagSet(declarations: FlagWithValueOrOrdinal<number>[]): BitFlagSet
|
||||
export function createBitFlagSet<D extends string>(
|
||||
declarations: Record<D, NamedFlagWithValueOrOrdinal<number>>,
|
||||
): BitFlagSet & Record<D, FlagDefinition<number, number>>
|
||||
): BitFlagSet & Record<D, FlagDefinition<number>>
|
||||
export function createBitFlagSet(declarations: ListOfFlagsWithValueOrOrdinal<number>): BitFlagSet {
|
||||
const builder = new BitFlagSetBuilder()
|
||||
applyDeclarations(declarations, builder)
|
||||
|
||||
104
node/src/definitions/collection.ts
Normal file
104
node/src/definitions/collection.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { FlagDefinition, FlagDefinitionFactory, PartialFlagDefinition } from '.'
|
||||
import { ENV_SET } from '~/env'
|
||||
|
||||
export class CollectionFlagDefinition<T> implements FlagDefinition<Set<T>> {
|
||||
private readonly _value: T | undefined
|
||||
private readonly _alias: string | undefined
|
||||
private readonly _parents: CollectionFlagDefinition<T>[]
|
||||
private readonly _children: CollectionFlagDefinition<T>[]
|
||||
|
||||
public constructor(
|
||||
value: T | undefined,
|
||||
alias: string | undefined,
|
||||
parents: CollectionFlagDefinition<T>[],
|
||||
) {
|
||||
this._value = value
|
||||
this._alias = alias
|
||||
this._parents = parents
|
||||
this._children = []
|
||||
|
||||
for (const parent of this._parents) {
|
||||
parent._children.push(this)
|
||||
}
|
||||
}
|
||||
|
||||
public get alias(): string | undefined {
|
||||
return this._alias
|
||||
}
|
||||
|
||||
public get values(): Set<T> {
|
||||
let values = new Set<T>()
|
||||
if (this._value === undefined) {
|
||||
for (const parent of this._parents) {
|
||||
values = ENV_SET.union.call(values, parent.values) as Set<T>
|
||||
}
|
||||
} else {
|
||||
values.add(this._value)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
public isIn(set: Set<T>): boolean {
|
||||
let result = this._value === undefined || set.has(this._value)
|
||||
for (const parent of this._parents) {
|
||||
result &&= parent.isIn(set)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public addTo(set: Set<T>): Set<T> {
|
||||
const result = new Set(set)
|
||||
if (this._value !== undefined) {
|
||||
result.add(this._value)
|
||||
}
|
||||
for (const parent of this._parents) {
|
||||
parent.addToMutable(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private addToMutable(set: Set<T>): void {
|
||||
if (this._value !== undefined) {
|
||||
set.add(this._value)
|
||||
}
|
||||
for (const parent of this._parents) {
|
||||
parent.addToMutable(set)
|
||||
}
|
||||
}
|
||||
|
||||
public removeFrom(set: Set<T>): Set<T> {
|
||||
const result = new Set(set)
|
||||
if (this._value !== undefined) {
|
||||
result.delete(this._value)
|
||||
}
|
||||
for (const parent of this._parents) {
|
||||
parent.removeFromMutable(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public removeFromMutable(set: Set<T>): void {
|
||||
if (this._value !== undefined) {
|
||||
set.delete(this._value)
|
||||
}
|
||||
for (const child of this._children) {
|
||||
child.removeFromMutable(set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CollectionFlagDefinitionFactory<T> implements FlagDefinitionFactory<T, Set<T>> {
|
||||
public makeDefinitions(
|
||||
sortedPartialDefinitions: PartialFlagDefinition<T>[],
|
||||
results: Map<PartialFlagDefinition<T>, FlagDefinition<Set<T>>>,
|
||||
): void {
|
||||
for (const pfd of sortedPartialDefinitions) {
|
||||
const parents: CollectionFlagDefinition<T>[] = []
|
||||
for (const parentPfd of pfd.parents) {
|
||||
parents.push(results.get(parentPfd) as CollectionFlagDefinition<T>)
|
||||
}
|
||||
|
||||
results.set(pfd, new CollectionFlagDefinition(pfd.value, pfd.alias, parents))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
export interface FlagsDictionary<F, S> {
|
||||
findByAlias(alias: string): FlagDefinition<F, S> | undefined
|
||||
findByAlias(alias: string): FlagDefinition<S> | undefined
|
||||
|
||||
findByValue(value: F): FlagDefinition<F, S> | undefined
|
||||
findByValue(value: F): FlagDefinition<S> | undefined
|
||||
}
|
||||
|
||||
export interface FlagDefinition<F, S> {
|
||||
export interface FlagDefinition<S> {
|
||||
/**
|
||||
* The alias of the flag.
|
||||
*/
|
||||
@@ -39,9 +39,9 @@ export interface FlagDefinition<F, S> {
|
||||
|
||||
export const valueToString = Symbol()
|
||||
|
||||
export function printFlagValue(flag: FlagDefinition<unknown, unknown>): string {
|
||||
export function printFlagValue(flag: FlagDefinition<unknown>): string {
|
||||
if (valueToString in flag) {
|
||||
return (flag[valueToString] as Function)()
|
||||
return (flag[valueToString] as () => string)()
|
||||
} else {
|
||||
return String(flag.values)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ interface PrecomputedValues {
|
||||
subtractive: number
|
||||
}
|
||||
|
||||
export class BitFlagDefinition implements FlagDefinition<number, number> {
|
||||
export class BitFlagDefinition implements FlagDefinition<number> {
|
||||
private readonly _baseValue: number
|
||||
private readonly _additiveValue: number
|
||||
private readonly _subtractiveValue: number
|
||||
@@ -43,7 +43,7 @@ export class BitFlagDefinition implements FlagDefinition<number, number> {
|
||||
export class BitFlagDefinitionFactory implements FlagDefinitionFactory<number, number> {
|
||||
public makeDefinitions(
|
||||
sortedPartialDefinitions: PartialFlagDefinition<number>[],
|
||||
results: Map<PartialFlagDefinition<number>, FlagDefinition<number, number>>,
|
||||
results: Map<PartialFlagDefinition<number>, FlagDefinition<number>>,
|
||||
): void {
|
||||
const precomputedValues = new Map<PartialFlagDefinition<number>, PrecomputedValues>()
|
||||
|
||||
|
||||
@@ -11,18 +11,12 @@ export const ENV_BI = Object.freeze(
|
||||
type SetBinaryOperation = <T>(this: Set<T>, other: Set<T>) => Set<T>
|
||||
type SetBinaryPredicate = <T>(this: Set<T>, other: Set<T>) => boolean
|
||||
|
||||
export const ENV_SET = Object.freeze(
|
||||
typeof Set === 'function'
|
||||
? {
|
||||
AVAILABLE: true,
|
||||
export const ENV_SET = Object.freeze({
|
||||
union: polyfillUnion(Set.prototype),
|
||||
intersection: polyfillIntersection(Set.prototype),
|
||||
difference: polyfillDifference(Set.prototype),
|
||||
isSupersetOf: polyfillIsSupersetOf(Set.prototype),
|
||||
}
|
||||
: { AVAILABLE: false },
|
||||
) as {
|
||||
readonly AVAILABLE: boolean
|
||||
}) as {
|
||||
readonly union: SetBinaryOperation
|
||||
readonly intersection: SetBinaryOperation
|
||||
readonly difference: SetBinaryOperation
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
import { FlagDefinition, FlagsDictionary } from '~/definitions'
|
||||
import { EnumerateFlags } from '~/enumeration'
|
||||
import { ENV_SET } from '~/env'
|
||||
|
||||
import type { FlagSet } from '.'
|
||||
import { EnumerateFlags, useIterator } from '../enumeration'
|
||||
import { ENV_SET } from '../env'
|
||||
import { UnavailableFeatureError } from '../errors'
|
||||
|
||||
export class CollectionFlagSet<T> implements FlagSet<T, Set<T>> {
|
||||
/**
|
||||
* Creates a new empty flag set.
|
||||
*
|
||||
* @throws UnavailableFeatureError When this constructor is called in an
|
||||
* environment that does not natively support {@link Set}s.
|
||||
*/
|
||||
public constructor() {
|
||||
if (!ENV_SET.AVAILABLE) {
|
||||
throw new UnavailableFeatureError('Sets')
|
||||
}
|
||||
private readonly _dictionary: FlagsDictionary<T, Set<T>>
|
||||
|
||||
public constructor(dictionary: FlagsDictionary<T, Set<T>>) {
|
||||
this._dictionary = dictionary
|
||||
}
|
||||
|
||||
public none(): Set<T> {
|
||||
return new Set()
|
||||
return new Set<T>()
|
||||
}
|
||||
|
||||
public of(...values: T[]): Set<T> {
|
||||
return new Set(values)
|
||||
}
|
||||
|
||||
public named(...aliases: string[]): Set<T> {
|
||||
const result = new Set<T>()
|
||||
for (const alias of aliases) {
|
||||
const definition = this.getFlag(alias)
|
||||
if (definition !== undefined) {
|
||||
for (const value of definition.values) {
|
||||
result.add(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public union(first: Set<T>, second: Set<T>): Set<T> {
|
||||
@@ -36,18 +48,57 @@ export class CollectionFlagSet<T> implements FlagSet<T, Set<T>> {
|
||||
return ENV_SET.isSupersetOf.call(first, second)
|
||||
}
|
||||
|
||||
public hasAny(flags: Set<T>, required: Set<T>): boolean {
|
||||
let result = false
|
||||
for (const value of required) {
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined && definition.isIn(flags)) {
|
||||
result = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public hasAll(flags: Set<T>, required: Set<T>): boolean {
|
||||
let result = true
|
||||
for (const value of required) {
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined && !definition.isIn(flags)) {
|
||||
result = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public enumerate(flags: Set<T>): EnumerateFlags<T> {
|
||||
return flags
|
||||
}
|
||||
|
||||
minimum(flags: Set<T>): Set<T> {
|
||||
throw new Error('Method not implemented.')
|
||||
public maximum(flags: Set<T>): Set<T> {
|
||||
let result = new Set<T>()
|
||||
for (const value of flags) {
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined) {
|
||||
result = definition.addTo(result)
|
||||
}
|
||||
maximum(flags: Set<T>): Set<T> {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public getFlag(alias: string): FlagDefinition<number, number> | undefined {
|
||||
return this._dictionary.lookUp(alias)
|
||||
public minimum(flags: Set<T>): Set<T> {
|
||||
let result = new Set<T>()
|
||||
for (const value of flags) {
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined && definition.isIn(flags)) {
|
||||
result = definition.addTo(result)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public getFlag(alias: string): FlagDefinition<Set<T>> | undefined {
|
||||
return this._dictionary.findByAlias(alias)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,28 +91,28 @@ export class BitFlagSet implements FlagSet<number, number> {
|
||||
}
|
||||
|
||||
public maximum(flags: number): number {
|
||||
let result = this.none()
|
||||
let result = 0
|
||||
for (const value of this.enumerate(flags)) {
|
||||
const flag = this._dictionary.findByValue(value)
|
||||
if (flag !== undefined) {
|
||||
result = flag.addTo(result)
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined) {
|
||||
result = definition.addTo(result)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public minimum(flags: number): number {
|
||||
let result = this.none()
|
||||
let result = 0
|
||||
for (const value of this.enumerate(flags)) {
|
||||
const flag = this._dictionary.findByValue(value)
|
||||
if (flag !== undefined && flag.isIn(flags)) {
|
||||
result = flag.addTo(result)
|
||||
const definition = this._dictionary.findByValue(value)
|
||||
if (definition !== undefined && definition.isIn(flags)) {
|
||||
result = definition.addTo(result)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public getFlag(alias: string): FlagDefinition<number, number> | undefined {
|
||||
public getFlag(alias: string): FlagDefinition<number> | undefined {
|
||||
return this._dictionary.findByAlias(alias)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { createBitFlagSet } from './builders'
|
||||
export { createBitFlagSet, createCollectionFlagSet } from './builders'
|
||||
export { FlagDefinition } from './definitions'
|
||||
export { InvalidBitFlagValueError } from './errors'
|
||||
export {
|
||||
|
||||
@@ -1,19 +1,41 @@
|
||||
import { CollectionFlagSet } from '~'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { CollectionFlagSet, createCollectionFlagSet } from '~'
|
||||
|
||||
function set<T>(...values: T[]): Set<T> {
|
||||
return new Set<T>(values)
|
||||
}
|
||||
|
||||
describe(CollectionFlagSet, () => {
|
||||
test('none', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.none()).toEqual(set())
|
||||
})
|
||||
|
||||
test('of', () => {
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.of()).toEqual(set())
|
||||
expect(flags.of('a')).toEqual(set('a'))
|
||||
expect(flags.of('x', 'y', 'z')).toEqual(set('x', 'y', 'z'))
|
||||
})
|
||||
|
||||
test('named', () => {
|
||||
const flags = createCollectionFlagSet([
|
||||
{ value: 12, as: 'a' },
|
||||
{ value: 45, as: 'b' },
|
||||
{ value: 78, as: 'c' },
|
||||
{ compose: ['a', 'b'], as: 'ab' },
|
||||
])
|
||||
|
||||
expect(flags.named()).toEqual(set())
|
||||
expect(flags.named('a')).toEqual(set(12))
|
||||
expect(flags.named('ab', 'c')).toEqual(set(12, 45, 78))
|
||||
})
|
||||
|
||||
test('union', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.union(set(), set())).toEqual(set())
|
||||
expect(flags.union(set('A'), set())).toEqual(set('A'))
|
||||
@@ -23,7 +45,7 @@ describe(CollectionFlagSet, () => {
|
||||
})
|
||||
|
||||
test('difference', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.difference(set(), set())).toEqual(set())
|
||||
expect(flags.difference(set('A'), set())).toEqual(set('A'))
|
||||
@@ -33,7 +55,7 @@ describe(CollectionFlagSet, () => {
|
||||
})
|
||||
|
||||
test('intersection', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.intersection(set(), set())).toEqual(set())
|
||||
expect(flags.intersection(set('A'), set())).toEqual(set())
|
||||
@@ -44,7 +66,7 @@ describe(CollectionFlagSet, () => {
|
||||
})
|
||||
|
||||
test('isSuperset', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect(flags.isSuperset(set(), set())).toBe(true)
|
||||
expect(flags.isSuperset(set('A', 'B'), set())).toBe(true)
|
||||
@@ -55,7 +77,7 @@ describe(CollectionFlagSet, () => {
|
||||
})
|
||||
|
||||
test('enumerate', () => {
|
||||
const flags = new CollectionFlagSet<string>()
|
||||
const flags = createCollectionFlagSet<string>([])
|
||||
|
||||
expect([...flags.enumerate(set())]).toEqual([])
|
||||
expect([...flags.enumerate(set('A'))]).toEqual(['A'])
|
||||
|
||||
@@ -34,37 +34,45 @@ describe(BitFlagSet, () => {
|
||||
})
|
||||
|
||||
test('union', () => {
|
||||
expect(BitFlags.union(0, 0)).toEqual(0)
|
||||
expect(BitFlags.union(1, 0)).toEqual(1)
|
||||
expect(BitFlags.union(0, 2)).toEqual(2)
|
||||
expect(BitFlags.union(1, 2)).toEqual(3)
|
||||
expect(BitFlags.union(3, 6)).toEqual(7)
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
expect(flags.union(0, 0)).toEqual(0)
|
||||
expect(flags.union(1, 0)).toEqual(1)
|
||||
expect(flags.union(0, 2)).toEqual(2)
|
||||
expect(flags.union(1, 2)).toEqual(3)
|
||||
expect(flags.union(3, 6)).toEqual(7)
|
||||
})
|
||||
|
||||
test('difference', () => {
|
||||
expect(BitFlags.difference(0, 0)).toEqual(0)
|
||||
expect(BitFlags.difference(1, 0)).toEqual(1)
|
||||
expect(BitFlags.difference(3, 6)).toEqual(1)
|
||||
expect(BitFlags.difference(6, 3)).toEqual(4)
|
||||
expect(BitFlags.difference(8, 17)).toEqual(8)
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
expect(flags.difference(0, 0)).toEqual(0)
|
||||
expect(flags.difference(1, 0)).toEqual(1)
|
||||
expect(flags.difference(3, 6)).toEqual(1)
|
||||
expect(flags.difference(6, 3)).toEqual(4)
|
||||
expect(flags.difference(8, 17)).toEqual(8)
|
||||
})
|
||||
|
||||
test('intersection', () => {
|
||||
expect(BitFlags.intersection(0, 0)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 0)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 2)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 3)).toEqual(1)
|
||||
expect(BitFlags.intersection(11, 5)).toEqual(1)
|
||||
expect(BitFlags.intersection(11, 7)).toEqual(3)
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
expect(flags.intersection(0, 0)).toEqual(0)
|
||||
expect(flags.intersection(1, 0)).toEqual(0)
|
||||
expect(flags.intersection(1, 2)).toEqual(0)
|
||||
expect(flags.intersection(1, 3)).toEqual(1)
|
||||
expect(flags.intersection(11, 5)).toEqual(1)
|
||||
expect(flags.intersection(11, 7)).toEqual(3)
|
||||
})
|
||||
|
||||
test('isSuperset', () => {
|
||||
expect(BitFlags.isSuperset(0, 0)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 0)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 1)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 3)).toBe(true)
|
||||
expect(BitFlags.isSuperset(0, 3)).toBe(false)
|
||||
expect(BitFlags.isSuperset(8, 4)).toBe(false)
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
expect(flags.isSuperset(0, 0)).toBe(true)
|
||||
expect(flags.isSuperset(3, 0)).toBe(true)
|
||||
expect(flags.isSuperset(3, 1)).toBe(true)
|
||||
expect(flags.isSuperset(3, 3)).toBe(true)
|
||||
expect(flags.isSuperset(0, 3)).toBe(false)
|
||||
expect(flags.isSuperset(8, 4)).toBe(false)
|
||||
})
|
||||
|
||||
test('hasAny', () => {
|
||||
@@ -100,12 +108,14 @@ describe(BitFlagSet, () => {
|
||||
})
|
||||
|
||||
test('enumerate', () => {
|
||||
expect([...BitFlags.enumerate(0)]).toEqual([])
|
||||
expect([...BitFlags.enumerate(1)]).toEqual([1])
|
||||
expect([...BitFlags.enumerate(2)]).toEqual([2])
|
||||
expect([...BitFlags.enumerate(3)]).toEqual([1, 2])
|
||||
expect([...BitFlags.enumerate(11)]).toEqual([1, 2, 8])
|
||||
expect([...BitFlags.enumerate(100)]).toEqual([4, 32, 64])
|
||||
const flags = createBitFlagSet([])
|
||||
|
||||
expect([...flags.enumerate(0)]).toEqual([])
|
||||
expect([...flags.enumerate(1)]).toEqual([1])
|
||||
expect([...flags.enumerate(2)]).toEqual([2])
|
||||
expect([...flags.enumerate(3)]).toEqual([1, 2])
|
||||
expect([...flags.enumerate(11)]).toEqual([1, 2, 8])
|
||||
expect([...flags.enumerate(100)]).toEqual([4, 32, 64])
|
||||
})
|
||||
|
||||
test('maximum', () => {
|
||||
@@ -140,3 +150,48 @@ describe(BitFlagSet, () => {
|
||||
expect(flags.minimum(13)).toEqual(5)
|
||||
})
|
||||
})
|
||||
|
||||
describe('BitFlags', () => {
|
||||
test('union', () => {
|
||||
expect(BitFlags.union(0, 0)).toEqual(0)
|
||||
expect(BitFlags.union(1, 0)).toEqual(1)
|
||||
expect(BitFlags.union(0, 2)).toEqual(2)
|
||||
expect(BitFlags.union(1, 2)).toEqual(3)
|
||||
expect(BitFlags.union(3, 6)).toEqual(7)
|
||||
})
|
||||
|
||||
test('difference', () => {
|
||||
expect(BitFlags.difference(0, 0)).toEqual(0)
|
||||
expect(BitFlags.difference(1, 0)).toEqual(1)
|
||||
expect(BitFlags.difference(3, 6)).toEqual(1)
|
||||
expect(BitFlags.difference(6, 3)).toEqual(4)
|
||||
expect(BitFlags.difference(8, 17)).toEqual(8)
|
||||
})
|
||||
|
||||
test('intersection', () => {
|
||||
expect(BitFlags.intersection(0, 0)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 0)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 2)).toEqual(0)
|
||||
expect(BitFlags.intersection(1, 3)).toEqual(1)
|
||||
expect(BitFlags.intersection(11, 5)).toEqual(1)
|
||||
expect(BitFlags.intersection(11, 7)).toEqual(3)
|
||||
})
|
||||
|
||||
test('isSuperset', () => {
|
||||
expect(BitFlags.isSuperset(0, 0)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 0)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 1)).toBe(true)
|
||||
expect(BitFlags.isSuperset(3, 3)).toBe(true)
|
||||
expect(BitFlags.isSuperset(0, 3)).toBe(false)
|
||||
expect(BitFlags.isSuperset(8, 4)).toBe(false)
|
||||
})
|
||||
|
||||
test('enumerate', () => {
|
||||
expect([...BitFlags.enumerate(0)]).toEqual([])
|
||||
expect([...BitFlags.enumerate(1)]).toEqual([1])
|
||||
expect([...BitFlags.enumerate(2)]).toEqual([2])
|
||||
expect([...BitFlags.enumerate(3)]).toEqual([1, 2])
|
||||
expect([...BitFlags.enumerate(11)]).toEqual([1, 2, 8])
|
||||
expect([...BitFlags.enumerate(100)]).toEqual([4, 32, 64])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user