diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-20 16:19:25 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-20 16:19:25 +0200 |
| commit | 87b155b913cea7f5c55b5a2391aff7819ba541a6 (patch) | |
| tree | 616df0de0f9fa8a08f6fd4156fa5fdac8fb9a1c3 | |
| parent | 263d0d889073d214229aef9655d3db29540c0d12 (diff) | |
| download | colitur-87b155b913cea7f5c55b5a2391aff7819ba541a6.tar.gz colitur-87b155b913cea7f5c55b5a2391aff7819ba541a6.zip | |
feat(config): sigla_style, sigla_book and sigla_tradition
Same flag > config > default precedence as --lang, and each reported by
config --show with its source, so an override is visible rather than
mysterious.
A language file's [sigla] section IS a style; a config key SELECTS one and
may override settings within it -- the two are not a duplicate setting.
| -rw-r--r-- | bin/main.ml | 147 | ||||
| -rw-r--r-- | lib/naming/config.ml | 13 | ||||
| -rw-r--r-- | lib/naming/config.mli | 24 | ||||
| -rw-r--r-- | test/cli.t | 99 | ||||
| -rw-r--r-- | test/test_config.ml | 35 |
5 files changed, 284 insertions, 34 deletions
diff --git a/bin/main.ml b/bin/main.ml index 5c9f342..8434586 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -672,13 +672,15 @@ let load_lang ~raw ~flag ~config = every other tradition uses -- one code path, not a special case for the default. - Not called from anywhere in this file yet: citations reach output at - exactly two places, [View.citation_ref] and [part_ref] below, and - threading [Sigla.t] (which this feeds) through both is a dedicated task - on its own, deliberately not done here alongside the loader. [-32] is - silenced for exactly that reason -- this is a complete, correct, - ready-to-call function with no caller yet, not dead code. *) -let[@warning "-32"] load_tradition name = + Called from [config_show] below (Task 8's own [--sigla-tradition] + plumbing), which discards the returned [tradition] and keeps only the + validation side effect -- `config --show` reports the RESOLVED STRING, + exactly like every other row, not a loaded object. Citations themselves + still reach output at exactly two places, [View.citation_ref] and + [part_ref] below, and threading the loaded [tradition] through both to + actually renumber a reference is Task 9's own dedicated job, not this + one's. *) +let load_tradition name = let path = Filename.concat (lang_dir ()) "traditions.ini" in let vulgate () = Colitur_citation.Book.vulgate in match read_file path with @@ -1157,6 +1159,24 @@ naming: it is `colitur lang`'s own identity table, under which every lookup echoes its key back unchanged. + --sigla-style CODE|FILE, --sigla-book full|abbr, --sigla-tradition NAME + settings for how a Mass reading CITATION is written -- WHICH + punctuation/abbreviation style, WHICH book form, and WHICH + numbering tradition. Each has a config-key counterpart + (`sigla_style`/`sigla_book`/`sigla_tradition`) resolved with + the identical flag > config > default precedence as --lang, and + each is reported by `colitur config --show` with its source. + Defaults: `sigla_style` the resolved language code (so a + booklet's citations follow its own --lang unless told + otherwise), `sigla_book` `abbr`, `sigla_tradition` `vulgate`. + An unrecognised `--sigla-book` is a hard ERROR (want `full` or + `abbr`), the same discipline as an unknown `--lang`; an + unrecognised `--sigla-tradition` is not -- it degrades to the + Vulgate with a stderr warning, because asking for a renumbering + is optional the way asking for a language is not. Settings + only, for now: this build resolves and reports them but does + not yet render a citation through them. + colitur lang --list which language files this build can find, and each one's own declared fallback, if any. colitur lang --dump CODE the named language's full key set, in INI @@ -1170,7 +1190,8 @@ naming: anything is unknown, so it fits a Makefile or a pre-commit hook. colitur config --show every effective setting -- lang, overlay, - template, format -- its resolved value, and + template, format, sigla_style, sigla_book, + sigla_tradition -- its resolved value, and where it came from: `flag`, `config` or `default`. See colitur-config(5) for the config file's location and full precedence. @@ -1322,6 +1343,10 @@ let with_year ys f = the same shape as [prune]. [dump]/[check]/[list]/[show] (Task 7, `colitur lang`/`colitur config`) follow the identical two shapes -- [dump]/[check] each take one value, [list]/[show] are bare. *) +(* [sigla_style]/[sigla_book]/[sigla_tradition] (Task 8) are three more + single-valued optional settings, the same shape as [lang] -- each has a + config-key counterpart in [Colitur_naming.Config] and is resolved through + the identical [Config.resolve] precedence (flag > config > default). *) type parsed_args = { overlays : string list; format : string option; @@ -1339,6 +1364,9 @@ type parsed_args = { check : string option; list : bool; show : bool; + sigla_style : string option; + sigla_book : string option; + sigla_tradition : string option; positional : string list; } @@ -1373,6 +1401,12 @@ let parse_args argv = | [ "--check" ] -> Error "--check needs a file path" | "--list" :: rest -> go { acc with list = true } rest | "--show" :: rest -> go { acc with show = true } rest + | "--sigla-style" :: v :: rest -> go { acc with sigla_style = Some v } rest + | [ "--sigla-style" ] -> Error "--sigla-style needs a language code or file path" + | "--sigla-book" :: v :: rest -> go { acc with sigla_book = Some v } rest + | [ "--sigla-book" ] -> Error "--sigla-book needs a value (full or abbr)" + | "--sigla-tradition" :: v :: rest -> go { acc with sigla_tradition = Some v } rest + | [ "--sigla-tradition" ] -> Error "--sigla-tradition needs a section name from lang/traditions.ini" (* The recognised bare flags pass through as positional words for the dispatch below to match; anything else beginning with '-' is rejected rather than silently treated as a command or a year. *) @@ -1386,7 +1420,8 @@ let parse_args argv = go { overlays = []; format = None; from_y = None; to_y = None; dtstamp = None; year = None; template = None; flavour = None; out = None; prune = false; lang = None; raw = false; - dump = None; check = None; list = false; show = false; positional = [] } + dump = None; check = None; list = false; show = false; sigla_style = None; sigla_book = None; + sigla_tradition = None; positional = [] } argv (* Sibling to [reject_overlays_for]: `emit`'s own four flags have no meaning @@ -1467,6 +1502,21 @@ let reject_lang_subcommand_flags_for cmd ~dump ~check ~list ~show = exit 2 end +(* Sibling again: `--sigla-style`/`--sigla-book`/`--sigla-tradition` (Task 8) + are settings plumbing only -- resolved and reported by `colitur config + --show` alone. Actually rendering a citation through them is Task 9's + job, so every OTHER command refuses the three flags rather than silently + accepting and ignoring them, the same discipline every rejector above + keeps; `config` is the one place that wires them in. *) +let reject_sigla_for cmd ~sigla_style ~sigla_book ~sigla_tradition = + if sigla_style <> None || sigla_book <> None || sigla_tradition <> None then begin + Printf.eprintf + "colitur: --sigla-style/--sigla-book/--sigla-tradition have no effect on `%s`; refusing rather \ + than ignoring them\n" + cmd; + exit 2 + end + (* `colitur check FILE...` -- load a user overlay, apply it to the real shipped calendar, and say what it did, without printing a year of output. @@ -1739,24 +1789,68 @@ let lang_check path = given these SAME command-line flags (so `config --show --lang fr` shows exactly what a real `--lang fr` run would use); [overlay] is a list, so it has no single "value" to resolve -- shown as one line per effective - entry instead, with its own source. *) -let config_show ~lang_flag ~template_flag ~format_flag ~overlays_flag config = + entry instead, with its own source. + + [sigla_style]/[sigla_book]/[sigla_tradition] (Task 8) join the same + scalar rows, resolved through the identical [Config.resolve]. Two are + NOT arbitrary strings, though, so "report" also means "validate", the + same way an unknown [--lang] is an error rather than a silent Latin + fallback: + - [sigla_book] is a closed two-value setting ([full]/[abbr]) -- + [Colitur_citation.Render.with_book] takes a variant, not a string, so + an unrecognised value could never mean anything downstream. Checked + HERE, not deferred to Task 9's actual renderer, because this is + currently the only place that consumes the value at all. + - [sigla_tradition] names a section of [lang/traditions.ini]; resolving + it for real (via [load_tradition], the same reader Task 9's renderer + will use) rather than only printing the string means a typo is caught + right here too -- though, unlike [sigla_book], [load_tradition] is + BY DESIGN never fatal (see its own comment: asking for a renumbering + is optional, unlike asking for a language), so an unknown tradition + degrades to a stderr warning and the Vulgate, exactly as it will under + Task 9, not a [config --show] failure. + [sigla_style] gets no such check: like [lang] itself, it is an open + language code or path, not a closed set, and [config --show] does not + validate [lang] either (that only happens when a command actually loads + it via [load_lang]). *) +let config_show ~lang_flag ~template_flag ~format_flag ~overlays_flag ~sigla_style_flag ~sigla_book_flag + ~sigla_tradition_flag config = let cpath = config_path () in Printf.printf "config file: %s (%s)\n" cpath (if cpath <> "" && Sys.file_exists cpath then "exists" else "not found"); let scalar name flag cfgval default = let v, src = Colitur_naming.Config.resolve ~flag ~config:cfgval ~default in - Printf.printf "%-10s %-24s (%s)\n" name v src + Printf.printf "%-16s %-24s (%s)\n" name v src; + v + in + let lang_value = scalar "lang" lang_flag (Colitur_naming.Config.lang config) "la" in + let _ = scalar "template" template_flag (Colitur_naming.Config.template config) "(none)" in + let _ = scalar "format" format_flag (Colitur_naming.Config.format config) "(none)" in + (* Default is the resolved LANGUAGE, not a literal "la": a booklet that + asked for --lang fr and named no --sigla-style of its own gets French + citations too, not a silent switch back to Latin punctuation. *) + let _ = scalar "sigla_style" sigla_style_flag (Colitur_naming.Config.sigla_style config) lang_value in + let sigla_book_value, sigla_book_src = + Colitur_naming.Config.resolve ~flag:sigla_book_flag ~config:(Colitur_naming.Config.sigla_book config) + ~default:"abbr" + in + if sigla_book_value <> "full" && sigla_book_value <> "abbr" then begin + Printf.eprintf "colitur: unknown --sigla-book %S (want \"full\" or \"abbr\")\n" sigla_book_value; + exit 2 + end; + Printf.printf "%-16s %-24s (%s)\n" "sigla_book" sigla_book_value sigla_book_src; + let sigla_tradition_value, sigla_tradition_src = + Colitur_naming.Config.resolve ~flag:sigla_tradition_flag + ~config:(Colitur_naming.Config.sigla_tradition config) ~default:"vulgate" in - scalar "lang" lang_flag (Colitur_naming.Config.lang config) "la"; - scalar "template" template_flag (Colitur_naming.Config.template config) "(none)"; - scalar "format" format_flag (Colitur_naming.Config.format config) "(none)"; + let _ = load_tradition sigla_tradition_value in + Printf.printf "%-16s %-24s (%s)\n" "sigla_tradition" sigla_tradition_value sigla_tradition_src; (match overlays_flag with - | _ :: _ as l -> List.iter (fun o -> Printf.printf "%-10s %-24s (%s)\n" "overlay" o "flag") l + | _ :: _ as l -> List.iter (fun o -> Printf.printf "%-16s %-24s (%s)\n" "overlay" o "flag") l | [] -> ( match Colitur_naming.Config.overlays config with - | [] -> Printf.printf "%-10s %-24s (%s)\n" "overlay" "(none)" "default" - | l -> List.iter (fun o -> Printf.printf "%-10s %-24s (%s)\n" "overlay" o "config") l)) + | [] -> Printf.printf "%-16s %-24s (%s)\n" "overlay" "(none)" "default" + | l -> List.iter (fun o -> Printf.printf "%-16s %-24s (%s)\n" "overlay" o "config") l)) (* `colitur new-overlay` -- a starter file on stdout, for redirection. Deliberately printed rather than written: the user picks the path, and a @@ -1819,12 +1913,13 @@ let () = Printf.eprintf "colitur: %s\n" msg; usage () | Ok { overlays; format; from_y; to_y; dtstamp; year; template; flavour; out; prune; lang; - raw; dump; check; list; show; positional } -> ( + raw; dump; check; list; show; sigla_style; sigla_book; sigla_tradition; positional } -> ( let reject_emit = reject_emit_flags_for ~format ~from_y ~to_y ~dtstamp in let reject_table = reject_table_flags_for ~year ~template ~flavour in let reject_publish = reject_publish_flags_for ~out ~prune in let reject_lang = reject_lang_for ~lang ~raw in let reject_lang_sub = reject_lang_subcommand_flags_for ~dump ~check ~list ~show in + let reject_sigla = reject_sigla_for ~sigla_style ~sigla_book ~sigla_tradition in (* Loaded once, unconditionally: a config file the user wrote and colitur cannot honour (missing HOME aside, [load_config] treats that as "no config" rather than an error) is worth surfacing on @@ -1855,6 +1950,7 @@ let () = reject_publish "--help"; reject_lang "--help"; reject_lang_sub "--help"; + reject_sigla "--help"; print_help () | [ ("-V" | "--version" | "version") ] -> reject_overlays_for "--version" overlays; @@ -1863,6 +1959,7 @@ let () = reject_publish "--version"; reject_lang "--version"; reject_lang_sub "--version"; + reject_sigla "--version"; print_endline version; exit 0 | [ "easter"; ys ] -> @@ -1872,6 +1969,7 @@ let () = reject_publish "easter"; reject_lang "easter"; reject_lang_sub "easter"; + reject_sigla "easter"; with_year ys easter_report | [ "temporal"; ys ] -> reject_overlays_for "temporal" overlays; @@ -1880,6 +1978,7 @@ let () = reject_publish "temporal"; reject_lang "temporal"; reject_lang_sub "temporal"; + reject_sigla "temporal"; with_year ys temporal_report | "check" :: (_ :: _ as files) -> reject_overlays_for "check" overlays; @@ -1888,6 +1987,7 @@ let () = reject_publish "check"; reject_lang "check"; reject_lang_sub "check"; + reject_sigla "check"; check_report files | [ "convert"; path ] -> reject_overlays_for "convert" overlays; @@ -1896,6 +1996,7 @@ let () = reject_publish "convert"; reject_lang "convert"; reject_lang_sub "convert"; + reject_sigla "convert"; convert_report path | [ "new-overlay" ] -> reject_overlays_for "new-overlay" overlays; @@ -1904,6 +2005,7 @@ let () = reject_publish "new-overlay"; reject_lang "new-overlay"; reject_lang_sub "new-overlay"; + reject_sigla "new-overlay"; print_string new_overlay_template; exit 0 | [ "lang" ] -> ( @@ -1912,6 +2014,7 @@ let () = reject_table "lang"; reject_publish "lang"; reject_lang "lang"; + reject_sigla "lang"; if show then begin Printf.eprintf "colitur: --show has no effect on `lang`; refusing rather than ignoring it\n"; exit 2 @@ -1956,23 +2059,27 @@ let () = exit 2 end; config_show ~lang_flag:lang ~template_flag:template ~format_flag:format ~overlays_flag:overlays + ~sigla_style_flag:sigla_style ~sigla_book_flag:sigla_book ~sigla_tradition_flag:sigla_tradition config | [ "day"; ys ] -> reject_emit "day"; reject_table "day"; reject_publish "day"; reject_lang_sub "day"; + reject_sigla "day"; with_year ys (day_report ~lang:(resolved_lang ()) ~overlays:effective_overlays) | [ "readings"; ys ] -> reject_emit "readings"; reject_table "readings"; reject_publish "readings"; reject_lang_sub "readings"; + reject_sigla "readings"; with_year ys (readings_report ~lang:(resolved_lang ()) ~overlays:effective_overlays) | [ "emit" ] -> ( reject_table "emit"; reject_publish "emit"; reject_lang_sub "emit"; + reject_sigla "emit"; match (match format with Some f -> Some f | None -> Colitur_naming.Config.format config) with | None -> Printf.eprintf "colitur: emit requires --format csv|json|sexp|xml|ics\n"; @@ -1992,6 +2099,7 @@ let () = reject_emit cmd; reject_publish cmd; reject_lang_sub cmd; + reject_sigla cmd; match (match template with Some t -> Some t | None -> Colitur_naming.Config.template config) with | None -> Printf.eprintf "colitur: %s requires --year YEAR and --template FILE\n" cmd; @@ -2010,6 +2118,7 @@ let () = reject_table "publish"; reject_format_for "publish" format; reject_lang_sub "publish"; + reject_sigla "publish"; match out with | None -> Printf.eprintf "colitur: publish requires --out DIR\n"; diff --git a/lib/naming/config.ml b/lib/naming/config.ml index 7d87d62..068b40a 100644 --- a/lib/naming/config.ml +++ b/lib/naming/config.ml @@ -5,18 +5,24 @@ type t = { overlays : string list; template : string option; format : string option; + sigla_style : string option; + sigla_book : string option; + sigla_tradition : string option; unknown_keys : string list; unknown_sections : string list; } let empty = - { lang = None; overlays = []; template = None; format = None; unknown_keys = []; - unknown_sections = [] } + { lang = None; overlays = []; template = None; format = None; sigla_style = None; + sigla_book = None; sigla_tradition = None; unknown_keys = []; unknown_sections = [] } let lang t = t.lang let overlays t = t.overlays let template t = t.template let format t = t.format +let sigla_style t = t.sigla_style +let sigla_book t = t.sigla_book +let sigla_tradition t = t.sigla_tradition let unknown_keys t = t.unknown_keys let unknown_sections t = t.unknown_sections @@ -65,6 +71,9 @@ let of_string text = | "lang" -> { acc with lang = Some v } | "template" -> { acc with template = Some v } | "format" -> { acc with format = Some v } + | "sigla_style" -> { acc with sigla_style = Some v } + | "sigla_book" -> { acc with sigla_book = Some v } + | "sigla_tradition" -> { acc with sigla_tradition = Some v } (* accumulates: a user has more than one overlay *) | "overlay" -> { acc with overlays = v :: acc.overlays } | other -> { acc with unknown_keys = other :: acc.unknown_keys }) diff --git a/lib/naming/config.mli b/lib/naming/config.mli index a84f95b..a5205c4 100644 --- a/lib/naming/config.mli +++ b/lib/naming/config.mli @@ -29,6 +29,30 @@ val overlays : t -> string list val template : t -> string option val format : t -> string option +(** Which citation style to render a reference in: a language CODE, looked + up the same way {!lang} is, or a path -- but a DIFFERENT axis from + {!lang}: a language file's own [\[sigla\]] section IS a style + ({!Colitur_citation.Render.style_of_fields}), and this key SELECTS + which file's [\[sigla\]] section supplies it, independently of which + file's other sections supply names elsewhere (a booklet may want + Polish names but Latin-convention citations). Same last-wins duplicate + policy as {!lang}. *) +val sigla_style : t -> string option + +(** [full] or [abbr] -- overrides the style's own [book] setting rather than + replacing the style outright, so a chosen style's punctuation survives + even when the book form is overridden ({!Colitur_citation.Render.with_book}). + Same last-wins duplicate policy as {!lang}. *) +val sigla_book : t -> string option + +(** The name of a section in [lang/traditions.ini] -- which BOOK a reference + DENOTES (Vulgate numbering by default), a different question again from + both {!sigla_style} (how a reference is WRITTEN) and {!lang} (what + everything else is CALLED): naming and numbering both vary by + convention, but not together. Same last-wins duplicate policy as + {!lang}. *) +val sigla_tradition : t -> string option + (** Keys present in the [\[defaults\]] section that this build does not understand. Reported, never fatal: a config written for a newer colitur must still work on an older one, but silently ignoring a line the user @@ -1258,10 +1258,13 @@ literally either): $ XDG_CONFIG_HOME=xdg-test colitur config --show config file: xdg-test/colitur/config.ini (not found) - lang la (default) - template (none) (default) - format (none) (default) - overlay (none) (default) + lang la (default) + template (none) (default) + format (none) (default) + sigla_style la (default) + sigla_book abbr (default) + sigla_tradition vulgate (default) + overlay (none) (default) A flag on the SAME command line previews exactly what it would resolve to on any other command -- `overlay` has no single scalar value, so it is @@ -1269,10 +1272,13 @@ listed one line per effective entry instead: $ XDG_CONFIG_HOME=xdg-test colitur config --show --lang fr --overlay mine.sexp config file: xdg-test/colitur/config.ini (not found) - lang fr (flag) - template (none) (default) - format (none) (default) - overlay mine.sexp (flag) + lang fr (flag) + template (none) (default) + format (none) (default) + sigla_style fr (default) + sigla_book abbr (default) + sigla_tradition vulgate (default) + overlay mine.sexp (flag) A real config file supplies a default that a command with no explicit flag then uses. An unrecognised key and an unrecognised section are each warned @@ -1284,13 +1290,82 @@ differently from a misspelled key inside a recognised one: $ printf '[defaults]\nlang = en\noverlay = /nonexistent/parish.sexp\nbogus = 1\n\n[deafults]\nlang = xx\n' > xdg-test/colitur/config.ini $ XDG_CONFIG_HOME=xdg-test colitur config --show config file: xdg-test/colitur/config.ini (exists) - lang en (config) - template (none) (default) - format (none) (default) - overlay /nonexistent/parish.sexp (config) + lang en (config) + template (none) (default) + format (none) (default) + sigla_style en (default) + sigla_book abbr (default) + sigla_tradition vulgate (default) + overlay /nonexistent/parish.sexp (config) colitur: xdg-test/colitur/config.ini: unknown setting "bogus" (ignored) colitur: xdg-test/colitur/config.ini: unknown section [deafults] (ignored) +`--sigla-style`/`--sigla-book`/`--sigla-tradition` (Task 8) resolve through +the identical flag > config > default precedence as --lang/--template/ +--format, each reported by its own row. `sigla_style` defaults to the +RESOLVED language, not a literal "la" -- a booklet that asked for a +different --lang gets its citations in that language too unless told +otherwise. Run through a fresh XDG_CONFIG_HOME, so this does not depend on +the config file the earlier examples left behind: + + $ XDG_CONFIG_HOME=xdg-sigla colitur config --show --sigla-style pl --sigla-book full --sigla-tradition modern + config file: xdg-sigla/colitur/config.ini (not found) + lang la (default) + template (none) (default) + format (none) (default) + sigla_style pl (flag) + sigla_book full (flag) + sigla_tradition modern (flag) + overlay (none) (default) + +An unrecognised `--sigla-book` is a hard usage ERROR -- exit 2, one line on +stderr -- the same discipline an unrecognised `--lang` gets, never a silent +fallback: `Colitur_citation.Render.with_book` takes a closed variant, not an +arbitrary string, so anything other than "full"/"abbr" could never mean +anything downstream. + + $ XDG_CONFIG_HOME=xdg-sigla colitur config --show --sigla-book bogus + config file: xdg-sigla/colitur/config.ini (not found) + lang la (default) + template (none) (default) + format (none) (default) + sigla_style la (default) + colitur: unknown --sigla-book "bogus" (want "full" or "abbr") + [2] + +An unrecognised `--sigla-tradition`, by contrast, is NOT fatal: it is +resolved for real against lang/traditions.ini (the same reader a future +renderer will use), and a name matching no section there degrades to the +Vulgate with a warning on stderr, exactly as an unknown tradition does +everywhere else in this project -- asking for a renumbering is optional the +way asking for a language is not, so a run is not lost over a typo here. +The warning itself carries lang/traditions.ini's own resolved PATH, which is +absolute and build-tree-specific -- grepped for rather than matched in +full, the same way the pre-existing "unknown language" case above already +sidesteps that same non-portability: + + $ XDG_CONFIG_HOME=xdg-sigla colitur config --show --sigla-tradition nonsense 2>/dev/null + config file: xdg-sigla/colitur/config.ini (not found) + lang la (default) + template (none) (default) + format (none) (default) + sigla_style la (default) + sigla_book abbr (default) + sigla_tradition nonsense (flag) + overlay (none) (default) + $ XDG_CONFIG_HOME=xdg-sigla colitur config --show --sigla-tradition nonsense 2>&1 >/dev/null | grep -c 'no tradition "nonsense"; falling back to the Vulgate' + 1 + +`--sigla-style`/`--sigla-book`/`--sigla-tradition` have no effect on any +other command yet -- resolving and reporting them is all this build does; +actually rendering a citation through them is a later task -- refused +rather than silently ignored, the same discipline `--dump`/`--check`/ +`--list`/`--show` already get above: + + $ colitur day 2027 --sigla-style la > /dev/null + colitur: --sigla-style/--sigla-book/--sigla-tradition have no effect on `day`; refusing rather than ignoring them + [2] + `config` requires --show: $ colitur config diff --git a/test/test_config.ml b/test/test_config.ml index 83da015..d348d9b 100644 --- a/test/test_config.ml +++ b/test/test_config.ml @@ -102,6 +102,35 @@ let test_two_defaults_blocks_report_no_unknown_sections () = let c = ok (C.of_string text) in Alcotest.(check (list string)) "no unknown sections" [] (C.unknown_sections c) +(* Task 8: sigla_style/sigla_book/sigla_tradition read the same way + lang/template/format do, in the same [\[defaults\]] section -- no new + section, and every key recognised (so [unknown_keys] stays empty). *) +let test_sigla_keys_are_read () = + let text = + "[defaults]\nsigla_style = la\nsigla_book = full\nsigla_tradition = modern\n" + in + match C.of_string text with + | Error e -> Alcotest.failf "parse: %s" e + | Ok c -> + Alcotest.(check (option string)) "style" (Some "la") (C.sigla_style c); + Alcotest.(check (option string)) "book" (Some "full") (C.sigla_book c); + Alcotest.(check (option string)) "tradition" (Some "modern") (C.sigla_tradition c); + Alcotest.(check (list string)) "nothing unknown" [] (C.unknown_keys c) + +(* The empty config carries no sigla settings either -- same "all None" + contract [test_empty_config_is_all_none] already asserts for lang. *) +let test_empty_config_sigla_keys_are_none () = + Alcotest.(check (option string)) "sigla_style" None (C.sigla_style C.empty); + Alcotest.(check (option string)) "sigla_book" None (C.sigla_book C.empty); + Alcotest.(check (option string)) "sigla_tradition" None (C.sigla_tradition C.empty) + +(* Same last-wins duplicate policy as lang/template/format: a key repeated + across two [\[defaults\]] blocks resolves to the LATER block's value. *) +let test_sigla_key_repeated_across_blocks_last_wins () = + let text = "[defaults]\nsigla_book = full\n\n[defaults]\nsigla_book = abbr\n" in + let c = ok (C.of_string text) in + Alcotest.(check (option string)) "later block's sigla_book wins" (Some "abbr") (C.sigla_book c) + let suite = ( "Config", [ Alcotest.test_case "reads defaults" `Quick test_reads_defaults; @@ -119,4 +148,8 @@ let suite = Alcotest.test_case "overlays accumulate across blocks" `Quick test_overlays_accumulate_across_blocks; Alcotest.test_case "two defaults blocks report no unknown sections" - `Quick test_two_defaults_blocks_report_no_unknown_sections ] ) + `Quick test_two_defaults_blocks_report_no_unknown_sections; + Alcotest.test_case "sigla keys are read" `Quick test_sigla_keys_are_read; + Alcotest.test_case "empty config sigla keys are none" `Quick test_empty_config_sigla_keys_are_none; + Alcotest.test_case "sigla key repeated across blocks last wins" + `Quick test_sigla_key_repeated_across_blocks_last_wins ] ) |
