Skip to content

Commit c4ad41f

Browse files
Added unicode tests for Swedish and arabic characters (#3372)
1 parent 031494f commit c4ad41f

1 file changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import assert from "node:assert/strict";
2+
import type {
3+
EditableTextEditor,
4+
Hats,
5+
HatStyleMap,
6+
TextEditor,
7+
TokenHat,
8+
} from "@cursorless/lib-common";
9+
import {
10+
FakeIDE,
11+
InMemoryTextEditor,
12+
Notifier,
13+
Range,
14+
tokenHatToPlainObject,
15+
} from "@cursorless/lib-common";
16+
import { createCursorlessEngine } from "../cursorlessEngine";
17+
18+
const lettersToPreserve = ["å", "ä", "ö", "ا", "ب", "ت", "ج"];
19+
const unicodeTestCases = [
20+
{ name: "Swedish å", content: "aåa", grapheme: "å" },
21+
{ name: "Swedish ä", content: "aäa", grapheme: "ä" },
22+
{ name: "Swedish ö", content: "oöo", grapheme: "ö" },
23+
{ name: "Arabic alif", content: "aاa", grapheme: "ا" },
24+
{ name: "Arabic taa", content: "aتa", grapheme: "ت" },
25+
{ name: "Arabic jeem", content: "aجa", grapheme: "ج" },
26+
{ name: "Arabic beh, isolated form", content: "اب", grapheme: "ب" },
27+
{ name: "Arabic beh, initial form", content: "ابا", grapheme: "ب" },
28+
{ name: "Arabic beh, medial form", content: "تبت", grapheme: "ب" },
29+
{ name: "Arabic beh, final form", content: "تب", grapheme: "ب" },
30+
];
31+
32+
suite("Unicode support", () => {
33+
for (const { name, content, grapheme } of unicodeTestCases) {
34+
test(`targets ${name}`, async () => {
35+
const ide = new UnicodeTestIDE(content);
36+
ide.configuration.mockConfiguration("tokenHatSplittingMode", {
37+
preserveCase: false,
38+
lettersToPreserve,
39+
symbolsToPreserve: [],
40+
});
41+
const engine = await createCursorlessEngine({
42+
ide,
43+
hats: createTestHats(),
44+
});
45+
const tokenRange = new Range(0, 0, 0, content.length);
46+
const forcedHat: TokenHat = {
47+
hatStyle: "default",
48+
grapheme,
49+
token: {
50+
editor: ide.editor,
51+
range: tokenRange,
52+
offsets: { start: 0, end: content.length },
53+
text: content,
54+
},
55+
hatRange: tokenRange,
56+
};
57+
58+
try {
59+
await engine.hatTokenMap.allocateHats([forcedHat], {
60+
startFresh: true,
61+
});
62+
const hatMap = await engine.hatTokenMap.getReadableMap(false);
63+
64+
assert.deepEqual(
65+
hatMap.getTokenHats(ide.editor).map(tokenHatToPlainObject),
66+
[
67+
{
68+
hatStyle: "default",
69+
grapheme,
70+
hatRange: {
71+
start: { line: 0, character: 1 },
72+
end: { line: 0, character: 2 },
73+
},
74+
},
75+
],
76+
);
77+
78+
await engine.commandApi.runCommand({
79+
version: 7,
80+
spokenForm: `change ${grapheme}`,
81+
action: {
82+
name: "clearAndSetSelection",
83+
target: {
84+
type: "primitive",
85+
mark: {
86+
type: "decoratedSymbol",
87+
symbolColor: "default",
88+
character: grapheme,
89+
},
90+
},
91+
},
92+
usePrePhraseSnapshot: false,
93+
});
94+
95+
assert.equal(ide.editor.document.getText(), "");
96+
} finally {
97+
ide.exit();
98+
}
99+
});
100+
}
101+
});
102+
103+
class UnicodeTestIDE extends FakeIDE {
104+
readonly editor: InMemoryTextEditor;
105+
106+
constructor(content: string) {
107+
super();
108+
this.editor = new InMemoryTextEditor({ ide: this, content });
109+
}
110+
111+
get activeTextEditor() {
112+
return this.editor;
113+
}
114+
115+
get visibleTextEditors() {
116+
return [this.editor];
117+
}
118+
119+
getEditableTextEditor(editor: TextEditor): EditableTextEditor {
120+
assert.ok(this.editor.isEqual(editor));
121+
return this.editor;
122+
}
123+
}
124+
125+
function createTestHats(): Hats {
126+
return {
127+
isEnabled: true,
128+
enabledHatStyles: { default: { penalty: 0 }, blue: { penalty: 1 } },
129+
onDidChangeEnabledHatStyles: new Notifier<[HatStyleMap]>().registerListener,
130+
onDidChangeIsEnabled: new Notifier<[boolean]>().registerListener,
131+
setHatRanges: () => Promise.resolve(),
132+
};
133+
}

0 commit comments

Comments
 (0)