feat(bearing): 일체 choice gated by the pair eccentricity rule (승인 2026-10-26)
- PierInput.bearingLayout: 분리 (default) or 일체, tracked for changes. - 일체 is selectable only when there is at least one pair and every pair is within 100 mm; otherwise the chip is disabled with the reason. - Validation: B01 (info) when 일체 is chosen and allowed, the block shape is still the 분리 shape; B02 (warning) when it is not allowed and the model falls back to 분리. - The 일체 block shape (2500 × 1200) is not modelled yet. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd18665d6a
commit
2af5cfb144
7 files changed
+75
-7
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildPier, type BlockModel } from '../src/core/geometry';
|
||||
import { bearingEdgeDistances, PAIR_ECCENTRICITY_LIMIT_MM, pairEccentricities } from '../src/core/bearing-layout';
|
||||
import { bearingEdgeDistances, integratedCheck, PAIR_ECCENTRICITY_LIMIT_MM, pairEccentricities } from '../src/core/bearing-layout';
|
||||
import { validatePier } from '../src/core/validate';
|
||||
import type { Issue } from '../src/core/types';
|
||||
import { loadP1 } from './helpers';
|
||||
|
||||
const model = buildPier(loadP1());
|
||||
@@ -46,3 +48,30 @@ describe('받침 배치 규칙 (승인 2026-10-26)', () => {
|
||||
expect(pairEccentricities([block(1, '전열', 1), block(2, '전열', 3), block(6, '후열', 1.05)])).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('일체 배치 선택 (승인 2026-10-26)', () => {
|
||||
it('P1 allows 일체 because every pair is within 100 mm', () => {
|
||||
expect(integratedCheck(model.blocks)).toEqual({ allowed: true, overLimit: [] });
|
||||
});
|
||||
|
||||
it('one pair over the limit blocks 일체 and lists that pair', () => {
|
||||
const r = integratedCheck([block(1, '전열', 1.0), block(1, '후열', 1.12)]);
|
||||
expect(r.allowed).toBe(false);
|
||||
expect(r.overLimit.map((p) => p.frontNo)).toEqual([1]);
|
||||
});
|
||||
|
||||
it('no pairs at all does not allow 일체', () => {
|
||||
expect(integratedCheck([]).allowed).toBe(false);
|
||||
});
|
||||
|
||||
it('the model keeps 분리 for now and says so (B01); a 일체 that is not allowed is refused with B02', () => {
|
||||
const input = loadP1();
|
||||
const ok: Issue[] = [];
|
||||
validatePier({ ...input, bearingLayout: '일체' }, model, ok);
|
||||
expect(ok.map((i) => i.code)).toContain('B01');
|
||||
const bad: Issue[] = [];
|
||||
const fake = { ...model, blocks: [block(1, '전열', 1.0), block(1, '후열', 1.12)] } as unknown as typeof model;
|
||||
validatePier({ ...input, bearingLayout: '일체' }, fake, bad);
|
||||
expect(bad.map((i) => i.code)).toContain('B02');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user