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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0808f57d0576986304dbf6cdb9e0b6d857518ad36913ad7562ca4eb6efa80db
|
4
|
+
data.tar.gz: 69ffc24df78d574268e1825e6be0d18fc892feea45bd264d1fa1f6251cd16a3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82eb97709de2f051afa526e12d8f0458be26fc9dbd691ef36298a6cea5943749018e3df1a0426e94123fbbd9796fa59814b87371cf062efaa5b617cd2772186c
|
7
|
+
data.tar.gz: f93557afe166d056ab41149bf870bd76f8a2fbb51ffcbd6a3ef7c98dc4567800d9499d109fd31f4d6272bf31de803d77590def8c75e438f9bcb8cd7d9cc65e39
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2024-09-11 00:07:51 UTC using RuboCop version 1.66.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
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
|
+
# Offense count: 1
|
18
|
+
# Configuration parameters: Severity, Include.
|
19
|
+
# Include: **/*.gemspec
|
20
|
+
Gemspec/RequiredRubyVersion:
|
21
|
+
Exclude:
|
22
|
+
- 'modspec.gemspec'
|
23
|
+
|
24
|
+
# Offense count: 10
|
25
|
+
# This cop supports safe autocorrection (--autocorrect).
|
26
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
27
|
+
# SupportedStyles: aligned, indented, indented_relative_to_receiver
|
28
|
+
Layout/MultilineMethodCallIndentation:
|
29
|
+
Exclude:
|
30
|
+
- 'modspec.gemspec'
|
31
|
+
- 'spec/modspec/suite_spec.rb'
|
32
|
+
|
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
|
+
# Offense count: 1
|
45
|
+
# Configuration parameters: CountComments, CountAsOne.
|
46
|
+
Metrics/ClassLength:
|
47
|
+
Max: 204
|
48
|
+
|
49
|
+
# 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
|
58
|
+
|
59
|
+
# Offense count: 1
|
60
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
61
|
+
Metrics/PerceivedComplexity:
|
62
|
+
Max: 12
|
63
|
+
|
64
|
+
# Offense count: 1
|
65
|
+
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros.
|
66
|
+
# NamePrefix: is_, has_, have_
|
67
|
+
# ForbiddenPrefixes: is_, has_, have_
|
68
|
+
# AllowedMethods: is_a?
|
69
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
70
|
+
Naming/PredicateName:
|
71
|
+
Exclude:
|
72
|
+
- 'spec/**/*'
|
73
|
+
- 'lib/modspec/normative_statement.rb'
|
74
|
+
|
75
|
+
# Offense count: 6
|
76
|
+
# Configuration parameters: AllowedConstants.
|
77
|
+
Style/Documentation:
|
78
|
+
Exclude:
|
79
|
+
- 'spec/**/*'
|
80
|
+
- 'test/**/*'
|
81
|
+
- 'lib/modspec/conformance_class.rb'
|
82
|
+
- 'lib/modspec/conformance_test.rb'
|
83
|
+
- 'lib/modspec/normative_statement.rb'
|
84
|
+
- 'lib/modspec/normative_statements_class.rb'
|
85
|
+
- 'lib/modspec/suite.rb'
|
86
|
+
|
87
|
+
# Offense count: 2
|
88
|
+
# This cop supports safe autocorrection (--autocorrect).
|
89
|
+
Style/IfUnlessModifier:
|
90
|
+
Exclude:
|
91
|
+
- 'lib/modspec/conformance_class.rb'
|
92
|
+
- 'lib/modspec/normative_statements_class.rb'
|
93
|
+
|
94
|
+
# Offense count: 27
|
95
|
+
# This cop supports safe autocorrection (--autocorrect).
|
96
|
+
# Configuration parameters: EnforcedStyleForMultiline.
|
97
|
+
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
98
|
+
Style/TrailingCommaInArguments:
|
99
|
+
Exclude:
|
100
|
+
- 'spec/modspec/conformance_class_spec.rb'
|
101
|
+
- 'spec/modspec/conformance_test_spec.rb'
|
102
|
+
- 'spec/modspec/normative_statement_spec.rb'
|
103
|
+
- 'spec/modspec/normative_statements_class_spec.rb'
|
104
|
+
|
105
|
+
# Offense count: 6
|
106
|
+
# This cop supports safe autocorrection (--autocorrect).
|
107
|
+
# Configuration parameters: EnforcedStyleForMultiline.
|
108
|
+
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
109
|
+
Style/TrailingCommaInArrayLiteral:
|
110
|
+
Exclude:
|
111
|
+
- 'spec/modspec/conformance_class_spec.rb'
|
112
|
+
|
113
|
+
# Offense count: 13
|
114
|
+
# This cop supports safe autocorrection (--autocorrect).
|
115
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
116
|
+
# URISchemes: http, https
|
117
|
+
Layout/LineLength:
|
118
|
+
Max: 247
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
@@ -2,44 +2,535 @@
|
|
2
2
|
|
3
3
|
== Purpose
|
4
4
|
|
5
|
-
The `modspec` Ruby
|
5
|
+
The `modspec` Ruby library allows you to work with OGC ModSpec instances
|
6
|
+
and export/load them from/to YAML.
|
6
7
|
|
7
|
-
|
8
|
+
OGC ModSpec is a specification for specifying requirements and conformance tests
|
9
|
+
for standards, described in OGC 08-131r3.
|
8
10
|
|
11
|
+
== Features
|
9
12
|
|
10
|
-
|
13
|
+
This library allows you to:
|
11
14
|
|
12
|
-
|
15
|
+
* Create and manipulate ModSpec instances:
|
16
|
+
** normative statements
|
17
|
+
** conformance tests
|
18
|
+
** normative statements classes
|
19
|
+
** conformance classes
|
20
|
+
** unified ModSpec suite
|
13
21
|
|
14
|
-
|
22
|
+
* Load and save objects from/to YAML
|
23
|
+
* Perform validations on ModSpec instances
|
24
|
+
* Combine ModSpec suites
|
25
|
+
|
26
|
+
|
27
|
+
== Installation
|
28
|
+
|
29
|
+
Add this line to your application's Gemfile:
|
15
30
|
|
16
31
|
[source,ruby]
|
17
32
|
----
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
33
|
+
gem 'modspec'
|
34
|
+
----
|
35
|
+
|
36
|
+
Then execute:
|
37
|
+
|
38
|
+
[source,shell]
|
39
|
+
----
|
40
|
+
$ bundle install
|
41
|
+
----
|
42
|
+
|
43
|
+
Or install it yourself:
|
44
|
+
|
45
|
+
[source,shell]
|
46
|
+
----
|
47
|
+
$ gem install modspec
|
48
|
+
----
|
49
|
+
|
50
|
+
== Basics
|
51
|
+
|
52
|
+
ModSpec instances all have the following core attributes:
|
53
|
+
|
54
|
+
`identifier`:: A unique identifier for the instance, as a URI.
|
55
|
+
|
56
|
+
** The pattern for a ModSpec class is `/<type>/<class>`, where
|
57
|
+
*** `<type>` is the type of the instance (`req` for normative statement, `conf` for conformance test)
|
58
|
+
*** `<class>` is the name of the class (normative statements class or conformance class)
|
59
|
+
|
60
|
+
** The pattern for a normative statement or conformance test is `/<type>/<class>/<name>`, where
|
61
|
+
|
62
|
+
*** `<type>` is the type of the instance (`req` for normative statement, `conf` for conformance test)
|
63
|
+
*** `<class>` is the name of the class (normative statements class or conformance class)
|
64
|
+
*** `<name>` is the name of the instance
|
65
|
+
|
66
|
+
`name`::
|
67
|
+
A human-readable name for the instance
|
68
|
+
|
69
|
+
`description`::
|
70
|
+
A description of the instance
|
71
|
+
|
72
|
+
`guidance`::
|
73
|
+
Guidance on how to implement the instance
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
== Usage
|
78
|
+
|
79
|
+
=== Normative statements class
|
80
|
+
|
81
|
+
A normative statements class groups related normative statements.
|
82
|
+
|
83
|
+
A normative statements class has the following attributes in addition to the core attributes:
|
84
|
+
|
85
|
+
`subject`::
|
86
|
+
The subject of the normative statements class
|
87
|
+
|
88
|
+
`dependencies`::
|
89
|
+
URI(s) of normative statement classes that this class depends on
|
90
|
+
|
91
|
+
`normative_statements`::
|
92
|
+
A list of normative statements that belong to this class
|
93
|
+
|
94
|
+
`belongs_to`::
|
95
|
+
The normative statements class that this class belongs to
|
96
|
+
|
97
|
+
`reference`::
|
98
|
+
A reference to an external document or resource
|
99
|
+
|
100
|
+
`source`::
|
101
|
+
The source of the normative statements class
|
102
|
+
|
103
|
+
|
104
|
+
.Working with normative statements classes
|
105
|
+
[example]
|
106
|
+
====
|
107
|
+
[source,ruby]
|
108
|
+
----
|
109
|
+
normative_statements_class = Modspec::NormativeStatementsClass.new(
|
110
|
+
identifier: "/req/example",
|
111
|
+
name: "Requirements class",
|
112
|
+
dependencies: ["/req/baf"],
|
113
|
+
normative_statements: [normative_statement]
|
114
|
+
)
|
22
115
|
----
|
23
116
|
|
117
|
+
[source,ruby]
|
118
|
+
----
|
119
|
+
normative_statements_class.to_yaml
|
120
|
+
----
|
121
|
+
|
122
|
+
[source,yaml]
|
123
|
+
----
|
124
|
+
identifier: "/req/example"
|
125
|
+
name: "Requirements class"
|
126
|
+
dependencies:
|
127
|
+
- "/req/baf"
|
128
|
+
normative_statements:
|
129
|
+
- identifier: "/req/example/foo"
|
130
|
+
name: "Example requirement"
|
131
|
+
statement: "This is an example requirement."
|
132
|
+
dependencies:
|
133
|
+
- "/req/bar"
|
134
|
+
- "/req/baz/2"
|
135
|
+
----
|
24
136
|
|
25
137
|
[source,ruby]
|
26
138
|
----
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
139
|
+
> yaml = IO.read('example.yaml')
|
140
|
+
> normative_statements_class = Modspec::NormativeStatementsClass.from_yaml(yaml)
|
141
|
+
> <#Modspec::NormativeStatementsClass:0x00007f8b1b8b3d08 @identifier="/req/example", @name="Requirements class", @dependencies=["/req/baf"], @normative_statements=[<#Modspec::NormativeStatement:0x00007f8b1b8b3d08 @identifier="/req/example/foo", @name="Example requirement", @statement="This is an example requirement.", @dependencies=["/req/bar", "/req/baz/2"]>]>
|
142
|
+
> normative_statements_class.name
|
143
|
+
> "Requirements class"
|
144
|
+
----
|
145
|
+
====
|
146
|
+
|
147
|
+
Validations:
|
148
|
+
|
149
|
+
* *Identifier prefix*: All normative statements within a normative statements
|
150
|
+
class must share the same identifier prefix as the class itself, followed by a
|
151
|
+
slash and then the statement's own identifier.
|
152
|
+
|
153
|
+
|
154
|
+
=== Normative statement
|
155
|
+
|
156
|
+
A normative statement represents a single requirement in the specification.
|
157
|
+
|
158
|
+
A normative statement has the following attributes in addition to the core attributes:
|
159
|
+
|
160
|
+
`subject`::
|
161
|
+
The subject of the normative statement
|
162
|
+
|
163
|
+
`obligation`::
|
164
|
+
The obligation level of the class, one of `requirement`, `recommendation`, `permission`. Defaults to `requirement`.
|
165
|
+
|
166
|
+
`statement`::
|
167
|
+
The text of the normative statement
|
168
|
+
|
169
|
+
`condition`::
|
170
|
+
Conditions that must be met for the statement to apply
|
171
|
+
|
172
|
+
`inherit`::
|
173
|
+
URI(s) of normative statement(s) that this statement inherits from
|
174
|
+
|
175
|
+
`indirect_dependency`::
|
176
|
+
URI(s) of normative statement(s) that this statement indirectly depends on
|
177
|
+
|
178
|
+
`implements`::
|
179
|
+
The higher-level normative statement that this statement implements
|
180
|
+
|
181
|
+
`dependencies`::
|
182
|
+
A list of identifiers for other normative statements that this statement depends on.
|
183
|
+
|
184
|
+
`belongs_to`::
|
185
|
+
The normative statements class that this statement belongs to.
|
186
|
+
|
187
|
+
`reference`::
|
188
|
+
A reference to an external document or resource
|
189
|
+
|
190
|
+
`parts`::
|
191
|
+
A list of normative statements classes that this class is composed
|
192
|
+
|
193
|
+
|
194
|
+
.Working with normative statements
|
195
|
+
[example]
|
196
|
+
====
|
197
|
+
[source,ruby]
|
198
|
+
----
|
199
|
+
normative_statement = Modspec::NormativeStatement.new(
|
200
|
+
identifier: "/req/example/foo",
|
201
|
+
name: "Example requirement",
|
202
|
+
statement: "This is an example requirement statement.",
|
203
|
+
obligation: "requirement", # default
|
204
|
+
parts: [
|
205
|
+
"This is a part of the requirement.",
|
206
|
+
"This is another part of the requirement."
|
207
|
+
]
|
208
|
+
dependencies: ["/req/bar", "/req/baz/2"]
|
209
|
+
)
|
210
|
+
----
|
211
|
+
|
212
|
+
[source,ruby]
|
213
|
+
----
|
214
|
+
normative_statement.to_yaml
|
215
|
+
----
|
216
|
+
|
217
|
+
Will give out:
|
218
|
+
|
219
|
+
[source,yaml]
|
220
|
+
----
|
221
|
+
identifier: /req/example/foo
|
222
|
+
name: Example requirement
|
223
|
+
statement: This is an example requirement statement.
|
224
|
+
dependencies:
|
225
|
+
- /req/bar
|
226
|
+
- /req/baz/2
|
227
|
+
----
|
228
|
+
|
229
|
+
And to load a normative statement from a YAML file:
|
230
|
+
|
231
|
+
[source,ruby]
|
232
|
+
----
|
233
|
+
> yaml = IO.read('example-foo.yaml')
|
234
|
+
> normative_statement = Modspec::NormativeStatement.from_yaml(yaml)
|
235
|
+
> <#Modspec::NormativeStatement:0x00007f8b1b8b3d08 @identifier="/req/example/foo", @name="Example requirement", @statement="This is an example requirement statement.", @dependencies=["/req/bar", "/req/baz/2"]>
|
236
|
+
> normative_statement.name
|
237
|
+
> "Example requirement"
|
238
|
+
----
|
239
|
+
====
|
240
|
+
|
241
|
+
|
242
|
+
Validations:
|
243
|
+
|
244
|
+
* *Unique identifier*: Each normative statement must have a unique identifier
|
245
|
+
within its parent normative statements class.
|
246
|
+
|
247
|
+
* *Valid dependencies*: The dependencies listed for a normative statement must
|
248
|
+
refer to valid identifiers of other normative statements.
|
249
|
+
|
250
|
+
|
251
|
+
=== Conformance class
|
252
|
+
|
253
|
+
A conformance class groups related conformance tests.
|
254
|
+
|
255
|
+
A conformance class has the following attributes in addition to the core attributes:
|
256
|
+
|
257
|
+
`tests`::
|
258
|
+
A set of conformance tests that belong to this class
|
259
|
+
|
260
|
+
`classification`::
|
261
|
+
A classification of the conformance class
|
262
|
+
|
263
|
+
`dependencies`::
|
264
|
+
A list of identifiers for other conformance classes that this class depends on
|
265
|
+
|
266
|
+
`target`::
|
267
|
+
A list of identifiers of normative statement(s) that this class targets
|
268
|
+
|
269
|
+
`belongs_to`::
|
270
|
+
A conformance class that this class belongs to
|
271
|
+
|
272
|
+
`reference`::
|
273
|
+
A reference to an external document or resource
|
274
|
+
|
275
|
+
|
276
|
+
.Working with conformance classes
|
277
|
+
[example]
|
278
|
+
====
|
279
|
+
[source,ruby]
|
280
|
+
----
|
281
|
+
conformance_class = Modspec::ConformanceClass.new(
|
282
|
+
identifier: "/conf/example",
|
283
|
+
name: "Conformance class",
|
284
|
+
tests: [conformance_test]
|
285
|
+
)
|
286
|
+
conformance_class.to_yaml
|
287
|
+
----
|
288
|
+
|
289
|
+
[source,yaml]
|
290
|
+
----
|
291
|
+
identifier: "/conf/example"
|
292
|
+
name: "Conformance class"
|
293
|
+
tests:
|
294
|
+
- identifier: "/conf/example/foo"
|
295
|
+
name: "Example test"
|
296
|
+
description: "This is an example conformance test."
|
297
|
+
targets:
|
298
|
+
- "/req/example/foo"
|
299
|
+
----
|
300
|
+
|
301
|
+
[source,ruby]
|
302
|
+
----
|
303
|
+
> yaml = IO.read('example.yaml')
|
304
|
+
> conformance_class = Modspec::ConformanceClass.from_yaml(yaml)
|
305
|
+
> <#Modspec::ConformanceClass:0x00007f8b1b8b3d08 @identifier="/conf/example", @name="Conformance class", @tests=[<#Modspec::ConformanceTest:0x00007f8b1b8b3d08 @identifier="/conf/example/foo", @name="Example test", @description="This is an example conformance test.", @targets=["/req/example/foo"]>], @abstract=false>
|
306
|
+
> conformance_class.name
|
307
|
+
> "Conformance class"
|
308
|
+
----
|
309
|
+
====
|
310
|
+
|
311
|
+
|
312
|
+
Validations:
|
313
|
+
|
314
|
+
* *Identifier prefix*: All conformance tests within a conformance class must
|
315
|
+
share the same identifier prefix as the class itself, followed by a slash and
|
316
|
+
then the test's own identifier.
|
317
|
+
|
318
|
+
* *Valid targets*: The targets listed for a conformance test must refer to valid
|
319
|
+
identifiers of existing normative statements.
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
=== Conformance test
|
324
|
+
|
325
|
+
A conformance test verifies compliance with one or more normative statements.
|
326
|
+
|
327
|
+
A conformance test has the following attributes in addition to the core attributes:
|
328
|
+
|
329
|
+
`targets`::
|
330
|
+
A list of identifiers for normative statements that this test targets
|
331
|
+
|
332
|
+
`belongs_to`::
|
333
|
+
The conformance class that this test belongs to
|
334
|
+
|
335
|
+
`guidance`::
|
336
|
+
Guidance on how to perform the test
|
337
|
+
|
338
|
+
`purpose`::
|
339
|
+
The purpose of the test
|
340
|
+
|
341
|
+
`method`::
|
342
|
+
The method used to perform the test
|
343
|
+
|
344
|
+
`type`::
|
345
|
+
The type of the test
|
346
|
+
|
347
|
+
`reference`::
|
348
|
+
A reference to an external document or resource
|
349
|
+
|
350
|
+
`abstract`::
|
351
|
+
A boolean indicating whether this test is abstract
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
.Working with conformance tests
|
356
|
+
[example]
|
357
|
+
====
|
358
|
+
[source,ruby]
|
359
|
+
----
|
360
|
+
conformance_test = Modspec::ConformanceTest.new(
|
361
|
+
identifier: "/conf/example/foo",
|
362
|
+
name: "Example test",
|
363
|
+
description: "This is an example conformance test.",
|
364
|
+
targets: ["/req/example/foo"],
|
365
|
+
test_method: "manual",
|
366
|
+
abstract: false
|
367
|
+
)
|
368
|
+
conformance_test.to_yaml
|
31
369
|
----
|
32
370
|
|
371
|
+
[source,yaml]
|
372
|
+
----
|
373
|
+
identifier: "/conf/example/foo"
|
374
|
+
name: "Example test"
|
375
|
+
description: "This is an example conformance test."
|
376
|
+
abstract: false
|
377
|
+
test_method: "manual"
|
378
|
+
targets:
|
379
|
+
- "/req/example/foo"
|
380
|
+
----
|
381
|
+
|
382
|
+
[source,ruby]
|
383
|
+
----
|
384
|
+
> yaml = IO.read('example.yaml')
|
385
|
+
> conformance_test = Modspec::ConformanceTest.from_yaml(yaml)
|
386
|
+
> <#Modspec::ConformanceTest:0x00007f8b1b8b3d08 @identifier="/conf/example/foo", @name="Example test", @description="This is an example conformance test.", @targets=["/req/example/foo"], @test_method="manual", @abstract=false>
|
387
|
+
> conformance_test.name
|
388
|
+
> "Example test"
|
389
|
+
----
|
390
|
+
====
|
391
|
+
|
392
|
+
|
393
|
+
Validations:
|
394
|
+
|
395
|
+
* *Valid targets*: The targets listed for a conformance test must refer to valid
|
396
|
+
identifiers of existing normative statements.
|
397
|
+
|
398
|
+
|
399
|
+
=== Suite
|
400
|
+
|
401
|
+
A suite represents the entire specification, including all normative statements
|
402
|
+
and conformance tests.
|
403
|
+
|
404
|
+
NOTE: This is not defined in the ModSpec specification.
|
405
|
+
|
406
|
+
.Working with suites
|
407
|
+
[example]
|
408
|
+
====
|
409
|
+
[source,ruby]
|
410
|
+
----
|
411
|
+
suite = Modspec::Suite.new(
|
412
|
+
identifier: "example-suite",
|
413
|
+
name: "Example suite",
|
414
|
+
normative_statements_classes: [normative_statements_class],
|
415
|
+
conformance_classes: [conformance_class]
|
416
|
+
)
|
417
|
+
suite.to_yaml
|
418
|
+
----
|
419
|
+
|
420
|
+
[source,yaml]
|
421
|
+
----
|
422
|
+
identifier: "example-suite"
|
423
|
+
name: "Example suite"
|
424
|
+
normative_statements_classes:
|
425
|
+
- identifier: "/req/example"
|
426
|
+
name: "Requirements class"
|
427
|
+
normative_statements:
|
428
|
+
- identifier: "/req/example/foo"
|
429
|
+
name: "Example requirement"
|
430
|
+
statement: "This is an example requirement statement."
|
431
|
+
dependencies:
|
432
|
+
- "/req/bar"
|
433
|
+
- "/req/baz/2"
|
434
|
+
conformance_classes:
|
435
|
+
- identifier: "/conf/example"
|
436
|
+
name: "Conformance class"
|
437
|
+
tests:
|
438
|
+
- identifier: "/conf/example/foo"
|
439
|
+
name: "Example test"
|
440
|
+
description: "This is an example conformance test."
|
441
|
+
targets:
|
442
|
+
- "/req/example/foo"
|
443
|
+
----
|
444
|
+
|
445
|
+
[source,ruby]
|
446
|
+
----
|
447
|
+
> yaml = IO.read('example-suite.yaml')
|
448
|
+
> suite = Modspec::Suite.from_yaml(yaml)
|
449
|
+
> <#Modspec::Suite:0x00007f8b1b8b3d08 @identifier="example-suite", @name="Example suite", @normative_statements_classes=[<#Modspec::NormativeStatementsClass:0x00007f8b1b8b3d08 @identifier="/req/example", @name="Requirements class", @dependencies=["/req/baf"], @normative_statements=[<#Modspec::NormativeStatement:0x00007f8b1b8b3d08 @identifier="/req/example/foo", @name="Example requirement", @statement="This is an example requirement statement.", @dependencies=["/req/bar", "/req/baz/2"]>]>], @conformance_classes=[<#Modspec::ConformanceClass:0x00007f8b1b8b3d08 @identifier="/conf/example", @name="Conformance class", @tests=[<#Modspec::ConformanceTest:0x00007f8b1b8b3d08 @identifier="/conf/example/foo", @name="Example test", @description="This is an example conformance test.", @targets=["/req/example/foo"]>], @abstract=false>]>
|
450
|
+
> suite.normative_statements_classes.first.name
|
451
|
+
> "Requirements class"
|
452
|
+
----
|
453
|
+
====
|
454
|
+
|
455
|
+
Validations:
|
456
|
+
|
457
|
+
* *No cyclic dependencies*: The suite ensures that there are no circular
|
458
|
+
dependencies among normative statements.
|
459
|
+
|
460
|
+
* *Label uniqueness*: Labels must be unique across all classes within the suite.
|
461
|
+
|
462
|
+
* *Dependency validation*: The suite verifies that all dependencies between
|
463
|
+
normative statements and conformance tests are valid and refer to existing
|
464
|
+
elements.
|
465
|
+
|
466
|
+
|
467
|
+
The Suite class provides a `from_yaml_files` method to load a Suite instance
|
468
|
+
from multiple YAML files. This is particularly useful when your specification is
|
469
|
+
split across several files for better organization and maintainability.
|
470
|
+
|
471
|
+
To load a Suite from multiple YAML files:
|
33
472
|
|
34
473
|
[source,ruby]
|
35
474
|
----
|
36
475
|
require 'modspec'
|
37
|
-
|
38
|
-
|
39
|
-
|
476
|
+
|
477
|
+
# Specify the paths to your YAML files
|
478
|
+
yaml_files = [
|
479
|
+
'path/to/normative_statements.yaml',
|
480
|
+
'path/to/conformance_tests.yaml'
|
481
|
+
]
|
482
|
+
|
483
|
+
# Create a Suite instance from the YAML files
|
484
|
+
suite = Modspec::Suite.from_yaml_files(yaml_files)
|
485
|
+
|
486
|
+
# Now you can work with the suite object
|
487
|
+
puts suite.name
|
488
|
+
puts suite.normative_statements_classes.count
|
489
|
+
puts suite.conformance_classes.count
|
490
|
+
----
|
491
|
+
|
492
|
+
|
493
|
+
The `Suite` class provides a `combine` method to merge two suites:
|
494
|
+
|
495
|
+
[source,ruby]
|
496
|
+
----
|
497
|
+
combined_suite = suite1.combine(suite2)
|
498
|
+
----
|
499
|
+
|
500
|
+
This method merges the two suites into a single suite, ensuring that the
|
501
|
+
resulting suite is consistent and free of conflicts.
|
502
|
+
|
503
|
+
|
504
|
+
=== Validation process
|
505
|
+
|
506
|
+
Validations are typically performed when:
|
507
|
+
|
508
|
+
. Creating or modifying individual elements (normative statements, conformance tests, etc.)
|
509
|
+
. Adding elements to their respective classes
|
510
|
+
. Combining suites
|
511
|
+
. Loading a suite from YAML or other formats
|
512
|
+
|
513
|
+
If any validation fails, an error or a collection of errors is returned,
|
514
|
+
describing the specific validation issues encountered.
|
515
|
+
|
516
|
+
To manually trigger validation on a suite:
|
517
|
+
|
518
|
+
[source,ruby]
|
519
|
+
----
|
520
|
+
errors = suite.validate_all
|
521
|
+
if errors.any?
|
522
|
+
puts "Validation errors:"
|
523
|
+
errors.each { |error| puts "- #{error}" }
|
524
|
+
else
|
525
|
+
puts "Suite is valid."
|
526
|
+
end
|
40
527
|
----
|
41
528
|
|
42
|
-
|
529
|
+
These validation mechanisms help ensure that the created ModSpec instances are
|
530
|
+
consistent, well-formed, and adhere to the expected structure and relationships.
|
531
|
+
|
532
|
+
|
533
|
+
== Copyright
|
43
534
|
|
44
535
|
This gem is developed, maintained and funded by
|
45
536
|
https://www.ribose.com[Ribose Inc.]
|