dcc 0.2.0 → 0.2.2

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +19 -0
  3. data/.github/workflows/release.yml +28 -0
  4. data/.gitignore +4 -0
  5. data/.rubocop_todo.yml +560 -10
  6. data/CHANGELOG.adoc +34 -1
  7. data/CONTRIBUTING.adoc +8 -1
  8. data/Gemfile +5 -7
  9. data/README.adoc +162 -7
  10. data/dcc.gemspec +9 -2
  11. data/docs/schema-versions.adoc +20 -7
  12. data/examples/build_minimal_dcc.rb +0 -0
  13. data/examples/convert_all_formats.rb +2 -1
  14. data/examples/parse_and_inspect.rb +0 -0
  15. data/examples/quantity_math_demo.rb +7 -7
  16. data/examples/validate_full.rb +1 -1
  17. data/lib/dcc/base/calibration_laboratory.rb +2 -1
  18. data/lib/dcc/base/condition.rb +5 -2
  19. data/lib/dcc/base/core_data.rb +8 -3
  20. data/lib/dcc/base/formula.rb +3 -3
  21. data/lib/dcc/base/identification.rb +6 -3
  22. data/lib/dcc/base/mathml.rb +33 -0
  23. data/lib/dcc/base/quantity.rb +2 -1
  24. data/lib/dcc/base/resp_person.rb +4 -2
  25. data/lib/dcc/base/text.rb +1 -1
  26. data/lib/dcc/base.rb +2 -1
  27. data/lib/dcc/builder/dsl.rb +1 -1
  28. data/lib/dcc/builder/session.rb +16 -14
  29. data/lib/dcc/builder.rb +3 -3
  30. data/lib/dcc/cli/cli.rb +152 -26
  31. data/lib/dcc/cli/formatters.rb +35 -7
  32. data/lib/dcc/cli.rb +1 -1
  33. data/lib/dcc/context_configuration.rb +2 -1
  34. data/lib/dcc/context_options.rb +4 -2
  35. data/lib/dcc/convert/csv.rb +27 -9
  36. data/lib/dcc/convert/html.rb +26 -110
  37. data/lib/dcc/convert/json.rb +10 -7
  38. data/lib/dcc/convert/liquid_filters.rb +58 -0
  39. data/lib/dcc/convert/result.rb +1 -1
  40. data/lib/dcc/convert/templates/report.liquid +250 -0
  41. data/lib/dcc/convert/yaml.rb +1 -1
  42. data/lib/dcc/convert.rb +1 -0
  43. data/lib/dcc/diff/change.rb +1 -1
  44. data/lib/dcc/diff/result.rb +8 -4
  45. data/lib/dcc/diff.rb +43 -11
  46. data/lib/dcc/error.rb +7 -0
  47. data/lib/dcc/extract/file.rb +3 -4
  48. data/lib/dcc/extract/formula/ast.rb +137 -0
  49. data/lib/dcc/extract/formula/evaluator.rb +357 -0
  50. data/lib/dcc/extract/formula/parser.rb +305 -0
  51. data/lib/dcc/extract/formula/quantity.rb +89 -0
  52. data/lib/dcc/extract/formula.rb +110 -0
  53. data/lib/dcc/extract/ring.rb +1 -1
  54. data/lib/dcc/extract.rb +1 -1
  55. data/lib/dcc/i18n/text_lookup.rb +8 -4
  56. data/lib/dcc/i18n.rb +1 -1
  57. data/lib/dcc/inspect/report.rb +51 -14
  58. data/lib/dcc/inspect.rb +1 -1
  59. data/lib/dcc/migrate/route.rb +44 -0
  60. data/lib/dcc/migrate/v2_to_v3.rb +445 -0
  61. data/lib/dcc/migrate.rb +130 -26
  62. data/lib/dcc/plugin/base.rb +64 -0
  63. data/lib/dcc/plugin/registry.rb +7 -2
  64. data/lib/dcc/plugin.rb +6 -2
  65. data/lib/dcc/quantity_format/formatter.rb +16 -10
  66. data/lib/dcc/quantity_format.rb +1 -1
  67. data/lib/dcc/quantity_math/complex.rb +252 -0
  68. data/lib/dcc/quantity_math/matrix.rb +217 -0
  69. data/lib/dcc/quantity_math/quantity.rb +1 -1
  70. data/lib/dcc/quantity_math/real.rb +6 -6
  71. data/lib/dcc/quantity_math.rb +31 -3
  72. data/lib/dcc/schema/version.rb +2 -2
  73. data/lib/dcc/server/app.html +282 -0
  74. data/lib/dcc/server/app.rb +171 -87
  75. data/lib/dcc/server/demo_cert.xml +244 -0
  76. data/lib/dcc/server/storage/entry.rb +1 -1
  77. data/lib/dcc/server/storage/memory.rb +3 -2
  78. data/lib/dcc/server/storage.rb +1 -1
  79. data/lib/dcc/server.rb +1 -1
  80. data/lib/dcc/si/base/complex.rb +1 -1
  81. data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
  82. data/lib/dcc/si/base/constant.rb +1 -1
  83. data/lib/dcc/si/base/coverage_interval.rb +36 -0
  84. data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
  85. data/lib/dcc/si/base/expanded_mu.rb +1 -1
  86. data/lib/dcc/si/base/expanded_unc.rb +34 -0
  87. data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
  88. data/lib/dcc/si/base/hybrid.rb +3 -2
  89. data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
  90. data/lib/dcc/si/base/real.rb +13 -3
  91. data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
  92. data/lib/dcc/si/base/si_list.rb +3 -2
  93. data/lib/dcc/si/base/standard_mu.rb +1 -1
  94. data/lib/dcc/si/base.rb +5 -2
  95. data/lib/dcc/si/v1/coverage_interval.rb +8 -0
  96. data/lib/dcc/si/v1/expanded_unc.rb +1 -16
  97. data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
  98. data/lib/dcc/si/v1.rb +5 -2
  99. data/lib/dcc/si/v2/coverage_interval.rb +8 -0
  100. data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
  101. data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
  102. data/lib/dcc/si/v2/expanded_unc.rb +8 -0
  103. data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
  104. data/lib/dcc/si/v2.rb +8 -3
  105. data/lib/dcc/signature/result.rb +2 -2
  106. data/lib/dcc/signature/signer.rb +31 -18
  107. data/lib/dcc/signature/verifier.rb +23 -21
  108. data/lib/dcc/signature.rb +1 -1
  109. data/lib/dcc/streaming/reader.rb +246 -0
  110. data/lib/dcc/streaming.rb +79 -0
  111. data/lib/dcc/transform/result.rb +1 -1
  112. data/lib/dcc/transform/xslt.rb +22 -12
  113. data/lib/dcc/transform.rb +5 -4
  114. data/lib/dcc/type/base64_binary.rb +5 -3
  115. data/lib/dcc/type/decimal_xml_list.rb +99 -13
  116. data/lib/dcc/type/iso_country_code.rb +3 -2
  117. data/lib/dcc/type/iso_language_code.rb +3 -2
  118. data/lib/dcc/type/schema_version.rb +3 -2
  119. data/lib/dcc/type/si_unit.rb +3 -2
  120. data/lib/dcc/type_guards.rb +3 -3
  121. data/lib/dcc/v2/calibration_laboratory.rb +2 -1
  122. data/lib/dcc/v2/condition.rb +22 -1
  123. data/lib/dcc/v2/configuration.rb +1 -1
  124. data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
  125. data/lib/dcc/v2/identification.rb +14 -1
  126. data/lib/dcc/v2/mathml.rb +8 -0
  127. data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
  128. data/lib/dcc/v2/quantity.rb +4 -2
  129. data/lib/dcc/v2.rb +4 -2
  130. data/lib/dcc/v3/calibration_laboratory.rb +2 -1
  131. data/lib/dcc/v3/configuration.rb +1 -1
  132. data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
  133. data/lib/dcc/v3/mathml.rb +8 -0
  134. data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
  135. data/lib/dcc/v3/quantity.rb +4 -2
  136. data/lib/dcc/v3.rb +12 -2
  137. data/lib/dcc/validate/business_rules.rb +23 -9
  138. data/lib/dcc/validate/issue.rb +2 -1
  139. data/lib/dcc/validate/result.rb +6 -4
  140. data/lib/dcc/validate/schematron/profile.rb +73 -18
  141. data/lib/dcc/validate/schematron/rule.rb +13 -3
  142. data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
  143. data/lib/dcc/validate/schematron/rules/base.rb +1 -2
  144. data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
  145. data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
  146. data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
  147. data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
  148. data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
  149. data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
  150. data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
  151. data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
  152. data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
  153. data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
  154. data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
  155. data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
  156. data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
  157. data/lib/dcc/validate/schematron/rules.rb +28 -14
  158. data/lib/dcc/validate/schematron.rb +1 -1
  159. data/lib/dcc/validate/xsd.rb +9 -3
  160. data/lib/dcc/validate.rb +1 -1
  161. data/lib/dcc/version.rb +1 -1
  162. data/lib/dcc/versioned_parser.rb +1 -1
  163. data/lib/dcc.rb +68 -10
  164. data/sample_dcc.xml +140 -0
  165. data/web/index.html +12 -0
  166. data/web/package-lock.json +1599 -0
  167. data/web/package.json +22 -0
  168. data/web/src/App.vue +349 -0
  169. data/web/src/lib/builder.ts +171 -0
  170. data/web/src/lib/dcc.ts +338 -0
  171. data/web/src/lib/units.json +5581 -0
  172. data/web/src/main.ts +5 -0
  173. data/web/src/style.css +27 -0
  174. data/web/tsconfig.json +15 -0
  175. data/web/vite.config.ts +14 -0
  176. metadata +148 -9
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -9,25 +8,31 @@ module Dcc
9
8
  # quantity level). Error if missing.
10
9
  class InfluenceConditionsPlacement < Base
11
10
  def check_on(dcc)
12
- return [] unless Dcc::TypeGuards.has_attribute?(dcc, :measurement_results)
11
+ return [] unless Dcc::TypeGuards.has_attribute?(dcc,
12
+ :measurement_results)
13
13
 
14
14
  mr_list = safe_attr(dcc.measurement_results, :measurement_result)
15
15
  return [] if mr_list.empty?
16
16
 
17
17
  any_present = mr_list.any? do |mr|
18
- next false unless Dcc::TypeGuards.has_attribute?(mr, :influence_conditions)
18
+ next false unless Dcc::TypeGuards.has_attribute?(mr,
19
+ :influence_conditions)
19
20
  next true unless mr.influence_conditions.nil?
20
21
 
21
22
  Dcc::TypeGuards.has_attribute?(mr, :results) && mr.results &&
22
23
  has_in_descendants?(mr.results)
23
24
  end
24
25
 
25
- any_present ? [] : [
26
- issue(
27
- severity: :error,
28
- message: "dcc:influenceConditions is missing everywhere",
29
- ),
30
- ]
26
+ if any_present
27
+ []
28
+ else
29
+ [
30
+ issue(
31
+ severity: :error,
32
+ message: "dcc:influenceConditions is missing everywhere",
33
+ ),
34
+ ]
35
+ end
31
36
  end
32
37
 
33
38
  private
@@ -35,13 +40,18 @@ module Dcc
35
40
  def has_in_descendants?(node)
36
41
  return false unless node.is_a?(::Lutaml::Model::Serializable)
37
42
 
38
- if Dcc::TypeGuards.has_attribute?(node, :influence_conditions) && !node.influence_conditions.nil?
43
+ if Dcc::TypeGuards.has_attribute?(node,
44
+ :influence_conditions) && !node.influence_conditions.nil?
39
45
  return true
40
46
  end
41
47
 
42
48
  node.class.attributes.each_key do |attr|
43
49
  value = node.public_send(attr)
44
- Array(value).any? { |c| has_in_descendants?(c) } if value.is_a?(::Array) || value.is_a?(::Lutaml::Model::Serializable)
50
+ if value.is_a?(::Array) || value.is_a?(::Lutaml::Model::Serializable)
51
+ Array(value).any? do |c|
52
+ has_in_descendants?(c)
53
+ end
54
+ end
45
55
  end
46
56
  false
47
57
  end
@@ -55,4 +65,4 @@ module Dcc
55
65
  end
56
66
  end
57
67
  end
58
- end
68
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -10,13 +9,17 @@ module Dcc
10
9
  # flag empties that escaped earlier casts.
11
10
  class IsoCodeValidation < Base
12
11
  def check_on(dcc)
13
- return [] unless Dcc::TypeGuards.has_attribute?(dcc, :administrative_data)
12
+ return [] unless Dcc::TypeGuards.has_attribute?(dcc,
13
+ :administrative_data)
14
14
 
15
15
  core = safe_attr(dcc.administrative_data, :core_data)
16
16
  return [] if core.nil?
17
17
 
18
18
  issues = []
19
- country = Dcc::TypeGuards.has_attribute?(core, :country_code_iso_3166_1) ? core.country_code_iso_3166_1 : nil
19
+ country = if Dcc::TypeGuards.has_attribute?(core,
20
+ :country_code_iso_3166_1)
21
+ core.country_code_iso_3166_1
22
+ end
20
23
  if country.nil? || country.to_s.empty?
21
24
  issues << issue(
22
25
  severity: :error,
@@ -24,17 +27,31 @@ module Dcc
24
27
  )
25
28
  end
26
29
 
27
- used = Dcc::TypeGuards.has_attribute?(core, :used_lang_code_iso_639_1) ? Array(core.used_lang_code_iso_639_1) : []
28
- issues << issue(
29
- severity: :error,
30
- message: "dcc:usedLangCodeISO639_1 must have at least one entry",
31
- ) if used.empty?
30
+ used = if Dcc::TypeGuards.has_attribute?(core,
31
+ :used_lang_code_iso_639_1)
32
+ Array(core.used_lang_code_iso_639_1)
33
+ else
34
+ []
35
+ end
36
+ if used.empty?
37
+ issues << issue(
38
+ severity: :error,
39
+ message: "dcc:usedLangCodeISO639_1 must have at least one entry",
40
+ )
41
+ end
32
42
 
33
- mandatory = Dcc::TypeGuards.has_attribute?(core, :mandatory_lang_code_iso_639_1) ? Array(core.mandatory_lang_code_iso_639_1) : []
34
- issues << issue(
35
- severity: :error,
36
- message: "dcc:mandatoryLangCodeISO639_1 must have at least one entry",
37
- ) if mandatory.empty?
43
+ mandatory = if Dcc::TypeGuards.has_attribute?(core,
44
+ :mandatory_lang_code_iso_639_1)
45
+ Array(core.mandatory_lang_code_iso_639_1)
46
+ else
47
+ []
48
+ end
49
+ if mandatory.empty?
50
+ issues << issue(
51
+ severity: :error,
52
+ message: "dcc:mandatoryLangCodeISO639_1 must have at least one entry",
53
+ )
54
+ end
38
55
 
39
56
  issues
40
57
  end
@@ -50,4 +67,4 @@ module Dcc
50
67
  end
51
68
  end
52
69
  end
53
- end
70
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -8,14 +7,22 @@ module Dcc
8
7
  # Errors on duplicate language codes in `dcc:usedLangCodeISO639_1`.
9
8
  class LanguageCodeDedup < Base
10
9
  def check_on(dcc)
11
- return [] unless Dcc::TypeGuards.has_attribute?(dcc, :administrative_data)
10
+ return [] unless Dcc::TypeGuards.has_attribute?(dcc,
11
+ :administrative_data)
12
12
 
13
13
  core = safe_attr(dcc.administrative_data, :core_data)
14
14
  return [] if core.nil?
15
15
 
16
- used = Dcc::TypeGuards.has_attribute?(core, :used_lang_code_iso_639_1) ? Array(core.used_lang_code_iso_639_1) : []
16
+ used = if Dcc::TypeGuards.has_attribute?(core,
17
+ :used_lang_code_iso_639_1)
18
+ Array(core.used_lang_code_iso_639_1)
19
+ else
20
+ []
21
+ end
17
22
  used_strings = used.map(&:to_s)
18
- duplicates = used_strings.group_by(&:itself).select { |_k, v| v.size > 1 }.keys
23
+ duplicates = used_strings.group_by(&:itself).select do |_k, v|
24
+ v.size > 1
25
+ end.keys
19
26
 
20
27
  duplicates.map do |dup|
21
28
  issue(
@@ -36,4 +43,4 @@ module Dcc
36
43
  end
37
44
  end
38
45
  end
39
- end
46
+ end
@@ -36,7 +36,10 @@ module Dcc
36
36
  node.class.attributes.each_key do |attr_name|
37
37
  value = node.public_send(attr_name)
38
38
  Array(value).each do |child|
39
- declared += collect_declared_non_si_units(child, visited) if child.is_a?(::Lutaml::Model::Serializable)
39
+ if child.is_a?(::Lutaml::Model::Serializable)
40
+ declared += collect_declared_non_si_units(child,
41
+ visited)
42
+ end
40
43
  end
41
44
  end
42
45
  declared
@@ -57,7 +60,9 @@ module Dcc
57
60
  extract_non_si_unit(node, accumulator)
58
61
  node.class.attributes.each_key do |attr_name|
59
62
  value = node.public_send(attr_name)
60
- Array(value).each { |child| walk_for_used_units(child, accumulator, visited) }
63
+ Array(value).each do |child|
64
+ walk_for_used_units(child, accumulator, visited)
65
+ end
61
66
  end
62
67
  end
63
68
 
@@ -78,5 +83,3 @@ module Dcc
78
83
  end
79
84
  end
80
85
  end
81
-
82
- require "set"
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -11,13 +10,17 @@ module Dcc
11
10
 
12
11
  def check_on(dcc)
13
12
  issues = []
14
- return issues unless Dcc::TypeGuards.has_attribute?(dcc, :administrative_data)
13
+ return issues unless Dcc::TypeGuards.has_attribute?(dcc,
14
+ :administrative_data)
15
15
 
16
16
  software_list = safe_attr(dcc.administrative_data, :dcc_software)
17
17
  return issues if software_list.nil?
18
18
 
19
19
  Array(safe_attr(software_list, :software)).each do |sw|
20
- release = Dcc::TypeGuards.has_attribute?(sw, :release) ? sw.release : nil
20
+ release = if Dcc::TypeGuards.has_attribute?(sw,
21
+ :release)
22
+ sw.release
23
+ end
21
24
  next if release.nil? || release.empty?
22
25
  next if release.match?(PATTERN)
23
26
 
@@ -41,4 +44,4 @@ module Dcc
41
44
  end
42
45
  end
43
46
  end
44
- end
47
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -12,20 +11,25 @@ module Dcc
12
11
  end
13
12
 
14
13
  def check_on(dcc)
15
- return [] unless Dcc::TypeGuards.has_attribute?(dcc, :schema_version)
14
+ return [] unless Dcc::TypeGuards.has_attribute?(dcc,
15
+ :schema_version)
16
16
 
17
17
  current = dcc.schema_version.to_s
18
18
  latest = ::Dcc::Schema::Version::DCC_LATEST
19
19
 
20
- current == latest ? [] : [
21
- issue(
22
- severity: :warning,
23
- message: "schemaVersion '#{current}' is not the latest release (#{latest})",
24
- ),
25
- ]
20
+ if current == latest
21
+ []
22
+ else
23
+ [
24
+ issue(
25
+ severity: :warning,
26
+ message: "schemaVersion '#{current}' is not the latest release (#{latest})",
27
+ ),
28
+ ]
29
+ end
26
30
  end
27
31
  end
28
32
  end
29
33
  end
30
34
  end
31
- end
35
+ end
@@ -5,9 +5,16 @@ module Dcc
5
5
  module Schematron
6
6
  module Rules
7
7
  # Validates that for every `si:realListXMLList` paired with an
8
- # `si:expandedUncXMLList`, the count of values matches the count
9
- # of uncertainty entries.
8
+ # `si:expandedUncXMLList`, each uncertainty list holds either one
9
+ # entry per value or a single entry broadcast across all of them.
10
10
  class UncertaintyConsistency < Base
11
+ UNCERTAINTY_LISTS = {
12
+ uncertainty_xml_list: "uncertaintyXMLList",
13
+ coverage_factor_xml_list: "coverageFactorXMLList",
14
+ coverage_probability_xml_list: "coverageProbabilityXMLList",
15
+ distribution_xml_list: "distributionXMLList",
16
+ }.freeze
17
+
11
18
  def check_on(dcc)
12
19
  issues = []
13
20
  return issues unless dcc.is_a?(::Lutaml::Model::Serializable)
@@ -24,7 +31,10 @@ module Dcc
24
31
 
25
32
  visited << node.object_id
26
33
 
27
- check_node(node, issues) if node.class.name.end_with?("::RealListXmlList")
34
+ if node.class.name.end_with?("::RealListXmlList")
35
+ check_node(node,
36
+ issues)
37
+ end
28
38
  descend(node, issues, visited)
29
39
  end
30
40
 
@@ -33,16 +43,37 @@ module Dcc
33
43
  unc = list_node.expanded_unc_xml_list
34
44
  return unless unc && values
35
45
 
36
- unc_count = Array(unc.uncertainty_xml_list).size
37
- value_count = Array(values).size
38
- return if unc_count == value_count || unc_count.zero?
46
+ value_count = entry_count(values)
47
+ UNCERTAINTY_LISTS.each do |attribute, xml_name|
48
+ count = entry_count(unc.public_send(attribute))
49
+ next if consistent?(count, value_count)
50
+
51
+ issues << count_mismatch(xml_name, count, value_count)
52
+ end
53
+ end
39
54
 
40
- issues << issue(
55
+ def count_mismatch(xml_name, count, value_count)
56
+ issue(
41
57
  severity: :error,
42
- message: "valueXMLList count (#{value_count}) does not match expandedUncertaintyXMLList count (#{unc_count})",
58
+ message: "valueXMLList count (#{value_count}) does not " \
59
+ "match #{xml_name} count (#{count})",
43
60
  )
44
61
  end
45
62
 
63
+ # Every list here is an xs:list, so its entries are whitespace
64
+ # separated whether the attribute holds a string or a decimal list.
65
+ def entry_count(list)
66
+ list.to_s.split.size
67
+ end
68
+
69
+ # A list either carries one entry per value or a single entry that
70
+ # broadcasts across all of them, the way unitXMLList does. Siblings
71
+ # decide independently: PTB ships documents pairing nine
72
+ # uncertainties with one shared coverage factor.
73
+ def consistent?(count, value_count)
74
+ count.zero? || count == 1 || count == value_count
75
+ end
76
+
46
77
  def descend(node, issues, visited)
47
78
  node.class.attributes.each_key do |attr_name|
48
79
  value = node.public_send(attr_name)
@@ -54,5 +85,3 @@ module Dcc
54
85
  end
55
86
  end
56
87
  end
57
-
58
- require "set"
@@ -29,7 +29,8 @@ module Dcc
29
29
  end
30
30
 
31
31
  def check_single_unit(node, issues)
32
- return unless node.class.name.end_with?("::Real", "::Complex", "::Constant")
32
+ return unless node.class.name.end_with?("::Real", "::Complex",
33
+ "::Constant")
33
34
  return unless node.respond_to?(:unit)
34
35
 
35
36
  unit = node.unit
@@ -70,5 +71,3 @@ module Dcc
70
71
  end
71
72
  end
72
73
  end
73
-
74
- require "set"
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -10,20 +9,24 @@ module Dcc
10
9
  class UsedMethodsPlacement < Base
11
10
  def check_on(dcc)
12
11
  issues = []
13
- return issues unless Dcc::TypeGuards.has_attribute?(dcc, :measurement_results)
12
+ return issues unless Dcc::TypeGuards.has_attribute?(dcc,
13
+ :measurement_results)
14
14
 
15
15
  mr_list = safe_attr(dcc.measurement_results, :measurement_result)
16
16
  return issues if mr_list.empty?
17
17
 
18
18
  any_used = mr_list.any? do |mr|
19
- Dcc::TypeGuards.has_attribute?(mr, :used_methods) && !mr.used_methods.nil? ||
19
+ (Dcc::TypeGuards.has_attribute?(mr,
20
+ :used_methods) && !mr.used_methods.nil?) ||
20
21
  mr_has_descendant?(mr, :used_methods)
21
22
  end
22
23
 
23
- issues << issue(
24
- severity: :error,
25
- message: "dcc:usedMethods is missing in every measurementResult and its descendants",
26
- ) unless any_used
24
+ unless any_used
25
+ issues << issue(
26
+ severity: :error,
27
+ message: "dcc:usedMethods is missing in every measurementResult and its descendants",
28
+ )
29
+ end
27
30
 
28
31
  issues
29
32
  end
@@ -31,7 +34,8 @@ module Dcc
31
34
  private
32
35
 
33
36
  def mr_has_descendant?(mr, attr_name)
34
- return false unless Dcc::TypeGuards.has_attribute?(mr, :results) && mr.results
37
+ return false unless Dcc::TypeGuards.has_attribute?(mr,
38
+ :results) && mr.results
35
39
 
36
40
  result = safe_attr(mr.results, :result)
37
41
  result.any? { |r| descendant_has?(r, attr_name) }
@@ -40,7 +44,8 @@ module Dcc
40
44
  def descendant_has?(node, attr_name)
41
45
  return false unless node.is_a?(::Lutaml::Model::Serializable)
42
46
 
43
- if Dcc::TypeGuards.has_attribute?(node, attr_name) && !node.public_send(attr_name).nil?
47
+ if Dcc::TypeGuards.has_attribute?(node,
48
+ attr_name) && !node.public_send(attr_name).nil?
44
49
  return true
45
50
  end
46
51
 
@@ -62,4 +67,4 @@ module Dcc
62
67
  end
63
68
  end
64
69
  end
65
- end
70
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -12,21 +11,27 @@ module Dcc
12
11
  end
13
12
 
14
13
  def check_on(dcc)
15
- return [] unless Dcc::TypeGuards.has_attribute?(dcc, :measurement_results)
14
+ return [] unless Dcc::TypeGuards.has_attribute?(dcc,
15
+ :measurement_results)
16
16
 
17
17
  mr_list = safe_attr(dcc.measurement_results, :measurement_result)
18
18
  return [] if mr_list.empty?
19
19
 
20
20
  present = mr_list.any? do |mr|
21
- Dcc::TypeGuards.has_attribute?(mr, :used_software) && !mr.used_software.nil?
21
+ Dcc::TypeGuards.has_attribute?(mr,
22
+ :used_software) && !mr.used_software.nil?
22
23
  end
23
24
 
24
- present ? [] : [
25
- issue(
26
- severity: :warning,
27
- message: "dcc:usedSoftware is missing on every measurementResult",
28
- ),
29
- ]
25
+ if present
26
+ []
27
+ else
28
+ [
29
+ issue(
30
+ severity: :warning,
31
+ message: "dcc:usedSoftware is missing on every measurementResult",
32
+ ),
33
+ ]
34
+ end
30
35
  end
31
36
 
32
37
  private
@@ -40,4 +45,4 @@ module Dcc
40
45
  end
41
46
  end
42
47
  end
43
- end
48
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module Dcc
5
4
  module Validate
6
5
  module Schematron
@@ -32,11 +31,13 @@ module Dcc
32
31
 
33
32
  node.class.attributes.each_key do |a|
34
33
  v = node.public_send(a)
35
- Array(v).each { |child| check_string_list_attribute(child, issues, attr, label) }
34
+ Array(v).each do |child|
35
+ check_string_list_attribute(child, issues, attr, label)
36
+ end
36
37
  end
37
38
  end
38
39
  end
39
40
  end
40
41
  end
41
42
  end
42
- end
43
+ end
@@ -10,20 +10,34 @@ module Dcc
10
10
  module Schematron
11
11
  module Rules
12
12
  autoload :Base, "dcc/validate/schematron/rules/base"
13
- autoload :UsedMethodsPlacement, "dcc/validate/schematron/rules/used_methods_placement"
14
- autoload :UsedSoftwarePlacement, "dcc/validate/schematron/rules/used_software_placement"
15
- autoload :InfluenceConditionsPlacement, "dcc/validate/schematron/rules/influence_conditions_placement"
16
- autoload :SchemaVersionCheck, "dcc/validate/schematron/rules/schema_version_check"
17
- autoload :IdRefIdLinking, "dcc/validate/schematron/rules/id_refid_linking"
18
- autoload :IsoCodeValidation, "dcc/validate/schematron/rules/iso_code_validation"
19
- autoload :DateRangeCheck, "dcc/validate/schematron/rules/date_range_check"
20
- autoload :ReleaseFormatCheck, "dcc/validate/schematron/rules/release_format_check"
21
- autoload :UncertaintyConsistency, "dcc/validate/schematron/rules/uncertainty_consistency"
22
- autoload :UnitFormatCheck, "dcc/validate/schematron/rules/unit_format_check"
23
- autoload :NonSiDeclaration, "dcc/validate/schematron/rules/non_si_declaration"
24
- autoload :LanguageCodeDedup, "dcc/validate/schematron/rules/language_code_dedup"
25
- autoload :XmlListSpacing, "dcc/validate/schematron/rules/xml_list_spacing"
26
- autoload :AdministrativeDataCompleteness, "dcc/validate/schematron/rules/administrative_data_completeness"
13
+ autoload :UsedMethodsPlacement,
14
+ "dcc/validate/schematron/rules/used_methods_placement"
15
+ autoload :UsedSoftwarePlacement,
16
+ "dcc/validate/schematron/rules/used_software_placement"
17
+ autoload :InfluenceConditionsPlacement,
18
+ "dcc/validate/schematron/rules/influence_conditions_placement"
19
+ autoload :SchemaVersionCheck,
20
+ "dcc/validate/schematron/rules/schema_version_check"
21
+ autoload :IdRefIdLinking,
22
+ "dcc/validate/schematron/rules/id_refid_linking"
23
+ autoload :IsoCodeValidation,
24
+ "dcc/validate/schematron/rules/iso_code_validation"
25
+ autoload :DateRangeCheck,
26
+ "dcc/validate/schematron/rules/date_range_check"
27
+ autoload :ReleaseFormatCheck,
28
+ "dcc/validate/schematron/rules/release_format_check"
29
+ autoload :UncertaintyConsistency,
30
+ "dcc/validate/schematron/rules/uncertainty_consistency"
31
+ autoload :UnitFormatCheck,
32
+ "dcc/validate/schematron/rules/unit_format_check"
33
+ autoload :NonSiDeclaration,
34
+ "dcc/validate/schematron/rules/non_si_declaration"
35
+ autoload :LanguageCodeDedup,
36
+ "dcc/validate/schematron/rules/language_code_dedup"
37
+ autoload :XmlListSpacing,
38
+ "dcc/validate/schematron/rules/xml_list_spacing"
39
+ autoload :AdministrativeDataCompleteness,
40
+ "dcc/validate/schematron/rules/administrative_data_completeness"
27
41
  end
28
42
  end
29
43
  end
@@ -19,4 +19,4 @@ module Dcc
19
19
  end
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -27,7 +27,9 @@ module Dcc
27
27
  resolved = ::Dcc::Schema::Version.resolve_dcc(version, xml: xml)
28
28
  schema = schema_for(resolved)
29
29
  doc = parse_xml(xml)
30
- errors = schema.validate(doc).map { |e| issue_from_nokogiri(e, resolved) }
30
+ errors = schema.validate(doc).map do |e|
31
+ issue_from_nokogiri(e, resolved)
32
+ end
31
33
 
32
34
  ::Dcc::Validate::Result.new(
33
35
  issues: errors,
@@ -60,10 +62,14 @@ module Dcc
60
62
  content = ::File.read(xsd_path)
61
63
  content.gsub(/schemaLocation\s*=\s*"([^"]+)"/) do |_match|
62
64
  relative = ::Regexp.last_match(1)
63
- next %{schemaLocation="#{relative}"} if relative.start_with?("http", "file://")
65
+ next %{schemaLocation="#{relative}"} if relative.start_with?(
66
+ "http", "file://"
67
+ )
64
68
 
65
69
  absolute = ::File.expand_path(relative, base_dir)
66
- %{schemaLocation="file://#{absolute}"}
70
+ uri_path = absolute.gsub(::File::ALT_SEPARATOR || "\\", "/")
71
+ uri_path = "/#{uri_path}" unless uri_path.start_with?("/")
72
+ %{schemaLocation="file://#{uri_path}"}
67
73
  end
68
74
  end
69
75
 
data/lib/dcc/validate.rb CHANGED
@@ -12,4 +12,4 @@ module Dcc
12
12
  autoload :Schematron, "dcc/validate/schematron"
13
13
  autoload :BusinessRules, "dcc/validate/business_rules"
14
14
  end
15
- end
15
+ end
data/lib/dcc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dcc
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
@@ -42,7 +42,7 @@ module Dcc
42
42
  end
43
43
 
44
44
  def root_element_symbol
45
- self.const_get(:ROOT_ELEMENT_TAG).to_sym
45
+ const_get(:ROOT_ELEMENT_TAG).to_sym
46
46
  end
47
47
  end
48
48
  end