mml 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +8 -2
  3. data/TODO.complete/1-v3-autoload.md +63 -0
  4. data/TODO.complete/2-v2-autoload.md +46 -0
  5. data/TODO.complete/3-no-require-relative.md +32 -0
  6. data/TODO.complete/4-remove-duplicate-register-model.md +31 -0
  7. data/TODO.complete/5-context-options-type-check.md +44 -0
  8. data/TODO.complete/6-context-configuration-type-check.md +32 -0
  9. data/TODO.complete/7-specs-for-refactor.md +38 -0
  10. data/lib/mml/context_configuration.rb +3 -1
  11. data/lib/mml/context_options.rb +10 -1
  12. data/lib/mml/v2/configuration.rb +0 -2
  13. data/lib/mml/v2.rb +382 -246
  14. data/lib/mml/v3/annotation.rb +0 -1
  15. data/lib/mml/v3/annotation_xml.rb +0 -1
  16. data/lib/mml/v3/apply.rb +0 -1
  17. data/lib/mml/v3/arith.rb +0 -22
  18. data/lib/mml/v3/bind.rb +0 -1
  19. data/lib/mml/v3/calculus.rb +0 -7
  20. data/lib/mml/v3/cbytes.rb +0 -1
  21. data/lib/mml/v3/cerror.rb +0 -1
  22. data/lib/mml/v3/ci.rb +0 -1
  23. data/lib/mml/v3/cn.rb +0 -1
  24. data/lib/mml/v3/configuration.rb +0 -2
  25. data/lib/mml/v3/constants.rb +0 -15
  26. data/lib/mml/v3/constructs.rb +0 -10
  27. data/lib/mml/v3/cs.rb +0 -1
  28. data/lib/mml/v3/csymbol.rb +0 -1
  29. data/lib/mml/v3/deprecated_content.rb +0 -7
  30. data/lib/mml/v3/elementary_functions.rb +0 -28
  31. data/lib/mml/v3/functions.rb +0 -6
  32. data/lib/mml/v3/linear_algebra.rb +0 -9
  33. data/lib/mml/v3/logic.rb +0 -7
  34. data/lib/mml/v3/maction.rb +0 -1
  35. data/lib/mml/v3/maligngroup.rb +0 -1
  36. data/lib/mml/v3/malignmark.rb +0 -1
  37. data/lib/mml/v3/math.rb +0 -2
  38. data/lib/mml/v3/menclose.rb +0 -1
  39. data/lib/mml/v3/merror.rb +0 -1
  40. data/lib/mml/v3/mfenced.rb +0 -1
  41. data/lib/mml/v3/mfrac.rb +0 -1
  42. data/lib/mml/v3/mfraction.rb +0 -1
  43. data/lib/mml/v3/mglyph.rb +0 -1
  44. data/lib/mml/v3/mi.rb +0 -1
  45. data/lib/mml/v3/mlabeledtr.rb +0 -1
  46. data/lib/mml/v3/mlongdiv.rb +0 -1
  47. data/lib/mml/v3/mmultiscripts.rb +0 -1
  48. data/lib/mml/v3/mn.rb +0 -1
  49. data/lib/mml/v3/mo.rb +0 -1
  50. data/lib/mml/v3/mover.rb +0 -1
  51. data/lib/mml/v3/mpadded.rb +0 -1
  52. data/lib/mml/v3/mphantom.rb +0 -1
  53. data/lib/mml/v3/mprescripts.rb +0 -1
  54. data/lib/mml/v3/mroot.rb +0 -1
  55. data/lib/mml/v3/mrow.rb +0 -1
  56. data/lib/mml/v3/ms.rb +0 -1
  57. data/lib/mml/v3/mscarries.rb +0 -1
  58. data/lib/mml/v3/mscarry.rb +0 -1
  59. data/lib/mml/v3/msgroup.rb +0 -1
  60. data/lib/mml/v3/msline.rb +0 -1
  61. data/lib/mml/v3/mspace.rb +0 -1
  62. data/lib/mml/v3/msqrt.rb +0 -1
  63. data/lib/mml/v3/msrow.rb +0 -1
  64. data/lib/mml/v3/mstack.rb +0 -1
  65. data/lib/mml/v3/mstyle.rb +0 -1
  66. data/lib/mml/v3/msub.rb +0 -1
  67. data/lib/mml/v3/msubsup.rb +0 -1
  68. data/lib/mml/v3/msup.rb +0 -1
  69. data/lib/mml/v3/mtable.rb +0 -1
  70. data/lib/mml/v3/mtd.rb +0 -1
  71. data/lib/mml/v3/mtext.rb +0 -1
  72. data/lib/mml/v3/mtr.rb +0 -1
  73. data/lib/mml/v3/munder.rb +0 -1
  74. data/lib/mml/v3/munderover.rb +0 -1
  75. data/lib/mml/v3/none.rb +0 -1
  76. data/lib/mml/v3/relations.rb +0 -9
  77. data/lib/mml/v3/semantics.rb +0 -1
  78. data/lib/mml/v3/sets.rb +0 -13
  79. data/lib/mml/v3/statistics.rb +0 -7
  80. data/lib/mml/v3/vector_calculus.rb +0 -4
  81. data/lib/mml/v3.rb +451 -73
  82. data/lib/mml/v4/annotation.rb +0 -1
  83. data/lib/mml/v4/configuration.rb +0 -2
  84. data/lib/mml/v4/elementary_functions.rb +0 -1
  85. data/lib/mml/v4/functions.rb +0 -1
  86. data/lib/mml/v4.rb +21 -17
  87. data/lib/mml/version.rb +1 -1
  88. data/lib/mml.rb +2 -0
  89. metadata +9 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06746c57ed678055de388f7762532af6ee4b2c5384357d02bfe5e70b171bc978
4
- data.tar.gz: cb6e5039fa287dc23cec0deb104c6f11b2916c0862d12accda17a62211adcc8c
3
+ metadata.gz: 753f58cf7a8516296624dc7eb472621cd4ecaab7a7d1c3f34d7e8d67eff9bbce
4
+ data.tar.gz: 062164c14aa4475421fc48ca37de907be75938d8b574a768cc8e8e374bd91252
5
5
  SHA512:
6
- metadata.gz: 6f323d41ded39d4f7098684c0be92c63b40fc74fa807eda838800015503760a73e08bfa4bd9601ab4a9087301f01a57b9b96376c3c3663c37cb5cee0fdd457c1
7
- data.tar.gz: de5b3d389ea005d3738933e0074f0400408e6be04ff86d058a17fd9bd705bd822b4f7e1cab93ef846542a6030681535c1570b9082a87b42ab1e780aefe9f04c2
6
+ metadata.gz: b43c4d0bd97523c911860ff881eb7375ae9755ac5755985408c27c4aa43246d57cd4b26d7a8bb00c8e5020ee1b9cf9d331f49a6e3a5524957f36469d3c5b9549
7
+ data.tar.gz: 5d93d2e051d43efb46e83e36bc5464339020e73742183369e6b45813cf3fcd90203c3d3440768c8259f0e174c6435b20863a994debf4417f30308391c9df2e90
data/CLAUDE.md CHANGED
@@ -95,9 +95,15 @@ end
95
95
 
96
96
  A `no_root` Lutaml model imported into container elements via `import_model`. It dynamically creates `#{tag}_value` attributes for each tag in `Configuration::SUPPORTED_TAGS`. Classes that receive it are listed in `Configuration::COMMON_ATTRIBUTES_CLASSES`.
97
97
 
98
- ### Per-file registration
98
+ ### Version module body registration
99
99
 
100
- Each `lib/mml/v{2,3,4}/<tag>.rb` ends with `Configuration.register_model(Klass, id: :tag)` so the type is registered as soon as the file is loaded (eager via `require_relative` at the bottom of each version file).
100
+ Each `lib/mml/v{2,3,4}.rb` declares `autoload :Klass, "mml/v{2,3,4}/klass"` for every element class, then calls `Configuration.register_model(Klass, id: :tag)` in the module body. The register_model call triggers autoload on first reference, preserving eager-registration semantics while using Ruby autoload (no `require_relative` for internal code).
101
+
102
+ Per-element files (e.g. `lib/mml/v3/math.rb`) define only the class — they no longer call `register_model` themselves. The version module is the single source of truth for registration.
103
+
104
+ For grouped files (e.g. `lib/mml/v3/arith.rb` defines 22 classes), each class has its own `autoload` entry pointing at the shared file.
105
+
106
+ `spec/mml/code_quality_spec.rb` enforces the lint rules and verifies every expected element ID is registered in its version's context.
101
107
 
102
108
  **Namespace:** All versions use the same URI (`http://www.w3.org/1998/Math/MathML`) — MathML 4 chose backward compatibility over a new namespace.
103
109
 
@@ -0,0 +1,63 @@
1
+ # TODO 1 — Migrate `lib/mml/v3.rb` from `require_relative` to `autoload`
2
+
3
+ ## Why
4
+ Global rule: never use `require_relative` for code inside our own library.
5
+ Use Ruby `autoload` declared in the immediate parent namespace's file
6
+ (`lib/mml/v3.rb`). `lib/mml/v4.rb` already follows this pattern; V3 should
7
+ match it for consistency (MECE/SSOT).
8
+
9
+ ## Scope
10
+ - `lib/mml/v3.rb` — replace every `require_relative "v3/..."` with the
11
+ corresponding `autoload :Klass, "mml/v3/..."`.
12
+ - Grouped files (e.g. `v3/arith.rb`) contain multiple classes — emit one
13
+ `autoload` line per class, all pointing at the same file path.
14
+ - Keep the existing `Configuration.register_model(...)` calls in the module
15
+ body — they trigger autoload on first reference and preserve eager
16
+ registration behavior.
17
+ - Foundational files (`configuration`, `namespace`, `common_elements`) also
18
+ switch to `autoload`.
19
+
20
+ ## Class → file map (V3)
21
+ ### One-class files (presentation)
22
+ Maction, Maligngroup, Malignmark, Menclose, Merror, Mfenced, Mfrac,
23
+ Mfraction, Mglyph, Mi, Mlabeledtr, Mlongdiv, Mmultiscripts, Mn, Mo, Mover,
24
+ Mpadded, Mphantom, Mprescripts, Mroot, Mrow, Ms, Mscarries, Mscarry,
25
+ Msgroup, Msline, Mspace, Msqrt, Msrow, Mstack, Mstyle, Msub, Msubsup, Msup,
26
+ Mtable, Mtd, Mtext, Mtr, Munder, Munderover, None, Semantics, Math
27
+
28
+ ### One-class files (content)
29
+ Apply, Cbytes, Cerror, Cs, Ci, Cn, Csymbol, AnnotationXml, Annotation,
30
+ Bind, Bvar, Condition, Degree, Interval, Inverse, Lambda, Otherwise, Piece,
31
+ Piecewise, Reln, Sep, Fn, Declare, Share
32
+
33
+ ### Grouped files (multiple classes per file)
34
+ - `v3/arith.rb` → Abs, Conjugate, Arg, Real, Imaginary, Floor, Ceiling,
35
+ Quotient, Divide, Rem, Minus, Plus, Times, Power, Root, Max, Min, Gcd, Lcm,
36
+ Sum, Product, Factorial
37
+ - `v3/calculus.rb` → Int, Diff, Partialdiff, Limit, Lowlimit, Uplimit, Tendsto
38
+ - `v3/constants.rb` → Naturalnumbers, Primes, Integers, Rationals, Reals,
39
+ Complexes, Emptyset, Exponentiale, Imaginaryi, Pi, Eulergamma, Mtrue,
40
+ Mfalse, Infinity, Notanumber
41
+ - `v3/elementary_functions.rb` → Exp, Ln, Log, Logbase, Sin, Cos, Tan, Sec,
42
+ Csc, Cot, Arcsin, Arccos, Arctan, Arccot, Arccsc, Arcsec, Sinh, Cosh, Tanh,
43
+ Sech, Csch, Coth, Arcsinh, Arccosh, Arctanh, Arccoth, Arccsch, Arcsech
44
+ - `v3/functions.rb` → Compose, Domain, Codomain, Image, Ident,
45
+ Domainofapplication
46
+ - `v3/linear_algebra.rb` → Vector, Matrix, Matrixrow, Determinant, Transpose,
47
+ Selector, Vectorproduct, Scalarproduct, Outerproduct
48
+ - `v3/logic.rb` → And, Or, Xor, Not, Exists, Forall, Implies
49
+ - `v3/relations.rb` → Eq, Neq, Leq, Lt, Geq, Gt, Equivalent, Approx, Factorof
50
+ - `v3/sets.rb` → Set, Mlist, Union, Intersect, In, Notin, Subset, Prsubset,
51
+ Notsubset, Notprsubset, Setdiff, Card, Cartesianproduct
52
+ - `v3/statistics.rb` → Mean, Sdev, Variance, Median, Mode, Moment, Momentabout
53
+ - `v3/vector_calculus.rb` → Divergence, Grad, Curl, Laplacian
54
+ - `v3/constructs.rb` → Bvar, Condition, Interval, Lambda, Inverse, Degree,
55
+ Piecewise, Piece, Otherwise, Sep
56
+ - `v3/deprecated_content.rb` → Fn, Reln, Declare, Share
57
+
58
+ ## Acceptance
59
+ - `grep -rn "require_relative" lib/mml/v3.rb` returns nothing.
60
+ - `bundle exec rspec` passes (2940+ examples, 36 pre-existing pending).
61
+ - `bundle exec rubocop lib/mml/v3.rb` clean.
62
+ - All `Mml::V3::*` constants remain accessible and registered after
63
+ `require "mml"`.
@@ -0,0 +1,46 @@
1
+ # TODO 2 — Migrate `lib/mml/v2.rb` from `require_relative` to `autoload`
2
+
3
+ ## Why
4
+ Same as TODO 1 but for V2. Mirror the V4 pattern.
5
+
6
+ ## Scope
7
+ - Replace every `require_relative "v2/..."` with `autoload :Klass, "mml/v2/..."`.
8
+ - Grouped files have multiple classes per file.
9
+
10
+ ## Class → file map (V2)
11
+ ### One-class files (presentation + content)
12
+ Same shape as V3 but in `v2/` directory: Maction, Maligngroup, Malignmark,
13
+ Menclose, Merror, Mfenced, Mfrac, Mfraction, Mglyph, Mi, Mlabeledtr, Mlongdiv,
14
+ Mmultiscripts, Mn, Mo, Mover, Mpadded, Mphantom, Mprescripts, Mroot, Mrow,
15
+ Ms, Mscarries, Mscarry, Msgroup, Msline, Mspace, Msqrt, Msrow, Mstack,
16
+ Mstyle, Msub, Msubsup, Msup, Mtable, Mtd, Mtext, Mtr, Munder, Munderover,
17
+ None, Semantics, Math, Annotation, AnnotationXml, Apply, Bvar, Bind, Ci,
18
+ Cn, Condition, Csymbol, Degree, Fn, Interval, Inverse, Lambda, Otherwise,
19
+ Piece, Piecewise, Reln, Sep
20
+
21
+ ### Grouped files
22
+ - `v2/arith.rb` → Abs, Conjugate, Arg, Real, Imaginary, Floor, Ceiling,
23
+ Quotient, Divide, Rem, Minus, Plus, Times, Power, Root, Max, Min, Gcd, Lcm,
24
+ Sum, Product, Factorial
25
+ - `v2/calculus.rb` → Int, Diff, Partialdiff, Limit, Lowlimit, Uplimit, Tendsto
26
+ - `v2/constants.rb` → Naturalnumbers, Primes, Integers, Rationals, Reals,
27
+ Complexes, Emptyset, Exponentiale, Imaginaryi, Pi, Eulergamma, Mtrue,
28
+ Mfalse, Infinity, Notanumber
29
+ - `v2/elementary_functions.rb` → Exp, Ln, Log, Logbase, Sin, Cos, Tan, Sec,
30
+ Csc, Cot, Arcsin, Arccos, Arctan, Arccot, Arccsc, Arcsec, Sinh, Cosh, Tanh,
31
+ Sech, Csch, Coth, Arcsinh, Arccosh, Arctanh, Arccoth, Arccsch, Arcsech
32
+ - `v2/functions.rb` → Compose, Domain, Codomain, Image, Ident,
33
+ Domainofapplication
34
+ - `v2/linear_algebra.rb` → Vector, Matrix, Matrixrow, Determinant, Transpose,
35
+ Selector, Vectorproduct, Scalarproduct, Outerproduct
36
+ - `v2/logic.rb` → And, Or, Xor, Not, Exists, Forall, Implies
37
+ - `v2/relations.rb` → Eq, Neq, Leq, Lt, Geq, Gt, Equivalent, Approx, Factorof
38
+ - `v2/sets.rb` → Set, Mlist, Union, Intersect, In, Notin, Subset, Prsubset,
39
+ Notsubset, Notprsubset, Setdiff, Card, Cartesianproduct
40
+ - `v2/statistics.rb` → Mean, Sdev, Variance, Median, Mode, Moment, Momentabout
41
+ - `v2/vector_calculus.rb` → Divergence, Grad, Curl, Laplacian
42
+
43
+ ## Acceptance
44
+ - `grep -rn "require_relative" lib/mml/v2.rb` returns nothing.
45
+ - `bundle exec rspec` passes.
46
+ - `bundle exec rubocop lib/mml/v2.rb` clean.
@@ -0,0 +1,32 @@
1
+ # TODO 3 — Eliminate remaining `require_relative` in `lib/mml/`
2
+
3
+ ## Why
4
+ After TODO 1 & 2, the only remaining `require_relative` calls in `lib/mml/`
5
+ are:
6
+ - `lib/mml/v2.rb:4` — `require_relative "versioned_parser"`
7
+ - `lib/mml/v3.rb:4` — `require_relative "versioned_parser"`
8
+ - `lib/mml/v4.rb:4` — `require_relative "versioned_parser"`
9
+ - `lib/mml/v{2,3,4}/configuration.rb:3` — `require_relative "../context_configuration"`
10
+ - `lib/mml/v{2,3,4}.rb` top — `require_relative "v{2,3,4}/configuration"`,
11
+ `"v{2,3,4}/namespace"`, `"v{2,3,4}/common_elements"` (V4 only today, but if
12
+ V2/V3 also adopt the same pattern during TODO 1/2 they need the same fix).
13
+
14
+ All of these can be replaced with autoloads declared in `lib/mml.rb` and in
15
+ the version module files.
16
+
17
+ ## Scope
18
+ 1. `lib/mml.rb` — add `autoload :VersionedParser, "mml/versioned_parser"`
19
+ (currently `ContextOptions` and others are autoloaded; `VersionedParser`
20
+ is missing).
21
+ 2. `lib/mml/v{2,3,4}/configuration.rb` — remove the
22
+ `require_relative "../context_configuration"` line. `Mml::ContextConfiguration`
23
+ is autoloaded from `lib/mml.rb`, so the `extend Mml::ContextConfiguration`
24
+ call resolves correctly.
25
+ 3. `lib/mml/v{2,3,4}.rb` — replace `require_relative "v{2,3,4}/configuration"`
26
+ and the foundational requires with `autoload` declarations.
27
+
28
+ ## Acceptance
29
+ - `grep -rn "require_relative" lib/mml/` returns zero matches.
30
+ - `bundle exec rspec` passes.
31
+ - `bundle exec rubocop lib/` clean.
32
+ - Smoke spec (TODO 7) confirms every `Mml::V{2,3,4}::*` class resolves.
@@ -0,0 +1,31 @@
1
+ # TODO 4 — Remove duplicate per-element `Configuration.register_model` (DRY/SSOT)
2
+
3
+ ## Why
4
+ After TODO 1 & 2, V2 and V3 will mirror V4's pattern of `autoload + module-body
5
+ register_model`. The per-element files (`lib/mml/v{2,3}/<tag>.rb`) currently
6
+ also end with `Configuration.register_model(Klass, id: :tag)`. That is
7
+ duplicate work — `register_model` overwrites the same key with the same class.
8
+
9
+ V4 is inconsistent: most files omit the per-element call, but `annotation.rb`,
10
+ `elementary_functions.rb`, and `functions.rb` still have it.
11
+
12
+ Single source of truth: the version module body (`lib/mml/v{2,3,4}.rb`).
13
+
14
+ ## Scope
15
+ - Remove the trailing `Configuration.register_model(...)` line from every
16
+ per-element file under `lib/mml/v2/`, `lib/mml/v3/`, `lib/mml/v4/`.
17
+ - Do NOT touch `lib/mml/v{2,3,4}.rb` (module-body registrations stay).
18
+
19
+ ## Files affected
20
+ - V3: 66 per-element files (every file under `lib/mml/v3/` except
21
+ `configuration.rb`, `namespace.rb`, `common_elements.rb`, `version.rb`).
22
+ - V2: ~62 per-element files.
23
+ - V4: 3 files — `annotation.rb`, `elementary_functions.rb`, `functions.rb`.
24
+
25
+ ## Acceptance
26
+ - `grep -rn "Configuration.register_model" lib/mml/v2 lib/mml/v3 lib/mml/v4 |
27
+ grep -v "v[234]\.rb:"` returns nothing (only version module files have it).
28
+ - `bundle exec rspec` passes.
29
+ - `bundle exec rubocop lib/` clean.
30
+ - Registration spec (TODO 7) confirms all element IDs are still registered
31
+ in their respective contexts.
@@ -0,0 +1,44 @@
1
+ # TODO 5 — Replace `respond_to?(:id)` with explicit type check in `context_options.rb`
2
+
3
+ ## Why
4
+ Global rule: never use `respond_to?` for type checking. Use `is_a?` or
5
+ design the type hierarchy so the check isn't needed.
6
+
7
+ `lib/mml/context_options.rb:34` uses `reference.respond_to?(:id)` to duck-type
8
+ any object that exposes an `id`. The actual types that can reach this code are:
9
+ - `Symbol` — handled earlier
10
+ - `String` — handled earlier
11
+ - `Lutaml::Model::TypeContext` (lutaml-model) — has `attr_reader :id`
12
+ - `Lutaml::Model::Register` (lutaml-model) — has `attr_reader :id`
13
+
14
+ ## Scope
15
+ - Replace the `respond_to?` branch with explicit `is_a?` checks against the
16
+ two known lutaml-model classes.
17
+ - Keep the `ArgumentError` fallback for unknown types — preserves
18
+ fail-fast behavior.
19
+
20
+ ## Implementation
21
+ ```ruby
22
+ def normalize_context_reference(reference)
23
+ return nil if reference.nil?
24
+ return reference if reference.is_a?(Symbol)
25
+ return reference.to_sym if reference.is_a?(String)
26
+ return reference.id.to_sym if context_reference_object?(reference)
27
+
28
+ raise ArgumentError,
29
+ "Unsupported context/register reference: #{reference.inspect}"
30
+ end
31
+
32
+ private
33
+
34
+ def context_reference_object?(reference)
35
+ reference.is_a?(Lutaml::Model::TypeContext) ||
36
+ reference.is_a?(Lutaml::Model::Register)
37
+ end
38
+ ```
39
+
40
+ ## Acceptance
41
+ - `grep -n "respond_to?" lib/mml/context_options.rb` returns nothing.
42
+ - `bundle exec rspec spec/mml/context_options_spec.rb` passes (new spec from
43
+ TODO 7).
44
+ - Existing parse/configuration specs still pass.
@@ -0,0 +1,32 @@
1
+ # TODO 6 — Replace `respond_to?(:clear_cache)` with explicit type check in `context_configuration.rb`
2
+
3
+ ## Why
4
+ Global rule: never use `respond_to?` for type checking.
5
+
6
+ `lib/mml/context_configuration.rb:144` uses
7
+ `klass.clear_cache(context_id) if klass.respond_to?(:clear_cache)`.
8
+
9
+ Every class registered via `Configuration.register_model` inherits from
10
+ `Lutaml::Model::Serializable`, which defines `clear_cache` as a class method
11
+ (see lutaml-model `lib/lutaml/model/serialize/initialization.rb:180`).
12
+
13
+ ## Scope
14
+ - Replace the `respond_to?` guard with an explicit type check:
15
+ `klass.is_a?(Class) && klass <= Lutaml::Model::Serialize`.
16
+ - Note the use of `<=` (subclass-or-equal) rather than `<` so that
17
+ `Serializable` itself would also qualify, matching the intent of "any class
18
+ in the Serializable hierarchy".
19
+
20
+ ## Implementation
21
+ ```ruby
22
+ def clear_cache(klass)
23
+ return unless klass.is_a?(Class) && (klass <= Lutaml::Model::Serialize)
24
+
25
+ klass.clear_cache(context_id)
26
+ end
27
+ ```
28
+
29
+ ## Acceptance
30
+ - `grep -n "respond_to?" lib/mml/context_configuration.rb` returns nothing.
31
+ - `bundle exec rspec` passes.
32
+ - `bundle exec rubocop lib/mml/context_configuration.rb` clean.
@@ -0,0 +1,38 @@
1
+ # TODO 7 — Add specs covering the refactorings
2
+
3
+ ## Why
4
+ Lock in the behavior of the refactorings in TODOs 1–6 so future regressions
5
+ are caught. MECE with existing specs:
6
+ - `spec/mml/adapter_configuration_spec.rb` — adapter selection
7
+ - `spec/mml/ordered_content_spec.rb` — mixed_content vs ordered
8
+ - `spec/mml/nested_in_mixed_content_spec.rb` — entity preservation in host
9
+ - `spec/lutaml_default_register_spec.rb` — every Serializable class has
10
+ `lutaml_default_register`
11
+ - `spec/context_support_spec.rb` — context creation/substitution
12
+
13
+ None of these cover:
14
+ - `ContextOptions.normalize_context_reference` for `TypeContext`/`Register`
15
+ inputs.
16
+ - Lint: no `require_relative` in `lib/mml/**/*.rb`.
17
+ - Lint: no `respond_to?` in `lib/mml/**/*.rb`.
18
+ - Lint: no `.send(` / `instance_variable_set` / `instance_variable_get` in
19
+ `lib/mml/**/*.rb`.
20
+ - Smoke: every `Mml::V{2,3,4}` autoload constant resolves and is registered
21
+ after `require "mml"`.
22
+
23
+ ## Scope
24
+ Create `spec/mml/code_quality_spec.rb` covering all four lint checks plus a
25
+ smoke test that iterates the Configuration register and asserts every
26
+ expected element ID is present for V2, V3, V4.
27
+
28
+ Update `spec/context_support_spec.rb` (or add a new spec) to cover
29
+ `ContextOptions.normalize_context_reference` with `TypeContext` and `Register`
30
+ inputs — these now flow through the new `is_a?` branches.
31
+
32
+ ## Acceptance
33
+ - New spec file(s) added.
34
+ - `bundle exec rspec` passes.
35
+ - `bundle exec rubocop` clean.
36
+ - Removing any autoload declaration or per-element class breaks the smoke
37
+ spec.
38
+ - Adding a new `require_relative` to `lib/mml/` breaks the lint spec.
@@ -141,7 +141,9 @@ module Mml
141
141
  end
142
142
 
143
143
  def clear_cache(klass)
144
- klass.clear_cache(context_id) if klass.respond_to?(:clear_cache)
144
+ return unless klass.is_a?(Class) && (klass <= Lutaml::Model::Serialize)
145
+
146
+ klass.clear_cache(context_id)
145
147
  end
146
148
  end
147
149
  end
@@ -31,7 +31,7 @@ module Mml
31
31
  return nil if reference.nil?
32
32
  return reference if reference.is_a?(Symbol)
33
33
  return reference.to_sym if reference.is_a?(String)
34
- return reference.id.to_sym if reference.respond_to?(:id)
34
+ return reference.id.to_sym if lutaml_context_reference?(reference)
35
35
 
36
36
  raise ArgumentError,
37
37
  "Unsupported context/register reference: #{reference.inspect}"
@@ -48,6 +48,15 @@ module Mml
48
48
  !context.equal?(Mml::UNSPECIFIED_CONTEXT)
49
49
  end
50
50
 
51
+ # Lutaml::Model exposes context identity through both TypeContext (returned
52
+ # by GlobalContext.context) and Register (the public registration handle).
53
+ # Both classes expose `attr_reader :id`. We accept either by explicit type
54
+ # check rather than `respond_to?` duck-typing so the contract is verifiable.
55
+ def lutaml_context_reference?(reference)
56
+ reference.is_a?(Lutaml::Model::TypeContext) ||
57
+ reference.is_a?(Lutaml::Model::Register)
58
+ end
59
+
51
60
  # MML accepts the old `register:` alias, but never both inputs at once.
52
61
  def raise_if_conflicting_context_options!(context, register)
53
62
  return unless context_specified?(context) && register
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../context_configuration"
4
-
5
3
  module Mml
6
4
  module V2
7
5
  module Configuration