Files
Todo-List/scripts/check-conflict-default.mjs
2026-09-12 13:55:57 +08:00

135 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 回归测试H7 — modified 默认选择是 'both'OR 合并状态)
//
// 背景:旧版 defaultResolutions 把 modified 默认设为 'b'(用本地)。这导致
// 磁盘侧修改的标记completed / important / current被默默丢弃 ——
// 用户可能根本不知道,文件里的重要标记就消失了。
//
// 修复v3.7+modified 默认 'both'OR 合并。current 在 v4 起改为:
// - 仅一边 current=true → OR 保留(修复 H3用户在 UI 标 [▶] 后,磁盘
// 还没同步,合并不丢标记)
// - 两边都 current=true → 强制 false仍是单值指针
// 跑法node scripts/check-conflict-default.mjs
import { defaultResolutions, diffCategories, applyResolutions } from '../src/utils/markdown-diff.js';
import { check, summary, printSummary } from './_lib/check.mjs';
const makeCat = (name, kind = 'normal', parentOtherTasks = true, tasks = []) =>
({ name, kind, isSpecial: false, meta: null, parentOtherTasks, tasks });
const container = { name: '全部任务', kind: 'other_tasks', isSpecial: true, meta: null, parentOtherTasks: false, tasks: [] };
const trash = { name: '回收站', kind: 'trash', isSpecial: true, meta: null, parentOtherTasks: false, tasks: [] };
// ── [1] defaultResolutionsmodified 默认 'both' ──
console.log('\n[1] defaultResolutionsmodified 默认 "both"');
{
// v4 起completed=true 任务也参与 diff按 effective cat name所以两侧都用
// completed=falseimportant 字段不同即可触发 modified。
const catsA = [
container,
makeCat('工作', 'normal', true, [
{ text: 'X', completed: false, important: true, current: false }, // 仅 A
]),
makeCat('学习', 'normal', true, [
{ text: 'Y', completed: false, important: true, current: false }, // modified两侧 important 不同)
]),
trash,
];
const catsB = [
container,
makeCat('工作', 'normal', true, [
{ text: 'Z', completed: false, important: false, current: false }, // 仅 B
]),
makeCat('学习', 'normal', true, [
{ text: 'Y', completed: false, important: false, current: false }, // 与 A 文本同important 不同
]),
trash,
];
const diff = diffCategories(catsA, catsB);
const res = defaultResolutions(diff);
check('diff 至少一条 modified', diff.modified.length >= 1,
`modified=${JSON.stringify(diff.modified)}`);
check('diff 有 onlyInAX', diff.onlyInA.length >= 1);
check('diff 有 onlyInBZ', diff.onlyInB.length >= 1);
// modified 默认值
const modifiedKey = diff.modified[0].key;
check(`modified 默认是 'both'`,
res[modifiedKey] === 'both',
`actual=${res[modifiedKey]}, key=${modifiedKey}`);
check(`onlyInA 默认是 'a'`,
res[diff.onlyInA[0].key] === 'a');
check(`onlyInB 默认是 'b'`,
res[diff.onlyInB[0].key] === 'b');
}
// ── [2] 仅 modified无 onlyIn* —— 默认仍 'both' ──
console.log('\n[2] 纯 modified 场景:默认值仍是 "both"');
{
// v4completed=false 两侧 + important 不同 —— 进入 modified 分支。
const catsA = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: true, current: false },
]), trash];
const catsB = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: false, current: false },
]), trash];
const diff = diffCategories(catsA, catsB);
const res = defaultResolutions(diff);
check('纯 modified diff 的 default 是 both',
diff.modified.length === 1 && res[diff.modified[0].key] === 'both',
`modified.len=${diff.modified.length}, res=${JSON.stringify(res)}`);
}
// ── [3] applyResolutionsmodified 默认 'both'(无显式 resolution 时) ──
console.log('\n[3] applyResolutionsmodified 默认 "both"OR 合并)');
{
// 两侧 completed=falseimportant 不同 → 进 modified
// catsB 有 current=truecatsA 是 false —— v4 H3 修复:单边 true 保留 OR 结果。
const catsA = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: false, current: false },
]), trash];
const catsB = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: true, current: true },
]), trash];
const diff = diffCategories(catsA, catsB);
// 不传 resolutions空对象—— 验证 applyResolutions 内部的默认值
const merged = applyResolutions(catsA, diff, {});
const t = merged.find(c => c.name === '工作').tasks[0];
check('默认合并后 completed = OR(false, false) = false两边都没勾选',
t.completed === false,
`t=${JSON.stringify(t)}`);
check('默认合并后 important = OR(false, true) = true',
t.important === true);
check('默认合并后 current = OR(false, true) = trueH3 修复:单边 true 不再被吞)',
t.current === true,
`t.current=${t.current}, expected true`);
}
// ── [4] current 双边 true → 合并后强制 false仍是单值指针 ──
console.log('\n[4] applyResolutionscurrent 双边 true → 强制 false');
{
// 两侧都标了 [▶] —— 矛盾,强制 false 让用户手动重选。
// 必须有其他状态字段不同(这里用 important让两侧落到 modified 分支;
// 完全相同的两侧会被 tasksStateEqual 判 unchanged根本不走 mergeTaskStates。
const catsA = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: false, current: true },
]), trash];
const catsB = [container, makeCat('工作', 'normal', true, [
{ text: 'T', completed: false, important: true, current: true },
]), trash];
const diff = diffCategories(catsA, catsB);
const merged = applyResolutions(catsA, diff, {});
const t = merged.find(c => c.name === '工作').tasks[0];
check('双边 current=true → 合并后 current=false',
t.current === false,
`t=${JSON.stringify(t)}`);
}
printSummary('check-conflict-default');