shacl 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c633e6028fd1289d59a32deaa5fa21392fef42e19775c5360176764573c59d55
4
- data.tar.gz: 1b531864030beee9032a51f47c06a4151fb41b5500d6fbf639d14261bdb14377
3
+ metadata.gz: d790df44442d54fd3787914c630d9ba5f4879988ce47616dbcc2ff62c8521876
4
+ data.tar.gz: bda5f350ad0393933cfe14391341de28e7cf30e6088717d555ccef43192ec28f
5
5
  SHA512:
6
- metadata.gz: 69660f8f352892612c02d2e487d2e01a0eec8f477024f175c58e30a07ab857aa271494f19b90955cc4b63c9889ed31ebdbcdae04ab0dd188d2949108798bf6f9
7
- data.tar.gz: 2e9f9e64e9ba01b171b06e35b6fc47427e3b5f6ba075d5aecb14497a9c84873a6716a029aceae925d85349b68609a8ec7987aceaa5d26e0ca77866fb385d1e4d
6
+ metadata.gz: f2cd4e4e2bc3686207c430be9cc582c80cc8012fc9719e902f4d72151833b3bd3a5f25d6c2b08005d3e79409378862d3d9b01c230ed794c534e92a05e18a96d3
7
+ data.tar.gz: 5c5a6d45bccecaa5cfdbb63a65b95934d42072f1bcce8f4060312ee0fb0c968f6f902bdfd7eba1263b6b67ef98471f272f6ef250db1aa0bd86e0cf3639877474
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is a pure-Ruby library for working with the [Shape Constraint Language][SHACL Spec] to validate the shape of [RDF][] graphs.
4
4
 
5
- [![Gem Version](https://badge.fury.io/rb/shacl.png)](https://badge.fury.io/rb/shacl)
5
+ [![Gem Version](https://badge.fury.io/rb/shacl.svg)](https://badge.fury.io/rb/shacl)
6
6
  [![Build Status](https://github.com/ruby-rdf/shacl/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/shacl/actions?query=workflow%3ACI)
7
7
  [![Coverage Status](https://coveralls.io/repos/github/ruby-rdf/shacl/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/shacl?branch=develop)
8
8
  [![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
@@ -87,10 +87,10 @@ This implementation is certainly not performant. Some things that can be be cons
87
87
 
88
88
  ## Dependencies
89
89
 
90
- * [Ruby](https://ruby-lang.org/) (>= 2.6)
91
- * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
90
+ * [Ruby](https://ruby-lang.org/) (>= 3.0)
91
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.3)
92
92
  * [SPARQL](https://rubygems.org/gems/sparql) (~> 3.2)
93
- * [json-ld](https://rubygems.org/gems/json-ld) (~> 3.2)
93
+ * [json-ld](https://rubygems.org/gems/json-ld) (~> 3.3)
94
94
  * [sxp](https://rubygems.org/gems/sxp) (~> 1.2)
95
95
 
96
96
  ## Installation
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.1
@@ -5,5 +5,63 @@ module SHACL::Algebra
5
5
  # Constraint Components define basic constraint behaivor through _mandatory_ and _optional_ parameters. Constraints are accessed through their parameters.
6
6
  #
7
7
  class ConstraintComponent < Operator
8
+
9
+ # Class Methods
10
+ class << self
11
+ ##
12
+ # Creates an operator instance from a parsed SHACL representation.
13
+ #
14
+ # Special case for SPARQL ConstraintComponents.
15
+ #
16
+ # @param [Hash] operator
17
+ # @param [Hash] options ({})
18
+ # @option options [Hash{String => RDF::URI}] :prefixes
19
+ # @return [Operator]
20
+ def from_json(operator, **options)
21
+ operands = []
22
+
23
+ # Component is known by its subject IRI
24
+ id = operator.fetch('id')
25
+
26
+ # Component class (for instantiation) is based on the _local name_ of the component IRI
27
+ class_name = ncname(id)
28
+
29
+ parameters = operator.fetch('parameter', []).inject({}) do |memo, param|
30
+ # Symbolize keys
31
+ param = param.inject({}) {|memo, (k,v)| memo.merge(k.to_sym => v)}
32
+
33
+ plc = ncname(param[:path])
34
+
35
+ # Add class and local name
36
+ param = param.merge(class: class_name, local_name: plc)
37
+ memo.merge(param[:path] => param)
38
+ end
39
+
40
+ # Add parameters to operator lookup
41
+ add_component(class_name, parameters)
42
+
43
+ # Add parameter identifiers to operands
44
+ operands << [:parameters, parameters.keys]
45
+
46
+ # FIXME: labelTemplate
47
+
48
+ validator = %w(validator nodeValidator propertyValidator).inject(nil) do |memo, p|
49
+ memo || (SPARQLConstraintComponent.from_json(operator[p]) if operator.key?(p))
50
+ end
51
+ raise SHACL::Error, "Constraint Component has no validator" unless validator
52
+
53
+ operands << [:validator, validator]
54
+
55
+ new(*operands, **options)
56
+ end
57
+
58
+ # Extract the NCName tail of an IRI as a symbol.
59
+ #
60
+ # @param [RDF::URI] uri
61
+ # @return [Symbol]
62
+ def ncname(uri)
63
+ uri.to_s.match(/(\w+)$/).to_s.to_sym
64
+ end
65
+ end
8
66
  end
9
67
  end
@@ -44,7 +44,7 @@ module SHACL::Algebra
44
44
  resultSeverity: options[:severity],
45
45
  component: RDF::Vocab::SHACL.ClosedConstraintComponent,
46
46
  **options)
47
- end.compact
47
+ end.flatten.compact
48
48
  elsif @options[:ignoredProperties]
49
49
  raise SHACL::Error, "shape has ignoredProperties without being closed"
50
50
  end
@@ -40,6 +40,7 @@ module SHACL::Algebra
40
40
  # Graph from which original shapes were loaded.
41
41
  # @return [RDF::Graph]
42
42
  attr_accessor :shapes_graph
43
+
43
44
  # Parameters to components.
44
45
  PARAMETERS = {
45
46
  and: {class: :AndConstraintComponent},
@@ -151,19 +152,19 @@ module SHACL::Algebra
151
152
  },
152
153
  property: {class: :PropertyConstraintComponent},
153
154
  qualifiedMaxCount: {
154
- class: :QualifiedMaxCountConstraintComponent,
155
+ class: :QualifiedValueConstraintComponent,
155
156
  datatype: RDF::XSD.integer,
156
157
  },
157
158
  qualifiedValueShape: {
158
- class: %i(QualifiedMaxCountConstraintComponent QualifiedMinCountConstraintComponent),
159
+ class: :QualifiedValueConstraintComponent,
159
160
  },
160
161
  qualifiedValueShapesDisjoint: {
161
- class: %i(QualifiedMaxCountConstraintComponent QualifiedMinCountConstraintComponent),
162
+ class: :QualifiedValueConstraintComponent,
162
163
  datatype: RDF::XSD.boolean,
163
164
  optional: true,
164
165
  },
165
166
  qualifiedMinCount: {
166
- class: :QualifiedMinCountConstraintComponent,
167
+ class: :QualifiedValueConstraintComponent,
167
168
  datatype: RDF::XSD.integer
168
169
  },
169
170
  sparql: {class: :SPARQLConstraintComponent},
@@ -175,21 +176,43 @@ module SHACL::Algebra
175
176
  xone: {class: :XoneConstraintComponent},
176
177
  }
177
178
 
178
- # Constraint Component classes indexed to their mandatory and optional parameters.
179
- #
180
- # @note for builtins, corresponding Ruby classes may not exist.
181
- COMPONENT_PARAMS = PARAMETERS.inject({}) do |memo, (param, properties)|
182
- memo.merge(Array(properties[:class]).inject(memo) do |mem, cls|
183
- entry = mem.fetch(cls, {})
184
- param_type = properties[:optional] ? :optional : :mandatory
185
- entry[param_type] ||= []
186
- entry[param_type] << param
187
- mem.merge(cls => entry)
188
- end)
189
- end
190
-
191
179
  ## Class methods
192
180
  class << self
181
+ # Add parameters and class def from a SPARQL-based Constraint Component
182
+ #
183
+ # @param [RDF::URI] cls The URI of the constraint component.
184
+ # @param [Hash{Symbol => Hash}] parameters Definitions of mandatory and optional parameters for this component.
185
+ def add_component(cls, parameters)
186
+ # Remember added paraemters.
187
+ # FIXME: should merge parameters
188
+ @added_parameters = (@added_parameters || {}).merge(parameters)
189
+ # Rebuild
190
+ @params = @component_params = nil
191
+ end
192
+
193
+ # Defined parameters for components, which may be supplemented by SPARQL-based Constraint Components. A parameter may be mapped to more than one component class.
194
+ #
195
+ # @return [Hash{Symbol => Hash}] Returns each parameter referencing the component classes it is used in, and the property validators for values of that parameter.
196
+ def params
197
+ @params ||= PARAMETERS.merge(@added_parameters || {})
198
+ end
199
+
200
+ # Constraint Component classes indexed to their mandatory and optional parameters, which may be supplemented by SPARQL-based Constraint Components.
201
+ #
202
+ # @return [Hash{Symbol => Hash}]
203
+ # Returns a hash relating each component URI to its optional and mandatory parameters.
204
+ def component_params
205
+ @component_params ||= params.inject({}) do |memo, (param, properties)|
206
+ memo.merge(Array(properties[:class]).inject(memo) do |mem, cls|
207
+ entry = mem.fetch(cls, {})
208
+ param_type = properties[:optional] ? :optional : :mandatory
209
+ entry[param_type] ||= []
210
+ entry[param_type] << param
211
+ mem.merge(cls => entry)
212
+ end)
213
+ end
214
+ end
215
+
193
216
  ##
194
217
  # Creates an operator instance from a parsed SHACL representation
195
218
  # @param [Hash] operator
@@ -205,7 +228,7 @@ module SHACL::Algebra
205
228
  # Node Options and operands on shape or node, which are not Constraint Component Parameters
206
229
  operator.each do |k, v|
207
230
  k = k.to_sym
208
- next if v.nil? || PARAMETERS.include?(k)
231
+ next if v.nil? || params.include?(k)
209
232
  case k
210
233
  # List properties
211
234
  when :id then node_opts[:id] = iri(v, vocab: false, **options)
@@ -234,8 +257,8 @@ module SHACL::Algebra
234
257
  used_components = {}
235
258
  operator.each do |k, v|
236
259
  k = k.to_sym
237
- next if v.nil? || !PARAMETERS.include?(k)
238
- param_props = PARAMETERS[k]
260
+ next if v.nil? || !params.include?(k)
261
+ param_props = params[k]
239
262
  param_classes = Array(param_props[:class])
240
263
 
241
264
  # Keep track of components which have been used.
@@ -293,10 +316,21 @@ module SHACL::Algebra
293
316
  name = klass.const_get(:NAME)
294
317
  # If the key `k` is the same as the NAME of the class, create the instance with the defined element values.
295
318
  if name == k
319
+ param_classes.each do |cls|
320
+ # Add `k` as a mandatory parameter fulfilled
321
+ (used_components[cls][:mandatory_parameters] ||= []) << k
322
+ end
323
+
324
+ # Instantiate the compoent
296
325
  elements.map {|e| klass.new(*e, **options.dup)}
297
326
  else
298
327
  # Add non-primary parameters for subsequent insertion
299
328
  param_classes.each do |cls|
329
+ # Add `k` as a mandatory parameter fulfilled if it is so defined
330
+ (used_components[cls][:mandatory_parameters] ||= []) << k unless
331
+ params[k][:optional]
332
+
333
+ # Add parameter as S-Expression operand
300
334
  (used_components[cls][:parameters] ||= []) << elements.unshift(k)
301
335
  end
302
336
  [] # No instances created
@@ -304,10 +338,12 @@ module SHACL::Algebra
304
338
  end
305
339
  end
306
340
 
307
- # Record the instances created by class and add as operands
341
+ # Record the instances created by class and its operands
308
342
  param_classes.each do |cls|
309
343
  used_components[cls][:instances] = instances
310
344
  end
345
+
346
+ # FIXME: Only add instances when all mandatory parameters are present.
311
347
  operands.push(*instances)
312
348
  end
313
349
 
@@ -17,8 +17,8 @@ module SHACL::Algebra
17
17
  params, ops = operands.partition {|o| o.is_a?(Array) && o.first.is_a?(Symbol)}
18
18
  params = params.inject({}) {|memo, a| memo.merge(a.first => a.last)}
19
19
 
20
- max_count = params[:qualifiedMinCount].to_i
21
- min_count = params[:qualifiedMinCount].to_i
20
+ max_count = params[:qualifiedMinCount]
21
+ min_count = params[:qualifiedMinCount]
22
22
  # FIXME: figure this out
23
23
  disjoint = !!params[:qualifiedValueShapesDisjoint]
24
24
 
@@ -29,13 +29,13 @@ module SHACL::Algebra
29
29
 
30
30
  count = results.select(&:conform?).length
31
31
  log_debug(NAME, depth: depth) {"#{count}/#{results} conforming shapes"}
32
- if count < min_count
32
+ if min_count && count < min_count.to_i
33
33
  not_satisfied(focus: node, path: path,
34
34
  message: "only #{count} conforming values, requires at least #{min_count}",
35
35
  resultSeverity: options.fetch(:severity),
36
36
  component: RDF::Vocab::SHACL.QualifiedMinCountConstraintComponent,
37
37
  depth: depth, **options)
38
- elsif count > max_count
38
+ elsif max_count && count > max_count.to_i
39
39
  not_satisfied(focus: node, path: path,
40
40
  message: "#{count} conforming values, requires at most #{max_count}",
41
41
  resultSeverity: options.fetch(:severity),
@@ -43,19 +43,11 @@ module SHACL::Algebra
43
43
  depth: depth, **options)
44
44
  else
45
45
  satisfy(focus: node, path: path,
46
- message: "#{min_count} <= #{count} <= #{max_count} values conform",
46
+ message: "#{min_count.to_i} <= #{count} <= #{max_count || 'inf'} values conform",
47
47
  component: RDF::Vocab::SHACL.QualifiedMinCountConstraintComponent,
48
48
  depth: depth, **options)
49
49
  end
50
50
  end
51
51
  end
52
52
  end
53
-
54
- # Version on QualifiedConstraintComponent with required `qualifiedMaxCount` parameter
55
- class QualifiedMaxCountConstraintComponent < QualifiedValueConstraintComponent
56
- end
57
-
58
- # Version on QualifiedConstraintComponent with required `qualifiedMinCount` parameter
59
- class QualifiedMinCountConstraintComponent < QualifiedValueConstraintComponent
60
- end
61
53
  end
data/lib/shacl/algebra.rb CHANGED
@@ -27,10 +27,19 @@ module SHACL
27
27
  return operator['@list'].map {|e| from_json(e, **options)} if operator.key?('@list')
28
28
 
29
29
  type = operator.fetch('type', [])
30
- type << (operator["path"] ? 'PropertyShape' : 'NodeShape') if type.empty?
30
+ if type.empty?
31
+ type << if operator["path"]
32
+ 'PropertyShape'
33
+ elsif operator['nodeValidator'] || operator['propertyValidator'] || operator['validator']
34
+ 'ConstraintComponent'
35
+ else
36
+ 'NodeShape'
37
+ end
38
+ end
31
39
  klass = case
32
40
  when type.include?('NodeShape') then NodeShape
33
41
  when type.include?('PropertyShape') then PropertyShape
42
+ when type.include?('ConstraintComponent') then ConstraintComponent
34
43
  else raise SHACL::Error, "from_json: unknown type #{type.inspect}"
35
44
  end
36
45
 
data/lib/shacl/shapes.rb CHANGED
@@ -61,9 +61,22 @@ module SHACL
61
61
  end
62
62
 
63
63
  # Serialize the graph as framed JSON-LD and initialize patterns, recursively.
64
- shape_json = JSON::LD::API.fromRdf(graph, useNativeTypes: true) do |expanded|
65
- JSON::LD::API.frame(expanded, SHAPES_FRAME, omitGraph: false, embed: '@always', expanded: true)
66
- end['@graph']
64
+ expanded = JSON::LD::API.fromRdf(graph, useNativeTypes: true)
65
+
66
+ # Node and Property constraints
67
+ shape_json = JSON::LD::API.frame(expanded, SHAPES_FRAME,
68
+ omitGraph: false,
69
+ embed: '@always',
70
+ expanded: true)['@graph']
71
+
72
+ # Any defined Constraint Components
73
+ components = JSON::LD::API.frame(expanded, COMPONENTS_FRAME,
74
+ omitGraph: false,
75
+ embed: '@always',
76
+ expanded: true)['@graph']
77
+
78
+ # Extract any constraint components and merge to top-level
79
+ shape_json = components + shape_json
67
80
 
68
81
  # Create an array of the framed shapes
69
82
  shapes = self.new(shape_json.map {|o| Algebra.from_json(o, **options)})
@@ -189,5 +202,48 @@ module SHACL
189
202
  "xone": {},
190
203
  "targetSubjectsOf": {}
191
204
  })).freeze
205
+
206
+ COMPONENTS_FRAME = JSON.parse(%({
207
+ "@context": {
208
+ "id": "@id",
209
+ "type": {"@id": "@type", "@container": "@set"},
210
+ "@vocab": "http://www.w3.org/ns/shacl#",
211
+ "owl": "http://www.w3.org/2002/07/owl#",
212
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
213
+ "shacl": "http://www.w3.org/ns/shacl#",
214
+ "sh": "http://www.w3.org/ns/shacl#",
215
+ "xsd": "http://www.w3.org/2001/XMLSchema#",
216
+ "and": {"@type": "@id"},
217
+ "annotationProperty": {"@type": "@id"},
218
+ "class": {"@type": "@id"},
219
+ "comment": "http://www.w3.org/2000/01/rdf-schema#comment",
220
+ "condition": {"@type": "@id"},
221
+ "datatype": {"@type": "@vocab"},
222
+ "declare": {"@type": "@id"},
223
+ "disjoint": {"@type": "@id"},
224
+ "entailment": {"@type": "@id"},
225
+ "equals": {"@type": "@id"},
226
+ "ignoredProperties": {"@type": "@id", "@container": "@list"},
227
+ "imports": {"@id": "owl:imports", "@type": "@id"},
228
+ "in": {"@type": "@none", "@container": "@list"},
229
+ "inversePath": {"@type": "@id"},
230
+ "label": "http://www.w3.org/2000/01/rdf-schema#label",
231
+ "languageIn": {"@container": "@list"},
232
+ "lessThan": {"@type": "@id"},
233
+ "lessThanOrEquals": {"@type": "@id"},
234
+ "namespace": {"@type": "xsd:anyURI"},
235
+ "nodeKind": {"@type": "@vocab"},
236
+ "or": {"@type": "@id"},
237
+ "path": {"@type": "@id"},
238
+ "prefixes": {"@type": "@id"},
239
+ "property": {"@type": "@id"},
240
+ "severity": {"@type": "@vocab"},
241
+ "sparql": {"@type": "@id"},
242
+ "targetClass": {"@type": "@id"},
243
+ "targetNode": {"@type": "@none"},
244
+ "xone": {"@type": "@id"}
245
+ },
246
+ "@type": "ConstraintComponent"
247
+ })).freeze
192
248
  end
193
249
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shacl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-07 00:00:00.000000000 Z
11
+ date: 2023-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -16,34 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 3.2.8
19
+ version: '3.3'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '3.2'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 3.2.8
26
+ version: '3.3'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: json-ld
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - "~>"
38
32
  - !ruby/object:Gem::Version
39
- version: '3.2'
33
+ version: '3.3'
40
34
  type: :runtime
41
35
  prerelease: false
42
36
  version_requirements: !ruby/object:Gem::Requirement
43
37
  requirements:
44
38
  - - "~>"
45
39
  - !ruby/object:Gem::Version
46
- version: '3.2'
40
+ version: '3.3'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: sxp
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -64,90 +58,84 @@ dependencies:
64
58
  requirements:
65
59
  - - "~>"
66
60
  - !ruby/object:Gem::Version
67
- version: '3.2'
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: 3.2.4
61
+ version: '3.3'
71
62
  type: :runtime
72
63
  prerelease: false
73
64
  version_requirements: !ruby/object:Gem::Requirement
74
65
  requirements:
75
66
  - - "~>"
76
67
  - !ruby/object:Gem::Version
77
- version: '3.2'
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: 3.2.4
68
+ version: '3.3'
81
69
  - !ruby/object:Gem::Dependency
82
70
  name: rdf-spec
83
71
  requirement: !ruby/object:Gem::Requirement
84
72
  requirements:
85
73
  - - "~>"
86
74
  - !ruby/object:Gem::Version
87
- version: '3.2'
75
+ version: '3.3'
88
76
  type: :development
89
77
  prerelease: false
90
78
  version_requirements: !ruby/object:Gem::Requirement
91
79
  requirements:
92
80
  - - "~>"
93
81
  - !ruby/object:Gem::Version
94
- version: '3.2'
82
+ version: '3.3'
95
83
  - !ruby/object:Gem::Dependency
96
84
  name: rdf-turtle
97
85
  requirement: !ruby/object:Gem::Requirement
98
86
  requirements:
99
87
  - - "~>"
100
88
  - !ruby/object:Gem::Version
101
- version: '3.2'
89
+ version: '3.3'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
93
  requirements:
106
94
  - - "~>"
107
95
  - !ruby/object:Gem::Version
108
- version: '3.2'
96
+ version: '3.3'
109
97
  - !ruby/object:Gem::Dependency
110
98
  name: rdf-vocab
111
99
  requirement: !ruby/object:Gem::Requirement
112
100
  requirements:
113
101
  - - "~>"
114
102
  - !ruby/object:Gem::Version
115
- version: '3.2'
103
+ version: '3.3'
116
104
  type: :development
117
105
  prerelease: false
118
106
  version_requirements: !ruby/object:Gem::Requirement
119
107
  requirements:
120
108
  - - "~>"
121
109
  - !ruby/object:Gem::Version
122
- version: '3.2'
110
+ version: '3.3'
123
111
  - !ruby/object:Gem::Dependency
124
112
  name: rdf-xsd
125
113
  requirement: !ruby/object:Gem::Requirement
126
114
  requirements:
127
115
  - - "~>"
128
116
  - !ruby/object:Gem::Version
129
- version: '3.2'
117
+ version: '3.3'
130
118
  type: :development
131
119
  prerelease: false
132
120
  version_requirements: !ruby/object:Gem::Requirement
133
121
  requirements:
134
122
  - - "~>"
135
123
  - !ruby/object:Gem::Version
136
- version: '3.2'
124
+ version: '3.3'
137
125
  - !ruby/object:Gem::Dependency
138
126
  name: rspec
139
127
  requirement: !ruby/object:Gem::Requirement
140
128
  requirements:
141
129
  - - "~>"
142
130
  - !ruby/object:Gem::Version
143
- version: '3.10'
131
+ version: '3.12'
144
132
  type: :development
145
133
  prerelease: false
146
134
  version_requirements: !ruby/object:Gem::Requirement
147
135
  requirements:
148
136
  - - "~>"
149
137
  - !ruby/object:Gem::Version
150
- version: '3.10'
138
+ version: '3.12'
151
139
  - !ruby/object:Gem::Dependency
152
140
  name: rspec-its
153
141
  requirement: !ruby/object:Gem::Requirement
@@ -225,14 +213,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
225
213
  requirements:
226
214
  - - ">="
227
215
  - !ruby/object:Gem::Version
228
- version: '2.6'
216
+ version: '3.0'
229
217
  required_rubygems_version: !ruby/object:Gem::Requirement
230
218
  requirements:
231
219
  - - ">="
232
220
  - !ruby/object:Gem::Version
233
221
  version: '0'
234
222
  requirements: []
235
- rubygems_version: 3.3.3
223
+ rubygems_version: 3.4.19
236
224
  signing_key:
237
225
  specification_version: 4
238
226
  summary: Implementation of Shapes Constraint Language (SHACL) for RDF.rb