@aster-cloud/aster-lang-ts 1.0.7 → 1.0.9
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/dist/src/config/lexicons/de-DE.d.ts.map +1 -1
- package/dist/src/config/lexicons/de-DE.js +1 -0
- package/dist/src/config/lexicons/de-DE.js.map +1 -1
- package/dist/src/config/lexicons/en-US.d.ts.map +1 -1
- package/dist/src/config/lexicons/en-US.js +1 -0
- package/dist/src/config/lexicons/en-US.js.map +1 -1
- package/dist/src/config/lexicons/hi-IN.d.ts.map +1 -1
- package/dist/src/config/lexicons/hi-IN.js +1 -0
- package/dist/src/config/lexicons/hi-IN.js.map +1 -1
- package/dist/src/config/lexicons/template.d.ts.map +1 -1
- package/dist/src/config/lexicons/template.js +1 -0
- package/dist/src/config/lexicons/template.js.map +1 -1
- package/dist/src/config/lexicons/zh-CN.d.ts.map +1 -1
- package/dist/src/config/lexicons/zh-CN.js +1 -0
- package/dist/src/config/lexicons/zh-CN.js.map +1 -1
- package/dist/src/config/semantic.d.ts +1 -0
- package/dist/src/config/semantic.d.ts.map +1 -1
- package/dist/src/config/semantic.js +1 -0
- package/dist/src/config/semantic.js.map +1 -1
- package/dist/src/config/token-kind.d.ts +3 -0
- package/dist/src/config/token-kind.d.ts.map +1 -1
- package/dist/src/config/token-kind.js +3 -0
- package/dist/src/config/token-kind.js.map +1 -1
- package/dist/src/parser/expr-stmt-parser.d.ts.map +1 -1
- package/dist/src/parser/expr-stmt-parser.js +212 -41
- package/dist/src/parser/expr-stmt-parser.js.map +1 -1
- package/dist/test/unit/alias-poem-story.test.d.ts +2 -0
- package/dist/test/unit/alias-poem-story.test.d.ts.map +1 -0
- package/dist/test/unit/alias-poem-story.test.js +106 -0
- package/dist/test/unit/alias-poem-story.test.js.map +1 -0
- package/dist/test/unit/apply-call.test.d.ts +2 -0
- package/dist/test/unit/apply-call.test.d.ts.map +1 -0
- package/dist/test/unit/apply-call.test.js +79 -0
- package/dist/test/unit/apply-call.test.js.map +1 -0
- package/dist/test/unit/multiline-continuation.test.d.ts +2 -0
- package/dist/test/unit/multiline-continuation.test.d.ts.map +1 -0
- package/dist/test/unit/multiline-continuation.test.js +87 -0
- package/dist/test/unit/multiline-continuation.test.js.map +1 -0
- package/dist/test/unit/tides-ballad.test.d.ts +2 -0
- package/dist/test/unit/tides-ballad.test.d.ts.map +1 -0
- package/dist/test/unit/tides-ballad.test.js +80 -0
- package/dist/test/unit/tides-ballad.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { compile, evaluate, EN_US, initializeAllBundledLexicons } from '../../src/browser.js';
|
|
4
|
+
// 等缩进多行表达式续行(ADR 0026)—— TS 引擎。续行(与语句起始行同缩进、二元运算符打头/结尾)
|
|
5
|
+
// 解析到与单行**完全相同**的 Core IR(零新节点);双引擎一致由 tier1-parity(multiline_continuation
|
|
6
|
+
// 样本)锁。安全性(Codex 审查 019f157b):只跨等缩进 NEWLINE,不碰 INDENT/DEDENT,块结构零风险。
|
|
7
|
+
initializeAllBundledLexicons();
|
|
8
|
+
function run(body, entry, ctx) {
|
|
9
|
+
const c = compile(`Module probe.\n${body}\n`, { lexicon: EN_US });
|
|
10
|
+
assert.ok(c.success && c.core, `compile: ${JSON.stringify(c.parseErrors ?? [])}`);
|
|
11
|
+
const ev = evaluate(c.core, entry, ctx);
|
|
12
|
+
assert.ok(ev.success, `eval: ${ev.error ?? ''}`);
|
|
13
|
+
return ev.value;
|
|
14
|
+
}
|
|
15
|
+
function compiles(body) {
|
|
16
|
+
return compile(`Module probe.\n${body}\n`, { lexicon: EN_US }).success;
|
|
17
|
+
}
|
|
18
|
+
/** 剥 origin 的结构指纹,用于比较多行版 ≡ 单行版 Core IR。 */
|
|
19
|
+
function fingerprint(body) {
|
|
20
|
+
const c = compile(`Module probe.\n${body}\n`, { lexicon: EN_US });
|
|
21
|
+
assert.ok(c.core, `compile: ${JSON.stringify(c.parseErrors ?? [])}`);
|
|
22
|
+
return JSON.stringify(stripOrigin(c.core));
|
|
23
|
+
}
|
|
24
|
+
function stripOrigin(o) {
|
|
25
|
+
if (Array.isArray(o))
|
|
26
|
+
return o.map(stripOrigin);
|
|
27
|
+
if (o && typeof o === 'object') {
|
|
28
|
+
const r = {};
|
|
29
|
+
for (const k of Object.keys(o)) {
|
|
30
|
+
if (k === 'origin' || k === 'span')
|
|
31
|
+
continue;
|
|
32
|
+
r[k] = stripOrigin(o[k]);
|
|
33
|
+
}
|
|
34
|
+
return r;
|
|
35
|
+
}
|
|
36
|
+
return o;
|
|
37
|
+
}
|
|
38
|
+
describe('ADR 0026 — 等缩进多行续行求值正确', () => {
|
|
39
|
+
it('加法链跨行:a plus 10 plus 20 (a=5) = 35', () => {
|
|
40
|
+
assert.equal(run('Rule total given a as Int, produce Int:\n Return a\n plus 10\n plus 20.', 'total', { a: 5 }), 35);
|
|
41
|
+
});
|
|
42
|
+
it('字符串拼接跨行', () => {
|
|
43
|
+
assert.equal(run('Rule g given name as Text, produce Text:\n Return "Hello, "\n plus name\n plus "!".', 'g', { name: 'world' }), 'Hello, world!');
|
|
44
|
+
});
|
|
45
|
+
it('行尾运算符续行:a plus\\n 10', () => {
|
|
46
|
+
assert.equal(run('Rule t given a as Int, produce Int:\n Return a plus\n 10.', 't', { a: 5 }), 15);
|
|
47
|
+
});
|
|
48
|
+
it('乘法链跨行', () => {
|
|
49
|
+
assert.equal(run('Rule s given a as Int, produce Int:\n Return a\n times 2\n times 3.', 's', { a: 4 }), 24);
|
|
50
|
+
});
|
|
51
|
+
it('比较+逻辑跨行', () => {
|
|
52
|
+
assert.equal(run('Rule r given x as Int, produce Bool:\n Return x at least 1\n and x at most 9.', 'r', { x: 5 }), true);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('ADR 0026 — 多行版 ≡ 单行版 Core IR(纯解析层)', () => {
|
|
56
|
+
it('加法链:多行与单行结构一致', () => {
|
|
57
|
+
const ml = fingerprint('Rule total given a as Int, produce Int:\n Return a\n plus 10\n plus 20.');
|
|
58
|
+
const sl = fingerprint('Rule total given a as Int, produce Int:\n Return a plus 10 plus 20.');
|
|
59
|
+
assert.equal(ml, sl);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('ADR 0026 — 边界(本批仅等缩进)', () => {
|
|
63
|
+
it('更深缩进续行仍拒(本批不支持)', () => {
|
|
64
|
+
assert.equal(compiles('Rule t given a as Int, produce Int:\n Return a\n plus 1.'), false);
|
|
65
|
+
});
|
|
66
|
+
it('不跨行续接第二个比较(不扩大 TS/Java 链式比较分歧)', () => {
|
|
67
|
+
// Codex 审查 019f157b §5:Java comparisonExpr 单比较非链式。续行若跨行续接第二个比较会
|
|
68
|
+
// 与 Java 分歧 → 故 `a < b\n< c` 多行链式比较不被续行接受(首个比较的行首/行尾续行仍支持)。
|
|
69
|
+
assert.equal(compiles('Rule r given a as Int, produce Bool:\n Return a less than 5\n less than 10.'), false);
|
|
70
|
+
// 但首个比较的行首续行仍可:`a\n< b`。
|
|
71
|
+
assert.equal(run('Rule r given a as Int, produce Bool:\n Return a\n less than 10.', 'r', { a: 5 }), true);
|
|
72
|
+
});
|
|
73
|
+
it('块边界不被续行误并:两条独立语句', () => {
|
|
74
|
+
const c = compile('Module probe.\nRule r given a as Int, produce Int:\n Let m be a plus 1.\n Return m.\n', { lexicon: EN_US });
|
|
75
|
+
assert.ok(c.success && c.core);
|
|
76
|
+
const fn = c.core.decls.find(d => d.kind === 'Func' && d.name === 'r');
|
|
77
|
+
assert.ok(fn && fn.kind === 'Func', 'rule r found');
|
|
78
|
+
assert.equal(fn.body?.statements.length, 2, '应为两条独立语句');
|
|
79
|
+
});
|
|
80
|
+
it('续行不影响行内运算符链(无换行时行为不变)', () => {
|
|
81
|
+
// 回归保护:单行运算符链照常工作,续行逻辑只在 NEWLINE 后命中,不干扰行内解析。
|
|
82
|
+
assert.equal(run('Rule r given a as Int, produce Int:\n Return a plus 1 plus 2 plus 3.', 'r', { a: 0 }), 6);
|
|
83
|
+
// 注:前缀 operatorCall `+(a,b)` 是 Java-grammar-only 形(TS 本就不支持,见 Codex 审查
|
|
84
|
+
// 019f157b 的双引擎差异),与本续行特性无关——续行只在 expr 循环内、NEWLINE 后触发。
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=multiline-continuation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiline-continuation.test.js","sourceRoot":"","sources":["../../../test/unit/multiline-continuation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAE9F,wDAAwD;AACxD,2EAA2E;AAC3E,qEAAqE;AACrE,4BAA4B,EAAE,CAAC;AAE/B,SAAS,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,GAA4B;IACpE,MAAM,CAAC,GAAG,OAAO,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,IAAI,CAAC,SAAS,CAAE,CAA+B,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACjH,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;IACjD,OAAO,EAAE,CAAC,KAAK,CAAC;AAClB,CAAC;AACD,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,OAAO,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;AACzE,CAAC;AACD,4CAA4C;AAC5C,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,IAAI,CAAC,SAAS,CAAE,CAA+B,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACpG,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC;AACD,SAAS,WAAW,CAAC,CAAU;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAA4B,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,MAAM;gBAAE,SAAS;YAC7C,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAE,CAA6B,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,4EAA4E,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACzH,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACjB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,wFAAwF,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC;IACvJ,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,6DAA6D,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACf,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,wEAAwE,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACjH,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACjB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,iFAAiF,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC5H,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;QACvB,MAAM,EAAE,GAAG,WAAW,CAAC,4EAA4E,CAAC,CAAC;QACrG,MAAM,EAAE,GAAG,WAAW,CAAC,sEAAsE,CAAC,CAAC;QAC/F,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;QACzB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,8DAA8D,CAAC,EAAE,KAAK,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,gEAAgE;QAChE,4DAA4D;QAC5D,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,+EAA+E,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/G,yBAAyB;QACzB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,mEAAmE,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,GAAG,OAAO,CAAC,yFAAyF,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACjI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,IAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;QACxE,MAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,cAAc,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,8CAA8C;QAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,uEAAuE,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7G,uEAAuE;QACvE,wDAAwD;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tides-ballad.test.d.ts","sourceRoot":"","sources":["../../../test/unit/tides-ballad.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { compile, evaluate, EN_US, initializeAllBundledLexicons } from '../../src/browser.js';
|
|
7
|
+
import { SemanticTokenKind } from '../../src/config/token-kind.js';
|
|
8
|
+
// examples/alias-poem-story/tides.ballad.aster 的 CI 防回归:第二首谣曲展示 Match(behold)分支 +
|
|
9
|
+
// List 生成(List.range/List.sum)+ 等缩进多行续行,全经生产引擎编译执行。与 nightfall 同用 Bard
|
|
10
|
+
// 方言别名(recognition-side,ADR 0022)。
|
|
11
|
+
initializeAllBundledLexicons();
|
|
12
|
+
/** 与 bard.mjs 同源的 Bard 方言(含 Match→behold / When→as)。 */
|
|
13
|
+
const BARD_EN = {
|
|
14
|
+
...EN_US,
|
|
15
|
+
id: 'bard-en',
|
|
16
|
+
name: 'Bard (English)',
|
|
17
|
+
aliases: {
|
|
18
|
+
[SemanticTokenKind.MODULE_DECL]: ['Ballad'],
|
|
19
|
+
[SemanticTokenKind.FUNC_TO]: ['Verse'],
|
|
20
|
+
[SemanticTokenKind.FUNC_GIVEN]: ['of'],
|
|
21
|
+
[SemanticTokenKind.LET]: ['let'],
|
|
22
|
+
[SemanticTokenKind.BE]: ['become'],
|
|
23
|
+
[SemanticTokenKind.IF]: ['where'],
|
|
24
|
+
[SemanticTokenKind.RETURN]: ['sing'],
|
|
25
|
+
[SemanticTokenKind.MATCH]: ['behold'],
|
|
26
|
+
[SemanticTokenKind.WHEN]: ['as'],
|
|
27
|
+
[SemanticTokenKind.PLUS]: ['then'],
|
|
28
|
+
[SemanticTokenKind.AT_MOST]: ['but'],
|
|
29
|
+
[SemanticTokenKind.AT_LEAST]: ['past'],
|
|
30
|
+
[SemanticTokenKind.MINUS_WORD]: ['less'],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
function repoRoot() {
|
|
34
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
for (let i = 0; i < 8; i++) {
|
|
36
|
+
if (existsSync(join(dir, 'package.json')) && existsSync(join(dir, 'examples')))
|
|
37
|
+
return dir;
|
|
38
|
+
dir = dirname(dir);
|
|
39
|
+
}
|
|
40
|
+
throw new Error('repo root (with examples/) not found');
|
|
41
|
+
}
|
|
42
|
+
const TIDES = readFileSync(join(repoRoot(), 'examples', 'alias-poem-story', 'tides.ballad.aster'), 'utf8');
|
|
43
|
+
function seasong(phase) {
|
|
44
|
+
const c = compile(TIDES, { lexicon: BARD_EN });
|
|
45
|
+
assert.ok(c.success && c.core, `tides compile: ${JSON.stringify(c.parseErrors ?? [])}`);
|
|
46
|
+
const ev = evaluate(c.core, 'seasong', { phase });
|
|
47
|
+
assert.ok(ev.success, `seasong: ${ev.error ?? ''}`);
|
|
48
|
+
return String(ev.value);
|
|
49
|
+
}
|
|
50
|
+
describe('examples/alias-poem-story — tides 谣曲 (Match + List)', () => {
|
|
51
|
+
it('Bard 方言源码编译成功', () => {
|
|
52
|
+
const c = compile(TIDES, { lexicon: BARD_EN });
|
|
53
|
+
assert.ok(c.success && c.core, `compile: ${JSON.stringify(c.parseErrors ?? [])}`);
|
|
54
|
+
});
|
|
55
|
+
it('Match(behold)按月相选 omen,四相各不同(押 -eep 韵)', () => {
|
|
56
|
+
// 第一行(moon 行)押 -eep 韵:deep / sleep / leap / creep。
|
|
57
|
+
assert.match(seasong(0), /^The new moon hides; the cove lies black and deep,/);
|
|
58
|
+
assert.match(seasong(1), /^The crescent leans; the shallows stir from sleep,/);
|
|
59
|
+
assert.match(seasong(2), /^The full moon climbs; the breakers rise to leap,/);
|
|
60
|
+
assert.match(seasong(3), /^The old moon wanes; the long grey waters creep,/);
|
|
61
|
+
});
|
|
62
|
+
it('List 驱动意象(数字退到幕后):swell 高度选潮汐意象,不念数字', () => {
|
|
63
|
+
// swell(count)=List.sum(List.range(1,count)) 算出高度,behold 高度选意象(不印数字);
|
|
64
|
+
// 第二行也押 -eep 韵(keep)。phase p → height = sum(1..p)(半开区间 range(1,p+1))。
|
|
65
|
+
assert.match(seasong(0), /and not one wave to keep\.$/); // height 0
|
|
66
|
+
assert.match(seasong(1), /and a single tide to keep\.$/); // height 1
|
|
67
|
+
assert.match(seasong(2), /and a rising tide to keep\.$/); // height 3
|
|
68
|
+
assert.match(seasong(3), /and a flood the shore will keep\.$/); // height 6
|
|
69
|
+
// 台面上看不到阿拉伯数字。
|
|
70
|
+
assert.doesNotMatch(seasong(3), /[0-9]/);
|
|
71
|
+
});
|
|
72
|
+
it('多行续行 + 分行:seasong 是两行押韵对句', () => {
|
|
73
|
+
const out = seasong(2);
|
|
74
|
+
const lines = out.split('\n');
|
|
75
|
+
assert.equal(lines.length, 2, 'moon 行 + swell 行');
|
|
76
|
+
assert.equal(lines[0], 'The full moon climbs; the breakers rise to leap,');
|
|
77
|
+
assert.equal(lines[1], 'and a rising tide to keep.');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=tides-ballad.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tides-ballad.test.js","sourceRoot":"","sources":["../../../test/unit/tides-ballad.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED