Tolerate missing terminal punctuation in dictée answers

Manual test: the Piper voice (previous commit) is now intelligible,
but typing exactly what's heard ("Les petits chats dorment", no
period) was rejected. The provisional audio never vocalizes
punctuation, so nothing tells the child to add it — penalizing its
absence punishes information they were never given.

DictationAnalyzer now strips terminal punctuation (. ! ? …) from both
sides before comparing, in the exact-match/variant check and before
word alignment, without touching punctuation elsewhere in the
sentence. A real error on the last word is still caught (added test).

A scene-level test reproducing the exact reported interaction
(tests/exercises/test_exercise_host_dictation.gd) failed before the
fix and passes after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Denis Defolie
2026-10-11 19:17:40 +02:00
parent b0dcedb402
commit 02755ced6f
6 changed files with 123 additions and 6 deletions
@@ -65,3 +65,23 @@ func test_accepted_variant_is_treated_as_correct() -> void:
func test_normalizes_before_comparing() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chats dorment.")
assert_true(result.is_correct)
## L'audio provisoire ne fait entendre aucune ponctuation (voir
## docs/specs/decisions.md, point 19/20) : l'omettre n'est pas une erreur.
func test_missing_terminal_punctuation_is_still_correct() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chats dorment")
assert_true(result.is_correct)
func test_different_terminal_punctuation_is_still_correct() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chats dorment!")
assert_true(result.is_correct)
func test_terminal_punctuation_tolerance_does_not_hide_a_real_error_on_the_last_word() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chats dorme")
assert_false(result.is_correct)
assert_eq(result.errors.size(), 1)
assert_eq(result.errors[0]["found"], "dorme")
assert_eq(result.errors[0]["expected"], "dorment.")