Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/chainlit/translations/ar-SA.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"favorites": {
"use": "استخدام رسالة مفضلة",
"headline": "الرسائل المفضلة",
"remove": "إزالة من المفضلة",
"empty": {
"title": "لا توجد رسائل محفوظة بعد",
"description": "ابدأ بإرسال رسالة وقم بتمييزها بنجمة أو ميّز رسالة من محادثاتك السابقة"
Expand Down
1 change: 1 addition & 0 deletions backend/chainlit/translations/da-DK.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"favorites": {
"use": "Brug en favorit besked",
"headline": "Favorit beskeder",
"remove": "Fjern favorit",
"empty": {
"title": "Ingen gemte prompts endnu",
"description": "Start med at sende en prompt og markere den med en stjerne, eller vælg en prompt fra tidligere samtaler"
Expand Down
6 changes: 6 additions & 0 deletions backend/chainlit/translations/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@
"components": {
"MultiSelectInput": {
"placeholder": "Wähle aus..."
},
"DatePickerInput": {
"placeholder": {
"single": "Datum auswählen",
"range": "Datumsbereich auswählen"
}
}
}
}
6 changes: 6 additions & 0 deletions backend/chainlit/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@
"components": {
"MultiSelectInput": {
"placeholder": "Seleziona..."
},
"DatePickerInput": {
"placeholder": {
"single": "Seleziona una data",
"range": "Seleziona un intervallo di date"
}
}
}
}
1 change: 1 addition & 0 deletions backend/chainlit/translations/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
},
"fileUpload": {
"dragDrop": "ここにファイルをドラッグ&ドロップ",
"browse": "ファイルを選択",
"sizeLimit": "制限:",
"errors": {
"failed": "アップロードに失敗しました",
Expand Down
6 changes: 6 additions & 0 deletions backend/chainlit/translations/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@
"components": {
"MultiSelectInput": {
"placeholder": "선택..."
},
"DatePickerInput": {
"placeholder": {
"single": "날짜 선택",
"range": "날짜 범위 선택"
}
}
}
}
40 changes: 40 additions & 0 deletions backend/tests/test_translations.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import json
import os
from io import StringIO
from unittest.mock import patch

import pytest

from chainlit.config import TRANSLATIONS_DIR
from chainlit.translations import compare_json_structures, lint_translation_json


Expand Down Expand Up @@ -384,3 +387,40 @@ def test_compare_preserves_error_order(self):
missing_errors = [e for e in errors if "Missing" in e]
assert len(extra_errors) == 2
assert len(missing_errors) == 3


def _load_translation(filename):
with open(os.path.join(TRANSLATIONS_DIR, filename), encoding="utf-8") as f:
return json.load(f)


_TRUTH_LOCALE = "en-US.json"
_LOCALE_FILES = sorted(f for f in os.listdir(TRANSLATIONS_DIR) if f.endswith(".json"))


class TestTranslationFileParity:
"""Every shipped locale file must carry every key in en-US.json.

This walks the real backend/chainlit/translations/ directory rather than
synthetic dictionaries, so a PR that adds a key to en-US.json without
updating the other locales fails here instead of shipping silently.
"""

@pytest.mark.parametrize("locale_file", _LOCALE_FILES)
def test_locale_has_no_missing_or_mismatched_keys(self, locale_file):
truth = _load_translation(_TRUTH_LOCALE)
# Comparing en-US.json to itself is expected to be trivially clean —
# it is both a locale file and the ground truth.
to_compare = _load_translation(locale_file)

errors = compare_json_structures(truth, to_compare)
# "Extra key" is excluded: a locale carrying a key en-US.json doesn't
# (yet) have is not a rendering regression. Missing keys and structure
# mismatches both are — a key present as the wrong shape (e.g. an
# object where en-US.json has a string) breaks rendering exactly like
# a missing key does, so both must fail here.
relevant = [e for e in errors if "Extra" not in e]

assert relevant == [], (
f"{locale_file} diverges from {_TRUTH_LOCALE}: {relevant}"
)