active-triples 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -9
  3. data/CHANGES.md +69 -0
  4. data/Gemfile +0 -2
  5. data/Guardfile +1 -2
  6. data/active-triples.gemspec +3 -3
  7. data/lib/active/triples.rb +1 -0
  8. data/lib/active_triples.rb +4 -0
  9. data/lib/active_triples/configurable.rb +3 -1
  10. data/lib/active_triples/configuration.rb +1 -0
  11. data/lib/active_triples/configuration/item.rb +1 -0
  12. data/lib/active_triples/configuration/item_factory.rb +1 -0
  13. data/lib/active_triples/configuration/merge_item.rb +5 -2
  14. data/lib/active_triples/extension_strategy.rb +1 -0
  15. data/lib/active_triples/identifiable.rb +1 -0
  16. data/lib/active_triples/list.rb +2 -0
  17. data/lib/active_triples/nested_attributes.rb +1 -1
  18. data/lib/active_triples/node_config.rb +5 -3
  19. data/lib/active_triples/persistable.rb +1 -0
  20. data/lib/active_triples/persistence_strategies/parent_strategy.rb +104 -29
  21. data/lib/active_triples/persistence_strategies/persistence_strategy.rb +15 -7
  22. data/lib/active_triples/persistence_strategies/repository_strategy.rb +26 -22
  23. data/lib/active_triples/properties.rb +84 -6
  24. data/lib/active_triples/property.rb +35 -4
  25. data/lib/active_triples/property_builder.rb +38 -4
  26. data/lib/active_triples/rdf_source.rb +225 -75
  27. data/lib/active_triples/reflection.rb +42 -3
  28. data/lib/active_triples/relation.rb +330 -73
  29. data/lib/active_triples/repositories.rb +4 -2
  30. data/lib/active_triples/resource.rb +1 -0
  31. data/lib/active_triples/schema.rb +1 -0
  32. data/lib/active_triples/undefined_property_error.rb +27 -0
  33. data/lib/active_triples/version.rb +2 -1
  34. data/spec/active_triples/configurable_spec.rb +3 -2
  35. data/spec/active_triples/configuration_spec.rb +2 -1
  36. data/spec/active_triples/extension_strategy_spec.rb +2 -1
  37. data/spec/active_triples/identifiable_spec.rb +7 -11
  38. data/spec/active_triples/list_spec.rb +1 -4
  39. data/spec/active_triples/nested_attributes_spec.rb +4 -3
  40. data/spec/active_triples/persistable_spec.rb +4 -1
  41. data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +141 -11
  42. data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +1 -0
  43. data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +32 -17
  44. data/spec/active_triples/properties_spec.rb +68 -33
  45. data/spec/active_triples/property_builder_spec.rb +36 -0
  46. data/spec/active_triples/property_spec.rb +15 -1
  47. data/spec/active_triples/rdf_source_spec.rb +544 -6
  48. data/spec/active_triples/reflection_spec.rb +78 -0
  49. data/spec/active_triples/relation_spec.rb +505 -3
  50. data/spec/active_triples/repositories_spec.rb +3 -1
  51. data/spec/active_triples/resource_spec.rb +90 -147
  52. data/spec/active_triples/schema_spec.rb +3 -2
  53. data/spec/active_triples_spec.rb +1 -0
  54. data/spec/integration/dummies/dummy_resource_a.rb +6 -0
  55. data/spec/integration/dummies/dummy_resource_b.rb +6 -0
  56. data/spec/integration/parent_persistence_spec.rb +18 -0
  57. data/spec/integration/reciprocal_properties_spec.rb +69 -0
  58. data/spec/pragmatic_context_spec.rb +10 -8
  59. data/spec/spec_helper.rb +5 -0
  60. data/spec/support/active_model_lint.rb +4 -6
  61. data/spec/support/dummies/basic_persistable.rb +2 -11
  62. data/spec/support/matchers.rb +11 -0
  63. data/spec/support/shared_examples/persistence_strategy.rb +3 -16
  64. metadata +20 -13
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ describe ActiveTriples::Reflection do
5
+ subject { klass.new }
6
+
7
+ let(:klass) { Class.new { include ActiveTriples::Reflection } }
8
+
9
+ let(:config_hash) do
10
+ { 'moomin' => double('moomin config'),
11
+ 'snorkmaiden' => double('snorkmaiden config') }
12
+ end
13
+
14
+ describe '#reflections' do
15
+ it 'gives reflections for the instance' do
16
+ expect(subject.reflections).to eq klass
17
+ end
18
+ end
19
+
20
+ describe '.properties=' do
21
+ it 'sets properties' do
22
+ expect { klass.properties = config_hash }
23
+ .to change { klass._active_triples_config }.to config_hash
24
+ end
25
+ end
26
+
27
+ describe '.properties' do
28
+ it 'gets the set properties' do
29
+ klass.properties = config_hash
30
+
31
+ expect(klass.properties).to eq config_hash
32
+ end
33
+ end
34
+
35
+ describe '.has_property?' do
36
+ before { klass.properties = config_hash }
37
+
38
+ it 'returns true for properties it has' do
39
+ klass._active_triples_config.each do |property, _|
40
+ expect(klass).to have_property property
41
+ end
42
+ end
43
+
44
+ it 'coerces to a string' do
45
+ klass._active_triples_config.each do |property, _|
46
+ expect(klass).to have_property property.to_sym
47
+ end
48
+ end
49
+
50
+ it 'returns false for unregistered properties' do
51
+ expect(klass).not_to have_property 'moominmama'
52
+ end
53
+ end
54
+
55
+ describe '.reflect_on_property' do
56
+ before { klass.properties = config_hash }
57
+
58
+ it 'gets the config for the requested property' do
59
+ klass._active_triples_config.each do |property, config|
60
+ expect(klass.reflect_on_property(property)).to eq config
61
+ end
62
+ end
63
+
64
+ it 'coerces to a string' do
65
+ klass._active_triples_config.each do |property, config|
66
+ expect(klass.reflect_on_property(property.to_sym)).to eq config
67
+ end
68
+ end
69
+
70
+ it 'raises an error on unregistered properties' do
71
+ expect { klass.reflect_on_property(:fake) }.to raise_error do |err|
72
+ expect(err).to be_a ActiveTriples::UndefinedPropertyError
73
+ expect(err.klass).to eq klass
74
+ expect(err.property).to eq :fake.to_s
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,7 +1,421 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
  require 'rdf/isomorphic'
3
4
 
4
5
  describe ActiveTriples::Relation do
6
+ let(:parent_resource) { double("parent resource", reflections: {}) }
7
+ let(:value_args) { double("value args", last: {}) }
8
+
9
+ let(:uri) { RDF::URI('http://example.org/moomin') }
10
+
11
+ subject { described_class.new(parent_resource, value_args) }
12
+
13
+ shared_context 'with URI property' do
14
+ subject { described_class.new(parent_resource, [property] ) }
15
+ let(:property) { uri }
16
+ end
17
+
18
+ shared_context 'with symbol property' do
19
+ subject { described_class.new(parent_resource, [property] ) }
20
+ let(:property) { :moomin }
21
+ let(:reflections) do
22
+ Class.new do
23
+ include ActiveTriples::RDFSource
24
+ property :moomin, predicate: RDF::URI('http://example.org/moomin')
25
+ end
26
+ end
27
+
28
+ before do
29
+ allow(parent_resource).to receive(:reflections).and_return(reflections)
30
+ end
31
+ end
32
+
33
+ shared_context 'with unregistered property' do
34
+ subject { described_class.new(parent_resource, [property] ) }
35
+ let(:property) { :moomin }
36
+ let(:reflections) { Class.new { include ActiveTriples::RDFSource } }
37
+
38
+ before do
39
+ allow(parent_resource).to receive(:reflections).and_return(reflections)
40
+ end
41
+ end
42
+
43
+ describe '#build' do
44
+ include_context 'with symbol property'
45
+
46
+ let(:parent_resource) { ActiveTriples::Resource.new }
47
+
48
+ it 'returns a new child node' do
49
+ expect(subject.build).to be_a ActiveTriples::RDFSource
50
+ end
51
+
52
+ it 'adds new child node to relation' do
53
+ expect { subject.build }.to change { subject.count }.by(1)
54
+ end
55
+
56
+ it 'builds child as new blank node by default' do
57
+ expect(subject.build).to be_node
58
+ end
59
+
60
+ it 'builds child with uri if given' do
61
+ uri = 'http://example.com/moomin'
62
+ expect(subject.build(id: uri)).to be_uri
63
+ end
64
+
65
+ context 'with configured properties' do
66
+ include_context 'with symbol property' do
67
+ before do
68
+ reflections.property :moomin,
69
+ predicate: RDF::Vocab::DC.relation,
70
+ class_name: 'WithTitle'
71
+ class WithTitle
72
+ include ActiveTriples::RDFSource
73
+ property :title, predicate: RDF::Vocab::DC.title
74
+ end
75
+ end
76
+
77
+ after { Object.send(:remove_const, :WithTitle) }
78
+ end
79
+
80
+ it 'sets attributes for built node' do
81
+ attributes = { title: 'moomin' }
82
+
83
+ expect(subject.build(attributes))
84
+ .to have_attributes(title: ['moomin'])
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#delete' do
90
+ include_context 'with symbol property'
91
+
92
+ let(:parent_resource) { ActiveTriples::Resource.new }
93
+
94
+ it 'handles a non-existent value' do
95
+ expect { subject.delete(1) }.not_to change { subject.to_a }
96
+ end
97
+
98
+ context 'with values' do
99
+ before { subject << values }
100
+
101
+ let(:node) { RDF::Node.new(:node) }
102
+ let(:uri) { RDF.Property }
103
+ let(:values) { ['1', 1, :one, false, DateTime.now, node, uri] }
104
+
105
+ it 'handles a non-existent value' do
106
+ expect { subject.delete('blah') }.not_to change { subject.to_a }
107
+ end
108
+
109
+ it 'deletes a matched value' do
110
+ expect { subject.delete(values.first) }
111
+ .to change { subject.to_a }
112
+ .to contain_exactly(*values[1..-1])
113
+ end
114
+
115
+ it 'deletes a URI value' do
116
+ values.delete(uri)
117
+ expect { subject.delete(uri) }
118
+ .to change { subject.to_a }
119
+ .to contain_exactly(*values)
120
+ end
121
+
122
+ it 'deletes a node value' do
123
+ values.delete(node)
124
+ expect { subject.delete(node) }
125
+ .to change { subject.to_a }
126
+ .to contain_exactly(*values)
127
+ end
128
+
129
+ it 'deletes a token value' do
130
+ values.delete(:one)
131
+ expect { subject.delete(:one) }
132
+ .to change { subject.to_a }
133
+ .to contain_exactly(*values)
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '#delete?' do
139
+ include_context 'with symbol property'
140
+
141
+ let(:parent_resource) { ActiveTriples::Resource.new }
142
+
143
+ it 'gives nil for non-existant value' do
144
+ expect(subject.delete?(1)).to be_nil
145
+ end
146
+
147
+ it 'returns value when deleted' do
148
+ subject.set(1)
149
+ expect(subject.delete?(1)).to eq 1
150
+ end
151
+
152
+ it 'deletes existing values' do
153
+ subject.set(1)
154
+ expect { subject.delete?(1) }
155
+ .to change { subject.to_a }.to be_empty
156
+ end
157
+ end
158
+
159
+ describe '#subtract' do
160
+ include_context 'with symbol property'
161
+
162
+ let(:parent_resource) { ActiveTriples::Resource.new }
163
+
164
+ it 'subtracts values as arguments' do
165
+ subject.set([1,2,3])
166
+ expect { subject.subtract(2,3) }
167
+ .to change { subject.to_a }.to contain_exactly(1)
168
+ end
169
+
170
+ it 'subtracts values as an enumerable' do
171
+ subject.set([1,2,3])
172
+ expect { subject.subtract([2,3]) }
173
+ .to change { subject.to_a }.to contain_exactly(1)
174
+ end
175
+
176
+ it 'subtracts token values' do
177
+ subject.set([:one, :two, :three])
178
+ expect { subject.subtract([:two, :three]) }
179
+ .to change { subject.to_a }.to contain_exactly(:one)
180
+ end
181
+ end
182
+
183
+ describe '#swap' do
184
+ include_context 'with symbol property'
185
+
186
+ let(:parent_resource) { ActiveTriples::Resource.new }
187
+
188
+ it 'returns nil when the value is not present' do
189
+ expect(subject.swap(1, 2)).to be_nil
190
+ end
191
+
192
+ it 'does not change contents for non-existent value' do
193
+ expect { subject.swap(1, 2) }.not_to change { subject.to_a }
194
+ end
195
+
196
+ it 'swaps the value' do
197
+ values = [1, 2, 3]
198
+ subject.set(values)
199
+ expect { subject.swap(1, 4) }
200
+ .to change { subject.to_a }.to contain_exactly(2, 3, 4)
201
+ end
202
+ end
203
+
204
+ describe '#clear' do
205
+ include_context 'with symbol property'
206
+ let(:parent_resource) { ActiveTriples::Resource.new }
207
+
208
+ context 'with values' do
209
+ before do
210
+ subject.parent << [subject.parent.rdf_subject,
211
+ subject.predicate,
212
+ 'moomin']
213
+ end
214
+
215
+ it 'clears the relation' do
216
+ expect { subject.clear }.to change { subject.result }
217
+ .from(['moomin']).to([])
218
+ end
219
+
220
+ it 'deletes statements from parent' do
221
+ query_pattern = [subject.parent.rdf_subject, subject.predicate, nil]
222
+
223
+ expect { subject.clear }
224
+ .to change { subject.parent.query(query_pattern) }.to([])
225
+ end
226
+ end
227
+
228
+ it 'is a no-op when relation is empty' do
229
+ subject.parent << [subject.parent.rdf_subject, RDF.type, 'moomin']
230
+ expect { subject.clear }.not_to change { subject.parent.statements.to_a }
231
+ end
232
+ end
233
+
234
+ describe '#<<' do
235
+ include_context 'with symbol property'
236
+ let(:parent_resource) { ActiveTriples::Resource.new }
237
+
238
+ it 'adds a value' do
239
+ expect { subject << :moomin }
240
+ .to change { subject.to_a }.to contain_exactly(:moomin)
241
+ end
242
+
243
+ it 'adds multiple values' do
244
+ values = [:moomin, :snork]
245
+ expect { subject << values }
246
+ .to change { subject.to_a }.to contain_exactly(*values)
247
+ end
248
+ end
249
+
250
+ describe "#predicate" do
251
+ context 'when the property is an RDF::Term' do
252
+ include_context 'with URI property'
253
+
254
+ it 'returns the specified RDF::Term' do
255
+ expect(subject.predicate).to eq uri
256
+ end
257
+ end
258
+
259
+ context 'when the property is a symbol' do
260
+ include_context 'with symbol property'
261
+
262
+ it 'returns the reflected property' do
263
+ expect(subject.predicate).to eq uri
264
+ end
265
+ end
266
+
267
+ context 'when the symbol property is unregistered' do
268
+ include_context 'with unregistered property'
269
+ it 'returns nil' do
270
+ expect(subject.predicate).to be_nil
271
+ end
272
+ end
273
+ end
274
+
275
+ describe "#property" do
276
+ context 'when the property is an RDF::Term' do
277
+ include_context 'with URI property'
278
+
279
+ it 'returns the specified RDF::Term' do
280
+ expect(subject.property).to eq property
281
+ end
282
+ end
283
+
284
+ context 'when the property is a symbol' do
285
+ include_context 'with symbol property'
286
+
287
+ it 'returns the property symbol' do
288
+ expect(subject.property).to eq property
289
+ end
290
+ end
291
+
292
+ context 'when the symbol property is unregistered' do
293
+ include_context 'with unregistered property'
294
+
295
+ it 'returns the property symbol' do
296
+ expect(subject.property).to eq property
297
+ end
298
+ end
299
+ end
300
+
301
+ describe '#first_or_create' do
302
+ let(:parent_resource) { ActiveTriples::Resource.new }
303
+
304
+ context 'with symbol' do
305
+ include_context 'with symbol property'
306
+
307
+ it 'creates a new node' do
308
+ expect { subject.first_or_create }.to change { subject.count }.by(1)
309
+ end
310
+
311
+ it 'returns existing node if present' do
312
+ node = subject.build
313
+ expect(subject.first_or_create).to eq node
314
+ end
315
+
316
+ it 'does not create a new node when one exists' do
317
+ subject.build
318
+ expect { subject.first_or_create }.not_to change { subject.count }
319
+ end
320
+
321
+ it 'returns literal value if appropriate' do
322
+ subject << literal = 'moomin'
323
+ expect(subject.first_or_create).to eq literal
324
+ end
325
+ end
326
+ end
327
+
328
+ describe '#result' do
329
+ context 'with nil predicate' do
330
+ include_context 'with unregistered property'
331
+
332
+ it 'is empty' do
333
+ expect(subject.result).to contain_exactly()
334
+ end
335
+ end
336
+
337
+ context 'with predicate' do
338
+ include_context 'with symbol property' do
339
+ let(:parent_resource) { ActiveTriples::Resource.new }
340
+ end
341
+
342
+ it 'is empty' do
343
+ expect(subject.result).to contain_exactly()
344
+ end
345
+
346
+ context 'with values' do
347
+ before do
348
+ values.each do |value|
349
+ subject.parent << [subject.parent.rdf_subject, uri, value]
350
+ end
351
+ end
352
+
353
+ let(:values) { ['Comet in Moominland', 'Finn Family Moomintroll'] }
354
+ let(:node) { RDF::Node.new }
355
+
356
+ it 'contain values' do
357
+ expect(subject.result).to contain_exactly(*values)
358
+ end
359
+
360
+ context 'with castable values' do
361
+ let(:values) do
362
+ [uri, RDF::URI('http://ex.org/too-ticky'), RDF::Node.new]
363
+ end
364
+
365
+ it 'casts Resource values' do
366
+ expect(subject.result)
367
+ .to contain_exactly(a_kind_of(ActiveTriples::Resource),
368
+ a_kind_of(ActiveTriples::Resource),
369
+ a_kind_of(ActiveTriples::Resource))
370
+ end
371
+
372
+ it 'cast values have correct URI' do
373
+ expect(subject.result.map(&:rdf_subject))
374
+ .to contain_exactly(*values)
375
+ end
376
+
377
+ context 'and persistence_strategy is configured' do
378
+ before do
379
+ reflections
380
+ .property :moomin,
381
+ predicate: RDF::URI('http://example.org/moomin'),
382
+ persist_to: ActiveTriples::RepositoryStrategy
383
+ end
384
+
385
+ it 'assigns persistence strategy' do
386
+ subject.result.each do |node|
387
+ expect(node.persistence_strategy)
388
+ .to be_a ActiveTriples::RepositoryStrategy
389
+ end
390
+ end
391
+ end
392
+
393
+ context 'and #cast? is false' do
394
+ let(:values) do
395
+ [uri, RDF::URI('http://ex.org/too-ticky'), RDF::Node.new,
396
+ 'moomin', Date.today]
397
+ end
398
+
399
+ it 'does not cast results' do
400
+ allow(subject).to receive(:cast?).and_return(false)
401
+ expect(subject.result).to contain_exactly(*values)
402
+ end
403
+ end
404
+
405
+ context 'when #return_literals? is true' do
406
+ let(:values) do
407
+ [RDF::Literal('moomin'), RDF::Literal(Date.today)]
408
+ end
409
+
410
+ it 'does not cast results' do
411
+ allow(subject).to receive(:return_literals?).and_return(true)
412
+ expect(subject.result).to contain_exactly(*values)
413
+ end
414
+ end
415
+ end
416
+ end
417
+ end
418
+ end
5
419
 
6
420
  describe "#rdf_subject" do
7
421
  let(:parent_resource) { double("parent resource", reflections: {}) }
@@ -10,32 +424,120 @@ describe ActiveTriples::Relation do
10
424
 
11
425
  context "when relation has 0 value arguments" do
12
426
  before { subject.value_arguments = double(length: 0) }
427
+
13
428
  it "should raise an error" do
14
- expect { subject.send(:rdf_subject) }.to raise_error
429
+ expect { subject.send(:rdf_subject) }.to raise_error ArgumentError
15
430
  end
16
431
  end
432
+
17
433
  context "when term has 1 value argument" do
18
434
  before do
19
435
  allow(subject.parent).to receive(:rdf_subject) { "parent subject" }
20
436
  subject.value_arguments = double(length: 1)
21
437
  end
438
+
22
439
  it "should call `rdf_subject' on the parent" do
23
440
  expect(subject.send(:rdf_subject) ).to eq "parent subject"
24
441
  end
442
+
25
443
  it " is a private method" do
26
444
  expect { subject.rdf_subject }.to raise_error NoMethodError
27
445
  end
28
446
  end
447
+
29
448
  context "when relation has 2 value arguments" do
30
449
  before { subject.value_arguments = double(length: 2, first: "first") }
450
+
31
451
  it "should return the first value argument" do
32
452
  expect(subject.send(:rdf_subject) ).to eq "first"
33
453
  end
34
454
  end
455
+
35
456
  context "when relation has 3 value arguments" do
36
457
  before { subject.value_arguments = double(length: 3) }
458
+
37
459
  it "should raise an error" do
38
- expect { subject.send(:rdf_subject) }.to raise_error
460
+ expect { subject.send(:rdf_subject) }.to raise_error ArgumentError
461
+ end
462
+ end
463
+ end
464
+
465
+ describe '#size' do
466
+ context 'with predicate' do
467
+ include_context 'with symbol property' do
468
+ let(:parent_resource) { ActiveTriples::Resource.new }
469
+ end
470
+
471
+ context 'with values' do
472
+ let(:values) { ['Comet in Moominland', 'Finn Family Moomintroll'] }
473
+ before do
474
+ values.each do |value|
475
+ subject.parent << [subject.parent.rdf_subject, uri, value]
476
+ end
477
+ end
478
+ it "returns the size of the result" do
479
+ expect(subject.size).to eq 2
480
+ end
481
+ end
482
+ end
483
+ end
484
+
485
+ describe '#set' do
486
+ include_context 'with unregistered property'
487
+
488
+ it 'raises UndefinedPropertyError' do
489
+ expect { subject.set('x') }
490
+ .to raise_error ActiveTriples::UndefinedPropertyError
491
+ end
492
+
493
+ context 'with predicate' do
494
+ include_context 'with symbol property' do
495
+ let(:parent_resource) { ActiveTriples::Resource.new }
496
+ end
497
+
498
+ it 'sets a value' do
499
+ expect { subject.set(:moomin) }
500
+ .to change { subject.to_a }.to contain_exactly(:moomin)
501
+ end
502
+
503
+ it 'sets mulitple values' do
504
+ values = [:moomin, :snork]
505
+ expect { subject.set(values) }
506
+ .to change { subject.to_a }.to contain_exactly(*values)
507
+ end
508
+
509
+ context 'and persistence config' do
510
+ before do
511
+ reflections
512
+ .property :moomin,
513
+ predicate: RDF::URI('http://example.org/moomin'),
514
+ persist_to: ActiveTriples::RepositoryStrategy
515
+ end
516
+
517
+ it 'returns values with persistence strategy set' do
518
+ expect(subject.set(RDF::Node.new).map(&:persistence_strategy))
519
+ .to contain_exactly(an_instance_of(ActiveTriples::RepositoryStrategy))
520
+ end
521
+ end
522
+ end
523
+ end
524
+
525
+ describe '#join' do
526
+ context 'with predicate' do
527
+ include_context 'with symbol property' do
528
+ let(:parent_resource) { ActiveTriples::Resource.new }
529
+ end
530
+
531
+ context 'with values' do
532
+ let(:values) { ['Comet in Moominland', 'Finn Family Moomintroll'] }
533
+ before do
534
+ values.each do |value|
535
+ subject.parent << [subject.parent.rdf_subject, uri, value]
536
+ end
537
+ end
538
+ it "returns joined strings" do
539
+ expect(subject.join(", ")).to eq "Comet in Moominland, Finn Family Moomintroll"
540
+ end
39
541
  end
40
542
  end
41
543
  end
@@ -65,6 +567,7 @@ describe ActiveTriples::Relation do
65
567
  expect(subject.send(:valid_datatype?, true)).to be true
66
568
  end
67
569
  end
570
+
68
571
  context "the value is a Resource" do
69
572
  after { Object.send(:remove_const, :DummyResource) }
70
573
  let(:resource) { DummyResource.new }
@@ -99,5 +602,4 @@ describe ActiveTriples::Relation do
99
602
  end
100
603
  end
101
604
  end
102
-
103
605
  end