Skip to content

Commit

Permalink
Add containment ref support
Browse files Browse the repository at this point in the history
  • Loading branch information
garethj2 committed Nov 27, 2024
1 parent 781f3c9 commit 01bbbcd
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
19 changes: 19 additions & 0 deletions spec/core/HNamespace.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1926,4 +1926,23 @@ describe('HNamespace', function (): void {
expect(tags).toEqual(['vav', 'equip'])
})
}) // #newDict()

describe('#getContainmentRefs()', function (): void {
it('returns a list of all the containment refs for a dict', function (): void {
expect(
defs
.getContainmentRefs()
.map((def) => def.defName)
.sort()
).toEqual(['equipRef', 'siteRef', 'spaceRef'])
})
}) // #getContainmentRefs()

describe('#findContainmentRefs()', function (): void {
it('returns a list of all the containment refs for a def', function (): void {
expect(
defs.findContainmentRefs('site').map((def) => def.defName)
).toEqual(['siteRef'])
})
}) // #findContainmentRefs()
})
78 changes: 78 additions & 0 deletions spec/core/Util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
disKey,
makeDefaultValue,
toKind,
addContainmentRefs,
} from '../../src/core/util'
import { Kind } from '../../src/core/Kind'
import { HBool } from '../../src/core/HBool'
Expand All @@ -32,6 +33,9 @@ import { HDict } from '../../src/core/HDict'
import { HVal } from '../../src/core/HVal'
import { HNa } from '../../src/core/HNa'
import { HGrid } from '../../src/core/HGrid'
import { HNamespace } from '../../src/core/HNamespace'
import { ZincReader } from '../../src/core/ZincReader'
import { readFile } from './file'

describe('util', function (): void {
describe('makeValue()', function (): void {
Expand Down Expand Up @@ -763,4 +767,78 @@ describe('util', function (): void {
expect(disKey('pod:key', i18n)).toBeUndefined()
})
}) // disKey()

describe('addContainmentRefs()', () => {
let defs: HNamespace

beforeAll(() => {
const zinc = readFile('./defsWithFeatures.zinc')
const grid = ZincReader.readValue(zinc) as HGrid
defs = new HNamespace(grid)
})

it('adds a siteRef to a floor', () => {
const dict = new HDict()

const refName = addContainmentRefs(
dict,
new HDict({
id: HRef.make('site'),
site: HMarker.make(),
}),
defs
)

expect(refName).toBe('siteRef')

expect(dict.toJSON()).toEqual({
siteRef: { _kind: Kind.Ref, val: 'site' },
})
})

it('adds a siteRef and an equipRef to a floor', () => {
const dict = new HDict()

const refName = addContainmentRefs(
dict,
new HDict({
id: HRef.make('equip'),
siteRef: HRef.make('site'),
equip: HMarker.make(),
}),
defs
)

expect(refName).toBe('equipRef')

expect(dict.toJSON()).toEqual({
siteRef: { _kind: Kind.Ref, val: 'site' },
equipRef: { _kind: Kind.Ref, val: 'equip' },
})
})

it('adds a siteRef, equipRef and a spaceRef to a floor', () => {
const dict = new HDict()

const refName = addContainmentRefs(
dict,
new HDict({
id: HRef.make('floor'),
siteRef: HRef.make('site'),
equipRef: HRef.make('equip'),
space: HMarker.make(),
floor: HMarker.make(),
}),
defs
)

expect(refName).toBe('spaceRef')

expect(dict.toJSON()).toEqual({
siteRef: { _kind: Kind.Ref, val: 'site' },
equipRef: { _kind: Kind.Ref, val: 'equip' },
spaceRef: { _kind: Kind.Ref, val: 'floor' },
})
})
}) // addContainmentRefs()
})
26 changes: 26 additions & 0 deletions src/core/HNamespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1647,4 +1647,30 @@ export class HNamespace {

return dict
}

/**
* Return all the containment refs available.
*
* @returns A list of all the containment refs.
*/
@memoize()
public getContainmentRefs(): HDict[] {
return this.allSubTypesOf('ref').filter((def) => def.has('containedBy'))
}

/**
* Return all the containment refs for the specified def.
*
* Please note, this will filter out any defs that are marked as deprecated.
*
* @param name The name of the def to search the ref for.
* @returns The containment defs.
*/
public findContainmentRefs(name: string | HSymbol): HDict[] {
return this.getContainmentRefs().filter(
(def) =>
!def.has('deprecated') &&
this.fits(name, def.get('containedBy') as HSymbol)
)
}
}
57 changes: 57 additions & 0 deletions src/core/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { HSymbol } from './HSymbol'
import { HList } from './HList'
import { HGrid } from './HGrid'
import { Scanner } from '../util/Scanner'
import { HNamespace } from './HNamespace'

/**
* Make the haystack value based on the supplied data.
Expand Down Expand Up @@ -526,3 +527,59 @@ export function disKey(
const [, pod, disKey] = /^([^:]+)::([^:]+)$/.exec(key.trim()) ?? []
return pod && disKey ? i18n(pod, disKey) : undefined
}

/**
* Add the containment refs to a record.
*
* This ensures all the containment refs are set up accordingly to the project haystack
* specification as well as additional refs that are defined in the defs namespace.
*
* - https://project-haystack.org/doc/docHaystack/Equips
* - https://project-haystack.org/doc/docHaystack/Points
* - https://project-haystack.org/doc/docHaystack/Spaces
*
* @param dict The new record.
* @param parent The parent record.
* @param namespace The defs namespace.
* @returns The primary containment ref name.
*/
export function addContainmentRefs(
dict: HDict,
parent: HDict,
namespace: HNamespace
): string {
const siteRef = parent.has('site')
? parent.get<HRef>('id')
: parent.get<HRef>('siteRef')

if (siteRef) {
dict.set('siteRef', siteRef)
}

const equipRef = parent.has('equip')
? parent.get<HRef>('id')
: parent.get<HRef>('equipRef')

if (equipRef) {
dict.set('equipRef', equipRef)
}

const spaceRef =
parent.has('space') || parent.has('floor')
? parent.get<HRef>('id')
: parent.get<HRef>('spaceRef')

if (spaceRef) {
dict.set('spaceRef', spaceRef)
}

const refName = namespace.findContainmentRefs(
namespace.reflect(parent).type.defName
)?.[0]?.defName

if (refName && !dict.has(refName)) {
dict.set(refName, parent.get('id') as HRef)
}

return refName ?? ''
}

0 comments on commit 01bbbcd

Please sign in to comment.