modspec 0.1.3 → 0.2.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.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.rubocop.yml +16 -7
- data/.rubocop_todo.yml +67 -80
- data/CLAUDE.md +61 -0
- data/Gemfile +5 -3
- data/lib/modspec/conformance_class.rb +4 -4
- data/lib/modspec/conformance_test.rb +21 -6
- data/lib/modspec/normative_statement.rb +10 -3
- data/lib/modspec/normative_statements_class.rb +7 -5
- data/lib/modspec/suite.rb +86 -34
- data/lib/modspec/version.rb +1 -1
- data/lib/modspec.rb +1 -12
- data/modspec.gemspec +3 -2
- data/spec/conformance_class.liquid +2 -2
- data/spec/fixtures/advanced-json-rc.yaml +5 -7
- data/spec/fixtures/advanced-rc.yaml +12 -14
- data/spec/fixtures/basic-quaternion-json-rc.yaml +5 -7
- data/spec/fixtures/basic-quaternion-json-strict-rc.yaml +4 -5
- data/spec/fixtures/basic-quaternion-rc.yaml +7 -8
- data/spec/fixtures/basic-ypr-json-rc.yaml +5 -8
- data/spec/fixtures/basic-ypr-rc.yaml +7 -7
- data/spec/fixtures/chain-json-rc.yaml +5 -7
- data/spec/fixtures/chain-rc.yaml +11 -13
- data/spec/fixtures/frame-spec-rc.yaml +10 -10
- data/spec/fixtures/global-rc.yaml +7 -4
- data/spec/fixtures/graph-json-rc.yaml +5 -7
- data/spec/fixtures/graph-rc.yaml +11 -13
- data/spec/fixtures/series-irregular-json-rc.yaml +5 -7
- data/spec/fixtures/series-irregular-rc.yaml +13 -15
- data/spec/fixtures/series-regular-json-rc.yaml +5 -7
- data/spec/fixtures/series-regular-rc.yaml +15 -17
- data/spec/fixtures/stream-json-rc.yaml +9 -11
- data/spec/fixtures/stream-rc.yaml +10 -12
- data/spec/fixtures/tangent-point-rc.yaml +10 -11
- data/spec/fixtures/time-rc.yaml +6 -8
- data/spec/modspec/conformance_class_spec.rb +29 -27
- data/spec/modspec/conformance_test_spec.rb +6 -5
- data/spec/modspec/normative_statement_spec.rb +16 -12
- data/spec/modspec/normative_statements_class_spec.rb +4 -4
- data/spec/modspec/suite_spec.rb +26 -22
- data/spec/modspec_spec.rb +7 -7
- data/spec/spec_helper.rb +1 -0
- metadata +7 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 925062f2457c7aa978de3d2eabc679f4a33b9177e8ba2f3a80494c46377ff0b8
|
|
4
|
+
data.tar.gz: '083c357ffd578b297ae28753e48dccacd08a10d202f336299b037d1d6b08fe9a'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce9246f0f6b4ce811bf498d52a59c25949ad0016b024ab215c332ce7e1e34fa311c2a78267a3a1b07cb1a2f0f468559c1aeaedb638c4552e9500016ad8a3235b
|
|
7
|
+
data.tar.gz: 7132a3d0194c87222d077752784d1d1d7197481d1db1ae356c9f959d8cccd8163f3ef268a2e4e6b75812095768e133ab6da81c629fd3d33b0122f7f2789079fe
|
data/.github/workflows/rake.yml
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
|
+
# See https://github.com/metanorma/cimas
|
|
3
|
+
inherit_from:
|
|
4
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
|
|
5
|
+
- .rubocop_todo.yml
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
inherit_mode:
|
|
8
|
+
merge:
|
|
9
|
+
- Exclude
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
# local repo-specific modifications
|
|
12
|
+
# ...
|
|
13
|
+
plugins:
|
|
14
|
+
- rubocop-rspec
|
|
15
|
+
- rubocop-performance
|
|
16
|
+
- rubocop-rake
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
AllCops:
|
|
19
|
+
TargetRubyVersion: 3.0
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,118 +1,105 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2026-05-05 14:09:35 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count: 4
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
|
|
12
|
-
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
|
13
|
-
Bundler/OrderedGems:
|
|
14
|
-
Exclude:
|
|
15
|
-
- 'Gemfile'
|
|
16
|
-
|
|
17
9
|
# Offense count: 1
|
|
18
|
-
# Configuration parameters: Severity, Include.
|
|
19
|
-
# Include: **/*.gemspec
|
|
20
10
|
Gemspec/RequiredRubyVersion:
|
|
21
11
|
Exclude:
|
|
22
12
|
- 'modspec.gemspec'
|
|
23
13
|
|
|
24
|
-
# Offense count:
|
|
14
|
+
# Offense count: 33
|
|
25
15
|
# This cop supports safe autocorrection (--autocorrect).
|
|
26
|
-
# Configuration parameters:
|
|
27
|
-
#
|
|
28
|
-
Layout/
|
|
16
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
17
|
+
# URISchemes: http, https
|
|
18
|
+
Layout/LineLength:
|
|
29
19
|
Exclude:
|
|
30
|
-
- 'modspec.
|
|
20
|
+
- 'lib/modspec/conformance_class.rb'
|
|
21
|
+
- 'lib/modspec/conformance_test.rb'
|
|
22
|
+
- 'lib/modspec/normative_statement.rb'
|
|
23
|
+
- 'lib/modspec/normative_statements_class.rb'
|
|
24
|
+
- 'lib/modspec/suite.rb'
|
|
25
|
+
- 'spec/modspec/conformance_class_spec.rb'
|
|
26
|
+
- 'spec/modspec/conformance_test_spec.rb'
|
|
27
|
+
- 'spec/modspec/normative_statement_spec.rb'
|
|
28
|
+
- 'spec/modspec/normative_statements_class_spec.rb'
|
|
31
29
|
- 'spec/modspec/suite_spec.rb'
|
|
32
30
|
|
|
33
31
|
# Offense count: 4
|
|
34
|
-
# Configuration parameters:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
40
|
-
# AllowedMethods: refine
|
|
41
|
-
Metrics/BlockLength:
|
|
42
|
-
Max: 138
|
|
32
|
+
# Configuration parameters: AllowComments, AllowEmptyLambdas.
|
|
33
|
+
Lint/EmptyBlock:
|
|
34
|
+
Exclude:
|
|
35
|
+
- 'spec/modspec/conformance_class_spec.rb'
|
|
36
|
+
- 'spec/modspec/suite_spec.rb'
|
|
43
37
|
|
|
44
38
|
# Offense count: 1
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
40
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
|
41
|
+
# NotImplementedExceptions: NotImplementedError
|
|
42
|
+
Lint/UnusedMethodArgument:
|
|
43
|
+
Exclude:
|
|
44
|
+
- 'lib/modspec/normative_statement.rb'
|
|
48
45
|
|
|
49
|
-
# Offense count:
|
|
50
|
-
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
51
|
-
Metrics/
|
|
52
|
-
|
|
46
|
+
# Offense count: 7
|
|
47
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
48
|
+
Metrics/AbcSize:
|
|
49
|
+
Exclude:
|
|
50
|
+
- 'lib/modspec/suite.rb'
|
|
53
51
|
|
|
54
52
|
# Offense count: 5
|
|
53
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
54
|
+
Metrics/CyclomaticComplexity:
|
|
55
|
+
Exclude:
|
|
56
|
+
- 'lib/modspec/suite.rb'
|
|
57
|
+
|
|
58
|
+
# Offense count: 9
|
|
55
59
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
56
60
|
Metrics/MethodLength:
|
|
57
|
-
Max:
|
|
61
|
+
Max: 21
|
|
58
62
|
|
|
59
|
-
# Offense count:
|
|
60
|
-
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
63
|
+
# Offense count: 3
|
|
64
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
61
65
|
Metrics/PerceivedComplexity:
|
|
62
|
-
Max: 12
|
|
63
|
-
|
|
64
|
-
# Offense count: 1
|
|
65
|
-
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
|
|
66
|
-
# NamePrefix: is_, has_, have_
|
|
67
|
-
# ForbiddenPrefixes: is_, has_, have_
|
|
68
|
-
# AllowedMethods: is_a?
|
|
69
|
-
# MethodDefinitionMacros: define_method, define_singleton_method
|
|
70
|
-
Naming/PredicateName:
|
|
71
66
|
Exclude:
|
|
72
|
-
- '
|
|
73
|
-
- 'lib/modspec/normative_statement.rb'
|
|
67
|
+
- 'lib/modspec/suite.rb'
|
|
74
68
|
|
|
75
|
-
# Offense count:
|
|
76
|
-
# Configuration parameters:
|
|
77
|
-
|
|
69
|
+
# Offense count: 1
|
|
70
|
+
# Configuration parameters: MinSize.
|
|
71
|
+
Performance/CollectionLiteralInLoop:
|
|
78
72
|
Exclude:
|
|
79
|
-
- 'spec/**/*'
|
|
80
|
-
- 'test/**/*'
|
|
81
|
-
- 'lib/modspec/conformance_class.rb'
|
|
82
|
-
- 'lib/modspec/conformance_test.rb'
|
|
83
|
-
- 'lib/modspec/normative_statement.rb'
|
|
84
|
-
- 'lib/modspec/normative_statements_class.rb'
|
|
85
73
|
- 'lib/modspec/suite.rb'
|
|
86
74
|
|
|
87
|
-
# Offense count:
|
|
88
|
-
#
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- 'lib/modspec/conformance_class.rb'
|
|
92
|
-
- 'lib/modspec/normative_statements_class.rb'
|
|
75
|
+
# Offense count: 5
|
|
76
|
+
# Configuration parameters: CountAsOne.
|
|
77
|
+
RSpec/ExampleLength:
|
|
78
|
+
Max: 15
|
|
93
79
|
|
|
94
|
-
# Offense count:
|
|
80
|
+
# Offense count: 1
|
|
95
81
|
# This cop supports safe autocorrection (--autocorrect).
|
|
96
|
-
|
|
97
|
-
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
|
98
|
-
Style/TrailingCommaInArguments:
|
|
82
|
+
RSpec/ExpectActual:
|
|
99
83
|
Exclude:
|
|
100
|
-
- 'spec/modspec/conformance_class_spec.rb'
|
|
101
|
-
- 'spec/modspec/conformance_test_spec.rb'
|
|
102
84
|
- 'spec/modspec/normative_statement_spec.rb'
|
|
103
|
-
- 'spec/modspec/normative_statements_class_spec.rb'
|
|
104
85
|
|
|
105
|
-
# Offense count:
|
|
106
|
-
#
|
|
107
|
-
|
|
108
|
-
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
|
109
|
-
Style/TrailingCommaInArrayLiteral:
|
|
86
|
+
# Offense count: 4
|
|
87
|
+
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
|
88
|
+
RSpec/IndexedLet:
|
|
110
89
|
Exclude:
|
|
111
|
-
- 'spec/modspec/
|
|
90
|
+
- 'spec/modspec/normative_statements_class_spec.rb'
|
|
91
|
+
- 'spec/modspec/suite_spec.rb'
|
|
112
92
|
|
|
113
|
-
# Offense count:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
93
|
+
# Offense count: 7
|
|
94
|
+
RSpec/MultipleExpectations:
|
|
95
|
+
Max: 9
|
|
96
|
+
|
|
97
|
+
# Offense count: 7
|
|
98
|
+
# Configuration parameters: AllowSubject.
|
|
99
|
+
RSpec/MultipleMemoizedHelpers:
|
|
100
|
+
Max: 12
|
|
101
|
+
|
|
102
|
+
# Offense count: 2
|
|
103
|
+
RSpec/RepeatedExample:
|
|
104
|
+
Exclude:
|
|
105
|
+
- 'spec/modspec_spec.rb'
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`modspec` is a Ruby gem for working with OGC ModSpec — a specification format (OGC 08-131r3) for defining requirements and conformance tests for standards. All models use `lutaml-model` (`Lutaml::Model::Serializable`) for serialization to/from YAML, JSON, and XML.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- **Run all tests:** `bundle exec rake` or `bundle exec rspec`
|
|
12
|
+
- **Run a single test file:** `bundle exec rspec spec/modspec/suite_spec.rb`
|
|
13
|
+
- **Run a single example:** `bundle exec rspec spec/modspec/suite_spec.rb:42`
|
|
14
|
+
- **Lint:** RuboCop is configured but not in the default rake task. Run with `bundle exec rubocop` if needed.
|
|
15
|
+
- **Console:** `bin/console` (loads IRB with the gem)
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
All model classes inherit from `Lutaml::Model::Serializable` and define attributes via the `attribute` DSL with serialization mappings in `xml do` blocks. YAML/JSON serialization comes from lutaml-model automatically.
|
|
20
|
+
|
|
21
|
+
### Identifier convention (critical)
|
|
22
|
+
|
|
23
|
+
Identifiers are URIs with a specific structure:
|
|
24
|
+
- Class-level: `/<type>/<class>` (e.g., `/req/example`, `/conf/example`)
|
|
25
|
+
- Instance-level: `/<type>/<class>/<name>` (e.g., `/req/example/foo`)
|
|
26
|
+
- Type prefix: `req` = normative statements, `conf` = conformance tests
|
|
27
|
+
|
|
28
|
+
Validation enforces that children share their parent's identifier prefix.
|
|
29
|
+
|
|
30
|
+
### Model hierarchy
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Suite
|
|
34
|
+
├── NormativeStatementsClass (collection) → groups normative statements
|
|
35
|
+
│ └── NormativeStatement (collection)
|
|
36
|
+
│ └── NormativeStatementPart (collection) → sub-parts of a statement
|
|
37
|
+
├── ConformanceClass (collection) → groups conformance tests
|
|
38
|
+
│ └── ConformanceTest (collection)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- `NormativeStatement` has obligation (`requirement`/`recommendation`/`permission`), dependencies, inherit, indirect_dependency, implements, parts
|
|
42
|
+
- `ConformanceTest` has targets (referencing normative statement identifiers), abstract flag, method, purpose
|
|
43
|
+
- `ConformanceTest` uses runtime-only `corresponding_requirements` and `parent_class` attrs set by `Suite#setup_relationships`
|
|
44
|
+
|
|
45
|
+
### Validation
|
|
46
|
+
|
|
47
|
+
Each model class has a `validate` method that returns an array of error strings. `Suite#validate` orchestrates full validation: cycles (dependency graph via DFS), label uniqueness, dependency resolution, and delegating to child class validators.
|
|
48
|
+
|
|
49
|
+
### Key Suite operations
|
|
50
|
+
|
|
51
|
+
- `combine(other_suite)` — merges two suites, deduplicating by identifier
|
|
52
|
+
- `from_yaml_files(*files)` — loads and combines multiple YAML files
|
|
53
|
+
- `setup_relationships` — cross-links conformance tests to their target normative statements
|
|
54
|
+
|
|
55
|
+
### Custom types
|
|
56
|
+
|
|
57
|
+
`Modspec::Identifier` extends `Lutaml::Model::Type::String` — used as the type for all identifier attributes and reference fields (dependencies, targets, inherit, etc.).
|
|
58
|
+
|
|
59
|
+
## Key dependency
|
|
60
|
+
|
|
61
|
+
`lutaml-model ~> 0.7.7` — provides the `Serializable` base class, attribute DSL, and serialization adapters. Breaking changes in lutaml-model may affect this gem.
|
data/Gemfile
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
# Specify your gem's dependencies in modspec.gemspec
|
|
6
5
|
gemspec
|
|
7
6
|
|
|
8
|
-
gem "
|
|
9
|
-
gem "pry"
|
|
7
|
+
gem "canon"
|
|
10
8
|
gem "rake"
|
|
11
9
|
gem "rspec"
|
|
10
|
+
gem "rubocop"
|
|
11
|
+
gem "rubocop-performance"
|
|
12
|
+
gem "rubocop-rake"
|
|
13
|
+
gem "rubocop-rspec"
|
|
@@ -18,7 +18,7 @@ module Modspec
|
|
|
18
18
|
attribute :reference, :string
|
|
19
19
|
|
|
20
20
|
xml do
|
|
21
|
-
|
|
21
|
+
element "conformance-class"
|
|
22
22
|
map_attribute "identifier", to: :identifier
|
|
23
23
|
map_element "name", to: :name
|
|
24
24
|
map_element "dependencies", to: :dependencies
|
|
@@ -32,7 +32,7 @@ module Modspec
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def validate
|
|
35
|
-
errors = super
|
|
35
|
+
errors = super
|
|
36
36
|
errors.concat(validate_identifier_prefix)
|
|
37
37
|
errors.concat(validate_class_children_mapping)
|
|
38
38
|
errors.concat(tests.flat_map(&:validate))
|
|
@@ -42,7 +42,7 @@ module Modspec
|
|
|
42
42
|
private
|
|
43
43
|
|
|
44
44
|
def validate_class_children_mapping
|
|
45
|
-
if tests.empty?
|
|
45
|
+
if tests.nil? || tests.empty?
|
|
46
46
|
["Conformance class #{identifier} has no child conformance tests"]
|
|
47
47
|
else
|
|
48
48
|
[]
|
|
@@ -52,7 +52,7 @@ module Modspec
|
|
|
52
52
|
def validate_identifier_prefix
|
|
53
53
|
errors = []
|
|
54
54
|
expected_prefix = "#{identifier}/"
|
|
55
|
-
tests
|
|
55
|
+
tests&.each do |test|
|
|
56
56
|
errors << "Conformance test #{test.identifier} does not share the expected prefix #{expected_prefix}" unless test.identifier.to_s.start_with?(expected_prefix)
|
|
57
57
|
end
|
|
58
58
|
errors
|
|
@@ -13,13 +13,13 @@ module Modspec
|
|
|
13
13
|
attribute :description, :string
|
|
14
14
|
attribute :guidance, :string, collection: true
|
|
15
15
|
attribute :purpose, :string
|
|
16
|
-
attribute :
|
|
16
|
+
attribute :test_method, :string
|
|
17
17
|
attribute :type, :string
|
|
18
18
|
attribute :reference, :string
|
|
19
19
|
attribute :abstract, :boolean
|
|
20
20
|
|
|
21
21
|
xml do
|
|
22
|
-
|
|
22
|
+
element "conformance-test"
|
|
23
23
|
map_attribute "identifier", to: :identifier
|
|
24
24
|
map_attribute "abstract", to: :abstract
|
|
25
25
|
map_element "name", to: :name
|
|
@@ -29,15 +29,30 @@ module Modspec
|
|
|
29
29
|
map_element "description", to: :description
|
|
30
30
|
map_element "guidance", to: :guidance
|
|
31
31
|
map_element "purpose", to: :purpose
|
|
32
|
-
map_element "method", to: :
|
|
32
|
+
map_element "method", to: :test_method
|
|
33
33
|
map_element "type", to: :type
|
|
34
34
|
map_element "reference", to: :reference
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
key_value do
|
|
38
|
+
map "identifier", to: :identifier
|
|
39
|
+
map "name", to: :name
|
|
40
|
+
map "dependencies", to: :dependencies
|
|
41
|
+
map "targets", to: :targets
|
|
42
|
+
map "belongs_to", to: :belongs_to
|
|
43
|
+
map "description", to: :description
|
|
44
|
+
map "guidance", to: :guidance
|
|
45
|
+
map "purpose", to: :purpose
|
|
46
|
+
map "method", to: :test_method
|
|
47
|
+
map "type", to: :type
|
|
48
|
+
map "reference", to: :reference
|
|
49
|
+
map "abstract", to: :abstract
|
|
50
|
+
end
|
|
51
|
+
|
|
37
52
|
attr_accessor :corresponding_requirements, :parent_class
|
|
38
53
|
|
|
39
54
|
def validate
|
|
40
|
-
errors = super
|
|
55
|
+
errors = super
|
|
41
56
|
errors.concat(validate_requirement_mapping)
|
|
42
57
|
errors.concat(validate_class_mapping)
|
|
43
58
|
errors
|
|
@@ -46,7 +61,7 @@ module Modspec
|
|
|
46
61
|
private
|
|
47
62
|
|
|
48
63
|
def validate_requirement_mapping
|
|
49
|
-
if corresponding_requirements.empty?
|
|
64
|
+
if corresponding_requirements.nil? || corresponding_requirements.empty?
|
|
50
65
|
["Conformance test #{identifier} has no corresponding requirements"]
|
|
51
66
|
else
|
|
52
67
|
[]
|
|
@@ -54,7 +69,7 @@ module Modspec
|
|
|
54
69
|
end
|
|
55
70
|
|
|
56
71
|
def validate_class_mapping
|
|
57
|
-
if parent_class.nil? || !parent_class.tests.include?(self)
|
|
72
|
+
if parent_class.nil? || parent_class.tests.nil? || !parent_class.tests.include?(self)
|
|
58
73
|
["Conformance test #{identifier} does not belong to its parent class"]
|
|
59
74
|
else
|
|
60
75
|
[]
|
|
@@ -29,7 +29,7 @@ module Modspec
|
|
|
29
29
|
default: -> { "requirement" }
|
|
30
30
|
|
|
31
31
|
xml do
|
|
32
|
-
|
|
32
|
+
element "normative-statement"
|
|
33
33
|
map_attribute "identifier", to: :identifier
|
|
34
34
|
map_element "name", to: :name
|
|
35
35
|
map_element "subject", to: :subject
|
|
@@ -46,7 +46,7 @@ module Modspec
|
|
|
46
46
|
map_element "parts", to: :parts
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def validate(suite = nil)
|
|
49
|
+
def validate(suite = nil, register: Lutaml::Model::Config.default_register)
|
|
50
50
|
errors = super()
|
|
51
51
|
errors.concat(validate_dependencies(suite)) if suite
|
|
52
52
|
errors.concat(validate_nested_requirement)
|
|
@@ -55,9 +55,16 @@ module Modspec
|
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
+
def all_dependencies
|
|
59
|
+
(
|
|
60
|
+
(dependencies || []) +
|
|
61
|
+
(indirect_dependency || []) +
|
|
62
|
+
(implements || [])
|
|
63
|
+
).flatten.compact
|
|
64
|
+
end
|
|
65
|
+
|
|
58
66
|
def validate_dependencies(suite)
|
|
59
67
|
errors = []
|
|
60
|
-
all_dependencies = (dependencies + indirect_dependency + implements).flatten.compact.map(&:to_s)
|
|
61
68
|
all_identifiers = suite.all_identifiers.map(&:to_s)
|
|
62
69
|
all_dependencies.each do |dep|
|
|
63
70
|
errors << "Requirement #{identifier} has an invalid dependency: #{dep}" unless all_identifiers.include?(dep)
|
|
@@ -12,19 +12,21 @@ module Modspec
|
|
|
12
12
|
attribute :subject, :string
|
|
13
13
|
attribute :guidance, :string, collection: true
|
|
14
14
|
attribute :dependencies, Identifier, collection: true
|
|
15
|
+
attribute :implements, Identifier, collection: true
|
|
15
16
|
attribute :normative_statements, NormativeStatement, collection: true
|
|
16
17
|
attribute :belongs_to, Identifier, collection: true
|
|
17
18
|
attribute :reference, :string
|
|
18
19
|
attribute :source, :string
|
|
19
20
|
|
|
20
21
|
xml do
|
|
21
|
-
|
|
22
|
+
element "normative-statements-class"
|
|
22
23
|
map_attribute "identifier", to: :identifier
|
|
23
24
|
map_element "name", to: :name
|
|
24
25
|
map_element "description", to: :description
|
|
25
26
|
map_element "subject", to: :subject
|
|
26
27
|
map_element "guidance", to: :guidance
|
|
27
28
|
map_element "dependencies", to: :dependencies
|
|
29
|
+
map_element "implements", to: :implements
|
|
28
30
|
map_element "normative-statements", to: :normative_statements
|
|
29
31
|
map_element "belongs_to", to: :belongs_to
|
|
30
32
|
map_element "reference", to: :reference
|
|
@@ -42,16 +44,16 @@ module Modspec
|
|
|
42
44
|
private
|
|
43
45
|
|
|
44
46
|
def validate_identifier_prefix
|
|
45
|
-
|
|
47
|
+
return [] if normative_statements.nil? || normative_statements.empty?
|
|
48
|
+
|
|
46
49
|
expected_prefix = "#{identifier}/"
|
|
47
|
-
normative_statements.
|
|
50
|
+
normative_statements.each_with_object([]) do |statement, errors|
|
|
48
51
|
errors << "Normative statement #{statement.identifier} does not share the expected prefix #{expected_prefix}" unless statement.identifier.to_s.start_with?(expected_prefix)
|
|
49
52
|
end
|
|
50
|
-
errors
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
def validate_class_children_mapping
|
|
54
|
-
if normative_statements.empty?
|
|
56
|
+
if normative_statements.nil? || normative_statements.empty?
|
|
55
57
|
["Requirement class #{identifier} has no child requirements"]
|
|
56
58
|
else
|
|
57
59
|
[]
|