判断修改
This commit is contained in:
1 parent
e06afc8c33
commit
4194a200c1
65 files changed
+9617
-109
No files matched your search
@@ -133,7 +133,11 @@ const minimumLabels = {
|
||||
修改散拼母团计划收客数: ['出发日期', '目标计划收客数'],
|
||||
追加散拼子单订房说明: ['预订客户', '出发日期', '追加内容'],
|
||||
独立团信息修改: ['预订客户', '出发日期', '目标修改'],
|
||||
安排变更: ['团号', '目标变更'],
|
||||
安排酒店变更: ['团号', '入住日期', '离店日期', '酒店搜索', '间数'],
|
||||
安排导游变更: ['团号', '导游搜索'],
|
||||
安排用车变更: ['团号', '结算单位搜索', '用车日期', '数量'],
|
||||
安排大交通变更: ['团号', '结算单位搜索', '交通日期', '数量'],
|
||||
'安排其他/备案变更': ['团号', '结算单位搜索', '业务日期'],
|
||||
取消订单: ['预订客户', '出发日期'],
|
||||
恢复订单: ['预订客户', '出发日期'],
|
||||
导出团队文件: ['预订客户', '出发日期', '文件类型']
|
||||
@@ -169,6 +173,17 @@ const fieldLines = (block) =>
|
||||
.slice(1)
|
||||
.filter((line) => line.includes(':'));
|
||||
|
||||
const arrangementUpdateDirectives = ['安排酒店变更', '安排导游变更', '安排用车变更', '安排大交通变更', '安排其他/备案变更'];
|
||||
const catalogPairs = operationSections.flatMap((section) => {
|
||||
const directives = section.directive === '安排变更' ? arrangementUpdateDirectives : [section.directive];
|
||||
const blocks = textBlocks(section.body);
|
||||
return directives.map((directive) => {
|
||||
const matching = blocks.filter((block) => block.startsWith(`${directive}\n`));
|
||||
return { directive, blocks: matching, template: matching[0], example: matching[1] };
|
||||
});
|
||||
});
|
||||
const pairByDirective = new Map(catalogPairs.map((pair) => [pair.directive, pair]));
|
||||
|
||||
const assertTwoBlockContract = (document, directives, source) => {
|
||||
const blocks = textBlocks(document);
|
||||
|
||||
@@ -192,17 +207,22 @@ test('catalog has exactly 19 ordered operations with adjacent template and examp
|
||||
);
|
||||
assert.deepEqual(operationSections.map((section) => section.directive), allDirectives);
|
||||
|
||||
for (const pair of catalogPairs) {
|
||||
assert.equal(pair.blocks.length, 2, `${pair.directive}: expected template and example`);
|
||||
assert.ok(pair.template, `${pair.directive}: missing template block`);
|
||||
assert.ok(pair.example, `${pair.directive}: missing example block`);
|
||||
assert.match(pair.template, /(必填):/u);
|
||||
assert.doesNotMatch(pair.example, /(必填|选填)/u);
|
||||
}
|
||||
for (const section of operationSections) {
|
||||
const template = labeledBlock(section, '模板');
|
||||
const example = labeledBlock(section, '示例');
|
||||
assert.ok(template, `${section.directive}: missing template block`);
|
||||
assert.ok(example, `${section.directive}: missing example block`);
|
||||
assert.equal(textBlocks(section.body).length, section.directive === '安排变更' ? 7 : 2, `${section.directive}: unexpected text blocks`);
|
||||
if (section.directive === '安排变更') {
|
||||
assert.match(textBlocks(section.body)[2], /^安排酒店变更\n团号:.+\n入住日期:.+\n离店日期:.+\n酒店搜索:.+\n间数:9$/u);
|
||||
const blocks = textBlocks(section.body);
|
||||
assert.deepEqual(blocks.map((block) => block.split('\n')[0]), arrangementUpdateDirectives.flatMap((directive) => [directive, directive]));
|
||||
continue;
|
||||
}
|
||||
assert.equal(template.split(/\r?\n/, 1)[0], section.directive);
|
||||
assert.equal(example.split(/\r?\n/, 1)[0], section.directive);
|
||||
assert.equal(textBlocks(section.body).length, 2);
|
||||
assert.ok(labeledBlock(section, '模板'));
|
||||
assert.ok(labeledBlock(section, '示例'));
|
||||
assert.ok(section.body.indexOf('#### 模板') < section.body.indexOf('#### 示例'));
|
||||
}
|
||||
|
||||
@@ -331,9 +351,9 @@ test('Agent parse Schema accepts business facts and rejects execution metadata',
|
||||
});
|
||||
|
||||
test('template fields are marked and examples contain only concrete values', () => {
|
||||
for (const section of operationSections) {
|
||||
const template = labeledBlock(section, '模板');
|
||||
const example = labeledBlock(section, '示例');
|
||||
for (const section of catalogPairs) {
|
||||
const template = section.template;
|
||||
const example = section.example;
|
||||
const fields = fieldLines(template);
|
||||
|
||||
assert.ok(fields.length > 0, `${section.directive}: expected at least one field`);
|
||||
@@ -351,8 +371,8 @@ test('template fields are marked and examples contain only concrete values', ()
|
||||
test('user templates never request ERP internal identifiers and use canonical customer label', () => {
|
||||
const forbiddenLabels = /^(?:母团\s*)?(?:tid|ddid|row_id|行\s*ID|账号|运行编号|测试标记|allowlist)((?:必填|选填)):/im;
|
||||
|
||||
for (const section of operationSections) {
|
||||
const template = labeledBlock(section, '模板');
|
||||
for (const section of catalogPairs) {
|
||||
const template = section.template;
|
||||
assert.doesNotMatch(template, forbiddenLabels);
|
||||
assert.doesNotMatch(template, /^预定客户((?:必填|选填)):/m, 'template must use 预订客户');
|
||||
}
|
||||
@@ -416,7 +436,7 @@ test('the two desktop-approved examples remain exactly copyable', () => {
|
||||
|
||||
test('every operation preserves its explicit minimum-required field set', () => {
|
||||
for (const [directive, expectedLabels] of Object.entries(minimumLabels)) {
|
||||
const template = labeledBlock(sectionByDirective.get(directive), '模板');
|
||||
const template = pairByDirective.get(directive).template;
|
||||
const actualLabels = fieldLines(template)
|
||||
.filter((line) => line.includes('(必填):'))
|
||||
.map((line) => line.slice(0, line.indexOf('(必填):')));
|
||||
@@ -441,9 +461,9 @@ test('modification input asks only for targets and export stays minimal', () =>
|
||||
'修改散拼母团计划收客数',
|
||||
'追加散拼子单订房说明',
|
||||
'独立团信息修改',
|
||||
'安排变更'
|
||||
...arrangementUpdateDirectives
|
||||
]) {
|
||||
assert.doesNotMatch(labeledBlock(sectionByDirective.get(directive), '模板'), forbiddenPreviousValueField);
|
||||
assert.doesNotMatch(pairByDirective.get(directive).template, forbiddenPreviousValueField);
|
||||
}
|
||||
|
||||
assert.deepEqual(minimumLabels['导出团队文件'], ['预订客户', '出发日期', '文件类型']);
|
||||
@@ -497,7 +517,15 @@ test('independent-order updates preserve broad parser targets while arrangement
|
||||
assert.match(updatingSkill, /兼容旧三段 `人数改为8\+1(占)\+1`/);
|
||||
assert.match(updatingSkill, /pax\.child_no_bed=1/);
|
||||
assert.match(sectionByDirective.get('独立团信息修改')?.body ?? '', /未出现的类别保持原值/);
|
||||
assert.match(labeledBlock(sectionByDirective.get('安排变更'), '示例'), /离店日期改为11-05;房间数改为15间/);
|
||||
const updates = sectionByDirective.get('安排变更').body;
|
||||
const [current, legacy] = updates.split('#### 旧版酒店指令兼容说明');
|
||||
assert.ok(legacy, 'legacy hotel syntax must be separately explained');
|
||||
assert.doesNotMatch(current, /^安排变更$|^目标变更[(:]|^安排类型[(:]/mu);
|
||||
assert.match(current, /日期填写原安排日期,只用于定位,不修改日期/);
|
||||
assert.match(legacy, /只接受酒店/);
|
||||
assert.match(legacy, /会实际修改离店日期/);
|
||||
assert.match(legacy, /默认针对酒店表单第一行/);
|
||||
assert.equal(textBlocks(legacy).length, 0, 'legacy syntax must not be presented as a current copyable template');
|
||||
assert.doesNotMatch(catalog, /需求登记:/);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user