modspec 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +67 -57
@@ -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
|