Fixed silent data loss when parsing DCC documents - #13
Open
HassanAkbar wants to merge 5 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes multiple causes of silent data loss when round-tripping DCC documents by correcting model registrations/mappings (DCC vs D-SI and MathML) and by fixing decimal XML list serialization, backed by new fidelity-focused specs.
Changes:
- Prevent D-SI type re-export from overwriting DCC’s own
:listregistration and add missing D-SIexpandedUnc/coverageIntervalwiring undersi:real. - Introduce
dcc:mathmlas a properdcc:xmlTypewrapper model (breaking API change:formula.mathml.math). - Fix decimal XML list casting/serialization to preserve space-separated wire form and avoid scientific notation leakage; expand tests to catch regressions.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| spec/parse_fidelity_spec.rb | Adds end-to-end round-trip element-count assertions to detect silent parse/serialize data loss. |
| spec/dcc/validate/schematron_spec.rb | Adds specs for broadcast-vs-per-value uncertainty list consistency validation. |
| spec/dcc/type_spec.rb | Adds tests for DecimalXmlList value-object behavior (equality, enumeration, YAML, attribute round-trip). |
| spec/dcc/convert/additional_spec.rb | Ensures CSV conversion doesn’t emit scientific notation for list values. |
| lib/dcc/validate/schematron/rules/uncertainty_consistency.rb | Extends rule to validate multiple uncertainty-related lists and allow broadcast semantics. |
| lib/dcc/v3/mathml.rb | Adds DCC v3 Mathml wrapper model registered as :mathml. |
| lib/dcc/v3.rb | Autoloads/registers Mathml; prevents D-SI re-export from overwriting DCC-owned model IDs (notably :list). |
| lib/dcc/v2/mathml.rb | Adds DCC v2 Mathml wrapper model registered as :mathml. |
| lib/dcc/v2.rb | Autoloads/registers Mathml in v2 element set. |
| lib/dcc/type/decimal_xml_list.rb | Reworks decimal XML list type into a value object to preserve wire format and correct serialization. |
| lib/dcc/si/v2/expanded_unc.rb | Adds D-SI v2 ExpandedUnc model registered as :expandedUnc. |
| lib/dcc/si/v2/coverage_interval.rb | Adds D-SI v2 CoverageInterval model registered as :coverageInterval. |
| lib/dcc/si/v2.rb | Autoloads/registers new v2 uncertainty models. |
| lib/dcc/si/v1/expanded_unc.rb | Refactors v1 ExpandedUnc to share base mapping module. |
| lib/dcc/si/v1/coverage_interval.rb | Adds D-SI v1 CoverageInterval model registered as :coverageInterval. |
| lib/dcc/si/v1.rb | Autoloads/registers v1 CoverageInterval. |
| lib/dcc/si/base/real.rb | Maps deprecated expandedUnc and coverageInterval under si:real. |
| lib/dcc/si/base/expanded_unc.rb | Introduces shared mapping for si:expandedUncType. |
| lib/dcc/si/base/coverage_interval.rb | Introduces shared mapping for si:coverageIntervalType. |
| lib/dcc/si/base.rb | Autoloads shared uncertainty base modules. |
| lib/dcc/diff.rb | Adjusts diff “primitive” detection to treat unknown value objects as leaf nodes. |
| lib/dcc/convert/csv.rb | Uses decimal list wire serialization for CSV output to avoid scientific notation. |
| lib/dcc/base/mathml.rb | Introduces shared DCC dcc:mathml wrapper mapping around ml:math. |
| lib/dcc/base/formula.rb | Changes formula.mathml from Mml::V3::Math to :mathml wrapper type. |
| CHANGELOG.adoc | Documents fixes and the breaking change for MathML wrapper behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.
Suppressed comments (1)
spec/parse_fidelity_spec.rb:52
- The new round-trip assertions for
dcc:listonly verify that the wrapper elements survive. If a regression causesdcc:listto parse as an empty list again, thelistcount can still match while nesteddcc:quantityelements are silently dropped (which is the failure mode described fordcclib/valid.xml). Consider also asserting quantity counts fordcclib/valid.xmlto lock in the original bug fix.
describe "dcc:quantity" do
it "round-trips every quantity in dcc_excel/example.xml" do
expect(counts("dcc_excel/example.xml", "quantity")).to eq(in: 20, out: 20)
end
end
HassanAkbar
marked this pull request as ready for review
July 31, 2026 10:28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reading a DCC file and writing it back silently dropped measurements. This fixes the six causes.
On
dcclib/valid.xml, 8 of 13 quantities and the entire measurement list disappeared,and the document still validated. The test suite stayed green because
round_trip_spec.rbonly asserted the output was a String containing one word.What was wrong:
Dcc::V3overwrote its own:listmodel with the D-SI one when re-exporting types.expandedUncandcoverageIntervalwere never wired intosi:real.dcc:mathmlwas mapped ontoMml::V3::Mathdirectly instead of through itsdcc:xmlTypewrapper, so it never parsed.DecimalXmlListserialized one list into N elements holding Ruby array literals.documents use.
Breaking:
formula.mathmlreturns aDcc::V2::Mathml/Dcc::V3::Mathmlwrapperinstead of an
Mml::V3::Math. Callers now readformula.mathml.math.Known and accepted:
lib/dcc/diff.rbis touched although it is not a parsing fix.Dcc::DiffraisedNoMethodErroron the new value object; it now treats anything it cannot descendinto as a leaf, which closes the class rather than special-casing one type.
Values#==accepts a plain Array buteql?does not. That is deliberate:eql?iswhat Hash uses and must stay strict.
dcc:statementormeasurementMetaDataare still dropped —dcc:datais unmapped onDcc::Base::Statement. Separate bug, documented in the spec.rubocop:disablein the D-SI mapping modules. Around twenty siblingmodules exceed the same metrics and are exempted by file; keeping these four shaped
like their siblings beats making them diverge.