modspec 0.1.4 → 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.
Files changed (45) 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 +16 -7
  5. data/.rubocop_todo.yml +67 -80
  6. data/CLAUDE.md +61 -0
  7. data/Gemfile +4 -3
  8. data/lib/modspec/conformance_class.rb +4 -6
  9. data/lib/modspec/conformance_test.rb +19 -4
  10. data/lib/modspec/normative_statement.rb +2 -2
  11. data/lib/modspec/normative_statements_class.rb +3 -1
  12. data/lib/modspec/suite.rb +45 -38
  13. data/lib/modspec/version.rb +1 -1
  14. data/lib/modspec.rb +1 -12
  15. data/modspec.gemspec +3 -2
  16. data/spec/conformance_class.liquid +2 -2
  17. data/spec/fixtures/advanced-json-rc.yaml +5 -7
  18. data/spec/fixtures/advanced-rc.yaml +12 -14
  19. data/spec/fixtures/basic-quaternion-json-rc.yaml +5 -7
  20. data/spec/fixtures/basic-quaternion-json-strict-rc.yaml +4 -5
  21. data/spec/fixtures/basic-quaternion-rc.yaml +7 -8
  22. data/spec/fixtures/basic-ypr-json-rc.yaml +5 -8
  23. data/spec/fixtures/basic-ypr-rc.yaml +7 -7
  24. data/spec/fixtures/chain-json-rc.yaml +5 -7
  25. data/spec/fixtures/chain-rc.yaml +11 -13
  26. data/spec/fixtures/frame-spec-rc.yaml +10 -10
  27. data/spec/fixtures/global-rc.yaml +7 -4
  28. data/spec/fixtures/graph-json-rc.yaml +5 -7
  29. data/spec/fixtures/graph-rc.yaml +11 -13
  30. data/spec/fixtures/series-irregular-json-rc.yaml +5 -7
  31. data/spec/fixtures/series-irregular-rc.yaml +13 -15
  32. data/spec/fixtures/series-regular-json-rc.yaml +5 -7
  33. data/spec/fixtures/series-regular-rc.yaml +15 -17
  34. data/spec/fixtures/stream-json-rc.yaml +9 -11
  35. data/spec/fixtures/stream-rc.yaml +10 -12
  36. data/spec/fixtures/tangent-point-rc.yaml +10 -11
  37. data/spec/fixtures/time-rc.yaml +6 -8
  38. data/spec/modspec/conformance_class_spec.rb +29 -27
  39. data/spec/modspec/conformance_test_spec.rb +6 -5
  40. data/spec/modspec/normative_statement_spec.rb +16 -12
  41. data/spec/modspec/normative_statements_class_spec.rb +4 -4
  42. data/spec/modspec/suite_spec.rb +26 -22
  43. data/spec/modspec_spec.rb +7 -7
  44. data/spec/spec_helper.rb +1 -0
  45. metadata +6 -4
@@ -1,22 +1,19 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: JSON encoding of Stream SDUs
4
- identifier: /req/stream-encoding-json
5
- description: |
6
- Requirements for the JSON encoding of Stream SDUs.
4
+ identifier: "/req/stream-encoding-json"
5
+ description: 'Requirements for the JSON encoding of Stream SDUs.'
7
6
  implements:
8
- - /req/stream
9
-
7
+ - "/req/stream"
10
8
  normative_statements:
11
-
12
9
  - name: Stream Element specification as JSON schema
13
- identifier: /req/stream-encoding-json/element
10
+ identifier: "/req/stream-encoding-json/element"
14
11
  statement: |
15
12
  A JSON-encoded GeoPose Stream Element SHALL conform to the GeoPose Stream Element
16
13
  JSON-Schema 2019-9 definition (<<streamelement_json_schema>>).
17
-
14
+ obligation: requirement
18
15
  - name: Stream Header specification as JSON schema
19
- identifier: /req/stream-encoding-json/header
16
+ identifier: "/req/stream-encoding-json/header"
20
17
  statement: |
21
18
  A JSON-encoded GeoPose Stream Element SHALL conform to the GeoPose Stream Header
22
19
  JSON-Schema 2019-9 definition (<<streamheader_json_schema>>).
@@ -24,9 +21,10 @@ normative_statements_classes:
24
21
  - |
25
22
  This JSON encoding is extensible because the JSON-Schema
26
23
  "additionalProperties" property is set to the default value of *true*.
27
-
24
+ obligation: requirement
28
25
  - name: Stream Record specification as JSON schema
29
- identifier: /req/stream-encoding-json/record
26
+ identifier: "/req/stream-encoding-json/record"
30
27
  statement: |
31
28
  A JSON-encoded GeoPose Stream Record (a recorded Stream) SHALL conform to the GeoPose Stream Record
32
29
  JSON-Schema 2019-9 definition (<<streamrecord_json_schema>>).
30
+ obligation: requirement
@@ -1,36 +1,34 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: StreamHeader and StreamElement logical model SDUs
4
- identifier: /req/stream
4
+ identifier: "/req/stream"
5
5
  description: |
6
6
  The Stream target supports a network of object relative poses. The graph is a
7
7
  directed acyclic graph, each node must either be an Extrinsic Frame or
8
8
  reachable from an Extrinsic Frame.
9
-
10
9
  dependencies:
11
- - /req/global
12
- - /req/frame-spec
13
-
10
+ - "/req/global"
11
+ - "/req/frame-spec"
14
12
  normative_statements:
15
-
16
13
  - name: Expression of outer frame in StreamHeader
17
- identifier: /req/stream/header-initial-frame
14
+ identifier: "/req/stream/header-initial-frame"
18
15
  statement: |
19
16
  The `StreamHeader.outerFrame` attribute shall represent the initial frame
20
17
  of the stream with a value that is an instant of the `ExplicitFrameSpec`
21
18
  object.
22
-
19
+ obligation: requirement
23
20
  - name: Expression of transition model in StreamHeader
24
- identifier: /req/stream/header-transition-model
21
+ identifier: "/req/stream/header-transition-model"
25
22
  statement: |
26
23
  The `StreamHeader.transitionModel` attribute shall have a value that is
27
24
  an instance of the `TransitionModel` enumeration.
28
-
25
+ obligation: requirement
29
26
  - name: Expression of stream elements in StreamElement
30
- identifier: /req/stream/element
27
+ identifier: "/req/stream/element"
31
28
  dependencies:
32
- - /req/time/instant
29
+ - "/req/time/instant"
33
30
  statement: |
34
31
  The `StreamElement.streamElement` attribute shall be implemented as an
35
32
  array of `FrameAndTimeElement` objects, each of which is a pair of
36
33
  `ExplicitFrameSpec` and `GeoPoseInstant` objects.
34
+ obligation: requirement
@@ -1,38 +1,37 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Tangent point requirements
4
- identifier: /req/tangent-point
5
- description: |
6
- Common tangent point requirements for SDUs that include tangent points.
7
- guidance: |
4
+ identifier: "/req/tangent-point"
5
+ description: 'Common tangent point requirements for SDUs that include tangent points.'
6
+ guidance:
7
+ - |-
8
8
  The tangent plane `longitude`, `latitude`, and `h` parameters are
9
9
  specified without any conditions or constraints on precision to be used in
10
10
  an implementation. Any such constraints would be found as requirements on a
11
11
  specific implementation as an encoding.
12
-
13
12
  normative_statements:
14
-
15
13
  - name: Tangent point height value specification
16
- identifier: /req/tangent-point/height
14
+ identifier: "/req/tangent-point/height"
17
15
  statement: |
18
16
  An instance of a GeoPose `tangentPoint.h` attribute SHALL be expressed as
19
17
  a height in meters above the WGS-84 ellipsoid, represented as a signed as
20
18
  a signed floating point value conforming to IEEE 754. If the tangent point
21
19
  is above the WGS-84 ellipsoid, the value SHALL be positive. If the tangent
22
20
  point is below the WGS-84 ellipsoid, the value SHALL be negative.
23
-
21
+ obligation: requirement
24
22
  - name: Tangent point latitude value specification
25
- identifier: /req/tangent-point/latitude
23
+ identifier: "/req/tangent-point/latitude"
26
24
  statement: |
27
25
  An instance of GeoPose tangentPoint.latitude attribute SHALL be expressed
28
26
  as decimal degrees and represented as a signed floating point
29
27
  value conforming to IEEE 754.. The minimum value shall be 90.0 degrees
30
28
  and the maximum value shall be 90.0 degrees.
31
-
29
+ obligation: requirement
32
30
  - name: Tangent point longitude value specification
33
- identifier: /req/tangent-point/longitude
31
+ identifier: "/req/tangent-point/longitude"
34
32
  statement: |
35
33
  An instance of a GeoPose tangentPoint.longitude attribute SHALL be
36
34
  expressed as decimal degrees and represented as a signed floating point
37
35
  value conforming to IEEE 754. The minimum value shall be -180.0 degrees
38
36
  and the maximum value shall be 180.0 degrees.
37
+ obligation: requirement
@@ -1,20 +1,18 @@
1
1
  ---
2
2
  normative_statements_classes:
3
3
  - name: Time specification requirements
4
- identifier: /req/time
5
- description: |
6
- Requirements on GeoPose time-related objects.
7
-
4
+ identifier: "/req/time"
5
+ description: 'Requirements on GeoPose time-related objects.'
8
6
  normative_statements:
9
-
10
7
  - name: Implementation of GeoPose_Instant
11
- identifier: /req/time/instant
8
+ identifier: "/req/time/instant"
12
9
  statement: |
13
10
  The `GeoPose_Instant` object shall express Unix Time in seconds multiplied
14
11
  by 1,000, with the unit of measure in milliseconds.
15
-
12
+ obligation: requirement
16
13
  - name: Implementation of GeoPose_Duration
17
- identifier: /req/time/duration
14
+ identifier: "/req/time/duration"
18
15
  statement: |
19
16
  The `GeoPose_Duration` object shall express time in seconds multiplied by
20
17
  1,000, with the unit of measure in milliseconds.
18
+ obligation: requirement
@@ -11,19 +11,19 @@ RSpec.describe Modspec::ConformanceClass do
11
11
  Modspec::NormativeStatement.new(
12
12
  identifier: "/req/basic-ypr/position",
13
13
  name: "Expression of outer frame",
14
- statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point."
14
+ statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
15
15
  ),
16
16
  Modspec::NormativeStatement.new(
17
17
  identifier: "/req/basic-ypr/angles",
18
18
  name: "Expression of inner frame",
19
- statement: "The `Basic_YPR.angles` attribute shall represent the inner frame, which is a rotation-only transformation with Yaw, Pitch, and Roll (YPR) angles."
20
- )
21
- ]
19
+ statement: "The `Basic_YPR.angles` attribute shall represent the inner frame, which is a rotation-only transformation with Yaw, Pitch, and Roll (YPR) angles.",
20
+ ),
21
+ ],
22
22
  )
23
23
  end
24
24
 
25
25
  let(:conformance_class) do
26
- Modspec::ConformanceClass.new(
26
+ described_class.new(
27
27
  identifier: "/conf/basic-ypr",
28
28
  name: "Basic-YPR logical model SDU conformance",
29
29
  target: ["/req/basic-ypr"],
@@ -37,7 +37,7 @@ RSpec.describe Modspec::ConformanceClass do
37
37
  targets: ["/req/basic-ypr/position"],
38
38
  description: "To confirm that an implementation of a Basic-YPR consists of an Outer Frame specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
39
39
  purpose: "Verify that this requirement is satisfied.",
40
- method: "Inspection"
40
+ test_method: "Inspection",
41
41
  ),
42
42
  Modspec::ConformanceTest.new(
43
43
  identifier: "/conf/basic-ypr/angles",
@@ -45,9 +45,9 @@ RSpec.describe Modspec::ConformanceClass do
45
45
  targets: ["/req/basic-ypr/angles"],
46
46
  description: "To confirm that the Inner Frame is expressed as a rotation-only transformation using Yaw, Pitch, and Roll angles.",
47
47
  purpose: "Verify that this requirement is satisfied.",
48
- method: "Inspection"
49
- )
50
- ]
48
+ test_method: "Inspection",
49
+ ),
50
+ ],
51
51
  )
52
52
  end
53
53
 
@@ -59,9 +59,9 @@ RSpec.describe Modspec::ConformanceClass do
59
59
  Modspec::NormativeStatement.new(
60
60
  identifier: "/req/global/sdu",
61
61
  name: "SDU conformance",
62
- statement: "SDUs shall conform to the logical model."
63
- )
64
- ]
62
+ statement: "SDUs shall conform to the logical model.",
63
+ ),
64
+ ],
65
65
  )
66
66
  end
67
67
 
@@ -73,14 +73,14 @@ RSpec.describe Modspec::ConformanceClass do
73
73
  Modspec::NormativeStatement.new(
74
74
  identifier: "/req/tangent-point/height",
75
75
  name: "Tangent point height",
76
- statement: "Tangent point height shall be specified."
77
- )
78
- ]
76
+ statement: "Tangent point height shall be specified.",
77
+ ),
78
+ ],
79
79
  )
80
80
  end
81
81
 
82
82
  let(:global_conf_class) do
83
- Modspec::ConformanceClass.new(
83
+ described_class.new(
84
84
  identifier: "/conf/global",
85
85
  name: "Global conformance",
86
86
  tests: [
@@ -90,14 +90,14 @@ RSpec.describe Modspec::ConformanceClass do
90
90
  targets: ["/req/global/sdu"],
91
91
  description: "To confirm that an implementation of an SDU conforms to the logical model.",
92
92
  purpose: "Verify that this requirement is satisfied.",
93
- method: "Inspection"
94
- )
95
- ]
93
+ test_method: "Inspection",
94
+ ),
95
+ ],
96
96
  )
97
97
  end
98
98
 
99
99
  let(:tangent_point_conf_class) do
100
- Modspec::ConformanceClass.new(
100
+ described_class.new(
101
101
  identifier: "/conf/tangent-point",
102
102
  name: "Tangent point conformance",
103
103
  tests: [
@@ -107,17 +107,19 @@ RSpec.describe Modspec::ConformanceClass do
107
107
  targets: ["/req/tangent-point/height"],
108
108
  description: "To confirm that an implementation of a Tangent Point specifies the height of the Tangent Point.",
109
109
  purpose: "Verify that this requirement is satisfied.",
110
- method: "Inspection"
111
- )
110
+ test_method: "Inspection",
111
+ ),
112
112
 
113
- ]
113
+ ],
114
114
  )
115
115
  end
116
116
 
117
117
  let(:suite) do
118
118
  suite = Modspec::Suite.new
119
- suite.conformance_classes = [conformance_class, global_conf_class, tangent_point_conf_class]
120
- suite.normative_statements_classes = [normative_statements_class, global_class, tangent_point_class]
119
+ suite.conformance_classes = [conformance_class, global_conf_class,
120
+ tangent_point_conf_class]
121
+ suite.normative_statements_classes = [normative_statements_class,
122
+ global_class, tangent_point_class]
121
123
  suite.setup_relationships
122
124
  suite
123
125
  end
@@ -139,8 +141,8 @@ RSpec.describe Modspec::ConformanceClass do
139
141
  it "returns no errors for a valid conformance class" do
140
142
  errors = suite.validate
141
143
  if errors.any?
142
- puts "Validation errors:"
143
- errors.each { |error| puts " #{error}" }
144
+
145
+ errors.each { |error| }
144
146
  end
145
147
  expect(errors).to be_empty
146
148
  end
@@ -5,7 +5,7 @@ RSpec.describe Modspec::ConformanceTest do
5
5
  Modspec::NormativeStatement.new(
6
6
  identifier: "/req/basic-ypr/position",
7
7
  name: "Expression of outer frame",
8
- statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point."
8
+ statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
9
9
  )
10
10
  end
11
11
 
@@ -13,18 +13,18 @@ RSpec.describe Modspec::ConformanceTest do
13
13
  Modspec::NormativeStatementsClass.new(
14
14
  identifier: "/req/basic-ypr",
15
15
  name: "Basic-YPR logical model SDU",
16
- normative_statements: [normative_statement]
16
+ normative_statements: [normative_statement],
17
17
  )
18
18
  end
19
19
 
20
20
  let(:conformance_test) do
21
- Modspec::ConformanceTest.new(
21
+ described_class.new(
22
22
  identifier: "/conf/basic-ypr/position",
23
23
  name: "Verify expression of outer frame",
24
24
  targets: ["/req/basic-ypr/position"],
25
25
  description: "To confirm that an implementation of a Basic-YPR consists of an Outer Frame specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
26
26
  purpose: "Verify that this requirement is satisfied.",
27
- method: "Inspection"
27
+ test_method: "Inspection",
28
28
  )
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ RSpec.describe Modspec::ConformanceTest do
32
32
  Modspec::ConformanceClass.new(
33
33
  identifier: "/conf/basic-ypr",
34
34
  name: "Basic-YPR logical model SDU conformance",
35
- tests: [conformance_test]
35
+ tests: [conformance_test],
36
36
  )
37
37
  end
38
38
 
@@ -66,6 +66,7 @@ RSpec.describe Modspec::ConformanceTest do
66
66
  expect(errors).to be_empty
67
67
  end
68
68
  end
69
+
69
70
  it "has a corresponding requirement" do
70
71
  expect(conformance_test.corresponding_requirements).to include(normative_statement)
71
72
  end
@@ -2,23 +2,23 @@
2
2
 
3
3
  RSpec.describe Modspec::NormativeStatement do
4
4
  let(:global_sdu_statement) do
5
- Modspec::NormativeStatement.new(
5
+ described_class.new(
6
6
  identifier: "/req/global/sdu",
7
7
  name: "SDU conforms to the 'Structural Data Unit - SDU' stereotype",
8
- statement: "Implementations using encoded SDUs SHALL conform to the logical description of the Logical Model elements with the 'Structural Data Unit - SDU' stereotype."
8
+ statement: "Implementations using encoded SDUs SHALL conform to the logical description of the Logical Model elements with the 'Structural Data Unit - SDU' stereotype.",
9
9
  )
10
10
  end
11
11
 
12
12
  let(:tangent_point_statement) do
13
- Modspec::NormativeStatement.new(
13
+ described_class.new(
14
14
  identifier: "/req/tangent-point",
15
15
  name: "Tangent point requirements",
16
- statement: "Common tangent point requirements for SDUs that include tangent points."
16
+ statement: "Common tangent point requirements for SDUs that include tangent points.",
17
17
  )
18
18
  end
19
19
 
20
20
  let(:normative_statement) do
21
- Modspec::NormativeStatement.new(
21
+ described_class.new(
22
22
  identifier: "/req/basic-ypr/position",
23
23
  name: "Expression of outer frame",
24
24
  statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
@@ -26,7 +26,7 @@ RSpec.describe Modspec::NormativeStatement do
26
26
  subject: "Basic_YPR.position",
27
27
  inherit: ["/req/global/sdu"],
28
28
  dependencies: ["/req/tangent-point"],
29
- guidance: ["Ensure the coordinate system is correctly specified."]
29
+ guidance: ["Ensure the coordinate system is correctly specified."],
30
30
  )
31
31
  end
32
32
 
@@ -34,17 +34,18 @@ RSpec.describe Modspec::NormativeStatement do
34
34
  suite = Modspec::Suite.new
35
35
  global_class = Modspec::NormativeStatementsClass.new(
36
36
  identifier: "/req/global",
37
- normative_statements: [global_sdu_statement]
37
+ normative_statements: [global_sdu_statement],
38
38
  )
39
39
  tangent_point_class = Modspec::NormativeStatementsClass.new(
40
40
  identifier: "/req/tangent-point",
41
- normative_statements: [tangent_point_statement]
41
+ normative_statements: [tangent_point_statement],
42
42
  )
43
43
  basic_ypr_class = Modspec::NormativeStatementsClass.new(
44
44
  identifier: "/req/basic-ypr",
45
- normative_statements: [normative_statement]
45
+ normative_statements: [normative_statement],
46
46
  )
47
- suite.normative_statements_classes = [global_class, tangent_point_class, basic_ypr_class]
47
+ suite.normative_statements_classes = [global_class, tangent_point_class,
48
+ basic_ypr_class]
48
49
  suite
49
50
  end
50
51
 
@@ -61,7 +62,8 @@ RSpec.describe Modspec::NormativeStatement do
61
62
  end
62
63
 
63
64
  it "has a valid obligation" do
64
- expect(%w[requirement recommendation permission]).to include(normative_statement.obligation)
65
+ expect(%w[requirement recommendation
66
+ permission]).to include(normative_statement.obligation)
65
67
  end
66
68
 
67
69
  describe "#validate" do
@@ -72,7 +74,9 @@ RSpec.describe Modspec::NormativeStatement do
72
74
 
73
75
  it "returns errors for an invalid obligation" do
74
76
  normative_statement.obligation = "invalid"
75
- expect { normative_statement.validate! }.to raise_error(Lutaml::Model::ValidationError) do |error|
77
+ expect do
78
+ normative_statement.validate!
79
+ end.to raise_error(Lutaml::Model::ValidationError) do |error|
76
80
  expect(error).to include(Lutaml::Model::InvalidValueError)
77
81
  expect(error.error_messages).to include("obligation is `invalid`, must be one of the following [recommendation, permission, requirement]")
78
82
  end
@@ -5,7 +5,7 @@ RSpec.describe Modspec::NormativeStatementsClass do
5
5
  Modspec::NormativeStatement.new(
6
6
  identifier: "/req/basic-ypr/position",
7
7
  name: "Expression of outer frame",
8
- statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point."
8
+ statement: "The `Basic_YPR.position` attribute shall represent the outer frame, specified by an implicit WGS-84 CRS and an implicit EPSG 4461-CS (LTP-ENU) coordinate system and explicit parameters to define the tangent point.",
9
9
  )
10
10
  end
11
11
 
@@ -13,17 +13,17 @@ RSpec.describe Modspec::NormativeStatementsClass do
13
13
  Modspec::NormativeStatement.new(
14
14
  identifier: "/req/basic-ypr/angles",
15
15
  name: "Expression of inner frame",
16
- statement: "The `Basic_YPR.angles` attribute shall represent the inner frame, which is a rotation-only transformation with Yaw, Pitch, and Roll (YPR) angles."
16
+ statement: "The `Basic_YPR.angles` attribute shall represent the inner frame, which is a rotation-only transformation with Yaw, Pitch, and Roll (YPR) angles.",
17
17
  )
18
18
  end
19
19
 
20
20
  let(:normative_statements_class) do
21
- Modspec::NormativeStatementsClass.new(
21
+ described_class.new(
22
22
  identifier: "/req/basic-ypr",
23
23
  name: "Basic-YPR logical model SDU",
24
24
  description: "The Basic-YPR Target has a simple structure with no options. Position is specified as a point in an LTP-ENU frame and rotation is specified by yaw, pitch, and roll angles specified in decimal degrees.",
25
25
  dependencies: ["/req/global", "/req/tangent-point"],
26
- normative_statements: [normative_statement1, normative_statement2]
26
+ normative_statements: [normative_statement1, normative_statement2],
27
27
  )
28
28
  end
29
29
 
@@ -9,10 +9,10 @@ RSpec.describe Modspec::Suite do
9
9
  let(:time_rc) { File.read("spec/fixtures/time-rc.yaml") }
10
10
  let(:frame_spec_rc) { File.read("spec/fixtures/frame-spec-rc.yaml") }
11
11
 
12
- let(:global_suite) { Modspec::Suite.from_yaml(global_rc) }
13
- let(:tangent_point_suite) { Modspec::Suite.from_yaml(tangent_point_rc) }
14
- let(:time_suite) { Modspec::Suite.from_yaml(time_rc) }
15
- let(:frame_spec_suite) { Modspec::Suite.from_yaml(frame_spec_rc) }
12
+ let(:global_suite) { described_class.from_yaml(global_rc) }
13
+ let(:tangent_point_suite) { described_class.from_yaml(tangent_point_rc) }
14
+ let(:time_suite) { described_class.from_yaml(time_rc) }
15
+ let(:frame_spec_suite) { described_class.from_yaml(frame_spec_rc) }
16
16
 
17
17
  describe ".from_yaml" do
18
18
  it "parses a requirements class YAML file" do
@@ -32,45 +32,49 @@ RSpec.describe Modspec::Suite do
32
32
  it "returns no errors for a valid combined suite" do
33
33
  base_suite = described_class.from_yaml(rc_yaml)
34
34
  combined_suite = base_suite
35
- .combine(global_suite)
36
- .combine(tangent_point_suite)
37
- .combine(time_suite)
38
- .combine(frame_spec_suite)
35
+ .combine(global_suite)
36
+ .combine(tangent_point_suite)
37
+ .combine(time_suite)
38
+ .combine(frame_spec_suite)
39
39
 
40
40
  errors = combined_suite.validate
41
41
  if errors.any?
42
- puts "Validation errors:"
43
- errors.each { |error| puts " #{error}" }
42
+
43
+ errors.each { |error| }
44
44
  end
45
45
  expect(errors).to be_empty
46
46
  end
47
47
  end
48
48
 
49
49
  describe "#combine" do
50
- let(:suite1) { described_class.from_yaml(File.read("spec/fixtures/basic-ypr-rc.yaml")) }
51
- let(:suite2) { described_class.from_yaml(File.read("spec/fixtures/basic-quaternion-rc.yaml")) }
50
+ let(:suite1) do
51
+ described_class.from_yaml(File.read("spec/fixtures/basic-ypr-rc.yaml"))
52
+ end
53
+ let(:suite2) do
54
+ described_class.from_yaml(File.read("spec/fixtures/basic-quaternion-rc.yaml"))
55
+ end
52
56
 
53
57
  it "combines two suites" do
54
58
  combined_suite = suite1.combine(suite2)
55
59
  expect(combined_suite.name).to eq("#{suite1.name} + #{suite2.name}")
56
60
  expect(combined_suite.normative_statements_classes.count).to eq(
57
61
  suite1.normative_statements_classes.count +
58
- suite2.normative_statements_classes.count
62
+ suite2.normative_statements_classes.count,
59
63
  )
60
64
  end
61
65
 
62
66
  it "resolves conflicts when combining suites" do
63
67
  combined_suite = suite1
64
- .combine(suite2)
65
- .combine(global_suite)
66
- .combine(tangent_point_suite)
67
- .combine(time_suite)
68
- .combine(frame_spec_suite)
68
+ .combine(suite2)
69
+ .combine(global_suite)
70
+ .combine(tangent_point_suite)
71
+ .combine(time_suite)
72
+ .combine(frame_spec_suite)
69
73
 
70
74
  errors = combined_suite.validate
71
75
  if errors.any?
72
- puts "Validation errors:"
73
- errors.each { |error| puts " #{error}" }
76
+
77
+ errors.each { |error| }
74
78
  end
75
79
  expect(errors).to be_empty
76
80
  end
@@ -93,8 +97,8 @@ RSpec.describe Modspec::Suite do
93
97
  errors = combined_suite.validate
94
98
 
95
99
  if errors.any?
96
- puts "Validation errors:"
97
- errors.each { |error| puts " #{error}" }
100
+
101
+ errors.each { |error| }
98
102
  end
99
103
 
100
104
  # Check for specific error types
data/spec/modspec_spec.rb CHANGED
@@ -2,24 +2,24 @@
2
2
 
3
3
  RSpec.describe Modspec do
4
4
  it "has a version number" do
5
- expect(Modspec::VERSION).not_to be nil
5
+ expect(Modspec::VERSION).not_to be_nil
6
6
  end
7
7
 
8
8
  Dir.glob("spec/fixtures/*-rc.yaml").each do |file|
9
9
  it "parses normative statements class #{file}" do
10
- yaml = IO.read(file)
11
- Modspec::Suite.from_yaml(yaml)
10
+ source_yaml = File.read(file)
11
+ output_yaml = Modspec::Suite.from_yaml(source_yaml).to_yaml
12
12
 
13
- # TODO: tests
13
+ expect(output_yaml).to be_yaml_equivalent_to(source_yaml)
14
14
  end
15
15
  end
16
16
 
17
17
  Dir.glob("spec/fixtures/*-cc.yaml").each do |file|
18
18
  it "parses conformance class #{file}" do
19
- yaml = IO.read(file)
20
- Modspec::Suite.from_yaml(yaml)
19
+ source_yaml = File.read(file)
20
+ output_yaml = Modspec::Suite.from_yaml(source_yaml).to_yaml
21
21
 
22
- # TODO: tests
22
+ expect(output_yaml).to be_yaml_equivalent_to(source_yaml)
23
23
  end
24
24
  end
25
25
  end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "modspec"
4
4
  require "yaml"
5
+ require "canon"
5
6
 
6
7
  RSpec.configure do |config|
7
8
  # Enable flags like --only-failures and --next-failure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-28 00:00:00.000000000 Z
11
+ date: 2026-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: 0.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.7'
26
+ version: 0.8.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +65,7 @@ files:
65
65
  - ".rspec"
66
66
  - ".rubocop.yml"
67
67
  - ".rubocop_todo.yml"
68
+ - CLAUDE.md
68
69
  - CODE_OF_CONDUCT.md
69
70
  - Gemfile
70
71
  - README.adoc
@@ -137,6 +138,7 @@ metadata:
137
138
  homepage_uri: https://github.com/metanorma/modspec-ruby
138
139
  source_code_uri: https://github.com/metanorma/modspec-ruby
139
140
  bug_tracker_uri: https://github.com/metanorma/modspec-ruby/issues
141
+ rubygems_mfa_required: 'true'
140
142
  post_install_message:
141
143
  rdoc_options: []
142
144
  require_paths: