135 lines
5.9 KiB
JavaScript
135 lines
5.9 KiB
JavaScript
// 回归测试: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] defaultResolutions:modified 默认 'both' ──
|
||
console.log('\n[1] defaultResolutions:modified 默认 "both"');
|
||
|
||
{
|
||
// v4 起:completed=true 任务也参与 diff(按 effective cat name),所以两侧都用
|
||
// completed=false,important 字段不同即可触发 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 有 onlyInA(X)', diff.onlyInA.length >= 1);
|
||
check('diff 有 onlyInB(Z)', 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"');
|
||
|
||
{
|
||
// v4:completed=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] applyResolutions:modified 默认 'both'(无显式 resolution 时) ──
|
||
console.log('\n[3] applyResolutions:modified 默认 "both"(OR 合并)');
|
||
|
||
{
|
||
// 两侧 completed=false;important 不同 → 进 modified;
|
||
// catsB 有 current=true,catsA 是 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) = true(H3 修复:单边 true 不再被吞)',
|
||
t.current === true,
|
||
`t.current=${t.current}, expected true`);
|
||
}
|
||
|
||
// ── [4] current 双边 true → 合并后强制 false(仍是单值指针) ──
|
||
console.log('\n[4] applyResolutions:current 双边 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');
|