diff --git a/docs/authoring-questions.md b/docs/authoring-questions.md index f8d3a7b..e774f0d 100644 --- a/docs/authoring-questions.md +++ b/docs/authoring-questions.md @@ -143,6 +143,30 @@ At least one other FGA-qualified reviewer should approve the rationale content b --- +## Fill-in-the-Blank Answer Matching + +`fill-blank` items are scored by comparing the student's typed input against every string in +`acceptedAnswers`. Matching is **normalized** on both sides before comparison: + +1. Leading/trailing whitespace is trimmed. +2. The string is Unicode-decomposed (NFKD) and combining diacritics are stripped (so `café` + and `cafe` are treated as equal). +3. The string is lowercased. +4. Runs of internal whitespace are collapsed to a single space. + +This means a student does not need to match case, accents, or exact spacing to be marked +correct. It does **not** perform numeric-word equivalence — `"10"` and `"ten"` are treated as +different answers. If a fill-blank item has a numeral form and a spelled-out form that should +both be accepted, list both explicitly in `acceptedAnswers`: + +```yaml +acceptedAnswers: + - "10" + - ten +``` + +--- + ## Quality Bar for Curated Items > This section restates V1-PLAN.md §10 with additional worked examples. diff --git a/src/components/calculator/MeasurementTools.tsx b/src/components/calculator/MeasurementTools.tsx index 273306a..9405be6 100644 --- a/src/components/calculator/MeasurementTools.tsx +++ b/src/components/calculator/MeasurementTools.tsx @@ -13,6 +13,17 @@ import { DensityEstimator } from './DensityEstimator'; import { HannemanRI } from './HannemanRI'; import { ToolSection } from '../ui/ToolSection'; +const JUMP_LINKS = [ + { id: 'sg', label: 'SG' }, + { id: 'ri-lookup', label: 'RI Lookup' }, + { id: 'birefringence', label: 'Birefringence' }, + { id: 'critical-angle', label: 'Critical Angle' }, + { id: 'dispersion', label: 'Dispersion' }, + { id: 'carat-estimate', label: 'Carat Estimator' }, + { id: 'density', label: 'Density' }, + { id: 'hanneman-ri', label: 'Hanneman RI' }, +]; + const ICON_PATHS = { scale: 'M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3', search: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z', @@ -26,6 +37,21 @@ const ICON_PATHS = { export function MeasurementTools() { return (
{question.explanation}
-{question.explanation}
+- The correct answer is: {correctAnswer} + The correct answer is: {correctAnswerDisplay}
)} {question.explanation && ( @@ -154,6 +316,7 @@ export function QuestionCard({+ This saved session has a display issue — start fresh? +
+ ++ This will clear your current answers and start the quiz over from the first question. +
+756 questions across all FGA subject areas. Practise at your own pace, or sit a timed mock exam.
diff --git a/src/components/quiz/QuizSetup.test.tsx b/src/components/quiz/QuizSetup.test.tsx new file mode 100644 index 0000000..0c9bd1b --- /dev/null +++ b/src/components/quiz/QuizSetup.test.tsx @@ -0,0 +1,80 @@ +import { describe, it, expect, vi } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { QuizSetup } from './QuizSetup'; +import { CATEGORIES } from '../../lib/quiz'; +import type { Category } from '../../lib/quiz'; + +function makeAvailableQuestions(overrides: Partial+ {selectedCategories.length} of {CATEGORIES.length} categories selected +
This question could not be displayed
++ It is missing data required for its question type. It has not been scored — skip + ahead to continue. +
+- Calculators for the bench: SG by hydrostatic weighing, RI lookup, birefringence, critical angle, carat estimation, and unit conversion. Also includes dichroscope, polariscope, and Chelsea-filter references. -
-