halkyon/packages/halkyon_editor/test/l10n/arb_files_test.dart
Tizian 「ティツィアーン」 648dfe4051
refactor(learn): the editor's general parts move to halkyon_editor (ADR 0033, D37)
Todo stores editor documents too, so the document, the editor, its view,
the format bar, links, the clipboard, scripts and EditorBlocks move, with
their strings and tests, to a shared package on the same appflowy_editor
fork. What is Learn's alone stays in Learn on top of it, and what the
editor took from it directly is inverted: EditorBlocks gains textMarks,
formatActions and onEditorClosed, RichContentEditor a wrapEditor, and an
InsertableBlock's name takes the BuildContext. Learn's screens use
LearnContentEditor and LearnContentView, which add Learn's blocks and the
grammar check. Learn behaves as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-07 21:49:48 +01:00

81 lines
2.4 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
/// The messages of the `.arb` file [name] in `lib/l10n/`, without metadata.
Map<String, String> _messages(String name) => {
for (final MapEntry(:key, :value) in (jsonDecode(
File('lib/l10n/$name').readAsStringSync(),
) as Map<String, Object?>).entries)
if (!key.startsWith('@')) key: value! as String,
};
/// The names of the placeholders in [message], with plural and select
/// arguments; the words of their branches don't count. (gen-l10n reads
/// quotes as text here: `use-escaping` is off.)
Set<String> _placeholders(String message) {
final names = <String>{};
// Even depths hold text and placeholders, odd ones a plural's branches.
var depth = 0;
for (var i = 0; i < message.length; i++) {
switch (message[i]) {
case '{':
final name = RegExp(r'\{\s*(\w+)\s*[,}]').matchAsPrefix(message, i);
if (name != null && depth.isEven) {
names.add(name.group(1)!);
}
depth++;
case '}':
depth--;
}
}
return names;
}
void main() {
final template = _messages('halkyon_editor_en.arb');
test('German has every message, with the same placeholders', () {
final german = _messages('halkyon_editor_de.arb');
expect(
template.keys.where((key) => !german.containsKey(key)),
isEmpty,
reason: 'untranslated',
);
expect(
german.keys.where((key) => !template.containsKey(key)),
isEmpty,
reason: 'not in the template',
);
for (final MapEntry(:key, :value) in german.entries) {
expect(_placeholders(value), _placeholders(template[key]!), reason: key);
}
});
test("the English variants override the template's messages only, with "
'the same placeholders', () {
for (final variant in [
'halkyon_editor_en_GB.arb',
'halkyon_editor_en_US.arb',
]) {
for (final MapEntry(:key, :value) in _messages(variant).entries) {
expect(template, contains(key), reason: '$variant: $key');
expect(
_placeholders(value),
_placeholders(template[key]!),
reason: '$variant: $key',
);
}
}
});
test('a placeholder is found also inside a plural', () {
expect(
_placeholders('{count, plural, =1{1 card} other{{count} cards in {t}}}'),
{'count', 't'},
);
expect(_placeholders("Couldn't open {name}"), {'name'});
});
}