Skip to content

Commit eced2a1

Browse files
committed
chore: 为logCommand 新增了一些测试
1 parent 0e335ca commit eced2a1

1 file changed

Lines changed: 196 additions & 0 deletions

File tree

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import { beforeEach, describe, expect, it } from 'vitest';
2+
import { createPinia, setActivePinia } from 'pinia';
3+
import type { Chunk, LogDocument, Message } from '@/types/log';
4+
import { useHistoryStore } from '@/stores/editor/historyStore';
5+
import { useLogCommands } from '@/stores/project/logCommands';
6+
import { useLogStore } from '@/stores/project/logStore';
7+
import { useStyleStore } from '@/stores/project/styleStore';
8+
9+
function message(id: string, playerName = `player-${id}`): Message {
10+
return {
11+
messageId: id,
12+
chunkId: 'stale',
13+
messageIndex: 99,
14+
playerName,
15+
account: `account-${id}`,
16+
time: new Date('2026-01-01T00:00:00Z'),
17+
content: id,
18+
isOoc: false,
19+
isCommand: false,
20+
role: 'pl',
21+
note: '',
22+
};
23+
}
24+
25+
function chunk(id: string, messages: Message[]): Chunk {
26+
return {
27+
chunkId: id,
28+
docId: 'stale',
29+
chunkName: id,
30+
chunkIndex: 99,
31+
messages,
32+
};
33+
}
34+
35+
function document(id: string, chunks: Chunk[]): LogDocument {
36+
return {
37+
docId: id,
38+
docName: id,
39+
docIndex: 99,
40+
chunks,
41+
};
42+
}
43+
44+
describe('log commands', () => {
45+
beforeEach(() => {
46+
setActivePinia(createPinia());
47+
});
48+
49+
it('normalizes the complete hierarchy after structural edits', () => {
50+
const log = useLogStore();
51+
const commands = useLogCommands();
52+
log.replaceDocuments([
53+
document('doc-a', [chunk('chunk-a', [message('a'), message('b')])]),
54+
document('doc-b', [chunk('chunk-b', [message('c')])]),
55+
]);
56+
57+
expect(commands.moveMessages(['b'], 'chunk-a', 'chunk-b', 0)).toBe(
58+
true,
59+
);
60+
61+
log.documents.forEach((doc, docIndex) => {
62+
expect(doc.docIndex).toBe(docIndex);
63+
doc.chunks.forEach((item, chunkIndex) => {
64+
expect(item.docId).toBe(doc.docId);
65+
expect(item.chunkIndex).toBe(chunkIndex);
66+
item.messages.forEach((itemMessage, messageIndex) => {
67+
expect(itemMessage.chunkId).toBe(item.chunkId);
68+
expect(itemMessage.messageIndex).toBe(messageIndex);
69+
});
70+
});
71+
});
72+
expect(
73+
log
74+
.findChunkById('chunk-b')
75+
?.messages.map((item) => item.messageId),
76+
).toEqual(['b', 'c']);
77+
});
78+
79+
it('captures exactly once for a change and not for a no-op', () => {
80+
const log = useLogStore();
81+
const commands = useLogCommands();
82+
const history = useHistoryStore();
83+
log.replaceDocuments([
84+
document('doc-a', [chunk('chunk-a', [message('a')])]),
85+
]);
86+
87+
expect(commands.updateMessage('chunk-a', 'a', { content: 'a' })).toBe(
88+
false,
89+
);
90+
expect(history.undoStack).toHaveLength(0);
91+
92+
expect(
93+
commands.updateMessage('chunk-a', 'a', { content: 'changed' }),
94+
).toBe(true);
95+
expect(history.undoStack).toHaveLength(1);
96+
97+
history.undo();
98+
expect(log.messagesById.get('a')?.content).toBe('a');
99+
history.redo();
100+
expect(log.messagesById.get('a')?.content).toBe('changed');
101+
});
102+
103+
it('renames and merges an identity as one undoable transaction', () => {
104+
const log = useLogStore();
105+
const commands = useLogCommands();
106+
const history = useHistoryStore();
107+
const style = useStyleStore();
108+
const source = message('a', 'Alice');
109+
const target = message('b', 'Bob');
110+
target.role = 'gm';
111+
log.replaceDocuments([
112+
document('doc-a', [chunk('chunk-a', [source, target])]),
113+
]);
114+
style.syncSystemRulesFromMessages(log.allMessages);
115+
116+
expect(commands.renameIdentity('playerName', 'Alice', 'Bob')).toBe(
117+
true,
118+
);
119+
expect(history.undoStack).toHaveLength(1);
120+
expect(log.allMessages.map((item) => item.playerName)).toEqual([
121+
'Bob',
122+
'Bob',
123+
]);
124+
expect(log.allMessages.map((item) => item.role)).toEqual(['gm', 'gm']);
125+
expect(
126+
style.systemRules.filter(
127+
(rule) => rule.filter.playerName === 'Bob',
128+
),
129+
).toHaveLength(1);
130+
131+
history.undo();
132+
expect(log.allMessages.map((item) => item.playerName)).toEqual([
133+
'Alice',
134+
'Bob',
135+
]);
136+
expect(
137+
style.systemRules.some(
138+
(rule) => rule.filter.playerName === 'Alice',
139+
),
140+
).toBe(true);
141+
});
142+
143+
it('moves, splits, and merges chunks while preserving indexes', () => {
144+
const log = useLogStore();
145+
const commands = useLogCommands();
146+
log.replaceDocuments([
147+
document('doc-a', [
148+
chunk('chunk-a', [message('a'), message('b')]),
149+
chunk('chunk-b', [message('c')]),
150+
]),
151+
document('doc-b', []),
152+
]);
153+
154+
expect(commands.splitChunk('chunk-a', 'b')).toBe(true);
155+
const splitChunk = log.documents[0].chunks[1];
156+
expect(splitChunk.messages.map((item) => item.messageId)).toEqual([
157+
'b',
158+
]);
159+
expect(commands.mergeChunks(['chunk-a', splitChunk.chunkId])).toBe(
160+
true,
161+
);
162+
expect(
163+
log
164+
.findChunkById('chunk-a')
165+
?.messages.map((item) => item.messageId),
166+
).toEqual(['a', 'b']);
167+
expect(commands.moveChunk('chunk-b', 'doc-b', 0)).toBe(true);
168+
expect(log.documents[1].chunks[0].docId).toBe('doc-b');
169+
expect(log.documents[1].chunks[0].chunkIndex).toBe(0);
170+
});
171+
172+
it('deletes a document with project and rule synchronization', () => {
173+
const log = useLogStore();
174+
const commands = useLogCommands();
175+
const history = useHistoryStore();
176+
const style = useStyleStore();
177+
log.replaceDocuments([
178+
document('doc-a', [chunk('chunk-a', [message('a', 'Alice')])]),
179+
document('doc-b', [chunk('chunk-b', [message('b', 'Bob')])]),
180+
]);
181+
style.syncSystemRulesFromMessages(log.allMessages);
182+
183+
expect(commands.deleteDocument('doc-a')).toBe(true);
184+
expect(history.undoStack).toHaveLength(1);
185+
expect(log.documents.map((doc) => doc.docId)).toEqual(['doc-b']);
186+
expect(
187+
style.systemRules.some(
188+
(rule) => rule.filter.playerName === 'Alice',
189+
),
190+
).toBe(false);
191+
expect(log.isImported).toBe(true);
192+
expect(commands.deleteDocument('doc-b')).toBe(true);
193+
expect(log.isImported).toBe(false);
194+
expect(commands.deleteDocument('missing')).toBe(false);
195+
});
196+
});

0 commit comments

Comments
 (0)