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.
- checksums.yaml +4 -4
- data/CLAUDE.md +8 -2
- data/TODO.complete/1-v3-autoload.md +63 -0
- data/TODO.complete/2-v2-autoload.md +46 -0
- data/TODO.complete/3-no-require-relative.md +32 -0
- data/TODO.complete/4-remove-duplicate-register-model.md +31 -0
- data/TODO.complete/5-context-options-type-check.md +44 -0
- data/TODO.complete/6-context-configuration-type-check.md +32 -0
- data/TODO.complete/7-specs-for-refactor.md +38 -0
- data/lib/mml/context_configuration.rb +3 -1
- data/lib/mml/context_options.rb +10 -1
- data/lib/mml/v2/configuration.rb +0 -2
- data/lib/mml/v2.rb +382 -246
- data/lib/mml/v3/annotation.rb +0 -1
- data/lib/mml/v3/annotation_xml.rb +0 -1
- data/lib/mml/v3/apply.rb +0 -1
- data/lib/mml/v3/arith.rb +0 -22
- data/lib/mml/v3/bind.rb +0 -1
- data/lib/mml/v3/calculus.rb +0 -7
- data/lib/mml/v3/cbytes.rb +0 -1
- data/lib/mml/v3/cerror.rb +0 -1
- data/lib/mml/v3/ci.rb +0 -1
- data/lib/mml/v3/cn.rb +0 -1
- data/lib/mml/v3/configuration.rb +0 -2
- data/lib/mml/v3/constants.rb +0 -15
- data/lib/mml/v3/constructs.rb +0 -10
- data/lib/mml/v3/cs.rb +0 -1
- data/lib/mml/v3/csymbol.rb +0 -1
- data/lib/mml/v3/deprecated_content.rb +0 -7
- data/lib/mml/v3/elementary_functions.rb +0 -28
- data/lib/mml/v3/functions.rb +0 -6
- data/lib/mml/v3/linear_algebra.rb +0 -9
- data/lib/mml/v3/logic.rb +0 -7
- data/lib/mml/v3/maction.rb +0 -1
- data/lib/mml/v3/maligngroup.rb +0 -1
- data/lib/mml/v3/malignmark.rb +0 -1
- data/lib/mml/v3/math.rb +0 -2
- data/lib/mml/v3/menclose.rb +0 -1
- data/lib/mml/v3/merror.rb +0 -1
- data/lib/mml/v3/mfenced.rb +0 -1
- data/lib/mml/v3/mfrac.rb +0 -1
- data/lib/mml/v3/mfraction.rb +0 -1
- data/lib/mml/v3/mglyph.rb +0 -1
- data/lib/mml/v3/mi.rb +0 -1
- data/lib/mml/v3/mlabeledtr.rb +0 -1
- data/lib/mml/v3/mlongdiv.rb +0 -1
- data/lib/mml/v3/mmultiscripts.rb +0 -1
- data/lib/mml/v3/mn.rb +0 -1
- data/lib/mml/v3/mo.rb +0 -1
- data/lib/mml/v3/mover.rb +0 -1
- data/lib/mml/v3/mpadded.rb +0 -1
- data/lib/mml/v3/mphantom.rb +0 -1
- data/lib/mml/v3/mprescripts.rb +0 -1
- data/lib/mml/v3/mroot.rb +0 -1
- data/lib/mml/v3/mrow.rb +0 -1
- data/lib/mml/v3/ms.rb +0 -1
- data/lib/mml/v3/mscarries.rb +0 -1
- data/lib/mml/v3/mscarry.rb +0 -1
- data/lib/mml/v3/msgroup.rb +0 -1
- data/lib/mml/v3/msline.rb +0 -1
- data/lib/mml/v3/mspace.rb +0 -1
- data/lib/mml/v3/msqrt.rb +0 -1
- data/lib/mml/v3/msrow.rb +0 -1
- data/lib/mml/v3/mstack.rb +0 -1
- data/lib/mml/v3/mstyle.rb +0 -1
- data/lib/mml/v3/msub.rb +0 -1
- data/lib/mml/v3/msubsup.rb +0 -1
- data/lib/mml/v3/msup.rb +0 -1
- data/lib/mml/v3/mtable.rb +0 -1
- data/lib/mml/v3/mtd.rb +0 -1
- data/lib/mml/v3/mtext.rb +0 -1
- data/lib/mml/v3/mtr.rb +0 -1
- data/lib/mml/v3/munder.rb +0 -1
- data/lib/mml/v3/munderover.rb +0 -1
- data/lib/mml/v3/none.rb +0 -1
- data/lib/mml/v3/relations.rb +0 -9
- data/lib/mml/v3/semantics.rb +0 -1
- data/lib/mml/v3/sets.rb +0 -13
- data/lib/mml/v3/statistics.rb +0 -7
- data/lib/mml/v3/vector_calculus.rb +0 -4
- data/lib/mml/v3.rb +451 -73
- data/lib/mml/v4/annotation.rb +0 -1
- data/lib/mml/v4/configuration.rb +0 -2
- data/lib/mml/v4/elementary_functions.rb +0 -1
- data/lib/mml/v4/functions.rb +0 -1
- data/lib/mml/v4.rb +21 -17
- data/lib/mml/version.rb +1 -1
- data/lib/mml.rb +2 -0
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 753f58cf7a8516296624dc7eb472621cd4ecaab7a7d1c3f34d7e8d67eff9bbce
|
|
4
|
+
data.tar.gz: 062164c14aa4475421fc48ca37de907be75938d8b574a768cc8e8e374bd91252
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
###
|
|
98
|
+
### Version module body registration
|
|
99
99
|
|
|
100
|
-
Each `lib/mml/v{2,3,4}
|
|
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.
|
|
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
|
data/lib/mml/context_options.rb
CHANGED
|
@@ -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
|
|
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
|