import Testing @testable import SharedModels @Suite("AnswerGrader") struct AnswerGraderTests { @Test("exact match is correct") func exact() { #expect(AnswerGrader.grade(userText: "tengo", canonical: "tengo") == .correct) #expect(AnswerGrader.grade(userText: "Tengo", canonical: "tengo") == .correct) #expect(AnswerGrader.grade(userText: " tengo ", canonical: "tengo") == .correct) } @Test("missing accent is close") func missingAccent() { #expect(AnswerGrader.grade(userText: "esta", canonical: "está") == .close) #expect(AnswerGrader.grade(userText: "nino", canonical: "niño") == .close) #expect(AnswerGrader.grade(userText: "asi", canonical: "así") == .close) } @Test("single-char typo is close") func singleCharTypo() { // deletion #expect(AnswerGrader.grade(userText: "tngo", canonical: "tengo") == .close) // insertion #expect(AnswerGrader.grade(userText: "tengoo", canonical: "tengo") == .close) // substitution #expect(AnswerGrader.grade(userText: "tengu", canonical: "tengo") == .close) } @Test("two-char typo is wrong") func twoCharTypo() { #expect(AnswerGrader.grade(userText: "tngu", canonical: "tengo") == .wrong) } @Test("empty is wrong") func empty() { #expect(AnswerGrader.grade(userText: "", canonical: "tengo") == .wrong) #expect(AnswerGrader.grade(userText: " ", canonical: "tengo") == .wrong) } @Test("alternates accepted") func alternates() { #expect(AnswerGrader.grade(userText: "flaca", canonical: "delgada", alternates: ["flaca"]) == .correct) #expect(AnswerGrader.grade(userText: "flacca", canonical: "delgada", alternates: ["flaca"]) == .close) } @Test("punctuation stripped") func punctuation() { #expect(AnswerGrader.grade(userText: "el libro.", canonical: "el libro") == .correct) #expect(AnswerGrader.grade(userText: "¿dónde?", canonical: "dónde") == .correct) } @Test("very different text is wrong") func wrong() { #expect(AnswerGrader.grade(userText: "hola", canonical: "tengo") == .wrong) #expect(AnswerGrader.grade(userText: "casa", canonical: "perro") == .wrong) } @Test("normalize produces expected output") func normalize() { #expect(AnswerGrader.normalize(" Hola ") == "hola") #expect(AnswerGrader.normalize("ABC!") == "abc") } @Test("stripAccents handles common Spanish diacritics") func stripAccents() { #expect(AnswerGrader.stripAccents("niño") == "nino") #expect(AnswerGrader.stripAccents("está") == "esta") #expect(AnswerGrader.stripAccents("güero") == "guero") } @Test("levenshtein computes edit distance") func levenshtein() { #expect(AnswerGrader.levenshtein("kitten", "sitting") == 3) #expect(AnswerGrader.levenshtein("flaw", "lawn") == 2) #expect(AnswerGrader.levenshtein("abc", "abc") == 0) #expect(AnswerGrader.levenshtein("", "abc") == 3) } }