Fix ungrammatical ein-word sentences and the a/the translation mismatch

The ein-Wörter level reused sentence frames written for definite articles
and blindly swapped in the ein/eine table, producing non-German like
'trotz eines Wetters' and 'während einer Woche' while the English still
said 'the'.

- Nouns gain a noIndef flag (mass nouns: Wetter, Regen, Musik, Arbeit;
  definite-idiom temporal/kinship nouns: Nacht, Woche, Vater, Mutter,
  Bruder, Schwester, Tochter). They are never paired with an ein-word.
- Frames with a custom English determiner (nach → 'after school',
  seit → 'since that week') are definite idioms and are skipped for
  ein-word questions.
- genArticleQ redraws prepositions whose frames are entirely ruled out
  (trotz has only mass nouns), instead of generating a bad sentence.
- Indefinite translations now use a/an to match the German article;
  definite levels keep 'the'.
- Tests pin all of this down (75 passing).
This commit is contained in:
2026-07-21 07:15:45 +00:00
parent c4c28f46ed
commit 1444814062
2 changed files with 74 additions and 25 deletions
+26
View File
@@ -109,6 +109,32 @@ describe('article questions', () => {
const seen = new Set(runSession(3, lv.preps.length).map(q => q.prepKey));
expect([...seen].sort()).toEqual([...lv.preps].sort());
});
it('ein-Wörter never pairs an ein-word with a mass/definite-only noun', () => {
for (const q of runSession(7, 400)) {
expect(q.noun.noIndef, `„ein ${q.noun.w}" should never be generated`).toBeFalsy();
}
});
it('ein-Wörter never uses definite-idiom frames (nach, seit) or all-mass preps (trotz)', () => {
for (const q of runSession(7, 400)) {
expect(['nach', 'seit', 'trotz']).not.toContain(q.prepKey);
}
});
it('ein-Wörter translations say a/an, matching the German article', () => {
for (const q of runSession(7, 400)) {
const usesA = q.translation.includes(` a ${q.noun.en}`) || q.translation.includes(` an ${q.noun.en}`);
expect(usesA, `"${q.translation}" should use a/an for „${q.ans} ${q.noun.w}"`).toBe(true);
expect(q.translation).not.toContain(` the ${q.noun.en}`);
}
});
it('definite levels still translate with "the"', () => {
for (const q of runSession(2, 200)) {
expect(q.translation).toContain(` the ${q.noun.en}`);
}
});
});
// ── Preposition case quiz ───────────────────────────────────