mirror of
https://github.com/we-promise/sure.git
synced 2026-09-03 13:51:29 +00:00
test(i18n): cover German locale completeness
This commit is contained in:
@@ -65,12 +65,15 @@ de:
|
||||
authorize: 'Autorisieren'
|
||||
deny: 'Ablehnen'
|
||||
error:
|
||||
go_back: 'Zurück'
|
||||
title: 'Ein Fehler ist aufgetreten'
|
||||
new:
|
||||
title: 'Autorisierung erforderlich'
|
||||
prompt: '%{client_name} Zugriff auf dein Konto erlauben?'
|
||||
able_to: 'Diese Anwendung kann Folgendes tun'
|
||||
show:
|
||||
authorization_code_label: 'Autorisierungscode:'
|
||||
copy_instructions: 'Kopiere diesen Code und füge ihn in der Anwendung ein.'
|
||||
title: 'Autorisierungscode'
|
||||
form_post:
|
||||
title: 'Dieses Formular absenden'
|
||||
|
||||
@@ -6,7 +6,7 @@ de:
|
||||
importing_wallets: Wallets werden von CoinStats importiert...
|
||||
checking_configuration: Wallet-Konfiguration wird geprüft...
|
||||
wallets_need_setup:
|
||||
one: "1 Wallet muss eingerichtet werden..."
|
||||
one: "%{count} Wallet muss eingerichtet werden..."
|
||||
other: "%{count} Wallets müssen eingerichtet werden..."
|
||||
processing_holdings: Bestände werden verarbeitet...
|
||||
calculating_balances: Salden werden berechnet...
|
||||
|
||||
@@ -4,8 +4,8 @@ de:
|
||||
attributes:
|
||||
user:
|
||||
email: E-Mail
|
||||
family: Familie
|
||||
family_id: Familie
|
||||
family: "%{moniker}"
|
||||
family_id: "%{moniker}"
|
||||
first_name: Vorname
|
||||
last_name: Nachname
|
||||
password: Passwort
|
||||
@@ -18,4 +18,3 @@ de:
|
||||
cannot_deactivate_admin_with_other_users: Admin kann das Konto nicht löschen, solange noch andere Benutzer vorhanden sind Bitte zuerst alle Mitglieder löschen
|
||||
profile_image:
|
||||
invalid_file_size: Dateigröße muss kleiner als %{max_megabytes}MB sein
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ de:
|
||||
one: "%{count} Konto verfügbar"
|
||||
other: "%{count} Konten verfügbar"
|
||||
select_all: Alle auswählen
|
||||
historical_import: Verlaufsimport
|
||||
import_selected: Ausgewählte importieren
|
||||
cancel: Abbrechen
|
||||
creating: Importiere...
|
||||
|
||||
@@ -110,6 +110,7 @@ de:
|
||||
creating_accounts: Konten werden angelegt …
|
||||
header_subtitle: Wähl die passende Kontoart für deine importierten Konten
|
||||
historical_data_range: 'Zeitraum der Historie:'
|
||||
psd2_savings_notice: 'Hinweis: Einige regulierte französische Sparkonten (Livret A, PEL, LEP, LDDS) sind über Open Banking (PSD2) nur eingeschränkt oder gar nicht verfügbar. Wenn ein Sparkonto fehlt, kannst du es manuell hinzufügen.'
|
||||
sync_start_date_help: Wähl, wie weit zurück die Transaktionshistorie geholt werden soll. Verfügbar sind maximal 2 Jahre.
|
||||
sync_start_date_label: 'Transaktionen synchronisieren ab:'
|
||||
title: Enable-Banking-Konten einrichten
|
||||
|
||||
@@ -94,11 +94,13 @@ de:
|
||||
heading: Archiviert
|
||||
chips:
|
||||
all: Alle
|
||||
aria: Ziele nach Status filtern
|
||||
behind: Hinter Plan
|
||||
completed: Erreicht
|
||||
no_target_date: Offen
|
||||
on_track: Im Plan
|
||||
paused: Pausiert
|
||||
chips_aria: Ziele nach Status filtern
|
||||
empty_filtered: Kein Ziel passt.
|
||||
goals_section:
|
||||
heading: Ziele
|
||||
@@ -152,6 +154,9 @@ de:
|
||||
pause:
|
||||
invalid_transition: Dieses Ziel lässt sich in seinem aktuellen Zustand nicht pausieren.
|
||||
success: Ziel pausiert.
|
||||
perform_transition!:
|
||||
invalid_transition: Ziel kann nicht in diesen Status wechseln.
|
||||
success: Ziel aktualisiert.
|
||||
reopen:
|
||||
invalid_transition: Dieses Ziel lässt sich in seinem aktuellen Zustand nicht wieder öffnen.
|
||||
success: Ziel wieder geöffnet.
|
||||
|
||||
@@ -42,12 +42,12 @@ de:
|
||||
fields:
|
||||
api_token:
|
||||
label: "API-Token"
|
||||
description: "Ihr schreibgeschützter API-Token aus dem IndexaCapital Dashboard"
|
||||
description: "Dein schreibgeschützter API-Token aus dem IndexaCapital Dashboard"
|
||||
placeholder_new: "API-Token hier einfügen"
|
||||
placeholder_update: "Neuen API-Token zum Aktualisieren eingeben"
|
||||
username:
|
||||
label: "Benutzername"
|
||||
description: "Ihr IndexaCapital Benutzername/E-Mail"
|
||||
description: "Dein IndexaCapital Benutzername/E-Mail"
|
||||
placeholder_new: "Benutzername hier einfügen"
|
||||
placeholder_update: "Neuen Benutzernamen zum Aktualisieren eingeben"
|
||||
document:
|
||||
@@ -57,7 +57,7 @@ de:
|
||||
placeholder_update: "Neue Dokument-ID zum Aktualisieren eingeben"
|
||||
password:
|
||||
label: "Passwort"
|
||||
description: "Ihr IndexaCapital Passwort"
|
||||
description: "Dein IndexaCapital Passwort"
|
||||
placeholder_new: "Passwort hier einfügen"
|
||||
placeholder_update: "Neues Passwort zum Aktualisieren eingeben"
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ de:
|
||||
invitation_mailer:
|
||||
invite_email:
|
||||
accept_button: Einladung annehmen
|
||||
body: "%{inviter} hat dich eingeladen, der Familie %{family} auf %{product_name} beizutreten."
|
||||
body: "%{inviter} hat dich eingeladen, der %{family} %{moniker} auf %{product_name} beizutreten."
|
||||
expiry_notice: Diese Einladung läuft in %{days} Tagen ab.
|
||||
greeting: Willkommen bei %{product_name}!
|
||||
|
||||
@@ -24,5 +24,5 @@ de:
|
||||
role_label: Rolle
|
||||
role_member: Mitglied
|
||||
submit: Einladung senden
|
||||
subtitle: Lad jemanden in deine %{moniker} ein
|
||||
subtitle: Lad jemanden in dein %{moniker}-Konto auf %{product_name} ein
|
||||
title: Jemanden einladen
|
||||
|
||||
@@ -8,7 +8,7 @@ de:
|
||||
description: "Mit %{name} verknüpfen"
|
||||
create:
|
||||
default_name: Kraken
|
||||
success: Erfolgreich mit Kraken verbunden. Ihr Börsenkonto wird synchronisiert.
|
||||
success: Erfolgreich mit Kraken verbunden. Dein Börsenkonto wird synchronisiert.
|
||||
update:
|
||||
success: Kraken-Verbindung erfolgreich aktualisiert.
|
||||
destroy:
|
||||
@@ -66,7 +66,7 @@ de:
|
||||
status_never: Noch nie synchronisiert
|
||||
delete: Löschen
|
||||
no_accounts_title: Keine Konten gefunden
|
||||
no_accounts_message: Ihr Kraken-Börsenkonto erscheint hier nach der Synchronisierung.
|
||||
no_accounts_message: Dein Kraken-Börsenkonto erscheint hier nach der Synchronisierung.
|
||||
setup_needed: Konto bereit zum Import
|
||||
setup_description: Importier diese Kraken-Verbindung als Krypto-Börsenkonto.
|
||||
setup_action: Konto importieren
|
||||
|
||||
@@ -20,6 +20,7 @@ de:
|
||||
other: "%{count} Konten mit leerem Namen können nicht verknüpft werden"
|
||||
link_failed: Konten konnten nicht verknüpft werden
|
||||
no_accounts_selected: Bitte wähle mindestens ein Konto aus
|
||||
no_api_key: Der Lunch-Flow-API-Key ist nicht eingerichtet. Richte ihn in den Einstellungen ein.
|
||||
partial_invalid: "%{created_count} Konto/Konten verknüpft, %{already_linked_count} waren bereits verknüpft, %{invalid_count} hatten ungültige Namen"
|
||||
partial_success: "%{created_count} Konto/Konten erfolgreich verknüpft. %{already_linked_count} Konto/Konten waren bereits verknüpft: %{already_linked_names}"
|
||||
success:
|
||||
@@ -50,6 +51,7 @@ de:
|
||||
link_accounts: Ausgewählte Konten verknüpfen
|
||||
no_accounts_found: Keine Konten gefunden. Bitte überprüfe deine API-Key-Konfiguration.
|
||||
no_api_key: Lunch‑Flow-API-Schlüssel ist nicht konfiguriert. Bitte konfiguriere ihn in den Einstellungen.
|
||||
no_credentials_configured: Richte zuerst deine Lunch-Flow-Zugangsdaten in den Anbietereinstellungen ein.
|
||||
no_name_placeholder: "(Kein Name)"
|
||||
title: Lunch‑Flow-Konten auswählen
|
||||
select_existing_account:
|
||||
@@ -63,6 +65,7 @@ de:
|
||||
no_account_specified: Kein Konto angegeben
|
||||
no_accounts_found: Keine Lunch‑Flow-Konten gefunden. Bitte überprüfe deine API-Key-Konfiguration.
|
||||
no_api_key: Lunch‑Flow-API-Schlüssel ist nicht konfiguriert. Bitte konfiguriere ihn in den Einstellungen.
|
||||
no_credentials_configured: Richte zuerst deine Lunch-Flow-Zugangsdaten in den Anbietereinstellungen ein.
|
||||
no_name_placeholder: "(Kein Name)"
|
||||
title: "%{account_name} mit Lunch‑Flow verknüpfen"
|
||||
link_existing_account:
|
||||
@@ -72,6 +75,7 @@ de:
|
||||
lunchflow_account_already_linked: Dieses Lunch‑Flow-Konto ist bereits mit einem anderen Konto verknüpft
|
||||
lunchflow_account_not_found: Lunch‑Flow-Konto nicht gefunden
|
||||
missing_parameters: Erforderliche Parameter fehlen
|
||||
no_api_key: Der Lunch-Flow-API-Key ist nicht eingerichtet. Richte ihn in den Anbietereinstellungen ein.
|
||||
success: "%{account_name} erfolgreich mit Lunch‑Flow verknüpft"
|
||||
setup_accounts:
|
||||
account_type_label: "Kontotyp:"
|
||||
|
||||
@@ -19,9 +19,9 @@ de:
|
||||
merge: Händler zusammenführen
|
||||
title: Händler
|
||||
family_title: Händler deiner %{moniker}
|
||||
family_empty: Noch keine Händler der Familie vorhanden
|
||||
family_empty: Noch keine Händler der %{moniker} vorhanden
|
||||
provider_title: Anbieter-Händler
|
||||
provider_empty: Noch keine Anbieter-Händler mit dieser Familie verbunden
|
||||
provider_empty: Noch keine Anbieter-Händler mit dieser %{moniker} verbunden
|
||||
provider_read_only: Anbieter-Händler werden von deinen verbundenen Instituten synchronisiert. Sie lassen sich hier nicht bearbeiten.
|
||||
provider_info: Diese Händler wurden automatisch von deinen Bankverbindungen oder der KI erkannt. Du kannst sie bearbeiten, um deine eigene Kopie zu erstellen, oder sie entfernen, um sie von deinen Transaktionen zu trennen.
|
||||
unlinked_title: Kürzlich getrennt
|
||||
|
||||
@@ -49,7 +49,11 @@ de:
|
||||
loading_message: Questrade-Konten werden geladen …
|
||||
loading_title: Wird geladen
|
||||
panel:
|
||||
disconnect: Trennen
|
||||
disconnect_confirm: Diese Questrade-Verbindung wirklich trennen? Dadurch werden alle synchronisierten Kontodaten entfernt.
|
||||
eyebrow: Questrade
|
||||
field_descriptions: 'Erläuterung der Felder:'
|
||||
help_text: Sure nutzt diese Zugangsdaten nur, um deine Questrade-Konten, Bestände und Aktivitäten zu synchronisieren.
|
||||
fields:
|
||||
api_server:
|
||||
description: Dein Questrade-API-Server
|
||||
@@ -68,6 +72,13 @@ de:
|
||||
setup_instructions: 'So richtest du es ein:'
|
||||
status_configured_html: Eingerichtet und einsatzbereit. Im Reiter <a href="%{accounts_path}" class="link">Konten</a> verwaltest und richtest du Konten ein.
|
||||
status_not_configured: Nicht eingerichtet
|
||||
steps:
|
||||
s1_html: Öffne dein <strong>Questrade-Dashboard</strong>.
|
||||
s2: Erstelle oder kopiere deine API-Zugangsdaten.
|
||||
s3_html: Füge den <strong>Refresh Token</strong> und den API-Server unten ein.
|
||||
s4: Speichere die Verbindung.
|
||||
s5: Starte einen Sync, um Konten zu finden.
|
||||
s6: Richte die gefundenen Konten im Konten-Reiter ein.
|
||||
step_1: Öffne dein Questrade-Dashboard und hol dir deine Zugangsdaten
|
||||
step_2: Trag die Zugangsdaten unten ein und klick auf Speichern
|
||||
step_3: Nach erfolgreicher Verbindung richtest du im Reiter „Konten“ die neuen Konten ein
|
||||
@@ -115,15 +126,21 @@ de:
|
||||
all_accounts_already_linked: Alle Questrade-Konten sind bereits verknüpft
|
||||
api_error: 'API-Fehler: %{message}'
|
||||
balance_label: 'Saldo:'
|
||||
buttons:
|
||||
cancel: Abbrechen
|
||||
link: Verknüpfen
|
||||
cancel: Abbrechen
|
||||
cancel_button: Abbrechen
|
||||
configure_name_in_provider: Import nicht möglich – hinterleg den Kontonamen in Questrade
|
||||
connect_hint: Verbinde ein Questrade-Konto, um den automatischen Abgleich zu nutzen.
|
||||
description: Wähl ein Questrade-Konto, das mit diesem Konto verknüpft werden soll. Transaktionen werden automatisch abgeglichen und Dubletten entfernt.
|
||||
dialog_title: Mit einem Questrade-Konto verknüpfen
|
||||
header: Mit Questrade verknüpfen
|
||||
link_account: Konto verknüpfen
|
||||
link_button: Dieses Konto verknüpfen
|
||||
linking_label: Verknüpft wird
|
||||
linking_to: 'Wird verknüpft mit:'
|
||||
none_available: Keine unverknüpften Questrade-Konten verfügbar.
|
||||
no_account_specified: Kein Konto angegeben
|
||||
no_accounts: Keine unverknüpften Questrade-Konten gefunden.
|
||||
no_accounts_found: Keine Questrade-Konten gefunden. Prüf die Konfiguration deines API-Keys.
|
||||
@@ -132,9 +149,11 @@ de:
|
||||
no_name_placeholder: "(kein Name)"
|
||||
settings_link: Zu den Anbietereinstellungen
|
||||
subtitle: Ein Questrade-Konto wählen
|
||||
page_title: Questrade-Konto verknüpfen
|
||||
title: "%{account_name} mit Questrade verknüpfen"
|
||||
setup_accounts:
|
||||
account_type_label: 'Kontoart:'
|
||||
all_linked: Alle Questrade-Konten sind bereits eingerichtet.
|
||||
account_types:
|
||||
credit_card: Kreditkarte
|
||||
crypto: Krypto-Konto
|
||||
@@ -149,6 +168,10 @@ de:
|
||||
all_accounts_linked: Alle deine Questrade-Konten sind bereits eingerichtet.
|
||||
api_error: 'API-Fehler: %{message}'
|
||||
balance: Saldo
|
||||
buttons:
|
||||
cancel: Abbrechen
|
||||
create: Konten anlegen
|
||||
done: Fertig
|
||||
cancel: Abbrechen
|
||||
choose_account_type: 'Wähl für jedes Questrade-Konto die passende Kontoart:'
|
||||
create_accounts: Konten anlegen
|
||||
@@ -156,6 +179,8 @@ de:
|
||||
creating_accounts: Konten werden angelegt …
|
||||
fetch_failed: Konten ließen sich nicht abrufen
|
||||
historical_data_range: 'Zeitraum der Historie:'
|
||||
dialog_title: Deine Questrade-Konten einrichten
|
||||
import_as: Importieren als
|
||||
import_selected: Gewählte Konten importieren
|
||||
instructions: Wähl die Konten, die du aus Questrade importieren willst. Du kannst mehrere auswählen.
|
||||
no_accounts: Aus dieser Questrade-Verbindung gibt es keine unverknüpften Konten.
|
||||
@@ -163,6 +188,7 @@ de:
|
||||
no_api_key: Der Questrade-API-Key ist nicht eingerichtet. Prüf deine Verbindungseinstellungen.
|
||||
select_all: Alle auswählen
|
||||
subtitle: Wähl die passende Kontoart für deine importierten Konten
|
||||
page_title: Questrade-Konten einrichten
|
||||
subtype_labels:
|
||||
credit_card: ''
|
||||
crypto: ''
|
||||
@@ -203,6 +229,10 @@ de:
|
||||
sync_start_date_help: Wähl, wie weit zurück die Transaktionshistorie geholt werden soll.
|
||||
sync_start_date_label: 'Transaktionen synchronisieren ab:'
|
||||
title: Questrade-Konten einrichten
|
||||
types:
|
||||
depository: Giro- oder Sparkonto
|
||||
investment: Investmentkonto
|
||||
skip: Überspringen
|
||||
setup_required:
|
||||
go_to_provider_settings: Zu den Anbietereinstellungen
|
||||
not_configured_description: Leg deine Questrade-Verbindung in den Anbietereinstellungen an und komm dann hierher zurück, um Konten zu verknüpfen.
|
||||
|
||||
@@ -15,7 +15,7 @@ de:
|
||||
success: Du hast dich erfolgreich registriert
|
||||
new:
|
||||
invitation_message: "%{inviter} hat dich eingeladen als %{role} beizutreten"
|
||||
join_family_title: "%{family} beitreten"
|
||||
join_family_title: "%{family} %{moniker} beitreten"
|
||||
role_admin: Administrator
|
||||
role_guest: Gast
|
||||
role_member: Mitglied
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
de:
|
||||
reports:
|
||||
index:
|
||||
period_aria: Berichtszeitraum
|
||||
title: Berichte
|
||||
subtitle: Umfassende Einblicke in deine finanzielle Situation
|
||||
export: CSV exportieren
|
||||
|
||||
@@ -23,7 +23,7 @@ de:
|
||||
payments:
|
||||
show:
|
||||
page_title: Zahlung
|
||||
subscription_subtitle: Aktualisiere dein Abonnement und deine Zahlungsdetails
|
||||
subscription_subtitle: Aktualisiere deine Kreditkartendaten
|
||||
subscription_title: Abonnement verwalten
|
||||
choose_level: Stufe wählen
|
||||
contributions_note: Beiträge zu %{product_name} erscheinen hier.
|
||||
@@ -177,6 +177,10 @@ de:
|
||||
encryption_warning:
|
||||
generate: 'Einen Satz erzeugst du mit: bin/rails db:encryption:init'
|
||||
intro: 'Sensible Daten wie API-Keys, Anbieter-Tokens, MFA-Geheimnisse und personenbezogene Angaben liegen unverschlüsselt auf der Platte. Setze diese Schlüssel in deinen Umgebungsvariablen oder Rails-Credentials, um die Verschlüsselung einzuschalten:'
|
||||
keys:
|
||||
- ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
|
||||
- ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
|
||||
- ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
|
||||
title: Verschlüsselungsschlüssel fehlen
|
||||
settings_nav:
|
||||
accounts_label: Konten
|
||||
|
||||
@@ -34,6 +34,7 @@ de:
|
||||
message: Neue Daten verfügbar
|
||||
refresh: Aktualisieren
|
||||
transaction_tabs:
|
||||
aria: Transaktionstyp
|
||||
expense: Ausgabe
|
||||
income: Einnahme
|
||||
transfer: Überweisung
|
||||
|
||||
@@ -86,7 +86,7 @@ de:
|
||||
all_skipped: "Alle Konten wurden übersprungen. Es wurden keine Konten erstellt."
|
||||
no_accounts: "Keine Konten zum Einrichten."
|
||||
success:
|
||||
one: "Ein SimpleFIN-Konto erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
|
||||
one: "%{count} SimpleFIN-Konto erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
|
||||
other: "%{count} SimpleFIN-Konten erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
|
||||
stale_accounts_processed: "Veraltete Konten: %{deleted} gelöscht, %{moved} verschoben."
|
||||
stale_accounts_errors:
|
||||
|
||||
@@ -30,7 +30,7 @@ en:
|
||||
label: "SimpleFIN Setup Token:"
|
||||
placeholder: "Paste your SimpleFIN setup token here..."
|
||||
help_text: "The token should be a long string starting with letters and numbers"
|
||||
title: Update SimpleFin Connection
|
||||
title: Update SimpleFIN Connection
|
||||
header_subtitle: Get a new setup token to reconnect your SimpleFIN account
|
||||
connection_needs_update: "Your SimpleFIN connection needs to be updated:"
|
||||
step_1_html: "Visit <a href=\"https://bridge.simplefin.org/simplefin/create\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-link hover:text-link underline\">SimpleFIN Bridge</a> to create a new setup token"
|
||||
@@ -39,9 +39,9 @@ en:
|
||||
update: Update
|
||||
cancel: Cancel
|
||||
setup_accounts:
|
||||
title: Set Up Your SimpleFin Accounts
|
||||
title: Set Up Your SimpleFIN Accounts
|
||||
header_subtitle: Choose the correct account types for your imported accounts
|
||||
choose_account_type: "Choose the correct account type for each SimpleFin account:"
|
||||
choose_account_type: "Choose the correct account type for each SimpleFIN account:"
|
||||
account_type_checking_savings: Checking or Savings
|
||||
account_type_checking_savings_desc: Regular bank accounts
|
||||
account_type_credit_card: Credit Card
|
||||
@@ -53,7 +53,7 @@ en:
|
||||
account_type_other_asset: Other Asset
|
||||
account_type_other_asset_desc: Everything else
|
||||
transaction_history_title: "Transaction History:"
|
||||
transaction_history_description_html: "SimpleFin typically provides <strong>60-90 days</strong> of transaction history, depending on your bank. After initial setup, new transactions will sync automatically going forward. Historical data availability varies by institution and account type."
|
||||
transaction_history_description_html: "SimpleFIN typically provides <strong>60-90 days</strong> of transaction history, depending on your bank. After initial setup, new transactions will sync automatically going forward. Historical data availability varies by institution and account type."
|
||||
account_type_label: "Account Type:"
|
||||
create_accounts: Create Accounts
|
||||
creating_accounts: Creating Accounts...
|
||||
|
||||
@@ -14,6 +14,8 @@ de:
|
||||
valuations: Wert
|
||||
value: Wert
|
||||
new:
|
||||
amount: Betrag
|
||||
submit: Kontostand hinzufügen
|
||||
title: Neuer Kontostand
|
||||
show:
|
||||
amount: Betrag
|
||||
@@ -38,8 +40,8 @@ de:
|
||||
title: Saldo aktualisieren
|
||||
update: Aktualisieren
|
||||
confirmation_contents:
|
||||
action_set: 'Neu:'
|
||||
action_update: 'Geändert:'
|
||||
action_set: gesetzt
|
||||
action_update: aktualisiert
|
||||
account_balance: Kontostand
|
||||
asset_value: Vermögenswert
|
||||
balance: Saldo
|
||||
@@ -53,7 +55,7 @@ de:
|
||||
"on": am
|
||||
property_value: Immobilienwert
|
||||
recalculate_notice: Alle späteren Transaktionen und Salden werden auf Basis dieser %{change_or_update} neu berechnet.
|
||||
this_will: Damit wird der Kontowert zum
|
||||
this_will: Damit wird der Kontowert %{action_verb} am
|
||||
to: auf
|
||||
to_colon: 'auf:'
|
||||
total_account_value: Gesamtwert des Kontos
|
||||
|
||||
@@ -84,6 +84,7 @@ de:
|
||||
description: Wähl das Wise-Währungsguthaben, das mit diesem Konto verknüpft werden soll. Transaktionen werden automatisch abgeglichen.
|
||||
link_account: Guthaben verknüpfen
|
||||
no_accounts_found: Keine unverknüpften Wise-Guthaben gefunden.
|
||||
not_found: Wise-Guthaben nicht gefunden.
|
||||
title: "%{account_name} mit Wise verknüpfen"
|
||||
select_profiles:
|
||||
already_connected_label: Bereits verbunden
|
||||
|
||||
@@ -1,13 +1,62 @@
|
||||
require "i18n/tasks"
|
||||
require "pathname"
|
||||
require "set"
|
||||
require "yaml"
|
||||
|
||||
# We're currently skipping some i18n tests to speed up development. Eventually, we'll make a dedicated
|
||||
# project for getting i18n working. More details on that here:
|
||||
# https://github.com/maybe-finance/maybe/issues/1225
|
||||
class I18nTest < ActiveSupport::TestCase
|
||||
GERMAN_COVERAGE_GLOBS = [
|
||||
"config/locales/breadcrumbs/*.yml",
|
||||
"config/locales/doorkeeper.*.yml",
|
||||
"config/locales/mailers/**/*.yml",
|
||||
"config/locales/models/**/*.yml",
|
||||
"config/locales/views/**/*.yml"
|
||||
]
|
||||
|
||||
def setup
|
||||
@i18n = I18n::Tasks::BaseTask.new
|
||||
end
|
||||
|
||||
def test_german_locale_files_parse
|
||||
german_locale_paths.each do |path|
|
||||
assert_nothing_raised do
|
||||
YAML.load_file(path, aliases: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_german_app_locale_covers_english_keys
|
||||
missing_keys = english_app_locale_leaves.keys.filter_map do |key|
|
||||
key unless translation_present?(german_app_locale_tree, key)
|
||||
end
|
||||
|
||||
assert_empty missing_keys.sort, "Missing German i18n keys:\n#{missing_keys.sort.join("\n")}"
|
||||
end
|
||||
|
||||
def test_german_app_locale_interpolations_match_english
|
||||
mismatches = english_app_locale_leaves.filter_map do |key, english_value|
|
||||
next unless english_value.is_a?(String)
|
||||
|
||||
german_value = translation_at(german_app_locale_tree, key)
|
||||
next if german_value.nil?
|
||||
|
||||
expected_interpolations = interpolation_keys(english_value)
|
||||
german_values =
|
||||
if german_value.is_a?(Hash)
|
||||
flatten_leaves(german_value).values.grep(String)
|
||||
else
|
||||
[ german_value ]
|
||||
end
|
||||
|
||||
bad_values = german_values.reject { |value| interpolation_keys(value) == expected_interpolations }
|
||||
"#{key}: expected #{expected_interpolations.to_a.sort}, got #{bad_values.map { |value| interpolation_keys(value).to_a.sort }.uniq}" if bad_values.any?
|
||||
end
|
||||
|
||||
assert_empty mismatches, "German i18n interpolation mismatches:\n#{mismatches.join("\n")}"
|
||||
end
|
||||
|
||||
def test_no_missing_keys
|
||||
skip "Skipping missing keys test"
|
||||
missing_keys = @i18n.missing_keys(locales: [ :en ])
|
||||
@@ -38,4 +87,74 @@ class I18nTest < ActiveSupport::TestCase
|
||||
"Please run `i18n-tasks check-consistent-interpolations' to show them"
|
||||
assert_empty inconsistent_interpolations, error_message
|
||||
end
|
||||
|
||||
private
|
||||
def english_app_locale_leaves
|
||||
@english_app_locale_leaves ||= flatten_leaves(english_app_locale_tree)
|
||||
end
|
||||
|
||||
def english_app_locale_tree
|
||||
@english_app_locale_tree ||= locale_tree("en")
|
||||
end
|
||||
|
||||
def german_app_locale_tree
|
||||
@german_app_locale_tree ||= locale_tree("de")
|
||||
end
|
||||
|
||||
def german_locale_paths
|
||||
@german_locale_paths ||= locale_paths.select { |path| path.basename.to_s.match?(/(^|[._-])de\.yml\z/) }
|
||||
end
|
||||
|
||||
def locale_tree(locale)
|
||||
locale_paths.each_with_object({}) do |path, tree|
|
||||
data = YAML.load_file(path, aliases: true) || {}
|
||||
deep_merge!(tree, data.fetch(locale, {}))
|
||||
end
|
||||
end
|
||||
|
||||
def locale_paths
|
||||
@locale_paths ||= GERMAN_COVERAGE_GLOBS.flat_map { |glob| Pathname.pwd.glob(glob) }.uniq
|
||||
end
|
||||
|
||||
def deep_merge!(target, source)
|
||||
source.each do |key, value|
|
||||
if target[key].is_a?(Hash) && value.is_a?(Hash)
|
||||
deep_merge!(target[key], value)
|
||||
else
|
||||
target[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
target
|
||||
end
|
||||
|
||||
def flatten_leaves(value, prefix = [], result = {})
|
||||
case value
|
||||
when Hash
|
||||
value.each { |key, child| flatten_leaves(child, prefix + [ key.to_s ], result) }
|
||||
else
|
||||
result[prefix.join(".")] = value
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def translation_at(tree, key)
|
||||
key.split(".").reduce(tree) do |current, segment|
|
||||
return nil unless current.is_a?(Hash) && current.key?(segment)
|
||||
|
||||
current[segment]
|
||||
end
|
||||
end
|
||||
|
||||
def translation_present?(tree, key)
|
||||
value = translation_at(tree, key)
|
||||
return false if value.nil?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def interpolation_keys(value)
|
||||
value.scan(/%\{([^}]+)\}/).flatten.to_set
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user