fix: harden array builder editing workflows
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
MAX_MICROPHONES,
|
||||
addMicrophone,
|
||||
arrayGeometryIssues,
|
||||
arrayStatistics,
|
||||
centerMicrophones,
|
||||
clampPositionToAperture,
|
||||
createArrayDefinition,
|
||||
@@ -9,6 +10,7 @@ import {
|
||||
generatePresetMicrophones,
|
||||
inferApertureShape,
|
||||
moveMicrophone,
|
||||
nextMicrophoneId,
|
||||
positionInsideAperture,
|
||||
removeMicrophone,
|
||||
replaceMicrophonesWithPreset,
|
||||
@@ -110,6 +112,45 @@ test("seed random preset은 재현되고 최소 간격과 형상 경계를 지
|
||||
}
|
||||
});
|
||||
|
||||
test("1,024채널 random preset은 공간 index로 고유 좌표를 빠르게 생성한다", () => {
|
||||
const startedAt = performance.now();
|
||||
const microphones = generatePresetMicrophones({
|
||||
type: "random",
|
||||
aperture: { width: 0.45, height: 0.45 },
|
||||
shape: "rectangle",
|
||||
count: 1024,
|
||||
seed: 20260828,
|
||||
minimumSpacingM: 0.002,
|
||||
});
|
||||
const elapsedMs = performance.now() - startedAt;
|
||||
assertEqual(microphones.length, 1024, "maximum random channel count");
|
||||
assertEqual(
|
||||
new Set(microphones.map((microphone) => microphone.position.join(","))).size,
|
||||
1024,
|
||||
"maximum random positions are unique",
|
||||
);
|
||||
assert(elapsedMs < 3000, "maximum random generation stays interactive: " + elapsedMs + " ms");
|
||||
|
||||
const failedAt = performance.now();
|
||||
assertThrows(
|
||||
() => generatePresetMicrophones({
|
||||
type: "random",
|
||||
aperture: { width: 0.45, height: 0.45 },
|
||||
shape: "rectangle",
|
||||
count: 1024,
|
||||
seed: 7,
|
||||
minimumSpacingM: 0.03,
|
||||
}),
|
||||
"배치할 수 없습니다",
|
||||
"dense maximum random failure",
|
||||
);
|
||||
const failedElapsedMs = performance.now() - failedAt;
|
||||
assert(
|
||||
failedElapsedMs < 3000,
|
||||
"impossible maximum random layout fails within a bound: " + failedElapsedMs + " ms",
|
||||
);
|
||||
});
|
||||
|
||||
test("불가능한 random 조건과 최대 채널 초과는 기존 배열을 보존한다", () => {
|
||||
const arrayDefinition = createArrayDefinition();
|
||||
const before = JSON.stringify(arrayDefinition.microphones);
|
||||
@@ -185,7 +226,7 @@ test("좌표 clamp, 중심 정렬과 aperture 맞춤이 명시적으로 동작
|
||||
assertNear(arrayDefinition.aperture.height, 0.021, 1e-12, "fitted height");
|
||||
});
|
||||
|
||||
test("설명과 좌표에서 원형 생성 형상을 합리적으로 추론한다", () => {
|
||||
test("문서의 명시적 형상 단서만으로 타원 생성 경계를 추론한다", () => {
|
||||
const spiral = createArrayDefinition({
|
||||
description: "Fermat spiral on circular aperture",
|
||||
presetType: "spiral",
|
||||
@@ -194,4 +235,42 @@ test("설명과 좌표에서 원형 생성 형상을 합리적으로 추론한
|
||||
assertEqual(inferApertureShape(spiral), "ellipse", "description inference");
|
||||
const grid = createArrayDefinition();
|
||||
assertEqual(inferApertureShape(grid), "rectangle", "grid inference");
|
||||
grid.description = "Spring-mounted rectangular array";
|
||||
assertEqual(inferApertureShape(grid), "rectangle", "word boundary avoids spring false positive");
|
||||
});
|
||||
|
||||
test("매우 큰 유한 좌표에서도 배열 중심 통계가 유한하게 유지된다", () => {
|
||||
const arrayDefinition = createArrayDefinition({ columns: 2, rows: 1 });
|
||||
arrayDefinition.microphones[0].position = [Number.MAX_VALUE, Number.MAX_VALUE, 0];
|
||||
arrayDefinition.microphones[1].position = [Number.MAX_VALUE, -Number.MAX_VALUE, 0];
|
||||
const statistics = arrayStatistics(arrayDefinition);
|
||||
assert(Number.isFinite(statistics.centroid[0]), "large x centroid remains finite");
|
||||
assert(Number.isFinite(statistics.centroid[1]), "large y centroid remains finite");
|
||||
assertEqual(statistics.centroid[0], Number.MAX_VALUE, "large x centroid");
|
||||
assertEqual(statistics.centroid[1], 0, "balanced y centroid");
|
||||
});
|
||||
|
||||
test("큰 숫자 suffix ID도 마이크 추가를 멈추지 않고 정확히 증가시킨다", () => {
|
||||
const arrayDefinition = createArrayDefinition({ columns: 1, rows: 1 });
|
||||
arrayDefinition.microphones[0].id = "mic-9007199254740992";
|
||||
assertEqual(
|
||||
nextMicrophoneId(arrayDefinition),
|
||||
"mic-9007199254740993",
|
||||
"BigInt suffix increment",
|
||||
);
|
||||
assertEqual(
|
||||
addMicrophone(arrayDefinition, [0.01, 0, 0]).id,
|
||||
"mic-9007199254740993",
|
||||
"manual add uses the safe ID",
|
||||
);
|
||||
});
|
||||
|
||||
test("고정밀 import 좌표는 실제 값이 다르면 중복으로 오인하지 않는다", () => {
|
||||
const arrayDefinition = createArrayDefinition({ columns: 2, rows: 1 });
|
||||
arrayDefinition.microphones[0].position = [0.0000000001, 0, 0];
|
||||
arrayDefinition.microphones[1].position = [0.0000000002, 0, 0];
|
||||
assert(
|
||||
!arrayGeometryIssues(arrayDefinition).some((issue) => issue.severity === "error"),
|
||||
"distinct high-precision positions",
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user