@bldrs-ai/conway 1.488.1413 → 1.494.1415
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiled/examples/browser-bundled.cjs +14 -2
- package/compiled/examples/cli-bundled.cjs +14 -2
- package/compiled/examples/cli-step-bundled.cjs +41 -3
- package/compiled/examples/validator-bundled.cjs +14 -2
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.js +2 -2
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +112 -1
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.js +65 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.js +5 -0
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts +1 -0
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/streamed_preview_channel.js +7 -1
- package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.d.ts.map +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.js +2 -2
- package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_typed_select_enum.test.js +60 -0
- package/compiled/src/step/parsing/step_deserialization_functions.d.ts +29 -0
- package/compiled/src/step/parsing/step_deserialization_functions.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_deserialization_functions.js +45 -0
- package/compiled/src/step/parsing/step_deserialization_functions.test.js +59 -1
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// A select member whose type is an enum may be written bare or in its typed
|
|
2
|
+
// form - `.NULL.` or `NULL_STYLE(.NULL.)`. Inside a SELECT the typed form is
|
|
3
|
+
// how a reader tells which member the value is, so exporters use it, and the
|
|
4
|
+
// NIST AP242 set uses it throughout.
|
|
5
|
+
//
|
|
6
|
+
// Reading the typed form used to throw 'Value in select must be populated',
|
|
7
|
+
// because the generated getter's enum fallback is a bare parse starting at
|
|
8
|
+
// the cursor and the wrapper made it fail. Entity-valued members were never
|
|
9
|
+
// affected - the parser indexes an inline TYPENAME(...) entity and
|
|
10
|
+
// extractBufferReference resolves it by address - so this was specific to
|
|
11
|
+
// enum members, and `null_style` / `IfcNullStyle` is the only enum inside a
|
|
12
|
+
// select in either schema. It accounted for 274 of the public regression
|
|
13
|
+
// baseline's error rows, every one of them a lost styled item. See
|
|
14
|
+
// bldrs-ai/conway#489.
|
|
15
|
+
//
|
|
16
|
+
// Both schemas are covered: the fix is emitted by the generator at two sites,
|
|
17
|
+
// one per schema, and a regeneration that reverted either would otherwise
|
|
18
|
+
// ship green. scripts/code-gen.cjs clones the generator unpinned, so that is
|
|
19
|
+
// not a hypothetical.
|
|
20
|
+
//
|
|
21
|
+
// Parser-only, so no geometry wasm is initialized here - importing it would
|
|
22
|
+
// make this fail at import in a checkout without the Dist built, for a
|
|
23
|
+
// dependency it never uses.
|
|
24
|
+
import { describe, expect, test } from "@jest/globals";
|
|
25
|
+
import IfcStepParser from "./ifc_step_parser.js";
|
|
26
|
+
import ParsingBuffer from "../parsing/parsing_buffer.js";
|
|
27
|
+
import { ParseResult } from "../step/parsing/step_parser.js";
|
|
28
|
+
import { IfcNullStyle, IfcPresentationStyleAssignment } from "./ifc4_gen/index.js";
|
|
29
|
+
const parser = IfcStepParser.Instance;
|
|
30
|
+
const TYPED_STYLE = `#10028 = IFCPRESENTATIONSTYLEASSIGNMENT((IFCNULLSTYLE(.NULL.)));`;
|
|
31
|
+
// The same value written bare, which always worked. Kept alongside so a
|
|
32
|
+
// change that fixes one by breaking the other cannot pass.
|
|
33
|
+
const BARE_STYLE = `#10028 = IFCPRESENTATIONSTYLEASSIGNMENT((.NULL.));`;
|
|
34
|
+
const STYLE_EXPRESS_ID = 10028;
|
|
35
|
+
/**
|
|
36
|
+
* Parse one IFCPRESENTATIONSTYLEASSIGNMENT and read back its styles.
|
|
37
|
+
*
|
|
38
|
+
* @param source The STEP text to parse.
|
|
39
|
+
* @return {Array<unknown>} The resolved styles array.
|
|
40
|
+
*/
|
|
41
|
+
function stylesOf(source) {
|
|
42
|
+
const [result, model] = parser.parseDataToModel(new ParsingBuffer(new TextEncoder().encode(source)));
|
|
43
|
+
if (model === void 0 ||
|
|
44
|
+
(result !== ParseResult.COMPLETE && result !== ParseResult.INCOMPLETE)) {
|
|
45
|
+
throw new Error(`parse failed with result ${result}`);
|
|
46
|
+
}
|
|
47
|
+
const assignment = model.getElementByExpressID(STYLE_EXPRESS_ID);
|
|
48
|
+
if (!(assignment instanceof IfcPresentationStyleAssignment)) {
|
|
49
|
+
throw new Error("expected an IfcPresentationStyleAssignment");
|
|
50
|
+
}
|
|
51
|
+
return assignment.Styles;
|
|
52
|
+
}
|
|
53
|
+
describe("a typed enum in an IFC select", () => {
|
|
54
|
+
test("IFCNULLSTYLE(.NULL.) resolves instead of throwing", () => {
|
|
55
|
+
expect(stylesOf(TYPED_STYLE)).toEqual([IfcNullStyle.NULL]);
|
|
56
|
+
});
|
|
57
|
+
test("the bare form still resolves", () => {
|
|
58
|
+
expect(stylesOf(BARE_STYLE)).toEqual([IfcNullStyle.NULL]);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -118,6 +118,35 @@ export declare function stepExtractArrayToken(buffer: Uint8Array, cursor: number
|
|
|
118
118
|
* @return {IterableIterator} Lazy iterator to extract value.
|
|
119
119
|
*/
|
|
120
120
|
export declare function stepExtractArray(buffer: Uint8Array, cursor: number, endCursor: number): IterableIterator<number>;
|
|
121
|
+
/**
|
|
122
|
+
* Step past a `TYPENAME(` wrapper to the value inside it, when the value at
|
|
123
|
+
* the cursor is written in its typed form and the type name matches.
|
|
124
|
+
*
|
|
125
|
+
* A select member may be written either bare or typed — `.NULL.` or
|
|
126
|
+
* `NULL_STYLE(.NULL.)` — and inside a SELECT the typed form is how a reader
|
|
127
|
+
* tells which member it is, so exporters legitimately use it. Entity-valued
|
|
128
|
+
* members already handle both, because the parser indexes an inline
|
|
129
|
+
* `TYPENAME(...)` entity and `extractBufferReference` resolves it by address.
|
|
130
|
+
* A member whose type is an enum has no entity to index, so its deserializer
|
|
131
|
+
* is a bare parse starting at the cursor, and the wrapper makes it fail.
|
|
132
|
+
* That cost 274 of the public regression baseline's error rows — every
|
|
133
|
+
* `PRESENTATION_STYLE_ASSIGNMENT((NULL_STYLE(.NULL.)))` in the corpus threw
|
|
134
|
+
* and lost its styled item. See bldrs-ai/conway#489.
|
|
135
|
+
*
|
|
136
|
+
* The type name is verified rather than skipped past, so this accepts only
|
|
137
|
+
* the value's own typed form: a mismatched wrapper stays a type error
|
|
138
|
+
* instead of being silently read as the member it isn't.
|
|
139
|
+
*
|
|
140
|
+
* @param buffer The buffer to read from.
|
|
141
|
+
* @param cursor The position the value starts at.
|
|
142
|
+
* @param endCursor The last position accessible for this read in the buffer.
|
|
143
|
+
* @param typeName The expected STEP type name of the wrapper, upper case —
|
|
144
|
+
* StepEntityIdentifierParser matches `[A-Z][A-Z0-9_]*`, so a lower-case
|
|
145
|
+
* spelling is not an identifier here and never reaches the comparison.
|
|
146
|
+
* @return {number} The position just inside the wrapper's parenthesis, or
|
|
147
|
+
* `cursor` unchanged when the value is not this type's typed form.
|
|
148
|
+
*/
|
|
149
|
+
export declare function stepEnterTypedValue(buffer: Uint8Array, cursor: number, endCursor: number, typeName: string): number;
|
|
121
150
|
/**
|
|
122
151
|
* Extracts an inline element and returns its cursor, or none if it can't be found.
|
|
123
152
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step_deserialization_functions.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_deserialization_functions.ts"],"names":[],"mappings":"AAkCA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAGD;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC,GAAI,CAAC,CAE9E;AAGD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAI,MAAM,CAExE;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAI,MAAM,CAEvE;AAGD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAUvC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CAM1C;AAGD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,OAAO,GAAG,IAAI,GAAG,SAAS,CAwBlD;AAGD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,OAAO,GAAG,SAAS,CAgB3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAK,MAAM,CA2E/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,CA0B9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,CA0C9B;AAED;;;;;;;;;GASG;AACH,wBAAiB,gBAAgB,CAC7B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,gBAAgB,CAAE,MAAM,CAAE,CAkGlD;AAGD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CA4C1C;AAID;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAK,MAAM,GAAG,SAAS,CAsC3C;AAED,QAAA,MAAM,eAAe,8JAAkC,CAAA;AAEvD,OAAO,EAAE,eAAe,EAAE,CAAA;AAE1B,QAAA,MAAM,iBAAiB,iGAAoC,CAAA;AAE3D,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAE5B,QAAA,MAAM,iBAAiB,4FAAiC,CAAA;AAExD,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"step_deserialization_functions.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_deserialization_functions.ts"],"names":[],"mappings":"AAkCA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAGD;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC,GAAI,CAAC,CAE9E;AAGD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAI,MAAM,CAExE;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAE,CAAC,EAAI,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAI,MAAM,CAEvE;AAGD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAUvC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CAM1C;AAGD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,OAAO,GAAG,IAAI,GAAG,SAAS,CAwBlD;AAGD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,OAAO,GAAG,SAAS,CAgB3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAK,MAAM,CA2E/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,CA0B9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,CA0C9B;AAED;;;;;;;;;GASG;AACH,wBAAiB,gBAAgB,CAC7B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,gBAAgB,CAAE,MAAM,CAAE,CAkGlD;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAI,MAAM,CAqB7B;AAGD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CA4C1C;AAID;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAAK,MAAM,GAAG,SAAS,CAsC3C;AAED,QAAA,MAAM,eAAe,8JAAkC,CAAA;AAEvD,OAAO,EAAE,eAAe,EAAE,CAAA;AAE1B,QAAA,MAAM,iBAAiB,iGAAoC,CAAA;AAE3D,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAE5B,QAAA,MAAM,iBAAiB,4FAAiC,CAAA;AAExD,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
|
|
@@ -367,6 +367,51 @@ export function* stepExtractArray(buffer, cursor, endCursor) {
|
|
|
367
367
|
throw new Error("Unterminated array");
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Step past a `TYPENAME(` wrapper to the value inside it, when the value at
|
|
372
|
+
* the cursor is written in its typed form and the type name matches.
|
|
373
|
+
*
|
|
374
|
+
* A select member may be written either bare or typed — `.NULL.` or
|
|
375
|
+
* `NULL_STYLE(.NULL.)` — and inside a SELECT the typed form is how a reader
|
|
376
|
+
* tells which member it is, so exporters legitimately use it. Entity-valued
|
|
377
|
+
* members already handle both, because the parser indexes an inline
|
|
378
|
+
* `TYPENAME(...)` entity and `extractBufferReference` resolves it by address.
|
|
379
|
+
* A member whose type is an enum has no entity to index, so its deserializer
|
|
380
|
+
* is a bare parse starting at the cursor, and the wrapper makes it fail.
|
|
381
|
+
* That cost 274 of the public regression baseline's error rows — every
|
|
382
|
+
* `PRESENTATION_STYLE_ASSIGNMENT((NULL_STYLE(.NULL.)))` in the corpus threw
|
|
383
|
+
* and lost its styled item. See bldrs-ai/conway#489.
|
|
384
|
+
*
|
|
385
|
+
* The type name is verified rather than skipped past, so this accepts only
|
|
386
|
+
* the value's own typed form: a mismatched wrapper stays a type error
|
|
387
|
+
* instead of being silently read as the member it isn't.
|
|
388
|
+
*
|
|
389
|
+
* @param buffer The buffer to read from.
|
|
390
|
+
* @param cursor The position the value starts at.
|
|
391
|
+
* @param endCursor The last position accessible for this read in the buffer.
|
|
392
|
+
* @param typeName The expected STEP type name of the wrapper, upper case —
|
|
393
|
+
* StepEntityIdentifierParser matches `[A-Z][A-Z0-9_]*`, so a lower-case
|
|
394
|
+
* spelling is not an identifier here and never reaches the comparison.
|
|
395
|
+
* @return {number} The position just inside the wrapper's parenthesis, or
|
|
396
|
+
* `cursor` unchanged when the value is not this type's typed form.
|
|
397
|
+
*/
|
|
398
|
+
export function stepEnterTypedValue(buffer, cursor, endCursor, typeName) {
|
|
399
|
+
const identifierEnd = identifierParser.match(buffer, cursor, endCursor);
|
|
400
|
+
if (identifierEnd === void 0 || (identifierEnd - cursor) !== typeName.length) {
|
|
401
|
+
return cursor;
|
|
402
|
+
}
|
|
403
|
+
for (let where = 0; where < typeName.length; ++where) {
|
|
404
|
+
if (buffer[cursor + where] !== typeName.charCodeAt(where)) {
|
|
405
|
+
return cursor;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// Delegate the rest to the inline-element reader rather than repeating its
|
|
409
|
+
// identifier/whitespace/comment/paren walk. Sharing it is not just less
|
|
410
|
+
// code: entity-valued select members reach their value through that exact
|
|
411
|
+
// function, so a divergence here would mean the two kinds of member in the
|
|
412
|
+
// SAME select disagreed about where a typed value begins.
|
|
413
|
+
return stepExtractInlineElemement(buffer, cursor, endCursor) ?? cursor;
|
|
414
|
+
}
|
|
370
415
|
/**
|
|
371
416
|
* Extracts an inline element and returns its cursor, or none if it can't be found.
|
|
372
417
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// unreachable after spill + release, where before it was retained via
|
|
8
8
|
// Context[parsingBufferReusable] → ParsingBuffer.buffer).
|
|
9
9
|
import { describe, expect, test } from "@jest/globals";
|
|
10
|
-
import { releaseScratchParsingBuffer, stepExtractNumber, } from "./step_deserialization_functions.js";
|
|
10
|
+
import { releaseScratchParsingBuffer, stepEnterTypedValue, stepExtractNumber, } from "./step_deserialization_functions.js";
|
|
11
11
|
const REAL_VALUE = 42.5;
|
|
12
12
|
const INT_VALUE = 7;
|
|
13
13
|
describe("releaseScratchParsingBuffer", () => {
|
|
@@ -25,3 +25,61 @@ describe("releaseScratchParsingBuffer", () => {
|
|
|
25
25
|
expect(stepExtractNumber(bytes, 0, bytes.length)).toBe(REAL_VALUE);
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
|
+
describe("stepEnterTypedValue", () => {
|
|
29
|
+
/**
|
|
30
|
+
* Encode and enter, returning both the cursor and what it points at, so a
|
|
31
|
+
* failed expectation says which byte the function landed on.
|
|
32
|
+
*
|
|
33
|
+
* @param text The STEP text to read from position 0.
|
|
34
|
+
* @param typeName The expected wrapper type name.
|
|
35
|
+
* @return {[number, string]} The returned cursor and the character there.
|
|
36
|
+
*/
|
|
37
|
+
const enter = (text, typeName) => {
|
|
38
|
+
const bytes = new TextEncoder().encode(text);
|
|
39
|
+
const cursor = stepEnterTypedValue(bytes, 0, bytes.length, typeName);
|
|
40
|
+
return [cursor, text[cursor] ?? ""];
|
|
41
|
+
};
|
|
42
|
+
test("enters a matching wrapper, landing on the value", () => {
|
|
43
|
+
// The case from bldrs-ai/conway#489: 274 occurrences in the public
|
|
44
|
+
// regression baseline, every one of them throwing and losing its
|
|
45
|
+
// styled item because the enum parse started on the 'N'.
|
|
46
|
+
// Positions derived rather than written out, so the expectation says
|
|
47
|
+
// "just past the wrapper" rather than asserting an opaque index.
|
|
48
|
+
expect(enter("NULL_STYLE(.NULL.)", "NULL_STYLE"))
|
|
49
|
+
.toEqual(["NULL_STYLE(".length, "."]);
|
|
50
|
+
expect(enter("IFCNULLSTYLE(.NULL.)", "IFCNULLSTYLE"))
|
|
51
|
+
.toEqual(["IFCNULLSTYLE(".length, "."]);
|
|
52
|
+
});
|
|
53
|
+
test("leaves a bare value alone", () => {
|
|
54
|
+
// Both forms are legal for a select member, so entering must be a no-op
|
|
55
|
+
// on the bare one rather than a precondition.
|
|
56
|
+
expect(enter(".NULL.", "NULL_STYLE")).toEqual([0, "."]);
|
|
57
|
+
});
|
|
58
|
+
test("does not treat a lower-case spelling as the type name", () => {
|
|
59
|
+
// Not a policy choice here: StepEntityIdentifierParser matches
|
|
60
|
+
// `[A-Z][A-Z0-9_]*`, so a lower-case wrapper is not an identifier at all
|
|
61
|
+
// and the value is left to be read bare (where it then fails as the
|
|
62
|
+
// malformed input it is).
|
|
63
|
+
expect(enter("null_style(.NULL.)", "NULL_STYLE")).toEqual([0, "n"]);
|
|
64
|
+
});
|
|
65
|
+
test("skips whitespace and comments before and after the paren", () => {
|
|
66
|
+
const spaced = "NULL_STYLE /* c */ ( /* d */ .NULL.)";
|
|
67
|
+
expect(enter(spaced, "NULL_STYLE")).toEqual([spaced.indexOf(".NULL."), "."]);
|
|
68
|
+
});
|
|
69
|
+
test("refuses a wrapper that is not this type", () => {
|
|
70
|
+
// The point of verifying the name rather than skipping any identifier:
|
|
71
|
+
// a mismatched wrapper stays a type error instead of being silently
|
|
72
|
+
// read as the member it is not.
|
|
73
|
+
expect(enter("SOME_OTHER_TYPE(.NULL.)", "NULL_STYLE")).toEqual([0, "S"]);
|
|
74
|
+
// A prefix must not match either - length is checked before the bytes.
|
|
75
|
+
expect(enter("NULL_STYLE_EXTRA(.NULL.)", "NULL_STYLE")).toEqual([0, "N"]);
|
|
76
|
+
});
|
|
77
|
+
test("refuses an identifier with no parenthesis", () => {
|
|
78
|
+
expect(enter("NULL_STYLE", "NULL_STYLE")).toEqual([0, "N"]);
|
|
79
|
+
expect(enter("NULL_STYLE.NULL.", "NULL_STYLE")).toEqual([0, "N"]);
|
|
80
|
+
});
|
|
81
|
+
test("refuses a reference or a bare number", () => {
|
|
82
|
+
expect(enter("#4085", "NULL_STYLE")).toEqual([0, "#"]);
|
|
83
|
+
expect(enter("0.7", "NULL_STYLE")).toEqual([0, "0"]);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
// only the first segment (major) is meaningful and is the one CI carries forward.
|
|
6
6
|
// Must stay in `vN.N.N` shape: the CI stamp regex, scripts/updateVersion.mjs, and
|
|
7
7
|
// statistics.ts all match `v\d+\.\d+\.\d+`.
|
|
8
|
-
const versionString = 'Conway v1.
|
|
8
|
+
const versionString = 'Conway v1.494.1415';
|
|
9
9
|
export { versionString };
|