feat: revamp README.md for enhanced project clarity and user engagement. Introduce a new project description, features list, and supported exams section. Update environment variable examples in .env.example for better developer onboarding. Refactor GeneratePage and job state management to improve user experience with job dismissal functionality. Enhance AI question generation with new language rules and regeneration capabilities, ensuring compliance with exam standards.
72e7de2 | import { describe, expect, it } from "bun:test"; | |
| import { | |
| getQuestionLanguageErrors, | |
| isLikelyIndonesianContent, | |
| getTargetLanguage, | |
| getExplanationLanguageErrors, | |
| } from "../language-rules"; | |
| describe("language-rules", () => { | |
| it("detects Indonesian question text for JLPT", () => { | |
| const errors = getQuestionLanguageErrors( | |
| { | |
| questionText: "Menurut paragraf tersebut, apakah pernyataan berikut benar?", | |
| options: [ | |
| { key: "A", text: "ใฏใใๆญฃใใใงใ" }, | |
| { key: "B", text: "ใใใใ้ใใพใ" }, | |
| ], | |
| }, | |
| "JLPT", | |
| ); | |
| expect(errors.some((e) => e.includes("questionText"))).toBe(true); | |
| }); | |
| it("accepts Japanese question text for JLPT", () => { | |
| const errors = getQuestionLanguageErrors( | |
| { | |
| questionText: "ใใฎๆ็ซ ใซใใใจใ็ญ่ ใฎไธปๅผตใจใใฆๆญฃใใใใฎใฏใฉใใใ", | |
| options: [ | |
| { key: "A", text: "็ฐๅขๅ้กใฏๆทฑๅปๅใใฆใใ" }, | |
| { key: "B", text: "็ตๆธๆ้ทใ ใใ้่ฆใ " }, | |
| ], | |
| }, | |
| "JLPT", | |
| ); | |
| expect(errors).toHaveLength(0); | |
| }); | |
| it("flags Indonesian options", () => { | |
| expect(isLikelyIndonesianContent("Pilihan yang benar menurut teks")).toBe(true); | |
| }); | |
| it("returns Japanese for JLPT", () => { | |
| expect(getTargetLanguage("JLPT")).toBe("Japanese"); | |
| }); | |
| it("accepts mixed Indonesian + Japanese in explanation", () => { | |
| const errors = getExplanationLanguageErrors( | |
| "Jawaban A benar karena kata ็ฐๅข(ใใใใใ) di paragraf kedua merujuk pada lingkungan hidup.", | |
| ); | |
| expect(errors).toHaveLength(0); | |
| }); | |
| it("rejects explanation with only Japanese and no Indonesian prose", () => { | |
| const errors = getExplanationLanguageErrors( | |
| "ใใฎๆ็ซ ใซใใใจใๆญฃใใ็ญใใฏAใงใใ", | |
| ); | |
| expect(errors.length).toBeGreaterThan(0); | |
| }); | |
| it("rejects English-only explanation", () => { | |
| const errors = getExplanationLanguageErrors( | |
| "The correct answer is A because the passage clearly states the main idea.", | |
| ); | |
| expect(errors.some((e) => e.includes("Bahasa Indonesia"))).toBe(true); | |
| }); | |
| }); | |