Files
aventuriers-des-mots/tests/correction/test_dictation_analyzer.gd
T
Denis Defolie 02755ced6f 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>
2026-10-11 19:17:40 +02:00

88 lines
3.5 KiB
GDScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends GutTest
## Tests de DictationAnalyzer : alignement, classification lexicale/grammaticale
## via annotation, majuscule, variantes acceptees.
var dictation: Dictionary = {
"target_text": "Les petits chats dorment.",
"words":
[
{"text": "Les", "expects_capital": true},
{"text": "petits", "rule_id": "regle_accord_adjectif"},
{"text": "chats"},
{"text": "dorment."},
],
"accepted_variants": [],
}
func test_exact_match_is_correct() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chats dorment.")
assert_true(result.is_correct)
assert_eq(result.errors, [])
func test_annotated_word_error_is_classified_as_grammatical() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petit chats dorment.")
assert_false(result.is_correct)
assert_eq(result.errors.size(), 1)
assert_eq(result.errors[0]["error_type"], "grammatical")
assert_eq(result.errors[0]["rule_id"], "regle_accord_adjectif")
assert_eq(result.errors[0]["found"], "petit")
assert_eq(result.errors[0]["expected"], "petits")
func test_unannotated_word_error_is_unclassified() -> void:
var result := DictationAnalyzer.analyze(dictation, "Les petits chat dorment.")
assert_false(result.is_correct)
assert_eq(result.errors.size(), 1)
assert_eq(result.errors[0]["error_type"], "unclassified")
assert_eq(result.errors[0]["rule_id"], "")
func test_missing_word_does_not_cascade_into_further_errors() -> void:
# Le mot "petits" est omis : sans alignement, cela provoquerait deux
# erreurs en cascade sur "chats" et "dorment.".
var result := DictationAnalyzer.analyze(dictation, "Les chats dorment.")
assert_false(result.is_correct)
assert_eq(result.errors.size(), 1)
assert_eq(result.errors[0]["rule_id"], "regle_accord_adjectif")
func test_missing_capital_is_reported_separately() -> void:
var result := DictationAnalyzer.analyze(dictation, "les petits chats dorment.")
assert_false(result.is_correct)
assert_eq(result.errors.size(), 1)
assert_eq(result.errors[0]["error_type"], "capitalization")
func test_accepted_variant_is_treated_as_correct() -> void:
var dictation_with_variant: Dictionary = dictation.duplicate(true)
dictation_with_variant["accepted_variants"] = ["Les petits chats dorment"]
var result := DictationAnalyzer.analyze(dictation_with_variant, "Les petits chats dorment")
assert_true(result.is_correct)
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.")