modspec 0.1.4 → 0.2.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +4 -0
  3. data/.github/workflows/release.yml +5 -0
  4. data/.rubocop.yml +18 -6
  5. data/.rubocop_todo.yml +108 -76
  6. data/CLAUDE.md +61 -0
  7. data/Gemfile +4 -3
  8. data/lib/modspec/conformance_class.rb +4 -8
  9. data/lib/modspec/conformance_test.rb +19 -5
  10. data/lib/modspec/identifier.rb +0 -1
  11. data/lib/modspec/normative_statement.rb +3 -39
  12. data/lib/modspec/normative_statements_class.rb +3 -3
  13. data/lib/modspec/suite.rb +73 -82
  14. data/lib/modspec/version.rb +1 -1
  15. data/lib/modspec.rb +8 -22
  16. data/modspec.gemspec +3 -2
  17. data/spec/conformance_class.liquid +2 -2
  18. data/spec/fixtures/advanced-json-rc.yaml +5 -7
  19. data/spec/fixtures/advanced-rc.yaml +12 -14
  20. data/spec/fixtures/basic-quaternion-json-rc.yaml +5 -7
  21. data/spec/fixtures/basic-quaternion-json-strict-rc.yaml +4 -5
  22. data/spec/fixtures/basic-quaternion-rc.yaml +7 -8
  23. data/spec/fixtures/basic-ypr-json-rc.yaml +5 -8
  24. data/spec/fixtures/basic-ypr-rc.yaml +7 -7
  25. data/spec/fixtures/chain-json-rc.yaml +5 -7
  26. data/spec/fixtures/chain-rc.yaml +11 -13
  27. data/spec/fixtures/frame-spec-rc.yaml +10 -10
  28. data/spec/fixtures/global-rc.yaml +7 -4
  29. data/spec/fixtures/graph-json-rc.yaml +5 -7
  30. data/spec/fixtures/graph-rc.yaml +11 -13
  31. data/spec/fixtures/series-irregular-json-rc.yaml +5 -7
  32. data/spec/fixtures/series-irregular-rc.yaml +13 -15
  33. data/spec/fixtures/series-regular-json-rc.yaml +5 -7
  34. data/spec/fixtures/series-regular-rc.yaml +15 -17
  35. data/spec/fixtures/stream-json-rc.yaml +9 -11
  36. data/spec/fixtures/stream-rc.yaml +10 -12
  37. data/spec/fixtures/tangent-point-rc.yaml +10 -11
  38. data/spec/fixtures/time-rc.yaml +6 -8
  39. data/spec/modspec/conformance_class_spec.rb +44 -35
  40. data/spec/modspec/conformance_test_spec.rb +26 -7
  41. data/spec/modspec/normative_statement_spec.rb +16 -12
  42. data/spec/modspec/normative_statements_class_spec.rb +18 -6
  43. data/spec/modspec/suite_spec.rb +198 -37
  44. data/spec/modspec_spec.rb +7 -7
  45. data/spec/spec_helper.rb +1 -0
  46. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c39d089400518c8882fa0cfc55582fa27cd73c9358faf2224aeb5535a238fc55
4
- data.tar.gz: c7b5fcf2a9c36ab12751ac964b6d95528a21330228872c75851bdf2211a8d885
3
+ metadata.gz: 74bb2806f9ebad2c91453ba473103f5e581c76b78223d9eeba79f4580e8858db
4
+ data.tar.gz: cb2903e0b33726419f118c65f64ad5463a2bef0b385643f877de977bc447f8d9
5
5
  SHA512:
6
- metadata.gz: d8e4371eea18c40f1b660841ff6d1723b8a8536acd248a65d87d6d4526bba35ea0b00970e7199bdeaee51114c1cd214233859c2265d1f43fb742831f19c71568
7
- data.tar.gz: 7f6f7f555aaa1ce91e300240ce57f37e69d77e1fb4f1ff0fb020e8afc69c195c3a287f2540bbcce31019481915a2fb2d1ba748670f1c9f6ce622eb6d4b720e58
6
+ metadata.gz: d31ab6413761a379a95aa692e94471538daa63cb507ecfcf25ab6e4b3bc34cdfc22d8234ca4239e0159921bdd203ce4e8bec8bec3e4d99323222c34d49d59ac0
7
+ data.tar.gz: 615225d2adf7b489e0d627147b3a3dbdd43009ed0c96df174f690b9ebeec6c7c752eb5a684505f6822af40d7ee9710ef2a165e9aa601ba6144d82b52a2192a38
@@ -2,6 +2,10 @@
2
2
  # See https://github.com/metanorma/cimas
3
3
  name: rake
4
4
 
5
+ permissions:
6
+ contents: write
7
+ packages: write
8
+
5
9
  on:
6
10
  push:
7
11
  branches: [ master, main ]
@@ -2,6 +2,11 @@
2
2
  # See https://github.com/metanorma/cimas
3
3
  name: release
4
4
 
5
+ permissions:
6
+ contents: write
7
+ packages: write
8
+ id-token: write
9
+
5
10
  on:
6
11
  workflow_dispatch:
7
12
  inputs:
data/.rubocop.yml CHANGED
@@ -1,10 +1,22 @@
1
- inherit_from: .rubocop_todo.yml
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
6
+
7
+ inherit_mode:
8
+ merge:
9
+ - Exclude
10
+
11
+ # local repo-specific modifications
12
+ # ...
13
+ plugins:
14
+ - rubocop-rspec
15
+ - rubocop-performance
16
+ - rubocop-rake
2
17
 
3
18
  AllCops:
4
19
  TargetRubyVersion: 3.0
5
20
 
6
- Style/StringLiterals:
7
- EnforcedStyle: double_quotes
8
-
9
- Style/StringLiteralsInInterpolation:
10
- EnforcedStyle: double_quotes
21
+ RSpec/ExampleLength:
22
+ Max: 30
data/.rubocop_todo.yml CHANGED
@@ -1,118 +1,150 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-09-11 00:07:51 UTC using RuboCop version 1.66.1.
3
+ # on 2026-05-06 00:19:18 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: 10
14
+ # Offense count: 7
25
15
  # This cop supports safe autocorrection (--autocorrect).
26
16
  # Configuration parameters: EnforcedStyle, IndentationWidth.
27
- # SupportedStyles: aligned, indented, indented_relative_to_receiver
28
- Layout/MultilineMethodCallIndentation:
17
+ # SupportedStyles: with_first_argument, with_fixed_indentation
18
+ Layout/ArgumentAlignment:
29
19
  Exclude:
30
- - 'modspec.gemspec'
20
+ - 'lib/modspec/suite.rb'
31
21
  - 'spec/modspec/suite_spec.rb'
32
22
 
33
- # Offense count: 4
34
- # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
35
- Metrics/AbcSize:
36
- Max: 33
37
-
38
- # Offense count: 6
39
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
40
- # AllowedMethods: refine
41
- Metrics/BlockLength:
42
- Max: 138
43
-
44
23
  # Offense count: 1
45
- # Configuration parameters: CountComments, CountAsOne.
46
- Metrics/ClassLength:
47
- Max: 204
24
+ # This cop supports safe autocorrection (--autocorrect).
25
+ # Configuration parameters: EnforcedStyleAlignWith.
26
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
27
+ Layout/BlockAlignment:
28
+ Exclude:
29
+ - 'lib/modspec/suite.rb'
48
30
 
49
31
  # Offense count: 1
50
- # Configuration parameters: AllowedMethods, AllowedPatterns.
51
- Metrics/CyclomaticComplexity:
52
- Max: 12
53
-
54
- # Offense count: 5
55
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
56
- Metrics/MethodLength:
57
- Max: 18
32
+ # This cop supports safe autocorrection (--autocorrect).
33
+ Layout/BlockEndNewline:
34
+ Exclude:
35
+ - 'lib/modspec/suite.rb'
58
36
 
59
- # Offense count: 1
60
- # Configuration parameters: AllowedMethods, AllowedPatterns.
61
- Metrics/PerceivedComplexity:
62
- Max: 12
37
+ # Offense count: 6
38
+ # This cop supports safe autocorrection (--autocorrect).
39
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
40
+ # SupportedHashRocketStyles: key, separator, table
41
+ # SupportedColonStyles: key, separator, table
42
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
43
+ Layout/HashAlignment:
44
+ Exclude:
45
+ - 'spec/modspec/suite_spec.rb'
63
46
 
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:
47
+ # Offense count: 2
48
+ # This cop supports safe autocorrection (--autocorrect).
49
+ # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
50
+ # SupportedStylesAlignWith: start_of_line, relative_to_receiver
51
+ Layout/IndentationWidth:
71
52
  Exclude:
72
- - 'spec/**/*'
73
- - 'lib/modspec/normative_statement.rb'
53
+ - 'lib/modspec/suite.rb'
74
54
 
75
- # Offense count: 6
76
- # Configuration parameters: AllowedConstants.
77
- Style/Documentation:
55
+ # Offense count: 36
56
+ # This cop supports safe autocorrection (--autocorrect).
57
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
58
+ # URISchemes: http, https
59
+ Layout/LineLength:
78
60
  Exclude:
79
- - 'spec/**/*'
80
- - 'test/**/*'
81
61
  - 'lib/modspec/conformance_class.rb'
82
62
  - 'lib/modspec/conformance_test.rb'
83
- - 'lib/modspec/normative_statement.rb'
84
63
  - 'lib/modspec/normative_statements_class.rb'
85
64
  - 'lib/modspec/suite.rb'
65
+ - 'spec/modspec/conformance_class_spec.rb'
66
+ - 'spec/modspec/conformance_test_spec.rb'
67
+ - 'spec/modspec/normative_statement_spec.rb'
68
+ - 'spec/modspec/normative_statements_class_spec.rb'
69
+ - 'spec/modspec/suite_spec.rb'
86
70
 
87
- # Offense count: 2
71
+ # Offense count: 4
88
72
  # This cop supports safe autocorrection (--autocorrect).
89
- Style/IfUnlessModifier:
73
+ # Configuration parameters: AllowInHeredoc.
74
+ Layout/TrailingWhitespace:
90
75
  Exclude:
91
- - 'lib/modspec/conformance_class.rb'
92
- - 'lib/modspec/normative_statements_class.rb'
76
+ - 'lib/modspec/suite.rb'
77
+ - 'spec/modspec/suite_spec.rb'
78
+
79
+ # Offense count: 5
80
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
81
+ Metrics/AbcSize:
82
+ Exclude:
83
+ - 'lib/modspec/suite.rb'
84
+
85
+ # Offense count: 5
86
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
87
+ Metrics/CyclomaticComplexity:
88
+ Exclude:
89
+ - 'lib/modspec/suite.rb'
90
+
91
+ # Offense count: 9
92
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
93
+ Metrics/MethodLength:
94
+ Max: 19
95
+
96
+ # Offense count: 2
97
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
98
+ Metrics/PerceivedComplexity:
99
+ Exclude:
100
+ - 'lib/modspec/suite.rb'
93
101
 
94
- # Offense count: 27
102
+ # Offense count: 2
103
+ # Configuration parameters: MinSize.
104
+ Performance/CollectionLiteralInLoop:
105
+ Exclude:
106
+ - 'lib/modspec/suite.rb'
107
+
108
+ # Offense count: 1
95
109
  # This cop supports safe autocorrection (--autocorrect).
96
- # Configuration parameters: EnforcedStyleForMultiline.
97
- # SupportedStylesForMultiline: comma, consistent_comma, no_comma
98
- Style/TrailingCommaInArguments:
110
+ RSpec/ExpectActual:
99
111
  Exclude:
100
- - 'spec/modspec/conformance_class_spec.rb'
101
- - 'spec/modspec/conformance_test_spec.rb'
102
112
  - 'spec/modspec/normative_statement_spec.rb'
113
+
114
+ # Offense count: 4
115
+ # Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
116
+ RSpec/IndexedLet:
117
+ Exclude:
103
118
  - 'spec/modspec/normative_statements_class_spec.rb'
119
+ - 'spec/modspec/suite_spec.rb'
104
120
 
105
- # Offense count: 6
121
+ # Offense count: 8
122
+ RSpec/MultipleExpectations:
123
+ Max: 9
124
+
125
+ # Offense count: 7
126
+ # Configuration parameters: AllowSubject.
127
+ RSpec/MultipleMemoizedHelpers:
128
+ Max: 12
129
+
130
+ # Offense count: 2
131
+ RSpec/RepeatedExample:
132
+ Exclude:
133
+ - 'spec/modspec_spec.rb'
134
+
135
+ # Offense count: 1
106
136
  # This cop supports safe autocorrection (--autocorrect).
107
- # Configuration parameters: EnforcedStyleForMultiline.
108
- # SupportedStylesForMultiline: comma, consistent_comma, no_comma
109
- Style/TrailingCommaInArrayLiteral:
137
+ # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
138
+ # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
139
+ # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
140
+ # FunctionalMethods: let, let!, subject, watch
141
+ # AllowedMethods: lambda, proc, it
142
+ Style/BlockDelimiters:
110
143
  Exclude:
111
- - 'spec/modspec/conformance_class_spec.rb'
144
+ - 'lib/modspec/suite.rb'
112
145
 
113
- # Offense count: 13
146
+ # Offense count: 2
114
147
  # This cop supports safe autocorrection (--autocorrect).
115
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
116
- # URISchemes: http, https
117
- Layout/LineLength:
118
- Max: 247
148
+ Style/MultilineIfModifier:
149
+ Exclude:
150
+ - 'lib/modspec/suite.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,11 +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 "equivalent-xml"
9
- gem "pry"
7
+ gem "canon"
10
8
  gem "rake"
11
9
  gem "rspec"
12
10
  gem "rubocop"
11
+ gem "rubocop-performance"
12
+ gem "rubocop-rake"
13
+ gem "rubocop-rspec"
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "conformance_test"
5
- require_relative "identifier"
6
4
 
7
5
  module Modspec
8
6
  class ConformanceClass < Lutaml::Model::Serializable
@@ -18,7 +16,7 @@ module Modspec
18
16
  attribute :reference, :string
19
17
 
20
18
  xml do
21
- root "conformance-class"
19
+ element "conformance-class"
22
20
  map_attribute "identifier", to: :identifier
23
21
  map_element "name", to: :name
24
22
  map_element "dependencies", to: :dependencies
@@ -32,7 +30,7 @@ module Modspec
32
30
  end
33
31
 
34
32
  def validate
35
- errors = super()
33
+ errors = super
36
34
  errors.concat(validate_identifier_prefix)
37
35
  errors.concat(validate_class_children_mapping)
38
36
  errors.concat(tests.flat_map(&:validate))
@@ -52,10 +50,8 @@ module Modspec
52
50
  def validate_identifier_prefix
53
51
  errors = []
54
52
  expected_prefix = "#{identifier}/"
55
- if tests
56
- tests.each do |test|
57
- errors << "Conformance test #{test.identifier} does not share the expected prefix #{expected_prefix}" unless test.identifier.to_s.start_with?(expected_prefix)
58
- end
53
+ tests&.each do |test|
54
+ errors << "Conformance test #{test.identifier} does not share the expected prefix #{expected_prefix}" unless test.identifier.to_s.start_with?(expected_prefix)
59
55
  end
60
56
  errors
61
57
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "identifier"
5
4
 
6
5
  module Modspec
7
6
  class ConformanceTest < Lutaml::Model::Serializable
@@ -13,13 +12,13 @@ module Modspec
13
12
  attribute :description, :string
14
13
  attribute :guidance, :string, collection: true
15
14
  attribute :purpose, :string
16
- attribute :method, :string # Inspection, etc.
15
+ attribute :test_method, :string
17
16
  attribute :type, :string
18
17
  attribute :reference, :string
19
18
  attribute :abstract, :boolean
20
19
 
21
20
  xml do
22
- root "conformance-test"
21
+ element "conformance-test"
23
22
  map_attribute "identifier", to: :identifier
24
23
  map_attribute "abstract", to: :abstract
25
24
  map_element "name", to: :name
@@ -29,15 +28,30 @@ module Modspec
29
28
  map_element "description", to: :description
30
29
  map_element "guidance", to: :guidance
31
30
  map_element "purpose", to: :purpose
32
- map_element "method", to: :method
31
+ map_element "method", to: :test_method
33
32
  map_element "type", to: :type
34
33
  map_element "reference", to: :reference
35
34
  end
36
35
 
36
+ key_value do
37
+ map "identifier", to: :identifier
38
+ map "name", to: :name
39
+ map "dependencies", to: :dependencies
40
+ map "targets", to: :targets
41
+ map "belongs_to", to: :belongs_to
42
+ map "description", to: :description
43
+ map "guidance", to: :guidance
44
+ map "purpose", to: :purpose
45
+ map "method", to: :test_method
46
+ map "type", to: :type
47
+ map "reference", to: :reference
48
+ map "abstract", to: :abstract
49
+ end
50
+
37
51
  attr_accessor :corresponding_requirements, :parent_class
38
52
 
39
53
  def validate
40
- errors = super()
54
+ errors = super
41
55
  errors.concat(validate_requirement_mapping)
42
56
  errors.concat(validate_class_mapping)
43
57
  errors
@@ -4,6 +4,5 @@ require "lutaml/model"
4
4
 
5
5
  module Modspec
6
6
  class Identifier < Lutaml::Model::Type::String
7
- # attribute :identifier, :string
8
7
  end
9
8
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "identifier"
5
4
 
6
5
  module Modspec
7
6
  class NormativeStatementPart < Lutaml::Model::Serializable
@@ -29,7 +28,7 @@ module Modspec
29
28
  default: -> { "requirement" }
30
29
 
31
30
  xml do
32
- root "normative-statement"
31
+ element "normative-statement"
33
32
  map_attribute "identifier", to: :identifier
34
33
  map_element "name", to: :name
35
34
  map_element "subject", to: :subject
@@ -46,43 +45,8 @@ module Modspec
46
45
  map_element "parts", to: :parts
47
46
  end
48
47
 
49
- def validate(suite = nil)
50
- errors = super()
51
- errors.concat(validate_dependencies(suite)) if suite
52
- errors.concat(validate_nested_requirement)
53
- errors
54
- end
55
-
56
- private
57
-
58
- def all_dependencies
59
- (
60
- (dependencies || []) +
61
- (indirect_dependency || []) +
62
- (implements || [])
63
- ).flatten.compact
64
- end
65
-
66
- def validate_dependencies(suite)
67
- errors = []
68
- all_identifiers = suite.all_identifiers.map(&:to_s)
69
- all_dependencies.each do |dep|
70
- errors << "Requirement #{identifier} has an invalid dependency: #{dep}" unless all_identifiers.include?(dep)
71
- end
72
- errors
73
- end
74
-
75
- def validate_nested_requirement
76
- if has_parent_requirement?
77
- ["Nested requirement detected: #{identifier}"]
78
- else
79
- []
80
- end
81
- end
82
-
83
- def has_parent_requirement?
84
- # Implementation depends on how you determine if a requirement is nested
85
- false
48
+ def validate(_suite = nil, register: Lutaml::Model::Config.default_register)
49
+ super(register: register)
86
50
  end
87
51
  end
88
52
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
- require_relative "normative_statement"
5
- require_relative "identifier"
6
4
 
7
5
  module Modspec
8
6
  class NormativeStatementsClass < Lutaml::Model::Serializable
@@ -12,19 +10,21 @@ module Modspec
12
10
  attribute :subject, :string
13
11
  attribute :guidance, :string, collection: true
14
12
  attribute :dependencies, Identifier, collection: true
13
+ attribute :implements, Identifier, collection: true
15
14
  attribute :normative_statements, NormativeStatement, collection: true
16
15
  attribute :belongs_to, Identifier, collection: true
17
16
  attribute :reference, :string
18
17
  attribute :source, :string
19
18
 
20
19
  xml do
21
- root "normative-statements-class"
20
+ element "normative-statements-class"
22
21
  map_attribute "identifier", to: :identifier
23
22
  map_element "name", to: :name
24
23
  map_element "description", to: :description
25
24
  map_element "subject", to: :subject
26
25
  map_element "guidance", to: :guidance
27
26
  map_element "dependencies", to: :dependencies
27
+ map_element "implements", to: :implements
28
28
  map_element "normative-statements", to: :normative_statements
29
29
  map_element "belongs_to", to: :belongs_to
30
30
  map_element "reference", to: :reference