Daily Practice per section: mixed drills, stricter unlock, tick-and-skip one-tap
- One-tap mode no longer shows the answer when you're right: a green tick flashes and it skips straight to the next question. Wrong answers still show the full correction and now wait for an explicit Next tap. - Every tab (Prepositions, Articles, Possessives, Pronouns) gets its own pinned Daily Practice card. Sessions mix questions from every lesson in the tab via a shuffle-bag over lesson ids. - Daily Practice is locked until every lesson in its section has been passed (one full round at 70%); the locked card shows x/y progress. - Finishing a daily session offers 'Continue: <section> Daily Practice' cycling to the next tab with an unlocked daily, with play again and back to menu as secondary options.
This commit is contained in:
@@ -258,6 +258,32 @@ describe('no nominative anywhere', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Daily practice (per-tab mixed sessions) ─────────────────
|
||||
|
||||
describe('daily practice', () => {
|
||||
const dailies = LEVELS.filter(l => l.daily);
|
||||
|
||||
it('every tab has exactly one daily level', () => {
|
||||
expect(dailies.map(l => l.tab).sort()).toEqual(['article', 'poss', 'prep', 'pronoun']);
|
||||
});
|
||||
|
||||
it.each(dailies.map(l => [l.id, l.tab]))('daily %s mixes every lesson type of the %s tab', (id, tab) => {
|
||||
const expected = new Set(LEVELS.filter(l => l.tab === tab && !l.daily).map(l => l.type));
|
||||
const seen = new Set(runSession(id, 80).map(q => q.type));
|
||||
// Mixed definite-article lessons legitimately emit chunk questions too.
|
||||
for (const t of seen) expect([...expected, 'chunk'], `unexpected type ${t} in ${tab} daily`).toContain(t);
|
||||
for (const t of expected) expect(seen, `${tab} daily never produced a ${t} question`).toContain(t);
|
||||
});
|
||||
|
||||
it('daily questions always carry an answer', () => {
|
||||
for (const d of dailies) {
|
||||
for (const q of runSession(d.id, 100)) {
|
||||
expect(q.ans).toBeTruthy();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ── Every level generates without crashing ──────────────────
|
||||
|
||||
describe('all levels', () => {
|
||||
|
||||
Reference in New Issue
Block a user