1import { describe, expect, it } from "vite-plus/test";
2
3import { markdownProseDirection, textDirection } from "./textDirection";
4
5describe("textDirection", () => {
6 it.each([
7 ["Arabic", "اكتب دالة تجمع الأرقام", "rtl"],
8 ["Hebrew", "תקן את הבאג", "rtl"],
9 ["English", "fix the failing test", "ltr"],
10 [
11 "Arabic that opens with an English term",
12 "StrictMode: يعيد الـ render مرتين في التطوير",
13 "rtl",
14 ],
15 ["English quoting one Arabic word", "translate the label مرحبا for the login screen", "ltr"],
16 [
17 "tied sentences use the whole-text word majority",
18 "Done. تم إصلاح المشكلة في الملف الرئيسي",
19 "rtl",
20 ],
21 ["a tie, by its first word", "React مكتبة", "ltr"],
22 ["a tie that opens in Arabic", "مكتبة React", "rtl"],
23 ["Arabic around numbers and punctuation", "عدّل السطر 42، ثم شغّل الاختبارات (3)", "rtl"],
24 [
25 "mostly Arabic sentences beside one long English one",
26 "هذا مثال على paragraph يحتوي على نص عربي و English words معًا. Arabic text should flow right-to-left while English words like JavaScript, React, and API should remain left-to-right within the same line. الأرقام 1234567890 ورموز مثل @username و #hashtag و 100$ تظهر في الاتجاه الصحيح. هذه جملة لاختبار RTL rendering في المتصفح أو المحرر.",
27 "rtl",
28 ],
29 [
30 "mostly English sentences beside one Arabic one",
31 "Run the migration first. ثم شغّل الاختبارات كلها. Then deploy to staging.",
32 "ltr",
33 ],
34 [
35 "Arabic with inline abbreviations",
36 "هذه جملة عربية تتحدث عن e.g. React i.e. TypeScript JavaScript",
37 "rtl",
38 ],
39 [
40 "an abbreviation at a sentence boundary",
41 "This long English sentence describes the technology sector in the U.S. هذه جملة عربية. وهذه جملة عربية أخرى.",
42 "rtl",
43 ],
44 ])("reads %s", (_, text, direction) => {
45 expect(textDirection(text)).toBe(direction);
46 });
47
48 it("leaves text without letters to its surroundings", () => {
49 expect(textDirection("42 — 7 ✓")).toBeUndefined();
50 });
51});
52
53describe("markdownProseDirection", () => {
54 it.each([
55 [
56 "Hebrew around a code block",
57 "תתקן את זה:\n```ts\nexport function useCheckout(props: CheckoutProps) {\n return props.items.length;\n}\n```\nותריץ שוב",
58 "rtl",
59 ],
60 ["Hebrew around inline code", "לערוך את `apps/web/src/chat.tsx` או להשאיר `useMemo`?", "rtl"],
61 ["Hebrew around double-backtick code", "תבדוק ``const a = `b c d e` + f`` עכשיו", "rtl"],
62 [
63 "Hebrew after a four-backtick fence",
64 "````md\none two three four five six\n````\nשלום עולם, זה עובד",
65 "rtl",
66 ],
67 [
68 "Hebrew after a tilde fence",
69 "~~~\nnpm run build --filter web --force\n~~~\nזה נכשל אצלי",
70 "rtl",
71 ],
72 [
73 "Hebrew before an unclosed fence",
74 "שלום, הנה השגיאה:\n```\nError: cannot find module react dom client",
75 "rtl",
76 ],
77 ["Hebrew around a URL", "ראה https://github.com/pingdotgg/t3code/pull/24050 לפני", "rtl"],
78 ["English around inline code", "Should I edit `useMemo` or keep it?", "ltr"],
79 ["English quoting one Hebrew word", "Please check the שלום label before the release", "ltr"],
80 ])("reads %s", (_, markdown, direction) => {
81 expect(markdownProseDirection(markdown)).toBe(direction);
82 });
83
84 it("leaves markdown without prose letters to its surroundings", () => {
85 expect(markdownProseDirection("```\nconst a = 1;\n```")).toBeUndefined();
86 });
87});