Files
tatsuki/node/tests/_archive/collection.test.ts

241 lines
8.2 KiB
TypeScript

import { CollectionFlagSet } from '@module'
import { ok } from 'node:assert'
function set<T>(...values: T[]): Set<T> {
return new Set<T>(values)
}
test('Union of two sets', () => {
const flags = new CollectionFlagSet<string>()
expect(flags.union(set(), set())).toEqual(set())
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')
)
})
test('Difference of two sets', () => {
const flags = new CollectionFlagSet<string>()
expect(flags.difference(set(), set())).toEqual(set())
expect(flags.difference(set('A'), set())).toEqual(set('A'))
expect(flags.difference(set('A', 'B'), set('B', 'C'))).toEqual(set('A'))
expect(flags.difference(set('B', 'C'), set('A', 'B'))).toEqual(set('C'))
expect(flags.difference(set('D'), set('A', 'E'))).toEqual(set('D'))
})
test('Intersection of two sets', () => {
const flags = new CollectionFlagSet<string>()
expect(flags.intersection(set(), set())).toEqual(set())
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')
)
})
test('Iterate over a set', () => {
const flags = new CollectionFlagSet<string>()
expect([...flags.iterate(set())]).toEqual([])
expect([...flags.iterate(set('A'))]).toEqual(['A'])
expect([...flags.iterate(set('A', 'B', 'C'))]).toEqual(['A', 'B', 'C'])
})
test('Normalise to minimum', () => {
const flags = new CollectionFlagSet<string>()
const flagA = flags.flag('A')
const flagB = flags.flag('B', flagA)
const flagC = flags.flag('C', flagA)
const flagD = flags.flag('D', flagC)
expect(flags.minimum(set())).toEqual(set())
expect(flags.minimum(set('A'))).toEqual(set('A'))
expect(flags.minimum(set('B'))).toEqual(set())
expect(flags.minimum(set('A', 'B'))).toEqual(set('A', 'B'))
expect(flags.minimum(set('A', 'B', 'D'))).toEqual(set('A', 'B'))
expect(flags.minimum(set('A', 'C', 'D'))).toEqual(set('A', 'C', 'D'))
expect(flags.minimum(set('A', 'E'))).toEqual(set('A'))
})
test('Normalise to maximum', () => {
const flags = new CollectionFlagSet<string>()
const flagA = flags.flag('A')
const flagB = flags.flag('B', flagA)
const flagC = flags.flag('C', flagA)
const flagD = flags.flag('D', flagC)
expect(flags.maximum(set())).toEqual(set())
expect(flags.maximum(set('A'))).toEqual(set('A'))
expect(flags.maximum(set('B'))).toEqual(set('B', 'A'))
expect(flags.maximum(set('A', 'B'))).toEqual(set('A', 'B'))
expect(flags.maximum(set('A', 'B', 'D'))).toEqual(set('A', 'B', 'D', 'C'))
expect(flags.maximum(set('A', 'C', 'D'))).toEqual(set('A', 'C', 'D'))
expect(flags.maximum(set('A', 'E'))).toEqual(set('A'))
})
test('Add to set', () => {
const flags = new CollectionFlagSet<string>()
const flagB = flags.flag('B')
const flagC = flags.flag('C')
const flagsBAndC = flags.flag(flagB, flagC)
expect(flagB.addTo(set('A'))).toEqual(set('A', 'B'))
expect(flagC.addTo(set('A'))).toEqual(set('A', 'C'))
expect(flagsBAndC.addTo(set('A'))).toEqual(set('A', 'B', 'C'))
})
test('Remove from set', () => {
const flags = new CollectionFlagSet<string>()
const flagA = flags.flag('A')
const flagB = flags.flag('B')
const flagC = flags.flag('C', flagA)
expect(flagA.removeFrom(set('A', 'B', 'C'))).toEqual(set('B'))
expect(flagB.removeFrom(set('A', 'B', 'C'))).toEqual(set('A', 'C'))
expect(flagC.removeFrom(set('A', 'B', 'C'))).toEqual(set('A', 'B'))
})
test('Is in set', () => {
const flags = new CollectionFlagSet<string>()
const flagA = flags.flag('A')
const flagB = flags.flag('B')
const flagC = flags.flag('C', flagA)
expect(flagA.isIn(set('A'))).toBe(true)
expect(flagB.isIn(set('A', 'B'))).toBe(true)
expect(flagC.isIn(set('C'))).toBe(false)
expect(flagC.isIn(set('A', 'C'))).toBe(true)
})
test('Is abstract', () => {
const flags = new CollectionFlagSet<string>()
const flagA = flags.flag('A')
const flagB = flags.flag('B')
const flagsAAndB = flags.flag(flagA, flagB)
const flagC = flags.flag('C', flagsAAndB)
expect(flagA.isAbstract).toBe(false)
expect(flagB.isAbstract).toBe(false)
expect(flagsAAndB.isAbstract).toBe(true)
expect(flagC.isAbstract).toBe(false)
})
test('Environment without Set', async () => {
const originalSet = globalThis.Set
// @ts-ignore
delete globalThis.Set
let module: { CollectionFlagSet: typeof CollectionFlagSet }
await jest.isolateModulesAsync(async () => {
module = await import('@module')
})
expect(() => new module.CollectionFlagSet()).toThrow()
globalThis.Set = originalSet
})
test('Environment with Set.prototype.union', async () => {
ok(!('union' in globalThis.Set.prototype))
const mockUnion = jest.fn((_) => new Set())
// @ts-ignore
globalThis.Set.prototype.union = mockUnion
let module: { CollectionFlagSet: typeof CollectionFlagSet } | undefined
await jest.isolateModulesAsync(async () => {
module = await import('@module')
})
ok(module !== undefined)
const set1 = new Set()
const set2 = new Set()
const flags = new module.CollectionFlagSet()
flags.union(set1, set2)
expect(mockUnion).toHaveBeenCalledTimes(1)
expect(mockUnion.mock.contexts[0]).toBe(set1)
expect(mockUnion.mock.calls[0][0]).toBe(set2)
// @ts-ignore
delete globalThis.Set.prototype.union
})
test('Environment with Set.prototype.difference', async () => {
ok(!('difference' in globalThis.Set.prototype))
const mockDifference = jest.fn((_) => new Set())
// @ts-ignore
globalThis.Set.prototype.difference = mockDifference
let module: { CollectionFlagSet: typeof CollectionFlagSet } | undefined
await jest.isolateModulesAsync(async () => {
module = await import('@module')
})
ok(module !== undefined)
const set1 = new Set()
const set2 = new Set()
const flags = new module.CollectionFlagSet()
flags.difference(set1, set2)
expect(mockDifference).toHaveBeenCalledTimes(1)
expect(mockDifference.mock.contexts[0]).toBe(set1)
expect(mockDifference.mock.calls[0][0]).toBe(set2)
// @ts-ignore
delete globalThis.Set.prototype.difference
})
test('Environment with Set.prototype.intersection', async () => {
ok(!('intersection' in globalThis.Set.prototype))
const mockIntersection = jest.fn((_) => new Set())
// @ts-ignore
globalThis.Set.prototype.intersection = mockIntersection
let module: { CollectionFlagSet: typeof CollectionFlagSet } | undefined
await jest.isolateModulesAsync(async () => {
module = await import('@module')
})
ok(module !== undefined)
const set1 = new Set()
const set2 = new Set()
const flags = new module.CollectionFlagSet()
flags.intersection(set1, set2)
expect(mockIntersection).toHaveBeenCalledTimes(1)
expect(mockIntersection.mock.contexts[0]).toBe(set1)
expect(mockIntersection.mock.calls[0][0]).toBe(set2)
// @ts-ignore
delete globalThis.Set.prototype.intersection
})
test('Environment with Set.prototype.isSupersetOf', async () => {
ok(!('isSupersetOf' in globalThis.Set.prototype))
const mockIsSupersetOf = jest.fn((_) => new Set())
// @ts-ignore
globalThis.Set.prototype.isSupersetOf = mockIsSupersetOf
let module: { CollectionFlagSet: typeof CollectionFlagSet } | undefined
await jest.isolateModulesAsync(async () => {
module = await import('@module')
})
ok(module !== undefined)
const set1 = new Set()
const set2 = new Set()
const flags = new module.CollectionFlagSet()
flags.isSupersetOf(set1, set2)
expect(mockIsSupersetOf).toHaveBeenCalledTimes(1)
expect(mockIsSupersetOf.mock.contexts[0]).toBe(set1)
expect(mockIsSupersetOf.mock.calls[0][0]).toBe(set2)
// @ts-ignore
delete globalThis.Set.prototype.isSupersetOf
})