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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +19 -0
- data/.github/workflows/release.yml +28 -0
- data/.gitignore +4 -0
- data/.rubocop_todo.yml +560 -10
- data/CHANGELOG.adoc +34 -1
- data/CONTRIBUTING.adoc +8 -1
- data/Gemfile +5 -7
- data/README.adoc +162 -7
- data/dcc.gemspec +9 -2
- data/docs/schema-versions.adoc +20 -7
- data/examples/build_minimal_dcc.rb +0 -0
- data/examples/convert_all_formats.rb +2 -1
- data/examples/parse_and_inspect.rb +0 -0
- data/examples/quantity_math_demo.rb +7 -7
- data/examples/validate_full.rb +1 -1
- data/lib/dcc/base/calibration_laboratory.rb +2 -1
- data/lib/dcc/base/condition.rb +5 -2
- data/lib/dcc/base/core_data.rb +8 -3
- data/lib/dcc/base/formula.rb +3 -3
- data/lib/dcc/base/identification.rb +6 -3
- data/lib/dcc/base/mathml.rb +33 -0
- data/lib/dcc/base/quantity.rb +2 -1
- data/lib/dcc/base/resp_person.rb +4 -2
- data/lib/dcc/base/text.rb +1 -1
- data/lib/dcc/base.rb +2 -1
- data/lib/dcc/builder/dsl.rb +1 -1
- data/lib/dcc/builder/session.rb +16 -14
- data/lib/dcc/builder.rb +3 -3
- data/lib/dcc/cli/cli.rb +152 -26
- data/lib/dcc/cli/formatters.rb +35 -7
- data/lib/dcc/cli.rb +1 -1
- data/lib/dcc/context_configuration.rb +2 -1
- data/lib/dcc/context_options.rb +4 -2
- data/lib/dcc/convert/csv.rb +27 -9
- data/lib/dcc/convert/html.rb +26 -110
- data/lib/dcc/convert/json.rb +10 -7
- data/lib/dcc/convert/liquid_filters.rb +58 -0
- data/lib/dcc/convert/result.rb +1 -1
- data/lib/dcc/convert/templates/report.liquid +250 -0
- data/lib/dcc/convert/yaml.rb +1 -1
- data/lib/dcc/convert.rb +1 -0
- data/lib/dcc/diff/change.rb +1 -1
- data/lib/dcc/diff/result.rb +8 -4
- data/lib/dcc/diff.rb +43 -11
- data/lib/dcc/error.rb +7 -0
- data/lib/dcc/extract/file.rb +3 -4
- data/lib/dcc/extract/formula/ast.rb +137 -0
- data/lib/dcc/extract/formula/evaluator.rb +357 -0
- data/lib/dcc/extract/formula/parser.rb +305 -0
- data/lib/dcc/extract/formula/quantity.rb +89 -0
- data/lib/dcc/extract/formula.rb +110 -0
- data/lib/dcc/extract/ring.rb +1 -1
- data/lib/dcc/extract.rb +1 -1
- data/lib/dcc/i18n/text_lookup.rb +8 -4
- data/lib/dcc/i18n.rb +1 -1
- data/lib/dcc/inspect/report.rb +51 -14
- data/lib/dcc/inspect.rb +1 -1
- data/lib/dcc/migrate/route.rb +44 -0
- data/lib/dcc/migrate/v2_to_v3.rb +445 -0
- data/lib/dcc/migrate.rb +130 -26
- data/lib/dcc/plugin/base.rb +64 -0
- data/lib/dcc/plugin/registry.rb +7 -2
- data/lib/dcc/plugin.rb +6 -2
- data/lib/dcc/quantity_format/formatter.rb +16 -10
- data/lib/dcc/quantity_format.rb +1 -1
- data/lib/dcc/quantity_math/complex.rb +252 -0
- data/lib/dcc/quantity_math/matrix.rb +217 -0
- data/lib/dcc/quantity_math/quantity.rb +1 -1
- data/lib/dcc/quantity_math/real.rb +6 -6
- data/lib/dcc/quantity_math.rb +31 -3
- data/lib/dcc/schema/version.rb +2 -2
- data/lib/dcc/server/app.html +282 -0
- data/lib/dcc/server/app.rb +171 -87
- data/lib/dcc/server/demo_cert.xml +244 -0
- data/lib/dcc/server/storage/entry.rb +1 -1
- data/lib/dcc/server/storage/memory.rb +3 -2
- data/lib/dcc/server/storage.rb +1 -1
- data/lib/dcc/server.rb +1 -1
- data/lib/dcc/si/base/complex.rb +1 -1
- data/lib/dcc/si/base/complex_list_xml_list.rb +1 -1
- data/lib/dcc/si/base/constant.rb +1 -1
- data/lib/dcc/si/base/coverage_interval.rb +36 -0
- data/lib/dcc/si/base/coverage_interval_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_mu.rb +1 -1
- data/lib/dcc/si/base/expanded_unc.rb +34 -0
- data/lib/dcc/si/base/expanded_unc_xml_list.rb +3 -2
- data/lib/dcc/si/base/hybrid.rb +3 -2
- data/lib/dcc/si/base/measurement_uncertainty_univariate.rb +1 -1
- data/lib/dcc/si/base/real.rb +13 -3
- data/lib/dcc/si/base/real_list_xml_list.rb +5 -3
- data/lib/dcc/si/base/si_list.rb +3 -2
- data/lib/dcc/si/base/standard_mu.rb +1 -1
- data/lib/dcc/si/base.rb +5 -2
- data/lib/dcc/si/v1/coverage_interval.rb +8 -0
- data/lib/dcc/si/v1/expanded_unc.rb +1 -16
- data/lib/dcc/si/v1/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v1.rb +5 -2
- data/lib/dcc/si/v2/coverage_interval.rb +8 -0
- data/lib/dcc/si/v2/coverage_interval_mu_xml_list.rb +4 -2
- data/lib/dcc/si/v2/expanded_mu_xml_list.rb +2 -1
- data/lib/dcc/si/v2/expanded_unc.rb +8 -0
- data/lib/dcc/si/v2/measurement_uncertainty_univariate.rb +2 -1
- data/lib/dcc/si/v2.rb +8 -3
- data/lib/dcc/signature/result.rb +2 -2
- data/lib/dcc/signature/signer.rb +31 -18
- data/lib/dcc/signature/verifier.rb +23 -21
- data/lib/dcc/signature.rb +1 -1
- data/lib/dcc/streaming/reader.rb +246 -0
- data/lib/dcc/streaming.rb +79 -0
- data/lib/dcc/transform/result.rb +1 -1
- data/lib/dcc/transform/xslt.rb +22 -12
- data/lib/dcc/transform.rb +5 -4
- data/lib/dcc/type/base64_binary.rb +5 -3
- data/lib/dcc/type/decimal_xml_list.rb +99 -13
- data/lib/dcc/type/iso_country_code.rb +3 -2
- data/lib/dcc/type/iso_language_code.rb +3 -2
- data/lib/dcc/type/schema_version.rb +3 -2
- data/lib/dcc/type/si_unit.rb +3 -2
- data/lib/dcc/type_guards.rb +3 -3
- data/lib/dcc/v2/calibration_laboratory.rb +2 -1
- data/lib/dcc/v2/condition.rb +22 -1
- data/lib/dcc/v2/configuration.rb +1 -1
- data/lib/dcc/v2/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v2/identification.rb +14 -1
- data/lib/dcc/v2/mathml.rb +8 -0
- data/lib/dcc/v2/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v2/quantity.rb +4 -2
- data/lib/dcc/v2.rb +4 -2
- data/lib/dcc/v3/calibration_laboratory.rb +2 -1
- data/lib/dcc/v3/configuration.rb +1 -1
- data/lib/dcc/v3/digital_calibration_certificate.rb +2 -1
- data/lib/dcc/v3/mathml.rb +8 -0
- data/lib/dcc/v3/measurement_meta_data_list.rb +2 -1
- data/lib/dcc/v3/quantity.rb +4 -2
- data/lib/dcc/v3.rb +12 -2
- data/lib/dcc/validate/business_rules.rb +23 -9
- data/lib/dcc/validate/issue.rb +2 -1
- data/lib/dcc/validate/result.rb +6 -4
- data/lib/dcc/validate/schematron/profile.rb +73 -18
- data/lib/dcc/validate/schematron/rule.rb +13 -3
- data/lib/dcc/validate/schematron/rules/administrative_data_completeness.rb +11 -4
- data/lib/dcc/validate/schematron/rules/base.rb +1 -2
- data/lib/dcc/validate/schematron/rules/date_range_check.rb +11 -5
- data/lib/dcc/validate/schematron/rules/id_refid_linking.rb +0 -3
- data/lib/dcc/validate/schematron/rules/influence_conditions_placement.rb +22 -12
- data/lib/dcc/validate/schematron/rules/iso_code_validation.rb +31 -14
- data/lib/dcc/validate/schematron/rules/language_code_dedup.rb +12 -5
- data/lib/dcc/validate/schematron/rules/non_si_declaration.rb +7 -4
- data/lib/dcc/validate/schematron/rules/release_format_check.rb +7 -4
- data/lib/dcc/validate/schematron/rules/schema_version_check.rb +13 -9
- data/lib/dcc/validate/schematron/rules/uncertainty_consistency.rb +39 -10
- data/lib/dcc/validate/schematron/rules/unit_format_check.rb +2 -3
- data/lib/dcc/validate/schematron/rules/used_methods_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/used_software_placement.rb +15 -10
- data/lib/dcc/validate/schematron/rules/xml_list_spacing.rb +4 -3
- data/lib/dcc/validate/schematron/rules.rb +28 -14
- data/lib/dcc/validate/schematron.rb +1 -1
- data/lib/dcc/validate/xsd.rb +9 -3
- data/lib/dcc/validate.rb +1 -1
- data/lib/dcc/version.rb +1 -1
- data/lib/dcc/versioned_parser.rb +1 -1
- data/lib/dcc.rb +68 -10
- data/sample_dcc.xml +140 -0
- data/web/index.html +12 -0
- data/web/package-lock.json +1599 -0
- data/web/package.json +22 -0
- data/web/src/App.vue +349 -0
- data/web/src/lib/builder.ts +171 -0
- data/web/src/lib/dcc.ts +338 -0
- data/web/src/lib/units.json +5581 -0
- data/web/src/main.ts +5 -0
- data/web/src/style.css +27 -0
- data/web/tsconfig.json +15 -0
- data/web/vite.config.ts +14 -0
- 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,
|
|
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,
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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`,
|
|
9
|
-
# of
|
|
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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
55
|
+
def count_mismatch(xml_name, count, value_count)
|
|
56
|
+
issue(
|
|
41
57
|
severity: :error,
|
|
42
|
-
message: "valueXMLList count (#{value_count}) does not
|
|
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",
|
|
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,
|
|
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,
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
21
|
+
Dcc::TypeGuards.has_attribute?(mr,
|
|
22
|
+
:used_software) && !mr.used_software.nil?
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
present
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
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,
|
|
14
|
-
|
|
15
|
-
autoload :
|
|
16
|
-
|
|
17
|
-
autoload :
|
|
18
|
-
|
|
19
|
-
autoload :
|
|
20
|
-
|
|
21
|
-
autoload :
|
|
22
|
-
|
|
23
|
-
autoload :
|
|
24
|
-
|
|
25
|
-
autoload :
|
|
26
|
-
|
|
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
|
data/lib/dcc/validate/xsd.rb
CHANGED
|
@@ -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
|
|
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?(
|
|
65
|
+
next %{schemaLocation="#{relative}"} if relative.start_with?(
|
|
66
|
+
"http", "file://"
|
|
67
|
+
)
|
|
64
68
|
|
|
65
69
|
absolute = ::File.expand_path(relative, base_dir)
|
|
66
|
-
|
|
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
data/lib/dcc/version.rb
CHANGED