Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/api/src/lib/geometry-pipeline.spec.ts is written in an unsupported language. File is not indexed.

0001 /**
0002  * The geometry pipeline seams as data: rule contributions merge by name
0003  * (a later name replaces an earlier one), each load selects one rule set and
0004  * one cut list, and post-processors run in registration order with their
0005  * `after` constraints.
0006  */
0007 import {
0008   GeometryPostProcessorRegistration,
0009   RootGeometryRules,
0010   orderGeometryPostProcessors,
0011   resolveRootGeometryRules,
0012   selectRootGeometryLoadRules,
0013 } from './geometry-pipeline';
0014 
0015 const removeBeam: RootGeometryRules = { cutLists: { central: { label: 'Central', remove: ['Beam'] } } };
0016 
0017 describe('pre-build TGeo rules', () => {
0018   it('merges contributions in order; a later name replaces an earlier one', async () => {
0019     const rules = await resolveRootGeometryRules([
0020       removeBeam,
0021       { editRules: { default: { detectors: [{ namePattern: '*/A*', editRules: [] }] } } },
0022       // A dynamic import, the way a pack keeps rule data out of the initial bundle
0023       () => Promise.resolve<RootGeometryRules>({ cutLists: { central: { remove: ['Beam', 'Far'] }, beamline: { remove: ['Q'] } } }),
0024     ]);
0025     expect(rules.cutLists).toEqual({ central: { remove: ['Beam', 'Far'] }, beamline: { remove: ['Q'] } });
0026     expect(Object.keys(rules.editRules ?? {})).toEqual(['default']);
0027   });
0028 
0029   it('selects the named rule set and cut list; off and unknown names select nothing', async () => {
0030     const rules = await resolveRootGeometryRules([removeBeam]);
0031     expect(selectRootGeometryLoadRules(rules, 'off', 'central')).toEqual({ editRules: [], cutList: ['Beam'] });
0032     expect(selectRootGeometryLoadRules(rules, 'default', 'unknown')).toEqual({ editRules: [], cutList: [] });
0033   });
0034 
0035   it('stays structured-cloneable, as the worker message requires', async () => {
0036     const rules = await resolveRootGeometryRules([removeBeam]);
0037     const selected = selectRootGeometryLoadRules(rules, 'off', 'central');
0038     expect(structuredClone(selected)).toEqual(selected);
0039   });
0040 });
0041 
0042 describe('orderGeometryPostProcessors', () => {
0043   const processor = (id: string, after?: string[]): GeometryPostProcessorRegistration =>
0044     ({ id, after, load: () => Promise.reject(new Error('not loaded in this spec')) });
0045   const ids = (list: GeometryPostProcessorRegistration[]) => list.map(registration => registration.id);
0046 
0047   it('keeps registration order without constraints', () => {
0048     expect(ids(orderGeometryPostProcessors([processor('a'), processor('b'), processor('c')]))).toEqual(['a', 'b', 'c']);
0049   });
0050 
0051   it('runs a processor after the ids in its `after`, and ignores ids nobody registered', () => {
0052     const ordered = orderGeometryPostProcessors([processor('arranger', ['mirrors']), processor('other', ['missing']), processor('mirrors')]);
0053     expect(ids(ordered)).toEqual(['other', 'mirrors', 'arranger']);
0054   });
0055 
0056   it('a later registration with the same id replaces the earlier one in place', () => {
0057     const replacement = processor('a', ['b']);
0058     const ordered = orderGeometryPostProcessors([processor('a'), processor('b'), replacement]);
0059     expect(ordered).toEqual([expect.objectContaining({ id: 'b' }), replacement]);
0060   });
0061 
0062   it('names the processors of an `after` cycle', () => {
0063     expect(() => orderGeometryPostProcessors([processor('a', ['b']), processor('b', ['a'])]))
0064       .toThrow('Geometry post-processors wait for each other: a, b');
0065   });
0066 });