modspec 0.1.0 → 0.1.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/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +118 -0
- data/Gemfile +4 -2
- data/README.adoc +508 -17
- data/lib/modspec/conformance_class.rb +39 -10
- data/lib/modspec/conformance_test.rb +40 -13
- data/lib/modspec/identifier.rb +5 -3
- data/lib/modspec/normative_statement.rb +49 -14
- data/lib/modspec/normative_statements_class.rb +39 -12
- data/lib/modspec/suite.rb +242 -5
- data/lib/modspec/version.rb +1 -1
- data/lib/modspec.rb +14 -4
- data/modspec.gemspec +8 -14
- data/spec/conformance_class.liquid +98 -0
- data/spec/fixtures/advanced-cc.yaml +52 -0
- data/spec/fixtures/advanced-json-cc.yaml +24 -0
- data/spec/fixtures/advanced-json-rc.yaml +16 -0
- data/spec/fixtures/advanced-rc.yaml +43 -0
- data/spec/fixtures/basic-quaternion-cc.yaml +44 -0
- data/spec/fixtures/basic-quaternion-json-cc.yaml +24 -0
- data/spec/fixtures/basic-quaternion-json-rc.yaml +17 -0
- data/spec/fixtures/basic-quaternion-json-strict-cc.yaml +22 -0
- data/spec/fixtures/basic-quaternion-json-strict-rc.yaml +19 -0
- data/spec/fixtures/basic-quaternion-rc.yaml +34 -0
- data/spec/fixtures/basic-ypr-cc.yaml +39 -0
- data/spec/fixtures/basic-ypr-json-cc.yaml +23 -0
- data/spec/fixtures/basic-ypr-json-rc.yaml +21 -0
- data/spec/fixtures/basic-ypr-rc.yaml +32 -0
- data/spec/fixtures/chain-cc.yaml +50 -0
- data/spec/fixtures/chain-json-cc.yaml +24 -0
- data/spec/fixtures/chain-json-rc.yaml +20 -0
- data/spec/fixtures/chain-rc.yaml +36 -0
- data/spec/fixtures/frame-spec-cc.yaml +43 -0
- data/spec/fixtures/frame-spec-rc.yaml +27 -0
- data/spec/fixtures/global-cc.yaml +38 -0
- data/spec/fixtures/global-rc.yaml +23 -0
- data/spec/fixtures/graph-cc.yaml +48 -0
- data/spec/fixtures/graph-json-cc.yaml +24 -0
- data/spec/fixtures/graph-json-rc.yaml +20 -0
- data/spec/fixtures/graph-rc.yaml +38 -0
- data/spec/fixtures/series-irregular-cc.yaml +58 -0
- data/spec/fixtures/series-irregular-json-cc.yaml +24 -0
- data/spec/fixtures/series-irregular-json-rc.yaml +20 -0
- data/spec/fixtures/series-irregular-rc.yaml +41 -0
- data/spec/fixtures/series-regular-cc.yaml +63 -0
- data/spec/fixtures/series-regular-json-cc.yaml +24 -0
- data/spec/fixtures/series-regular-json-rc.yaml +20 -0
- data/spec/fixtures/series-regular-rc.yaml +46 -0
- data/spec/fixtures/stream-cc.yaml +49 -0
- data/spec/fixtures/stream-json-cc.yaml +48 -0
- data/spec/fixtures/stream-json-rc.yaml +32 -0
- data/spec/fixtures/stream-rc.yaml +36 -0
- data/spec/fixtures/tangent-point-cc.yaml +43 -0
- data/spec/fixtures/tangent-point-rc.yaml +38 -0
- data/spec/fixtures/time-cc.yaml +32 -0
- data/spec/fixtures/time-rc.yaml +20 -0
- data/spec/modspec/conformance_class_spec.rb +154 -0
- data/spec/modspec/conformance_test_spec.rb +76 -0
- data/spec/modspec/normative_statement_spec.rb +81 -0
- data/spec/modspec/normative_statements_class_spec.rb +61 -0
- data/spec/modspec/suite_spec.rb +109 -0
- data/spec/modspec_spec.rb +25 -0
- data/spec/requirements_class.liquid +93 -0
- data/spec/spec_helper.rb +16 -0
- metadata +71 -61
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
normative_statements_classes:
|
3
|
+
- name: JSON encoding of Stream SDUs
|
4
|
+
identifier: /req/stream-encoding-json
|
5
|
+
description: |
|
6
|
+
Requirements for the JSON encoding of Stream SDUs.
|
7
|
+
implements:
|
8
|
+
- /req/stream
|
9
|
+
|
10
|
+
normative_statements:
|
11
|
+
|
12
|
+
- name: Stream Element specification as JSON schema
|
13
|
+
identifier: /req/stream-encoding-json/element
|
14
|
+
statement: |
|
15
|
+
A JSON-encoded GeoPose Stream Element SHALL conform to the GeoPose Stream Element
|
16
|
+
JSON-Schema 2019-9 definition (<<streamelement_json_schema>>).
|
17
|
+
|
18
|
+
- name: Stream Header specification as JSON schema
|
19
|
+
identifier: /req/stream-encoding-json/header
|
20
|
+
statement: |
|
21
|
+
A JSON-encoded GeoPose Stream Element SHALL conform to the GeoPose Stream Header
|
22
|
+
JSON-Schema 2019-9 definition (<<streamheader_json_schema>>).
|
23
|
+
guidance:
|
24
|
+
- |
|
25
|
+
This JSON encoding is extensible because the JSON-Schema
|
26
|
+
"additionalProperties" property is set to the default value of *true*.
|
27
|
+
|
28
|
+
- name: Stream Record specification as JSON schema
|
29
|
+
identifier: /req/stream-encoding-json/record
|
30
|
+
statement: |
|
31
|
+
A JSON-encoded GeoPose Stream Record (a recorded Stream) SHALL conform to the GeoPose Stream Record
|
32
|
+
JSON-Schema 2019-9 definition (<<streamrecord_json_schema>>).
|
@@ -0,0 +1,36 @@
|
|
1
|
+
---
|
2
|
+
normative_statements_classes:
|
3
|
+
- name: StreamHeader and StreamElement logical model SDUs
|
4
|
+
identifier: /req/stream
|
5
|
+
description: |
|
6
|
+
The Stream target supports a network of object relative poses. The graph is a
|
7
|
+
directed acyclic graph, each node must either be an Extrinsic Frame or
|
8
|
+
reachable from an Extrinsic Frame.
|
9
|
+
|
10
|
+
dependencies:
|
11
|
+
- /req/global
|
12
|
+
- /req/frame-spec
|
13
|
+
|
14
|
+
normative_statements:
|
15
|
+
|
16
|
+
- name: Expression of outer frame in StreamHeader
|
17
|
+
identifier: /req/stream/header-initial-frame
|
18
|
+
statement: |
|
19
|
+
The `StreamHeader.outerFrame` attribute shall represent the initial frame
|
20
|
+
of the stream with a value that is an instant of the `ExplicitFrameSpec`
|
21
|
+
object.
|
22
|
+
|
23
|
+
- name: Expression of transition model in StreamHeader
|
24
|
+
identifier: /req/stream/header-transition-model
|
25
|
+
statement: |
|
26
|
+
The `StreamHeader.transitionModel` attribute shall have a value that is
|
27
|
+
an instance of the `TransitionModel` enumeration.
|
28
|
+
|
29
|
+
- name: Expression of stream elements in StreamElement
|
30
|
+
identifier: /req/stream/element
|
31
|
+
dependencies:
|
32
|
+
- /req/time/instant
|
33
|
+
statement: |
|
34
|
+
The `StreamElement.streamElement` attribute shall be implemented as an
|
35
|
+
array of `FrameAndTimeElement` objects, each of which is a pair of
|
36
|
+
`ExplicitFrameSpec` and `GeoPoseInstant` objects.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
---
|
2
|
+
conformance_classes:
|
3
|
+
- name: Tangent point conformance
|
4
|
+
identifier: /conf/tangent-point
|
5
|
+
target:
|
6
|
+
- /req/tangent-point
|
7
|
+
classification: "Target Type: SDU"
|
8
|
+
description: Conformance with tangent point requirements
|
9
|
+
|
10
|
+
tests:
|
11
|
+
- name: Verify tangent point height value meets specification
|
12
|
+
identifier: /conf/tangent-point/height
|
13
|
+
targets:
|
14
|
+
- /req/tangent-point/height
|
15
|
+
description: |
|
16
|
+
To confirm that a GeoPose `tangentPoint.h` attribute is expressed as a
|
17
|
+
height in meters above the WGS-84 ellipsoid and represented as a signed
|
18
|
+
real number.
|
19
|
+
purpose: |
|
20
|
+
Verify that this requirement is satisfied.
|
21
|
+
method: Inspection
|
22
|
+
|
23
|
+
- name: Verify tangent point latitude value meets specification
|
24
|
+
identifier: /conf/tangent-point/latitude
|
25
|
+
targets:
|
26
|
+
- /req/tangent-point/latitude
|
27
|
+
description: |
|
28
|
+
To confirm that a GeoPose `tangentPoint.latitude` attribute is expressed
|
29
|
+
as an angle in decimal degrees.
|
30
|
+
purpose: |
|
31
|
+
Verify that this requirement is satisfied
|
32
|
+
method: Inspection
|
33
|
+
|
34
|
+
- name: Verify tangent point longitude value meets specification
|
35
|
+
identifier: /conf/tangent-point/longitude
|
36
|
+
targets:
|
37
|
+
- /req/tangent-point/longitude
|
38
|
+
description: |
|
39
|
+
To confirm that a GeoPose `tangentPoint.longitude` attribute is expressed
|
40
|
+
as an angle in decimal degrees.
|
41
|
+
purpose: |
|
42
|
+
Verify that this requirement is satisfied
|
43
|
+
method: Inspection
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
normative_statements_classes:
|
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: |
|
8
|
+
The tangent plane `longitude`, `latitude`, and `h` parameters are
|
9
|
+
specified without any conditions or constraints on precision to be used in
|
10
|
+
an implementation. Any such constraints would be found as requirements on a
|
11
|
+
specific implementation as an encoding.
|
12
|
+
|
13
|
+
normative_statements:
|
14
|
+
|
15
|
+
- name: Tangent point height value specification
|
16
|
+
identifier: /req/tangent-point/height
|
17
|
+
statement: |
|
18
|
+
An instance of a GeoPose `tangentPoint.h` attribute SHALL be expressed as
|
19
|
+
a height in meters above the WGS-84 ellipsoid, represented as a signed as
|
20
|
+
a signed floating point value conforming to IEEE 754. If the tangent point
|
21
|
+
is above the WGS-84 ellipsoid, the value SHALL be positive. If the tangent
|
22
|
+
point is below the WGS-84 ellipsoid, the value SHALL be negative.
|
23
|
+
|
24
|
+
- name: Tangent point latitude value specification
|
25
|
+
identifier: /req/tangent-point/latitude
|
26
|
+
statement: |
|
27
|
+
An instance of GeoPose tangentPoint.latitude attribute SHALL be expressed
|
28
|
+
as decimal degrees and represented as a signed floating point
|
29
|
+
value conforming to IEEE 754.. The minimum value shall be 90.0 degrees
|
30
|
+
and the maximum value shall be 90.0 degrees.
|
31
|
+
|
32
|
+
- name: Tangent point longitude value specification
|
33
|
+
identifier: /req/tangent-point/longitude
|
34
|
+
statement: |
|
35
|
+
An instance of a GeoPose tangentPoint.longitude attribute SHALL be
|
36
|
+
expressed as decimal degrees and represented as a signed floating point
|
37
|
+
value conforming to IEEE 754. The minimum value shall be -180.0 degrees
|
38
|
+
and the maximum value shall be 180.0 degrees.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
conformance_classes:
|
3
|
+
- name: Time specification requirements
|
4
|
+
identifier: /conf/time
|
5
|
+
target:
|
6
|
+
- /req/time
|
7
|
+
description: Conformance with GeoPose time-related requirements
|
8
|
+
|
9
|
+
tests:
|
10
|
+
- name: Verify values of GeoPose_Instant
|
11
|
+
identifier: /conf/time/instant
|
12
|
+
targets:
|
13
|
+
- /req/time/instant
|
14
|
+
description: |
|
15
|
+
Verify that a `GeoPose_Instant` object expresses Unix time in seconds multiplied
|
16
|
+
by 1,000, with the unit of measure in milliseconds.
|
17
|
+
purpose: |
|
18
|
+
To confirm the correct properties of a GeoPose_Instant object.
|
19
|
+
method: Inspection
|
20
|
+
|
21
|
+
- name: Verify values of GeoPose_Duration
|
22
|
+
identifier: /conf/time/duration
|
23
|
+
targets:
|
24
|
+
- /req/time/duration
|
25
|
+
description: |
|
26
|
+
Verify that a `GeoPose_Duration` object expresses time in seconds multiplied
|
27
|
+
by 1,000, with the unit of measure in milliseconds.
|
28
|
+
purpose: |
|
29
|
+
To confirm that a FrameSpecification.id attribute contains a string
|
30
|
+
uniquely specifying the identity of a reference frame specification as
|
31
|
+
defined by that authority.
|
32
|
+
method: Inspection
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
normative_statements_classes:
|
3
|
+
- name: Time specification requirements
|
4
|
+
identifier: /req/time
|
5
|
+
description: |
|
6
|
+
Requirements on GeoPose time-related objects.
|
7
|
+
|
8
|
+
normative_statements:
|
9
|
+
|
10
|
+
- name: Implementation of GeoPose_Instant
|
11
|
+
identifier: /req/time/instant
|
12
|
+
statement: |
|
13
|
+
The `GeoPose_Instant` object shall express Unix Time in seconds multiplied
|
14
|
+
by 1,000, with the unit of measure in milliseconds.
|
15
|
+
|
16
|
+
- name: Implementation of GeoPose_Duration
|
17
|
+
identifier: /req/time/duration
|
18
|
+
statement: |
|
19
|
+
The `GeoPose_Duration` object shall express time in seconds multiplied by
|
20
|
+
1,000, with the unit of measure in milliseconds.
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Modspec::ConformanceClass do
|
4
|
+
let(:normative_statements_class) do
|
5
|
+
Modspec::NormativeStatementsClass.new(
|
6
|
+
identifier: "/req/basic-ypr",
|
7
|
+
name: "Basic-YPR logical model SDU",
|
8
|
+
description: "The Basic-YPR Target has a simple structure with no options.",
|
9
|
+
dependencies: ["/req/global", "/req/tangent-point"],
|
10
|
+
normative_statements: [
|
11
|
+
Modspec::NormativeStatement.new(
|
12
|
+
identifier: "/req/basic-ypr/position",
|
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."
|
15
|
+
),
|
16
|
+
Modspec::NormativeStatement.new(
|
17
|
+
identifier: "/req/basic-ypr/angles",
|
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
|
+
]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:conformance_class) do
|
26
|
+
Modspec::ConformanceClass.new(
|
27
|
+
identifier: "/conf/basic-ypr",
|
28
|
+
name: "Basic-YPR logical model SDU conformance",
|
29
|
+
target: ["/req/basic-ypr"],
|
30
|
+
classification: "Target Type: SDU",
|
31
|
+
description: "Conformance with Basic-YPR logical model SDU",
|
32
|
+
dependencies: ["/conf/global", "/conf/tangent-point"],
|
33
|
+
tests: [
|
34
|
+
Modspec::ConformanceTest.new(
|
35
|
+
identifier: "/conf/basic-ypr/position",
|
36
|
+
name: "Verify expression of outer frame",
|
37
|
+
targets: ["/req/basic-ypr/position"],
|
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
|
+
purpose: "Verify that this requirement is satisfied.",
|
40
|
+
method: "Inspection"
|
41
|
+
),
|
42
|
+
Modspec::ConformanceTest.new(
|
43
|
+
identifier: "/conf/basic-ypr/angles",
|
44
|
+
name: "Verify expression of inner frame",
|
45
|
+
targets: ["/req/basic-ypr/angles"],
|
46
|
+
description: "To confirm that the Inner Frame is expressed as a rotation-only transformation using Yaw, Pitch, and Roll angles.",
|
47
|
+
purpose: "Verify that this requirement is satisfied.",
|
48
|
+
method: "Inspection"
|
49
|
+
)
|
50
|
+
]
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:global_class) do
|
55
|
+
Modspec::NormativeStatementsClass.new(
|
56
|
+
identifier: "/req/global",
|
57
|
+
name: "Global requirements",
|
58
|
+
normative_statements: [
|
59
|
+
Modspec::NormativeStatement.new(
|
60
|
+
identifier: "/req/global/sdu",
|
61
|
+
name: "SDU conformance",
|
62
|
+
statement: "SDUs shall conform to the logical model."
|
63
|
+
)
|
64
|
+
]
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:tangent_point_class) do
|
69
|
+
Modspec::NormativeStatementsClass.new(
|
70
|
+
identifier: "/req/tangent-point",
|
71
|
+
name: "Tangent point requirements",
|
72
|
+
normative_statements: [
|
73
|
+
Modspec::NormativeStatement.new(
|
74
|
+
identifier: "/req/tangent-point/height",
|
75
|
+
name: "Tangent point height",
|
76
|
+
statement: "Tangent point height shall be specified."
|
77
|
+
)
|
78
|
+
]
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:global_conf_class) do
|
83
|
+
Modspec::ConformanceClass.new(
|
84
|
+
identifier: "/conf/global",
|
85
|
+
name: "Global conformance",
|
86
|
+
tests: [
|
87
|
+
Modspec::ConformanceTest.new(
|
88
|
+
identifier: "/conf/global/sdu",
|
89
|
+
name: "Verify SDU conformance",
|
90
|
+
targets: ["/req/global/sdu"],
|
91
|
+
description: "To confirm that an implementation of an SDU conforms to the logical model.",
|
92
|
+
purpose: "Verify that this requirement is satisfied.",
|
93
|
+
method: "Inspection"
|
94
|
+
)
|
95
|
+
]
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:tangent_point_conf_class) do
|
100
|
+
Modspec::ConformanceClass.new(
|
101
|
+
identifier: "/conf/tangent-point",
|
102
|
+
name: "Tangent point conformance",
|
103
|
+
tests: [
|
104
|
+
Modspec::ConformanceTest.new(
|
105
|
+
identifier: "/conf/tangent-point/height",
|
106
|
+
name: "Verify tangent point height",
|
107
|
+
targets: ["/req/tangent-point/height"],
|
108
|
+
description: "To confirm that an implementation of a Tangent Point specifies the height of the Tangent Point.",
|
109
|
+
purpose: "Verify that this requirement is satisfied.",
|
110
|
+
method: "Inspection"
|
111
|
+
)
|
112
|
+
|
113
|
+
]
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
let(:suite) do
|
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]
|
121
|
+
suite.setup_relationships
|
122
|
+
suite
|
123
|
+
end
|
124
|
+
|
125
|
+
it "has an identifier" do
|
126
|
+
expect(conformance_class.identifier).to eq("/conf/basic-ypr")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "has a name" do
|
130
|
+
expect(conformance_class.name).to eq("Basic-YPR logical model SDU conformance")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "has conformance tests" do
|
134
|
+
expect(conformance_class.tests).not_to be_empty
|
135
|
+
expect(conformance_class.tests.length).to eq(2)
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#validate" do
|
139
|
+
it "returns no errors for a valid conformance class" do
|
140
|
+
errors = suite.validate
|
141
|
+
if errors.any?
|
142
|
+
puts "Validation errors:"
|
143
|
+
errors.each { |error| puts " #{error}" }
|
144
|
+
end
|
145
|
+
expect(errors).to be_empty
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns errors if there are no conformance tests" do
|
149
|
+
conformance_class.tests = []
|
150
|
+
errors = conformance_class.validate
|
151
|
+
expect(errors).not_to be_empty
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Modspec::ConformanceTest do
|
4
|
+
let(:normative_statement) do
|
5
|
+
Modspec::NormativeStatement.new(
|
6
|
+
identifier: "/req/basic-ypr/position",
|
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."
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:normative_statements_class) do
|
13
|
+
Modspec::NormativeStatementsClass.new(
|
14
|
+
identifier: "/req/basic-ypr",
|
15
|
+
name: "Basic-YPR logical model SDU",
|
16
|
+
normative_statements: [normative_statement]
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:conformance_test) do
|
21
|
+
Modspec::ConformanceTest.new(
|
22
|
+
identifier: "/conf/basic-ypr/position",
|
23
|
+
name: "Verify expression of outer frame",
|
24
|
+
targets: ["/req/basic-ypr/position"],
|
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
|
+
purpose: "Verify that this requirement is satisfied.",
|
27
|
+
method: "Inspection"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:conformance_class) do
|
32
|
+
Modspec::ConformanceClass.new(
|
33
|
+
identifier: "/conf/basic-ypr",
|
34
|
+
name: "Basic-YPR logical model SDU conformance",
|
35
|
+
tests: [conformance_test]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:suite) do
|
40
|
+
suite = Modspec::Suite.new
|
41
|
+
suite.normative_statements_classes = [normative_statements_class]
|
42
|
+
suite.conformance_classes = [conformance_class]
|
43
|
+
suite.setup_relationships
|
44
|
+
suite
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
suite # Ensure the suite is created and relationships are set up
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has an identifier" do
|
52
|
+
expect(conformance_test.identifier).to eq("/conf/basic-ypr/position")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has a description" do
|
56
|
+
expect(conformance_test.description).not_to be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has targets" do
|
60
|
+
expect(conformance_test.targets).to eq(["/req/basic-ypr/position"])
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#validate" do
|
64
|
+
it "returns no errors for a valid conformance test" do
|
65
|
+
errors = conformance_test.validate
|
66
|
+
expect(errors).to be_empty
|
67
|
+
end
|
68
|
+
end
|
69
|
+
it "has a corresponding requirement" do
|
70
|
+
expect(conformance_test.corresponding_requirements).to include(normative_statement)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "belongs to a conformance class" do
|
74
|
+
expect(conformance_test.parent_class).to eq(conformance_class)
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Modspec::NormativeStatement do
|
4
|
+
let(:global_sdu_statement) do
|
5
|
+
Modspec::NormativeStatement.new(
|
6
|
+
identifier: "/req/global/sdu",
|
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."
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:tangent_point_statement) do
|
13
|
+
Modspec::NormativeStatement.new(
|
14
|
+
identifier: "/req/tangent-point",
|
15
|
+
name: "Tangent point requirements",
|
16
|
+
statement: "Common tangent point requirements for SDUs that include tangent points."
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:normative_statement) do
|
21
|
+
Modspec::NormativeStatement.new(
|
22
|
+
identifier: "/req/basic-ypr/position",
|
23
|
+
name: "Expression of outer frame",
|
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.",
|
25
|
+
obligation: "requirement",
|
26
|
+
subject: "Basic_YPR.position",
|
27
|
+
inherit: ["/req/global/sdu"],
|
28
|
+
dependencies: ["/req/tangent-point"],
|
29
|
+
guidance: ["Ensure the coordinate system is correctly specified."]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:suite) do
|
34
|
+
suite = Modspec::Suite.new
|
35
|
+
global_class = Modspec::NormativeStatementsClass.new(
|
36
|
+
identifier: "/req/global",
|
37
|
+
normative_statements: [global_sdu_statement]
|
38
|
+
)
|
39
|
+
tangent_point_class = Modspec::NormativeStatementsClass.new(
|
40
|
+
identifier: "/req/tangent-point",
|
41
|
+
normative_statements: [tangent_point_statement]
|
42
|
+
)
|
43
|
+
basic_ypr_class = Modspec::NormativeStatementsClass.new(
|
44
|
+
identifier: "/req/basic-ypr",
|
45
|
+
normative_statements: [normative_statement]
|
46
|
+
)
|
47
|
+
suite.normative_statements_classes = [global_class, tangent_point_class, basic_ypr_class]
|
48
|
+
suite
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has an identifier" do
|
52
|
+
expect(normative_statement.identifier).to eq("/req/basic-ypr/position")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has a name" do
|
56
|
+
expect(normative_statement.name).to eq("Expression of outer frame")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has a statement" do
|
60
|
+
expect(normative_statement.statement).not_to be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "has a valid obligation" do
|
64
|
+
expect(%w[requirement recommendation permission]).to include(normative_statement.obligation)
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#validate" do
|
68
|
+
it "returns no errors for a valid normative statement" do
|
69
|
+
errors = normative_statement.validate
|
70
|
+
expect(errors).to be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns errors for an invalid obligation" do
|
74
|
+
normative_statement.obligation = "invalid"
|
75
|
+
expect { normative_statement.validate! }.to raise_error(Lutaml::Model::ValidationError) do |error|
|
76
|
+
expect(error).to include(Lutaml::Model::InvalidValueError)
|
77
|
+
expect(error.error_messages).to include("obligation is `invalid`, must be one of the following [recommendation, permission, requirement]")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Modspec::NormativeStatementsClass do
|
4
|
+
let(:normative_statement1) do
|
5
|
+
Modspec::NormativeStatement.new(
|
6
|
+
identifier: "/req/basic-ypr/position",
|
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."
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:normative_statement2) do
|
13
|
+
Modspec::NormativeStatement.new(
|
14
|
+
identifier: "/req/basic-ypr/angles",
|
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."
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:normative_statements_class) do
|
21
|
+
Modspec::NormativeStatementsClass.new(
|
22
|
+
identifier: "/req/basic-ypr",
|
23
|
+
name: "Basic-YPR logical model SDU",
|
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
|
+
dependencies: ["/req/global", "/req/tangent-point"],
|
26
|
+
normative_statements: [normative_statement1, normative_statement2]
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:suite) do
|
31
|
+
suite = Modspec::Suite.new
|
32
|
+
suite.normative_statements_classes = [normative_statements_class]
|
33
|
+
suite
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has an identifier" do
|
37
|
+
expect(normative_statements_class.identifier).to eq("/req/basic-ypr")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has a name" do
|
41
|
+
expect(normative_statements_class.name).to eq("Basic-YPR logical model SDU")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has normative statements" do
|
45
|
+
expect(normative_statements_class.normative_statements).not_to be_empty
|
46
|
+
expect(normative_statements_class.normative_statements.length).to eq(2)
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#validate" do
|
50
|
+
it "returns no errors for a valid normative statements class" do
|
51
|
+
errors = normative_statements_class.validate
|
52
|
+
expect(errors).to be_empty
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns errors if there are no normative statements" do
|
56
|
+
normative_statements_class.normative_statements = []
|
57
|
+
errors = normative_statements_class.validate
|
58
|
+
expect(errors).not_to be_empty
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|