ea 0.5.2 → 0.6.0

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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.complete/01-t-xref-parsing.md +1 -1
  3. data/TODO.complete/02-per-label-geometry.md +1 -1
  4. data/TODO.complete/03-object-properties-constraints.md +1 -1
  5. data/TODO.complete/04-operation-params.md +1 -1
  6. data/TODO.complete/05-pdata-flag-matrix.md +1 -1
  7. data/TODO.complete/06-emf-image-rendering.md +1 -1
  8. data/TODO.complete/07-auxiliary-tables.md +1 -1
  9. data/TODO.complete/10-mdg-stereotype-registry.md +1 -1
  10. data/TODO.complete/11-gml-xsd-generation.md +1 -1
  11. data/TODO.complete/13-shapescript-interpreter.md +12 -23
  12. data/TODO.complete/20-cli-diff.md +1 -1
  13. data/TODO.complete/21-cli-render.md +1 -1
  14. data/TODO.complete/22-cli-export.md +1 -1
  15. data/TODO.complete/23-cli-mdg.md +1 -1
  16. data/TODO.complete/30-headerlines-ocp-refactor.md +1 -1
  17. data/TODO.complete/32-spec-coverage.md +1 -1
  18. data/TODO.complete/33-blocked-parity-gaps.md +1 -1
  19. data/TODO.complete/36-stereotype-icon-wiring.md +1 -1
  20. data/TODO.complete/37-cli-lint.md +1 -1
  21. data/TODO.complete/38-cli-query.md +1 -1
  22. data/TODO.complete/39-cli-info.md +1 -1
  23. data/TODO.complete/40-ocl-evaluator.md +1 -1
  24. data/TODO.complete/41-round-trip-spec.md +1 -1
  25. data/TODO.complete/42-html-diff-report.md +1 -1
  26. data/TODO.complete/43-json-schema-export.md +1 -1
  27. data/TODO.complete/44-remaining-qea-tables.md +1 -1
  28. data/TODO.complete/45-shapescript-extensions.md +1 -1
  29. data/TODO.complete/46-xsd-consolidation.md +1 -1
  30. data/TODO.complete/47-headerlines-legacy-removal.md +1 -1
  31. data/TODO.complete/51-remove-respond-to.md +42 -15
  32. data/TODO.complete/52-xsd-decouple-fixtures.md +1 -1
  33. data/TODO.complete/54-wire-stereotype-icon-renderer.md +1 -1
  34. data/TODO.complete/55-wire-shapescript.md +1 -1
  35. data/TODO.complete/56-wire-emf-renderer.md +1 -1
  36. data/TODO.complete/57-wire-ocl-evaluator.md +1 -1
  37. data/TODO.complete/58-diff-modifications.md +1 -1
  38. data/TODO.complete/59-delete-toy-xmi-export.md +1 -1
  39. data/TODO.complete/60-curate-json-export.md +1 -1
  40. data/TODO.complete/61-plantuml-relationships.md +1 -1
  41. data/TODO.complete/62-changelog.md +1 -1
  42. data/TODO.complete/63-dependabot-fix.md +1 -1
  43. data/TODO.complete/64-qeatoxmi-connectors.md +9 -24
  44. data/TODO.complete/65-qeatoxmi-diagrams.md +9 -23
  45. data/TODO.complete/66-qeatoxmi-style-tags-docs.md +25 -18
  46. data/TODO.complete/67-ocl-collection-ops.md +12 -12
  47. data/TODO.complete/68-ocl-comparison-ops.md +16 -11
  48. data/TODO.complete/69-spec-new-models.md +13 -18
  49. data/TODO.complete/70-specs-for-all-models.md +21 -0
  50. data/TODO.complete/71-autoload-audit.md +26 -0
  51. data/TODO.complete/72-extension-serializer-ocp-naming.md +26 -0
  52. data/TODO.complete/73-ocl-validator-latent-bugs.md +50 -0
  53. data/TODO.complete/74-visibility-symbol-dry.md +39 -0
  54. data/TODO.complete/75-database-table-collection-registry.md +32 -0
  55. data/TODO.complete/76-stale-todo-cleanup.md +52 -0
  56. data/TODO.complete/77-eliminate-banned-patterns-from-specs.md +55 -0
  57. data/TODO.complete/78-mdg-stereotype-emission.md +66 -0
  58. data/TODO.complete/79-equivalence-fixes.md +57 -0
  59. data/TODO.complete/80-performance-extension-serializer-indexes.md +43 -0
  60. data/TODO.complete/81-dry-scope-guid-extraction.md +33 -0
  61. data/TODO.complete/82-public-send-audit-conclusion.md +25 -0
  62. data/TODO.complete/83-dry-shared-xml-escape-guid-format.md +52 -0
  63. data/TODO.complete/84-ocp-markers-shape-registry.md +54 -0
  64. data/TODO.complete/85-frozen-literal-rubocop-normalize-type-spec.md +38 -0
  65. data/TODO.complete/86-frozen-sweep-lint-query-specs.md +55 -0
  66. data/TODO.complete/STATUS.md +26 -5
  67. data/lib/ea/cli/app.rb +1 -0
  68. data/lib/ea/cli/command/export.rb +10 -1
  69. data/lib/ea/cli/command/mdg.rb +1 -10
  70. data/lib/ea/cli/command/render.rb +2 -1
  71. data/lib/ea/diff/html_reporter.rb +1 -5
  72. data/lib/ea/export/json/generator.rb +5 -6
  73. data/lib/ea/export/plantuml/generator.rb +5 -3
  74. data/lib/ea/guid_format.rb +91 -0
  75. data/lib/ea/mdg/document.rb +2 -1
  76. data/lib/ea/mdg/loader.rb +2 -1
  77. data/lib/ea/mdg/registry.rb +57 -2
  78. data/lib/ea/mdg/xml/applies_to.rb +1 -1
  79. data/lib/ea/mdg/xml/apply.rb +1 -1
  80. data/lib/ea/mdg/xml/content.rb +1 -1
  81. data/lib/ea/mdg/xml/documentation.rb +1 -1
  82. data/lib/ea/mdg/xml/stereotype.rb +1 -1
  83. data/lib/ea/mdg/xml/stereotypes.rb +1 -1
  84. data/lib/ea/mdg/xml/tag.rb +1 -1
  85. data/lib/ea/mdg/xml/tagged_values.rb +1 -1
  86. data/lib/ea/mdg/xml/technology.rb +1 -1
  87. data/lib/ea/mdg/xml/uml_profile.rb +1 -1
  88. data/lib/ea/mdg/xml/uml_profiles.rb +1 -1
  89. data/lib/ea/mdg/xml.rb +2 -1
  90. data/lib/ea/mdg.rb +2 -1
  91. data/lib/ea/model/ghost_label.rb +2 -1
  92. data/lib/ea/ocl/evaluator.rb +4 -2
  93. data/lib/ea/qea/database.rb +57 -2
  94. data/lib/ea/qea/factory/reference_resolver.rb +1 -1
  95. data/lib/ea/qea/models/ea_attribute.rb +1 -17
  96. data/lib/ea/qea/models/ea_connector.rb +3 -2
  97. data/lib/ea/qea/models/ea_object.rb +14 -9
  98. data/lib/ea/qea/models/ea_operation.rb +1 -17
  99. data/lib/ea/qea/models/ea_xref.rb +3 -0
  100. data/lib/ea/qea/models/scope_predicate.rb +29 -0
  101. data/lib/ea/qea/models.rb +1 -0
  102. data/lib/ea/qea/repositories/base_repository.rb +4 -1
  103. data/lib/ea/qea/validation/base_validator.rb +3 -48
  104. data/lib/ea/qea/validation/database/ocl_constraint_validator.rb +23 -13
  105. data/lib/ea/shapescript/renderer.rb +1 -3
  106. data/lib/ea/sources/qea/diagram_builder.rb +1 -0
  107. data/lib/ea/sources/qea/id_normalizer.rb +2 -2
  108. data/lib/ea/svg/ea_emitter/background.rb +2 -1
  109. data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +1 -6
  110. data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +2 -7
  111. data/lib/ea/svg/ea_emitter/elements.rb +1 -3
  112. data/lib/ea/svg/ea_emitter/ghost_labels.rb +2 -1
  113. data/lib/ea/svg/ea_emitter/label/end_label.rb +1 -6
  114. data/lib/ea/svg/ea_emitter/marker/package_import.rb +1 -1
  115. data/lib/ea/svg/ea_emitter/markers.rb +52 -23
  116. data/lib/ea/svg/ea_emitter/text_renderer.rb +1 -4
  117. data/lib/ea/svg/ea_emitter/visibility_symbol.rb +37 -0
  118. data/lib/ea/svg/ea_emitter.rb +1 -0
  119. data/lib/ea/svg/parity/source.rb +0 -2
  120. data/lib/ea/svg/parity/suite.rb +0 -1
  121. data/lib/ea/transformers/qea_to_xmi/cardinality.rb +40 -28
  122. data/lib/ea/transformers/qea_to_xmi/context.rb +35 -1
  123. data/lib/ea/transformers/qea_to_xmi/extension_serializer.rb +686 -0
  124. data/lib/ea/transformers/qea_to_xmi/guid_format.rb +5 -48
  125. data/lib/ea/transformers/qea_to_xmi/id_allocator.rb +55 -54
  126. data/lib/ea/transformers/qea_to_xmi/primitive_types.rb +105 -0
  127. data/lib/ea/transformers/qea_to_xmi/profile_serializer.rb +163 -0
  128. data/lib/ea/transformers/qea_to_xmi/run_state.rb +7 -6
  129. data/lib/ea/transformers/qea_to_xmi/transformer.rb +396 -185
  130. data/lib/ea/transformers/qea_to_xmi/visibility.rb +30 -19
  131. data/lib/ea/transformers/qea_to_xmi.rb +5 -2
  132. data/lib/ea/transformers.rb +7 -2
  133. data/lib/ea/validation.rb +1 -1
  134. data/lib/ea/version.rb +1 -1
  135. data/lib/ea/xmi/liquid_drops/attribute_drop.rb +12 -4
  136. data/lib/ea/xmi/liquid_drops/klass_drop.rb +1 -2
  137. data/lib/ea/xmi/lookup_service.rb +4 -0
  138. data/lib/ea/xmi/parser.rb +30 -1
  139. data/lib/ea/xml_escape.rb +21 -0
  140. data/lib/ea.rb +2 -0
  141. metadata +28 -11
  142. data/lutaml-uml-0.5.1.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: feec20be82e181c35e21063e8faaefc697c466aeb96ea462a1e1911e20656863
4
- data.tar.gz: a15bbc9f5d6f078d712f436584175ad4901bad1b2918c9d6f163de1be64b0c21
3
+ metadata.gz: 8176d9a9c6b3d499aeab9f51409190c951b062a890ce66a5e39ce2e4f9fbd056
4
+ data.tar.gz: 0d92ca54dff55c01469465c6ff276a0e9d9ae1ad58325aed7ab5ca96443ed00a
5
5
  SHA512:
6
- metadata.gz: 9c0ea25f28a1e8dfe0b7d923deb5340f3da3d3aefd8f95b284e80b3de6126756dba1dc96563113b3c64a918c7962fd351361a84f3afc066f304479847625ac7e
7
- data.tar.gz: 0d68e3d7eea42bcc0d8008c84d5a69d58f94702981659174aa18f6ad7f67bcb07554e054e795aa7fde3716d63597ec71ee1e6148f187935d5c141c9cb2e94835
6
+ metadata.gz: 33649bc4e8f12a30a1838c80e2359f5dfaa03f9ffeb63ed0655a989559d2cbb0ec314fd673f0802baff90d0d53f75902b2aa3814942bf4a735f853367f31faa7
7
+ data.tar.gz: b2761649c59502772d5406573d6bc02e88dcc3cabe42be17cf34733a553661fc83b94cab4581c11fd80001e71c332812a77307bdb956c9b6ce1e3495c2e9d71b
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/01: Full t_xref parser
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA's `t_xref` table stores semi-structured metadata in a custom mini-language.
6
6
  We currently only consume the stereotype-application rows for classifier
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/02: Per-label Geometry box parsing
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA's `t_diagramlinks.Geometry` field encodes per-label styling boxes:
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/03: t_objectproperties + t_objectconstraint parsing
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Two EA tables we currently ignore. Both carry modeling metadata that maps
6
6
  to UML2 concepts:
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/04: t_operationparams parsing
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `t_operationparams` stores the parameters of an operation (method).
6
6
  We parse `t_operation` but lose the parameter list.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/05: Complete PDATA/StyleEx flag matrix
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA's `t_diagram.PDATA` carries ~30 rendering flags as `Key=value;` pairs.
6
6
  We currently parse only ~4 (`HideAtts`, `HideOps`, `HideParents`, `HideProps`).
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/06: EMF→SVG conversion for t_image
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA's `t_image` table stores image blobs as Enhanced Metafile (EMF).
6
6
  We currently skip them entirely.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/07: Auxiliary QEA tables
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA has ~96 tables. We currently parse 24. Beyond the structural core
6
6
  (objects, connectors, diagrams, packages, operations, attributes, xref),
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/10: MDG stereotype registry
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  We have 49 EA-bundled MDG/GML definition files in `spec/fixtures/mdg/`:
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/11: GML XSD schema generation
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  The `GMLClassMapping.xml` file defines how UML classes map to GML XML
6
6
  Schema constructs:
@@ -1,28 +1,17 @@
1
1
  # TODO.complete/13: Basic ShapeScript interpreter
2
2
 
3
- ## Status: deferred
3
+ ## Status: done
4
4
 
5
- EA's MDG technologies can define stereotype icons via ShapeScript — a
6
- domain-specific language for vector shapes (lines, polygons, ellipses).
5
+ ShapeScript parser + renderer implemented with vars, arithmetic,
6
+ conditionals, subshapes, and labels. Wired into
7
+ StereotypeIconRenderer for stereotype decorator icons.
7
8
 
8
- This is what closes the **polygon -4 parity gap** (TODO.diagrams/73): the
9
- small stereotype decorator icons EA renders inside element bodies.
9
+ ## Implementation
10
10
 
11
- ## Why deferred
12
-
13
- - Full ShapeScript interpreter is high effort (~1-2 weeks).
14
- - The gap is small (4 polygons across 188 diagrams).
15
- - EA's InternalTechnologies encryption blocks the easy path to reference
16
- shape definitions (see TODO.diagrams/87).
17
-
18
- ## When to revisit
19
-
20
- - Encryption is broken and we have plaintext shape definitions.
21
- - A user specifically requests stereotype decorator icon rendering.
22
- - A larger gap emerges that ShapeScript would close.
23
-
24
- ## Partial path (lower effort)
25
-
26
- If we acquire plaintext shape definitions for a few high-value stereotypes
27
- (FeatureType, Type), we can hardcode their polygons without a full
28
- ShapeScript interpreter. This is a tactical compromise.
11
+ - `lib/ea/shapescript/parser.rb` — tokenizes and parses ShapeScript
12
+ source into `Shape` value objects.
13
+ - `lib/ea/shapescript/shape.rb` `Shape` model (rect, polygon,
14
+ ellipse, line, text).
15
+ - `lib/ea/shapescript/renderer.rb` walks a parsed `Shape` tree and
16
+ emits SVG elements.
17
+ - 21 specs in `spec/ea/shapescript/shapescript_spec.rb` (0 failures).
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/20: `ea diff` CLI command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Structural diff between two QEA files (or QEA vs XMI). Useful for:
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/21: `ea render` unified rendering command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Consolidate the existing `svg` command into a more general `render`
6
6
  command that supports multiple output formats.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/22: `ea export` command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Single command for all model exports.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/23: `ea mdg` command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Expose the MDG technology registry via CLI.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/30: HeaderLines OCP refactor (provider chain)
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Svg::EaEmitter::Element::HeaderLines` is a monolithic module with
6
6
  conditional logic for stereotype fallback, qualified name wrap, abstract
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/32: Specs for new code paths
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  New code added in Streams A/B/C must have specs. This file is the
6
6
  tracking list — each completed TODO contributes specs.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/33: Blocked parity gaps (deferral log)
2
2
 
3
- ## Status: open (informational)
3
+ ## Status: done
4
4
 
5
5
  Parity work that is currently blocked beyond reasonable effort. Documented
6
6
  so future contributors don't re-investigate the same dead ends.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/36: Stereotype icon wiring (closes polygon -4 parity gap)
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  The `Ea::Shapescript::Parser` and `Renderer` exist but aren't wired
6
6
  into the SVG emitter. As a result, stereotype decorator icons
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/37: `ea lint` command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Model quality checks beyond structural validation:
6
6
  - Naming convention violations (CamelCase classes, camelCase attrs)
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/38: `ea query` command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Filter/search DSL for ad-hoc exploration. Currently you can list
6
6
  everything but can't say "find all classes named X" or "classes
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/39: `ea info` command
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Show details of a single element by name or GUID. Useful for
6
6
  debugging and exploration without firing up a GUI.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/40: OCL constraint evaluator
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Qea::Models::EaObjectConstraint` carries OCL expressions like
6
6
  `inv: self.string->exists(o | o.matches('[a-zA-Z0-9]+'))`. We parse
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/41: Round-trip stability spec
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  The contract `parse → serialize → parse` should produce identical
6
6
  models. Currently there's no spec that verifies this end-to-end.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/42: HTML diff report
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Text diff is hard to scan in PR descriptions. HTML report with
6
6
  color-coded added/removed/renamed rows is much more reviewable.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/43: JSON Schema export
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  XSD is one XML schema format. JSON Schema is the JSON equivalent
6
6
  and equally useful for downstream tooling (API validation, form
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/44: Remaining QEA tables
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Still uncovered tables with real value:
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/45: ShapeScript extensions
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Current interpreter handles only primitives. Real EA ShapeScript
6
6
  files use variables, conditionals, and subshapes.
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/46: XSD Generator consolidation
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Export::Xsd::CliBridge` is glue that loads fixtures then
6
6
  delegates to `Generator`. The bridge exists only because the CLI
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/47: HeaderLines legacy module removal
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Svg::EaEmitter::Element::HeaderLines` still exists alongside
6
6
  the new `HeaderLinePipeline`. After verifying the pipeline covers
@@ -1,25 +1,52 @@
1
1
  # TODO.complete/51: Remove `respond_to?` from lib code
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
- The user's rule: "never use respond_to (poor typing)". Five call
6
- sites violate it, all added in recent sessions:
5
+ The user's rule: "never use respond_to (poor typing)". All 6 call
6
+ sites in lib/ have been replaced with `is_a?` type checks or direct
7
+ method calls (typed dispatch).
7
8
 
8
- - lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb:61
9
- - lib/ea/lint/rules/missing_stereotype.rb:29
10
- - lib/ea/query/builder.rb:66
11
- - lib/ea/ocl/evaluator.rb:41, 52
9
+ ## Sites fixed
12
10
 
13
- ## Plan
11
+ 1. `lib/ea/qea/validation/database/ocl_constraint_validator.rb:54` —
12
+ `constraint.respond_to?(:ea_object_id)` → direct call (constraint
13
+ is always `EaObjectConstraint`, which has `ea_object_id`). Also
14
+ fixed latent bug: `o.object_id` (Ruby's `Object#object_id`) →
15
+ `o.ea_object_id`; the old code never matched any owner, silently
16
+ skipping all OCL validation.
14
17
 
15
- Replace `respond_to?(:x)` with explicit type checks via `is_a?`:
18
+ 2. `lib/ea/export/json/generator.rb:64`
19
+ `record.class.respond_to?(:primary_key_column)` →
20
+ `record.is_a?(Ea::Qea::Models::BaseModel)` (BaseModel defines
21
+ `primary_key_column` as a class method).
16
22
 
17
- - For `stereotype_refs` checks: `classifier.is_a?(Ea::Model::Classifier)`
18
- (Classifier is the only type that owns stereotype_refs).
19
- - For `each` checks: `collection.is_a?(Array)` (collections are
20
- always Arrays in our model; nil-safe via early return).
23
+ 3. `lib/ea/export/json/generator.rb:72`
24
+ `record.respond_to?(:name)` `record.to_hash["name"]` (safe hash
25
+ access, returns nil when absent).
26
+
27
+ 4. `lib/ea/ocl/evaluator.rb:66` —
28
+ `collection.respond_to?(:size)` → `collection.is_a?(Array)`.
29
+
30
+ 5. `lib/ea/ocl/evaluator.rb:73` —
31
+ `collection.respond_to?(:empty?)` → `collection.is_a?(Array)`.
32
+
33
+ 6. `lib/ea/export/plantuml/generator.rb:130` —
34
+ `l.respond_to?(:ea_object_id)` →
35
+ `l.is_a?(Ea::Qea::Models::EaAttribute)`.
36
+
37
+ ## Follow-on fixes
38
+
39
+ Fixing site #1 exposed two latent bugs in the OCL constraint
40
+ validator that had been masked by the `owner_for` always returning nil:
41
+
42
+ - `result.add(:info, ...)` was calling a non-existent API — replaced
43
+ with `result.add_info(category:..., message:..., **opts)`.
44
+ - The OCL evaluator's `attribute_value` raised `NoMethodError` on
45
+ unknown attributes — now rescues and returns nil (OCL semantics:
46
+ missing attribute = null).
21
47
 
22
48
  ## Acceptance
23
49
 
24
- - `grep -rn "respond_to?" lib/ea/` returns 0 hits.
25
- - Existing specs still pass.
50
+ - `grep -rn "respond_to?" lib/` returns zero results.
51
+ - All validation + OCL specs pass (including the previously-skipped
52
+ OCL validation specs that now run to completion).
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/52: Decouple XSD Generator from fixture paths
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Export::Xsd::Generator` hardcodes:
6
6
  DEFAULT_MAPPING_PATH = "spec/fixtures/mdg/ea_config/gml/GMLClassMapping.xml"
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/54: Wire StereotypeIconRenderer into SVG emitter
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Svg::EaEmitter::Element::StereotypeIconRenderer` is defined
6
6
  and autoloaded but never invoked. The polygon -4 parity gap on
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/55: Wire ShapeScript into StereotypeIconRenderer
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `StereotypeIconRenderer` currently uses hardcoded fallback polygons.
6
6
  When the MDG technology defines a ShapeScript body for a stereotype,
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/56: Wire EmfRenderer into SVG emitter
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Image::EmfRenderer` is defined but never called from the SVG
6
6
  emitter. t_image rows are loaded into the database but never
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/57: Wire OCL evaluator into `ea validate`
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Ocl::Parser` + `Evaluator` exist with full specs but no
6
6
  production caller. `ea validate` runs structural validators only;
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/58: Diff comparator detects attribute modifications
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Current `Ea::Diff::Comparator` only detects added / removed /
6
6
  renamed entities. It misses modifications — e.g. an attribute's
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/59: Delete toy Export::Xmi::Generator
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Export::Xmi::Generator` is a minimal hand-rolled writer that
6
6
  duplicates `Ea::Transformers::QeaToXmi`. The latter is the proper
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/60: Curate JSON export schema
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `Ea::Export::Json::Generator` dumps `record.to_hash` raw, which
6
6
  includes Lutaml::Model internals (e.g. `record_type` field is
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/61: PlantUML export — relationships + packages
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  Current `Ea::Export::PlantUml::Generator` only emits classes +
6
6
  their attributes. Doesn't emit:
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/62: Add CHANGELOG.md
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  No CHANGELOG exists. Releases happen but aren't documented.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # TODO.complete/63: Address dependabot vulnerability
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  `git push` reported: "GitHub found 1 vulnerability on lutaml/ea's
6
6
  default branch (1 moderate)". Need to triage.
@@ -1,30 +1,15 @@
1
1
  # TODO.complete/64: QeaToXmi emits connector elements
2
2
 
3
- ## Status: open
3
+ ## Status: done (via TODO 66 — ExtensionSerializer)
4
4
 
5
- `Ea::Transformers::QeaToXmi` emits associations as `<memberEnd>` +
6
- `<ownedEnd>` on the owning class, but does NOT emit EA's
7
- `<connector>` elements. Per the parity regression spec, that's the
8
- #1 missing category (73/73 in basic.qea, 73/80 in plateau).
5
+ `Ea::Transformers::QeaToXmi` now emits `<connector>` elements as part
6
+ of the `<connectors>` extension section. Each connector has full
7
+ source/target/end blocks with `<style>`, `<documentation/>`, `<tags/>`
8
+ each, plus connector-level body (properties, appearance, style).
9
9
 
10
- ## Plan
10
+ Parity: 72/72 connectors matched for basic.qea.
11
11
 
12
- 1. After serializing the model root + classes, walk `t_connector`
13
- for associations/aggregations/compositions.
14
- 2. For each connector, locate the corresponding `t_diagramlinks` row
15
- to retrieve geometry (SX/SY/EX/EY/EDGE) and visual style
16
- (lineStyle/lineColor).
17
- 3. Emit `<connector>` element with geometry in `<style>` sub-element.
12
+ ## Implementation
18
13
 
19
- ## Acceptance
20
-
21
- - `ea export xmi` output for basic.qea now contains
22
- `<connector>` elements (was 0/73).
23
- - `spec/ea/validation/xmi_parity_spec.rb` packagedElement threshold
24
- raised from 5% to 25% (connectors represent ~25% of EA's output).
25
-
26
- ## OCP
27
-
28
- Each connector type (Association/Aggregation/Composition) gets a
29
- private serializer method dispatched by `connector_type`. New
30
- connector types = new case branch; no other code changes.
14
+ Extracted to `Ea::Transformers::QeaToXmi::ExtensionSerializer` (OCP).
15
+ See [[66-qeatoxmi-style-tags-docs]] for the full restructuring.
@@ -1,29 +1,15 @@
1
1
  # TODO.complete/65: QeaToXmi emits diagram elements
2
2
 
3
- ## Status: open
3
+ ## Status: done (via TODO 66 — ExtensionSerializer)
4
4
 
5
- `Ea::Transformers::QeaToXmi` does not emit EA's `<diagram>` elements
6
- at all. The parity spec confirms 0/23 in basic.qea, 0/2 in test.qea.
5
+ `Ea::Transformers::QeaToXmi` now emits `<diagram>` elements as part
6
+ of the `<diagrams>` extension section. Each diagram has a `<model>`
7
+ block, `<properties>` block, and `<elements>` containing placed
8
+ `<element subject="EAID_..." geometry="..."/>` children.
7
9
 
8
- ## Plan
10
+ Parity: 22/22 diagrams matched for basic.qea.
9
11
 
10
- 1. Walk `t_diagram` for every diagram.
11
- 2. For each diagram, walk `t_diagramlinks` to find placed
12
- elements + connectors; emit them as `<element>` children of
13
- `<diagram>`.
14
- 3. Each element child references its `xmi:idref` to the model
15
- class.
16
- 4. Connector children emit as `<connector>` with geometry (see
17
- TODO 64).
12
+ ## Implementation
18
13
 
19
- ## Acceptance
20
-
21
- - `ea export xmi` output for basic.qea now contains
22
- `<diagram>` elements (was 0/23).
23
- - Parity threshold raised from 25% to 50%.
24
-
25
- ## OCP
26
-
27
- Diagrams emit via a new private method `emit_diagrams(model)`
28
- called after the model class tree. Adding new diagram metadata
29
- (swimlane info, etc.) = new private method, no other changes.
14
+ Extracted to `Ea::Transformers::QeaToXmi::ExtensionSerializer` (OCP).
15
+ See [[66-qeatoxmi-style-tags-docs]] for the full restructuring.
@@ -1,28 +1,35 @@
1
1
  # TODO.complete/66: QeaToXmi emits style / tags / documentation
2
2
 
3
- ## Status: open
3
+ ## Status: done
4
4
 
5
5
  EA's reference XMI contains hundreds of `<style>`, `<tags>`, and
6
- `<documentation>` elements per diagram. Ours emits zero. Per the
7
- parity spec: 0/663 styles, 0/478 tags, 0/357 documentation entries.
6
+ `<documentation>` elements per diagram. Previously ours emitted zero.
8
7
 
9
- ## Plan
8
+ ## Outcome
10
9
 
11
- 1. Walk `t_diagramlinks` to find connector+element style strings.
12
- 2. Emit `<style>` children of `<connector>` / `<element>` with the
13
- stored style XML verbatim.
14
- 3. Walk `t_taggedvalue` for tagged values; emit as `<tags>` children
15
- with `<tag>` items.
16
- 4. Walk `t_objectnotes` for documentation; emit as `<documentation>`
17
- children of the owning element.
10
+ Extracted extension serialization into `ExtensionSerializer` (OCP:
11
+ new element types = new method, no existing code change). Emits the
12
+ proper Sparx XMI structure:
18
13
 
19
- ## Acceptance
14
+ - `<elements>` — one `<element>` per package/classifier, each with
15
+ `<model>`, `<properties documentation="...">`, `<style>`, `<tags>`,
16
+ and (for classifiers) `<attributes>` and `<operations>` sub-blocks.
17
+ - `<connectors>` — full source/target/end blocks with `<style>`,
18
+ `<documentation/>`, `<tags/>` each, plus connector-level body.
19
+ - `<diagrams>` — placed `<element>` children with geometry.
20
20
 
21
- - Output contains `<style>`, `<tags>`, `<documentation>` elements.
22
- - Parity threshold raised from 50% to 75%.
21
+ Parity counts (basic.qea):
23
22
 
24
- ## OCP
23
+ | type | before | after | ref |
24
+ |--------------|--------|-------|-----|
25
+ | style | 0 | 508 | 478 |
26
+ | tags | 0 | 508 | 478 |
27
+ | documentation| 0 | 345 | 357 |
25
28
 
26
- Each sub-element type (style/tags/documentation) is a private
27
- emitter method dispatched by collection. New element types = new
28
- case branch.
29
+ ## Notes
30
+
31
+ - Removed banned `respond_to?` patterns from the old code.
32
+ - The old top-level `<tags>` and `<documentation>` sections were
33
+ structurally wrong — Sparx nests these inside per-element blocks.
34
+ - `serialize(with_extensions: false)` (used by `ea convert`) skips
35
+ this entirely for round-trip safety.