ld4l-open_annotation_rdf 0.0.4

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.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +231 -0
  8. data/Rakefile +2 -0
  9. data/ld4l-open_annotation_rdf.gemspec +46 -0
  10. data/lib/ld4l/open_annotation_rdf.rb +66 -0
  11. data/lib/ld4l/open_annotation_rdf/annotation.rb +82 -0
  12. data/lib/ld4l/open_annotation_rdf/comment_annotation.rb +47 -0
  13. data/lib/ld4l/open_annotation_rdf/comment_body.rb +24 -0
  14. data/lib/ld4l/open_annotation_rdf/configuration.rb +127 -0
  15. data/lib/ld4l/open_annotation_rdf/semantic_tag_annotation.rb +66 -0
  16. data/lib/ld4l/open_annotation_rdf/semantic_tag_body.rb +70 -0
  17. data/lib/ld4l/open_annotation_rdf/tag_annotation.rb +98 -0
  18. data/lib/ld4l/open_annotation_rdf/tag_body.rb +83 -0
  19. data/lib/ld4l/open_annotation_rdf/version.rb +5 -0
  20. data/lib/ld4l/open_annotation_rdf/vocab/cnt.rb +6 -0
  21. data/lib/ld4l/open_annotation_rdf/vocab/dctypes.rb +5 -0
  22. data/lib/ld4l/open_annotation_rdf/vocab/oa.rb +23 -0
  23. data/spec/ld4l/open_annotation_rdf/annotation_spec.rb +603 -0
  24. data/spec/ld4l/open_annotation_rdf/comment_annotation_spec.rb +559 -0
  25. data/spec/ld4l/open_annotation_rdf/comment_body_spec.rb +371 -0
  26. data/spec/ld4l/open_annotation_rdf/configuration_spec.rb +194 -0
  27. data/spec/ld4l/open_annotation_rdf/semantic_tag_annotation_spec.rb +619 -0
  28. data/spec/ld4l/open_annotation_rdf/semantic_tag_body_spec.rb +412 -0
  29. data/spec/ld4l/open_annotation_rdf/tag_annotation_spec.rb +672 -0
  30. data/spec/ld4l/open_annotation_rdf/tag_body_spec.rb +430 -0
  31. data/spec/ld4l/open_annotation_rdf_spec.rb +57 -0
  32. data/spec/spec_helper.rb +21 -0
  33. metadata +201 -0
@@ -0,0 +1,430 @@
1
+ require 'spec_helper'
2
+ require 'ld4l/open_annotation_rdf/vocab/dctypes'
3
+ require 'ld4l/open_annotation_rdf/vocab/oa'
4
+
5
+
6
+ describe 'LD4L::OpenAnnotationRDF::TagBody' do
7
+
8
+ subject { LD4L::OpenAnnotationRDF::TagBody.new }
9
+
10
+ describe 'rdf_subject' do
11
+ it "should be a blank node if we haven't set it" do
12
+ expect(subject.rdf_subject.node?).to be true
13
+ end
14
+
15
+ it "should be settable when it has not been set yet" do
16
+ subject.set_subject! RDF::URI('http://example.org/moomin')
17
+ expect(subject.rdf_subject).to eq RDF::URI('http://example.org/moomin')
18
+ end
19
+
20
+ it "should append to base URI when setting to non-URI subject" do
21
+ subject.set_subject! '123'
22
+ expect(subject.rdf_subject).to eq RDF::URI("#{LD4L::OpenAnnotationRDF::TagBody.base_uri}123")
23
+ end
24
+
25
+ describe 'when changing subject' do
26
+ before do
27
+ subject << RDF::Statement.new(subject.rdf_subject, RDF::DC.title, RDF::Literal('Comet in Moominland'))
28
+ subject << RDF::Statement.new(RDF::URI('http://example.org/moomin_comics'), RDF::DC.isPartOf, subject.rdf_subject)
29
+ subject << RDF::Statement.new(RDF::URI('http://example.org/moomin_comics'), RDF::DC.relation, 'http://example.org/moomin_land')
30
+ subject.set_subject! RDF::URI('http://example.org/moomin')
31
+ end
32
+
33
+ it 'should update graph subjects' do
34
+ expect(subject.has_statement?(RDF::Statement.new(subject.rdf_subject, RDF::DC.title, RDF::Literal('Comet in Moominland')))).to be true
35
+ end
36
+
37
+ it 'should update graph objects' do
38
+ expect(subject.has_statement?(RDF::Statement.new(RDF::URI('http://example.org/moomin_comics'), RDF::DC.isPartOf, subject.rdf_subject))).to be true
39
+ end
40
+
41
+ it 'should leave other uris alone' do
42
+ expect(subject.has_statement?(RDF::Statement.new(RDF::URI('http://example.org/moomin_comics'), RDF::DC.relation, 'http://example.org/moomin_land'))).to be true
43
+ end
44
+ end
45
+
46
+ describe 'created with URI subject' do
47
+ before do
48
+ subject.set_subject! RDF::URI('http://example.org/moomin')
49
+ end
50
+
51
+ it 'should not be settable' do
52
+ expect{ subject.set_subject! RDF::URI('http://example.org/moomin2') }.to raise_error
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ # -------------------------------------------------
59
+ # START -- Test attributes specific to this model
60
+ # -------------------------------------------------
61
+
62
+ describe 'type' do
63
+ it "should be set to text and astext from new" do
64
+ expect(subject.type.size).to eq 2
65
+ expect(subject.type).to include RDFVocabularies::OA.Tag
66
+ expect(subject.type).to include RDFVocabularies::CNT.ContentAsText
67
+ end
68
+ end
69
+
70
+ describe 'tag' do
71
+ it "should be empty array if we haven't set it" do
72
+ expect(subject.tag).to match_array([])
73
+ end
74
+
75
+ it "should be settable" do
76
+ subject.tag = "good"
77
+ expect(subject.tag).to eq ["good"]
78
+ end
79
+
80
+ it "should be changeable" do
81
+ subject.tag = "good"
82
+ subject.tag = "new_good"
83
+ expect(subject.tag).to eq ["new_good"]
84
+ end
85
+ end
86
+
87
+ describe "#annotations_using" do
88
+
89
+ context "when tag value is nil" do
90
+ it "should throw invalid arguement exception" do
91
+ expect{ LD4L::OpenAnnotationRDF::TagBody.annotations_using(nil) }.to raise_error
92
+ end
93
+ end
94
+
95
+ context "when tag value is a string of 0 length" do
96
+ it "should throw invalid arguement exception" do
97
+ expect{ LD4L::OpenAnnotationRDF::TagBody.annotations_using("") }.to raise_error
98
+ end
99
+ end
100
+
101
+ context "when tag value is not a string" do
102
+ it "should throw invalid arguement exception" do
103
+ expect{ LD4L::OpenAnnotationRDF::TagBody.annotations_using(3) }.to raise_error
104
+ end
105
+ end
106
+
107
+ context "when tags exist in the repository" do
108
+ before(:all) do
109
+ # Create inmemory repository
110
+ ta = LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta1')
111
+ ta.setTag('EXISTING_tag')
112
+ ta.persist!
113
+ ta = LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta2')
114
+ ta.setTag('EXISTING_tag')
115
+ ta.persist!
116
+ tb = LD4L::OpenAnnotationRDF::TagBody.new('http://example.org/UNUSED_tag')
117
+ tb.tag = 'UNUSED_tag'
118
+ tb.persist!
119
+ end
120
+ after(:all) do
121
+ LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta1').destroy!
122
+ LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta2').destroy!
123
+ LD4L::OpenAnnotationRDF::TagBody.new('http://example.org/UNUSED_tag').destroy!
124
+ end
125
+
126
+ it "should find annotations using a tag" do
127
+ annotations = LD4L::OpenAnnotationRDF::TagBody.annotations_using('EXISTING_tag')
128
+ expect( annotations.include?(RDF::URI('http://example.org/ta1')) ).to be true
129
+ expect( annotations.include?(RDF::URI('http://example.org/ta2')) ).to be true
130
+ expect( annotations.size ).to be 2
131
+ end
132
+
133
+ it "should find 0 annotations for unused tag" do
134
+ annotations = LD4L::OpenAnnotationRDF::TagBody.annotations_using('UNUSED_tag')
135
+ expect( annotations ).to eq []
136
+ end
137
+
138
+ it "should find 0 annotations for non-existent tag" do
139
+ annotations = LD4L::OpenAnnotationRDF::TagBody.annotations_using('NONEXISTING_tag')
140
+ expect( annotations ).to eq []
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#fetch_by_tag_value" do
146
+
147
+ context "when new value is nil" do
148
+ it "should throw invalid arguement exception" do
149
+ expect{ LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value(nil) }.to raise_error
150
+ end
151
+ end
152
+
153
+ context "when new value is a string of 0 length" do
154
+ it "should throw invalid arguement exception" do
155
+ expect{ LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value("") }.to raise_error
156
+ end
157
+ end
158
+
159
+ context "when new value is not a string" do
160
+ it "should throw invalid arguement exception" do
161
+ expect{ LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value(3) }.to raise_error
162
+ end
163
+ end
164
+
165
+ context "when tags exist in the repository" do
166
+ before(:all) do
167
+ # Create inmemory repository
168
+ ta = LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta1')
169
+ ta.setTag('EXISTING_tag')
170
+ ta.persist!
171
+ ta = LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta2')
172
+ ta.setTag('EXISTING_tag')
173
+ ta.persist!
174
+ tb = LD4L::OpenAnnotationRDF::TagBody.new('http://example.org/UNUSED_tag')
175
+ tb.tag = 'UNUSED_tag'
176
+ tb.persist!
177
+ end
178
+ after(:all) do
179
+ LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta1').destroy!
180
+ LD4L::OpenAnnotationRDF::TagAnnotation.new('http://example.org/ta2').destroy!
181
+ LD4L::OpenAnnotationRDF::TagBody.new('http://example.org/UNUSED_tag').destroy!
182
+ end
183
+
184
+ it "should not find non-existent tag" do
185
+ expect( LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value('NONEXISTING_tag') ).to be_nil
186
+ end
187
+
188
+ it "should not find existent tag even if not referenced in an annotation" do
189
+ tb = LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value('UNUSED_tag')
190
+ expect( tb ).not_to be_nil
191
+ expect( tb.rdf_subject.to_s ).to eq 'http://example.org/UNUSED_tag'
192
+ end
193
+
194
+ it "should find same existing tag body each time called" do
195
+ tb1 = LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value('EXISTING_tag')
196
+ tb2 = LD4L::OpenAnnotationRDF::TagBody.fetch_by_tag_value('EXISTING_tag')
197
+ expect(tb2.rdf_subject).to eq tb1.rdf_subject
198
+ end
199
+ end
200
+ end
201
+
202
+ describe '#localname_prefix' do
203
+ it "should return default prefix" do
204
+ prefix = LD4L::OpenAnnotationRDF::TagBody.localname_prefix
205
+ expect(prefix).to eq "tb"
206
+ end
207
+ end
208
+
209
+ # -----------------------------------------------
210
+ # END -- Test attributes specific to this model
211
+ # -----------------------------------------------
212
+
213
+
214
+ describe "#persisted?" do
215
+ context 'with a repository' do
216
+ before do
217
+ # Create inmemory repository
218
+ repository = RDF::Repository.new
219
+ allow(subject).to receive(:repository).and_return(repository)
220
+ end
221
+
222
+ context "when the object is new" do
223
+ it "should return false" do
224
+ expect(subject).not_to be_persisted
225
+ end
226
+ end
227
+
228
+ context "when it is saved" do
229
+ before do
230
+ subject.tag = "bla"
231
+ subject.persist!
232
+ end
233
+
234
+ it "should return true" do
235
+ expect(subject).to be_persisted
236
+ end
237
+
238
+ context "and then modified" do
239
+ before do
240
+ subject.tag = "newbla"
241
+ end
242
+
243
+ it "should return true" do
244
+ expect(subject).to be_persisted
245
+ end
246
+ end
247
+ context "and then reloaded" do
248
+ before do
249
+ subject.reload
250
+ end
251
+
252
+ it "should reset the tag" do
253
+ expect(subject.tag).to eq ["bla"]
254
+ end
255
+
256
+ it "should be persisted" do
257
+ expect(subject).to be_persisted
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ describe "#persist!" do
265
+ context "when the repository is set" do
266
+ context "and the item is not a blank node" do
267
+
268
+ subject {LD4L::OpenAnnotationRDF::TagBody.new("123")}
269
+
270
+ before do
271
+ # Create inmemory repository
272
+ @repo = RDF::Repository.new
273
+ allow(subject.class).to receive(:repository).and_return(nil)
274
+ allow(subject).to receive(:repository).and_return(@repo)
275
+ subject.tag = "bla"
276
+ subject.persist!
277
+ end
278
+
279
+ it "should persist to the repository" do
280
+ expect(@repo.statements.first).to eq subject.statements.first
281
+ end
282
+
283
+ it "should delete from the repository" do
284
+ subject.reload
285
+ expect(subject.tag).to eq ["bla"]
286
+ subject.tag = []
287
+ expect(subject.tag).to eq []
288
+ subject.persist!
289
+ subject.reload
290
+ expect(subject.tag).to eq []
291
+ expect(@repo.statements.to_a.length).to eq 2 # Only the 2 type statements
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+ describe '#destroy!' do
298
+ before do
299
+ subject << RDF::Statement(RDF::DC.LicenseDocument, RDF::DC.title, 'LICENSE')
300
+ end
301
+
302
+ subject { LD4L::OpenAnnotationRDF::TagBody.new('456')}
303
+
304
+ it 'should return true' do
305
+ expect(subject.destroy!).to be true
306
+ expect(subject.destroy).to be true
307
+ end
308
+
309
+ it 'should delete the graph' do
310
+ subject.destroy
311
+ expect(subject).to be_empty
312
+ end
313
+ end
314
+
315
+ describe '#rdf_label' do
316
+ subject {LD4L::OpenAnnotationRDF::TagBody.new("123")}
317
+
318
+ it 'should return an array of label values' do
319
+ expect(subject.rdf_label).to be_kind_of Array
320
+ end
321
+
322
+ it 'should return the default label as URI when no title property exists' do
323
+ expect(subject.rdf_label).to eq [RDF::URI("#{LD4L::OpenAnnotationRDF::TagBody.base_uri}123")]
324
+ end
325
+
326
+ it 'should prioritize configured label values' do
327
+ custom_label = RDF::URI('http://example.org/custom_label')
328
+ subject.class.configure :rdf_label => custom_label
329
+ subject << RDF::Statement(subject.rdf_subject, custom_label, RDF::Literal('New Label'))
330
+ expect(subject.rdf_label).to eq ['New Label']
331
+ end
332
+ end
333
+
334
+ describe '#solrize' do
335
+ it 'should return a label for bnodes' do
336
+ expect(subject.solrize).to eq subject.rdf_label
337
+ end
338
+
339
+ it 'should return a string of the resource uri' do
340
+ subject.set_subject! 'http://example.org/moomin'
341
+ expect(subject.solrize).to eq 'http://example.org/moomin'
342
+ end
343
+ end
344
+
345
+ describe 'editing the graph' do
346
+ it 'should write properties when statements are added' do
347
+ subject << RDF::Statement.new(subject.rdf_subject, RDFVocabularies::CNT.chars, 'good')
348
+ expect(subject.tag).to include 'good'
349
+ end
350
+
351
+ it 'should delete properties when statements are removed' do
352
+ subject << RDF::Statement.new(subject.rdf_subject, RDFVocabularies::CNT.chars, 'good')
353
+ subject.delete RDF::Statement.new(subject.rdf_subject, RDFVocabularies::CNT.chars, 'good')
354
+ expect(subject.tag).to eq []
355
+ end
356
+ end
357
+
358
+ describe 'big complex graphs' do
359
+ before do
360
+ class DummyPerson < ActiveTriples::Resource
361
+ configure :type => RDF::URI('http://example.org/Person')
362
+ property :foafname, :predicate => RDF::FOAF.name
363
+ property :publications, :predicate => RDF::FOAF.publications, :class_name => 'DummyDocument'
364
+ property :knows, :predicate => RDF::FOAF.knows, :class_name => DummyPerson
365
+ end
366
+
367
+ class DummyDocument < ActiveTriples::Resource
368
+ configure :type => RDF::URI('http://example.org/Document')
369
+ property :title, :predicate => RDF::DC.title
370
+ property :creator, :predicate => RDF::DC.creator, :class_name => 'DummyPerson'
371
+ end
372
+
373
+ LD4L::OpenAnnotationRDF::TagBody.property :item, :predicate => RDF::DC.relation, :class_name => DummyDocument
374
+ end
375
+
376
+ subject { LD4L::OpenAnnotationRDF::TagBody.new }
377
+
378
+ let (:document1) do
379
+ d = DummyDocument.new
380
+ d.title = 'Document One'
381
+ d
382
+ end
383
+
384
+ let (:document2) do
385
+ d = DummyDocument.new
386
+ d.title = 'Document Two'
387
+ d
388
+ end
389
+
390
+ let (:person1) do
391
+ p = DummyPerson.new
392
+ p.foafname = 'Alice'
393
+ p
394
+ end
395
+
396
+ let (:person2) do
397
+ p = DummyPerson.new
398
+ p.foafname = 'Bob'
399
+ p
400
+ end
401
+
402
+ let (:data) { <<END
403
+ _:1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/SomeClass> .
404
+ _:1 <http://purl.org/dc/terms/relation> _:2 .
405
+ _:2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Document> .
406
+ _:2 <http://purl.org/dc/terms/title> "Document One" .
407
+ _:2 <http://purl.org/dc/terms/creator> _:3 .
408
+ _:2 <http://purl.org/dc/terms/creator> _:4 .
409
+ _:4 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Person> .
410
+ _:4 <http://xmlns.com/foaf/0.1/name> "Bob" .
411
+ _:3 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Person> .
412
+ _:3 <http://xmlns.com/foaf/0.1/name> "Alice" .
413
+ _:3 <http://xmlns.com/foaf/0.1/knows> _:4 ."
414
+ END
415
+ }
416
+
417
+ after do
418
+ Object.send(:remove_const, "DummyDocument")
419
+ Object.send(:remove_const, "DummyPerson")
420
+ end
421
+
422
+ it 'should allow access to deep nodes' do
423
+ document1.creator = [person1, person2]
424
+ document2.creator = person1
425
+ person1.knows = person2
426
+ subject.item = [document1]
427
+ expect(subject.item.first.creator.first.knows.first.foafname).to eq ['Bob']
428
+ end
429
+ end
430
+ end
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+
3
+ describe "LD4L::OpenAnnotationRDF" do
4
+ describe "#configure" do
5
+
6
+ before do
7
+ LD4L::OpenAnnotationRDF.configure do |config|
8
+ config.base_uri = "http://localhost/test/"
9
+ config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid }
10
+ config.unique_tags = false
11
+ end
12
+ class DummyAnnotation < LD4L::OpenAnnotationRDF::Annotation
13
+ configure :type => RDFVocabularies::OA.Annotation, :base_uri => LD4L::OpenAnnotationRDF.configuration.base_uri, :repository => :default
14
+ end
15
+ end
16
+ after do
17
+ LD4L::OpenAnnotationRDF.reset
18
+ Object.send(:remove_const, "DummyAnnotation") if Object
19
+ end
20
+
21
+ it "should return configured value" do
22
+ config = LD4L::OpenAnnotationRDF.configuration
23
+ expect(config.base_uri).to eq "http://localhost/test/"
24
+ expect(config.localname_minter).to be_kind_of Proc
25
+ expect(config.unique_tags).to be false
26
+ end
27
+
28
+ it "should use configured value in DummyAnnotation" do
29
+ oa = DummyAnnotation.new('1')
30
+ expect(oa.rdf_subject.to_s).to eq "http://localhost/test/1"
31
+
32
+ oa = DummyAnnotation.new(ActiveTriples::LocalName::Minter.generate_local_name(
33
+ LD4L::OpenAnnotationRDF::Annotation, 10, 'foo',
34
+ &LD4L::OpenAnnotationRDF.configuration.localname_minter ))
35
+ expect(oa.rdf_subject.to_s.size).to eq 73
36
+ expect(oa.rdf_subject.to_s).to match /http:\/\/localhost\/test\/foo_configured_[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/
37
+ end
38
+ end
39
+
40
+ describe ".reset" do
41
+ before :each do
42
+ LD4L::OpenAnnotationRDF.configure do |config|
43
+ config.base_uri = "http://localhost/test/"
44
+ config.localname_minter = lambda { |prefix=""| prefix+'_configured_'+SecureRandom.uuid }
45
+ config.unique_tags = false
46
+ end
47
+ end
48
+
49
+ it "resets the configuration" do
50
+ LD4L::OpenAnnotationRDF.reset
51
+ config = LD4L::OpenAnnotationRDF.configuration
52
+ expect(config.base_uri).to eq "http://localhost/"
53
+ expect(config.localname_minter).to eq nil
54
+ expect(config.unique_tags).to be true
55
+ end
56
+ end
57
+ end