annotations2triannon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.env_example +44 -0
  3. data/.travis.yml +15 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE +202 -0
  6. data/README.md +31 -0
  7. data/Rakefile +50 -0
  8. data/annotations2triannon.gemspec +58 -0
  9. data/bin/console +5 -0
  10. data/bin/ctags.rb +8 -0
  11. data/bin/dms.rb +175 -0
  12. data/bin/revs.rb +17 -0
  13. data/bin/revs_annotations2csv.sh +66 -0
  14. data/lib/annotations2triannon/annotation_list.rb +37 -0
  15. data/lib/annotations2triannon/configuration.rb +52 -0
  16. data/lib/annotations2triannon/iiif_annotation_list.rb +17 -0
  17. data/lib/annotations2triannon/iiif_collection.rb +56 -0
  18. data/lib/annotations2triannon/iiif_manifest.rb +32 -0
  19. data/lib/annotations2triannon/iiif_navigator.rb +172 -0
  20. data/lib/annotations2triannon/manifest.rb +86 -0
  21. data/lib/annotations2triannon/open_annotation.rb +262 -0
  22. data/lib/annotations2triannon/open_annotation_harvest.rb +37 -0
  23. data/lib/annotations2triannon/resource.rb +264 -0
  24. data/lib/annotations2triannon/revs.rb +263 -0
  25. data/lib/annotations2triannon/revs_db.rb +69 -0
  26. data/lib/annotations2triannon/shared_canvas_annotation_list.rb +18 -0
  27. data/lib/annotations2triannon/shared_canvas_manifest.rb +32 -0
  28. data/lib/annotations2triannon.rb +27 -0
  29. data/lib/rdf/vocab/Content.rb +112 -0
  30. data/lib/rdf/vocab/sc.rb +233 -0
  31. data/lib/requires.rb +69 -0
  32. data/log/.gitignore +4 -0
  33. data/spec/lib/annotations2triannon/configuration_spec.rb +24 -0
  34. data/spec/lib/annotations2triannon/open_annotation_spec.rb +176 -0
  35. data/spec/lib/annotations2triannon/resource_spec.rb +53 -0
  36. data/spec/lib/annotations2triannon_spec.rb +45 -0
  37. data/spec/spec_helper.rb +10 -0
  38. metadata +387 -0
@@ -0,0 +1,233 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # This file generated manually from
3
+ # http://iiif.io/model/shared-canvas/1.0/index.html; it's likely incomplete!
4
+ #
5
+ # Note: this class fails to cooperate with:
6
+ # puts RDF::Graph.load( RDF::SC ).to_ttl
7
+ # That should work, e.g. see:
8
+ # puts RDF::Graph.load( RDF::RDFS ).to_ttl
9
+ #
10
+ require 'rdf'
11
+ module RDF
12
+ class SC < RDF::StrictVocabulary("http://www.shared-canvas.org/ns/")
13
+
14
+ # 2. Canvas Model
15
+ # http://iiif.io/model/shared-canvas/1.0/index.html#CanvasIntro
16
+
17
+ # 2.1 Canvas
18
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Canvas
19
+
20
+ term :Canvas,
21
+ label: 'Canvas'.freeze,
22
+ comment: %(The Class for a Canvas, which is the digital surrogate for a physical page within the model.).freeze,
23
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
24
+ type: 'owl:Class'.freeze
25
+
26
+ property :hasAnnotations,
27
+ label: 'hasAnnotations'.freeze,
28
+ comment: %(The relationship between a Canvas and a list of Annotations that target it or part of it. Each Canvas MAY have one or more lists of related annotations.).freeze,
29
+ domain: 'http://www.shared-canvas.org/ns/Canvas'.freeze,
30
+ range: 'http://www.shared-canvas.org/ns/AnnotationList'.freeze,
31
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
32
+ type: 'owl:ObjectProperty'.freeze
33
+
34
+ # 2.2 Zone
35
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Zone
36
+
37
+ term :Zone,
38
+ label: 'Zone'.freeze,
39
+ comment: %(Zones represent part of one or more Canvases).freeze,
40
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
41
+ type: 'owl:Class'.freeze
42
+
43
+ property :naturalAngle,
44
+ label: 'naturalAngle'.freeze,
45
+ comment: %(The relationship between a Canvas and a list of Annotations that target it or part of it. Each Canvas MAY have one or more lists of related annotations.).freeze,
46
+ domain: 'http://www.shared-canvas.org/ns/Zone'.freeze,
47
+ range: 'rdfs:Literal'.freeze,
48
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
49
+ type: 'owl:DatatypeProperty'.freeze
50
+
51
+
52
+ # 3. Annotations
53
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Annotation
54
+ # Modeled by Open Annotations <http://www.w3.org/ns/oa#>
55
+
56
+ # 3.1 Painting Motivation
57
+ # http://iiif.io/model/shared-canvas/1.0/index.html#BasicAnnotation
58
+
59
+ term :painting,
60
+ label: 'painting'.freeze,
61
+ comment: %(The motivation that represents the distinction between resources that should be painted onto the Canvas, rather than resources that are about the Canvas. If the target of the Annotation is not a Canvas or Zone, then the meaning is left to other communities to define.).freeze,
62
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
63
+ type: 'http://www.w3.org/ns/oa#Motivation'.freeze
64
+
65
+
66
+ # 4. Ordering Model
67
+ # http://iiif.io/model/shared-canvas/1.0/index.html#OrderingIntro
68
+ # The Shared Canvas model starts from the Object Reuse and Exchange
69
+ # specification, which provides a method for ordering based on Proxy nodes,
70
+ # however we introduce a simpler method for the most common case of a
71
+ # single, linear order.
72
+
73
+ # 4.1. Ordered Aggregations
74
+ # http://iiif.io/model/shared-canvas/1.0/index.html#OrderedAggregation
75
+ # Nothing to model here; see ore:Aggregation and rdf:List.
76
+
77
+ # 4.2. Sequences
78
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Sequence
79
+
80
+ term :Sequence,
81
+ label: 'Sequence'.freeze,
82
+ comment: %(An ordered aggregation of Canvases for the purpose of rendering them in that order.).freeze,
83
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
84
+ subClassOf: 'http://www.openarchives.org/ore/terms/Aggregation'.freeze,
85
+ type: 'owl:Class'.freeze
86
+
87
+ property :hasContentRange,
88
+ label: 'hasContentRange'.freeze,
89
+ comment: %(A pointer to an sc:Range which contains the content bearing pages of the sequence. If sc:hasContentRange is not supplied, then it defaults to the entire Sequence.).freeze,
90
+ domain: 'http://www.shared-canvas.org/ns/Sequence'.freeze,
91
+ range: 'http://www.shared-canvas.org/ns/Range'.freeze,
92
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
93
+ type: "owl:ObjectProperty".freeze
94
+
95
+ property :readingDirection,
96
+ label: 'readingDirection'.freeze,
97
+ comment: %("Left-to-Right" or "Right-to-Left" for the reading direction of this sequence for animating page viewers.).freeze,
98
+ domain: 'http://www.shared-canvas.org/ns/Sequence'.freeze,
99
+ range: 'rdfs:Literal'.freeze,
100
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
101
+ type: 'owl:DatatypeProperty'.freeze
102
+
103
+ # 4.3. Ranges
104
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Range
105
+
106
+ term :Range,
107
+ label: 'Range'.freeze,
108
+ comment: %(An ordered aggregation of Canvases for the purpose of rendering them in that order.).freeze,
109
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
110
+ subClassOf: 'http://www.openarchives.org/ore/terms/Aggregation'.freeze,
111
+ type: 'owl:Class'.freeze
112
+
113
+
114
+ # 5. Discovery Model
115
+ # http://iiif.io/model/shared-canvas/1.0/index.html#DiscoveryIntro
116
+
117
+ # 5.1. Annotation Lists
118
+
119
+ term :AnnotationList,
120
+ label: 'AnnotationList'.freeze,
121
+ comment: %(An ordered aggregation of Annotations.).freeze,
122
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
123
+ type: 'owl:Class'.freeze
124
+
125
+ property :forCanvas,
126
+ label: 'forCanvas'.freeze,
127
+ comment: %(The relationship between the AnnotationList and any Canvas that are the targets of the included Annotations. Typically this relationship is used to describe the AnnotationList in a Manifest to allow clients to determine which lists should be retrieved.).freeze,
128
+ domain: ['http://www.shared-canvas.org/ns/AnnotationList'.freeze, 'http://www.shared-canvas.org/ns/Layer'.freeze, 'http://www.shared-canvas.org/ns/Manifest'.freeze],
129
+ range: 'http://www.shared-canvas.org/ns/Canvas'.freeze,
130
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
131
+ type: 'owl:ObjectProperty'.freeze
132
+
133
+ property :forMotivation,
134
+ label: 'forMotivation'.freeze,
135
+ comment: %(A shortcut relationship that implies that all of the Annotations in the list have that particular Motivation. ).freeze,
136
+ domain: ['http://www.shared-canvas.org/ns/AnnotationList'.freeze, 'http://www.shared-canvas.org/ns/Layer'.freeze],
137
+ range: 'http://www.w3.org/ns/oa#Motivation'.freeze,
138
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
139
+ type: 'owl:ObjectProperty'.freeze
140
+
141
+
142
+ # 5.2. Layers
143
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Layer
144
+
145
+ term :Layer,
146
+ label: 'Layer'.freeze,
147
+ comment: %(An ordered aggregation of Annotations or Annotation Lists.).freeze,
148
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
149
+ type: 'owl:Class'.freeze
150
+
151
+ # All of the properties of AnnotationList are also useful for Layer:
152
+ # See sc:forCanvas and sc:forMotivation above.
153
+
154
+ # 5.3. Manifests
155
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Manifest
156
+
157
+ term :Manifest,
158
+ label: 'Manifest'.freeze,
159
+ comment: %(The Manifest is what ties everything together. It is an Aggregation of the Layers, AnnotationLists and Sequences that make up the description of the facsimile. As such the Manifest is representative of the Book, Newspaper, Scroll or whatever physical object is being represented in the facsimile. A Manifest MUST have an rdf:label giving a human readable name for it. This label is to be used for rendering purposes to inform the user what they are looking at.).freeze,
160
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
161
+ type: 'owl:Class'.freeze
162
+
163
+ # sc:Manifest shares the sc:forCanvas property with sc:AnnotationList and sc:Layer.
164
+
165
+ # 5.4. Collections
166
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Collection
167
+ # Shared Canvas does not address collections of Manifests (or of other
168
+ # Collections) directly. Ordered or regular ore:Aggregations are recommended
169
+ # as the basis of describing collections in a manner that would be compliant
170
+ # with the Shared Canvas guidelines.
171
+
172
+
173
+ # 5.5. Services and Bibliographic Information
174
+ # http://iiif.io/model/shared-canvas/1.0/index.html#Collection-Info
175
+
176
+ property :hasRelatedService,
177
+ label: 'hasRelatedService'.freeze,
178
+ comment: %(The relationship between a resource in the Shared Canvas model and the endpoint for a related service.).freeze,
179
+ domain: 'owl:Thing'.freeze, # ?
180
+ range: 'owl:Thing'.freeze, # ?
181
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
182
+ type: 'owl:ObjectProperty'.freeze
183
+
184
+ property :hasRelatedDescription,
185
+ label: 'hasRelatedDescription'.freeze,
186
+ comment: %(The relationship between a resource in the Shared Canvas model and a related description of the real world object.).freeze,
187
+ domain: 'owl:Thing'.freeze, # ?
188
+ range: 'owl:Thing'.freeze, # ?
189
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
190
+ type: 'owl:ObjectProperty'.freeze
191
+
192
+ property :agentLabel,
193
+ label: 'agentLabel'.freeze,
194
+ comment: %(A name and possibly role of a person or organization associated with the physical object which is being represented by the Shared Canvas object. For example: "Froissart (author)").freeze,
195
+ domain: 'owl:Thing'.freeze, # ?
196
+ range: 'rdfs:Literal'.freeze,
197
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
198
+ type: 'owl:DatatypeProperty'.freeze
199
+
200
+ property :dateLabel,
201
+ label: 'dateLabel'.freeze,
202
+ comment: %(A date or date range and possiby role associated with the physical object. For example: "Illustrated c. 1200").freeze,
203
+ domain: 'owl:Thing'.freeze, # ?
204
+ range: 'rdfs:Literal'.freeze,
205
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
206
+ type: 'owl:DatatypeProperty'.freeze
207
+
208
+ property :locationLabel,
209
+ label: 'locationLabel'.freeze,
210
+ comment: %(A location and possibly role associated with the physical object. For example: "Paris, France (created)").freeze,
211
+ domain: 'owl:Thing'.freeze, # ?
212
+ range: 'rdfs:Literal'.freeze,
213
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
214
+ type: 'owl:DatatypeProperty'.freeze
215
+
216
+ property :attributionLabel,
217
+ label: 'attributionLabel'.freeze,
218
+ comment: %(An attribution that must be displayed along with the resource. For example: "Held at A Library (NY)").freeze,
219
+ domain: 'owl:Thing'.freeze, # ?
220
+ range: 'rdfs:Literal'.freeze,
221
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
222
+ type: 'owl:DatatypeProperty'.freeze
223
+
224
+ property :rightsLabel,
225
+ label: 'rightsLabel'.freeze,
226
+ comment: %(A rights or license statement, describing how the facsimile may be reused.).freeze,
227
+ domain: 'owl:Thing'.freeze, # ?
228
+ range: 'rdfs:Literal'.freeze,
229
+ 'rdfs:isDefinedBy' => 'http://www.shared-canvas.org/ns/'.freeze,
230
+ type: 'owl:DatatypeProperty'.freeze
231
+
232
+ end
233
+ end
data/lib/requires.rb ADDED
@@ -0,0 +1,69 @@
1
+ require 'dotenv'
2
+ Dotenv.load
3
+
4
+ require 'pry'
5
+ require 'pry-doc'
6
+
7
+ # Using rest-client with options to enable
8
+ # a client HTTP cache
9
+ require 'rest-client'
10
+ RestClient.proxy = ENV['http_proxy'] unless ENV['http_proxy'].nil?
11
+ RestClient.proxy = ENV['HTTP_PROXY'] unless ENV['HTTP_PROXY'].nil?
12
+ if ENV['RACK_CACHE_ENABLED'].to_s.upcase == 'TRUE'
13
+ require 'dalli'
14
+ require 'restclient/components'
15
+ require 'rack/cache'
16
+ # RestClient.enable Rack::CommonLogger
17
+ RestClient.enable Rack::CommonLogger, STDOUT
18
+ # Enable the HTTP cache to store meta and entity data according
19
+ # to the env config values or the defaults given here. See
20
+ # http://rtomayko.github.io/rack-cache/configuration for available options.
21
+ metastore = ENV['RACK_CACHE_METASTORE'] || 'file:/tmp/cache/meta'
22
+ entitystore = ENV['RACK_CACHE_ENTITYSTORE'] || 'file:/tmp/cache/body'
23
+ verbose = ENV['RACK_CACHE_VERBOSE'].to_s.upcase == 'TRUE' || false
24
+ RestClient.enable Rack::Cache,
25
+ :metastore => metastore, :entitystore => entitystore, :verbose => verbose
26
+ # Prime the HTTP cache with some common json-ld contexts used for
27
+ # IIIF and open annotations.
28
+ contexts = [
29
+ 'http://iiif.io/api/image/1/context.json',
30
+ 'http://iiif.io/api/image/2/context.json',
31
+ 'http://iiif.io/api/presentation/1/context.json',
32
+ 'http://iiif.io/api/presentation/2/context.json',
33
+ 'http://www.shared-canvas.org/ns/context.json'
34
+ ]
35
+ contexts.each {|c| RestClient.get c }
36
+ end
37
+
38
+ require 'addressable/uri'
39
+ require 'json'
40
+ require 'uuid'
41
+
42
+ require 'linkeddata'
43
+ require 'rdf/iiif'
44
+ require 'rdf-vocab'
45
+ require_relative 'rdf/vocab/Content.rb'
46
+ require_relative 'rdf/vocab/sc.rb'
47
+
48
+ require 'triannon-client'
49
+
50
+ # OpenAnnotationHarvest module (standalone module for includes)
51
+ require_relative 'annotations2triannon/open_annotation_harvest'
52
+
53
+ # Annotations2triannon module
54
+ require_relative 'annotations2triannon/configuration'
55
+ require_relative 'annotations2triannon/resource'
56
+ require_relative 'annotations2triannon/manifest'
57
+ require_relative 'annotations2triannon/annotation_list'
58
+ require_relative 'annotations2triannon/iiif_collection'
59
+ require_relative 'annotations2triannon/iiif_manifest'
60
+ require_relative 'annotations2triannon/iiif_annotation_list'
61
+ require_relative 'annotations2triannon/shared_canvas_manifest'
62
+ require_relative 'annotations2triannon/shared_canvas_annotation_list'
63
+ require_relative 'annotations2triannon/open_annotation'
64
+ require_relative 'annotations2triannon/iiif_navigator'
65
+
66
+ if ENV['REVS_ENABLED'].to_s.upcase == 'TRUE'
67
+ require_relative 'annotations2triannon/revs'
68
+ end
69
+
data/log/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ module Annotations2triannon
4
+
5
+ describe Configuration do
6
+
7
+ describe '#debug' do
8
+ it 'default value is false' do
9
+ ENV['DEBUG'] = nil
10
+ config = Configuration.new
11
+ expect(config.debug).to be_falsey
12
+ end
13
+ end
14
+
15
+ describe '#debug=' do
16
+ it 'can set value' do
17
+ config = Configuration.new
18
+ config.debug = true
19
+ expect(config.debug).to be_truthy
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ describe Annotations2triannon::OpenAnnotation do
4
+
5
+ let(:g1) {
6
+ Annotations2triannon::OpenAnnotation.new RDF::Graph.new.from_ttl("
7
+ <http://my.identifiers.com/oa_comment> a <http://www.w3.org/ns/oa#Annotation>;
8
+ <http://www.w3.org/ns/oa#hasBody> [
9
+ a <http://www.w3.org/2011/content#ContentAsText>,
10
+ <http://purl.org/dc/dcmitype/Text>;
11
+ <http://www.w3.org/2011/content#chars> \"I love this!\"
12
+ ];
13
+ <http://www.w3.org/ns/oa#hasTarget> <http://purl.stanford.edu/kq131cs7229>;
14
+ <http://www.w3.org/ns/oa#motivatedBy> <http://www.w3.org/ns/oa#commenting> ;
15
+ <http://www.w3.org/ns/oa#annotatedBy> <http://my.identifiers.com/contributor> . ")
16
+ }
17
+
18
+ let(:g2) {
19
+ Annotations2triannon::OpenAnnotation.new RDF::Graph.new.from_jsonld(
20
+ '{
21
+ "@context": "http://www.w3.org/ns/oa-context-20130208.json",
22
+ "@id": "http://my.identifiers.com/oa_bookmark",
23
+ "@type": "oa:Annotation",
24
+ "motivatedBy": "oa:bookmarking",
25
+ "hasTarget": "http://purl.stanford.edu/kq131cs7229"
26
+ }' )
27
+ }
28
+
29
+ let(:g3) {
30
+ Annotations2triannon::OpenAnnotation.new RDF::Graph.new.from_jsonld(
31
+ '{
32
+ "@context": "http://www.w3.org/ns/oa-context-20130208.json",
33
+ "@id": "http://my.identifiers.com/oa_empty",
34
+ "@type": "oa:Annotation"
35
+ }' )
36
+ }
37
+
38
+ context '#annotatedBy' do
39
+ it 'returns an array' do
40
+ expect(g1.annotatedBy).to be_a Array
41
+ expect(g1.annotatedBy).not_to be_empty
42
+ expect(g3.annotatedBy).to be_a Array
43
+ expect(g3.annotatedBy).to be_empty
44
+ end
45
+ end
46
+
47
+ context '#annotatedBy?' do
48
+ it 'returns a boolean' do
49
+ expect(g1.annotatedBy?).to be_truthy
50
+ expect(g2.annotatedBy?).to be_falsy
51
+ expect(g3.annotatedBy?).to be_falsy
52
+ end
53
+ it 'accepts a string URI' do
54
+ uri = 'http://my.identifiers.com/contributor'
55
+ expect(g1.annotatedBy? uri).to be_truthy
56
+ expect(g2.annotatedBy? uri).to be_falsy
57
+ expect(g3.annotatedBy? uri).to be_falsy
58
+ end
59
+ it 'accepts an Addressable::URI' do
60
+ uri = 'http://my.identifiers.com/contributor'
61
+ uri = Addressable::URI.parse(uri)
62
+ expect(g1.annotatedBy? uri).to be_truthy
63
+ expect(g2.annotatedBy? uri).to be_falsy
64
+ expect(g3.annotatedBy? uri).to be_falsy
65
+ end
66
+ it 'accepts an RDF::URI' do
67
+ uri = 'http://my.identifiers.com/contributor'
68
+ uri = RDF::URI.parse(uri)
69
+ expect(g1.annotatedBy? uri).to be_truthy
70
+ expect(g2.annotatedBy? uri).to be_falsy
71
+ expect(g3.annotatedBy? uri).to be_falsy
72
+ end
73
+ end
74
+
75
+ context '#hasBody' do
76
+ it 'returns an array' do
77
+ expect(g1.hasBody).to be_a Array
78
+ expect(g1.hasBody).not_to be_empty
79
+ expect(g2.hasBody).to be_a Array
80
+ expect(g2.hasBody).to be_empty
81
+ expect(g3.hasBody).to be_a Array
82
+ expect(g3.hasBody).to be_empty
83
+ end
84
+ end
85
+
86
+ context '#hasBody?' do
87
+ it 'returns a boolean' do
88
+ expect(g1.hasBody?).to be_truthy
89
+ expect(g2.hasBody?).to be_falsy # note g1 and g2 are truthy here
90
+ expect(g3.hasBody?).to be_falsy
91
+ end
92
+ end
93
+
94
+ context '#hasTarget' do
95
+ it 'returns an array' do
96
+ expect(g1.hasTarget).to be_a Array
97
+ expect(g1.hasTarget).not_to be_empty
98
+ expect(g2.hasTarget).to be_a Array
99
+ expect(g2.hasTarget).not_to be_empty
100
+ expect(g3.hasTarget).to be_a Array
101
+ expect(g3.hasTarget).to be_empty
102
+ end
103
+ end
104
+
105
+ context '#hasTarget?' do
106
+ it 'returns a boolean' do
107
+ expect(g1.hasTarget?).to be_truthy
108
+ expect(g2.hasTarget?).to be_truthy
109
+ expect(g3.hasTarget?).to be_falsy
110
+ end
111
+ end
112
+
113
+ context '#motivatedBy' do
114
+ uri = 'http://www.w3.org/ns/oa#commenting'
115
+ def expect_motivatedBy(uri)
116
+ expect(g1.motivatedBy uri).not_to be_empty
117
+ expect(g2.motivatedBy uri).to be_empty # note g1 and g2 differ here
118
+ expect(g3.motivatedBy uri).to be_empty
119
+ end
120
+ it 'returns an array' do
121
+ expect(g1.motivatedBy).to be_a Array
122
+ expect(g1.motivatedBy).not_to be_empty
123
+ expect(g3.motivatedBy).to be_a Array
124
+ expect(g3.motivatedBy).to be_empty
125
+ end
126
+ it 'accepts a string URI' do
127
+ expect_motivatedBy uri
128
+ end
129
+ it 'accepts an Addressable::URI' do
130
+ expect_motivatedBy Addressable::URI.parse(uri)
131
+ end
132
+ it 'accepts an RDF::URI' do
133
+ expect_motivatedBy RDF::URI.parse(uri)
134
+ end
135
+ end
136
+
137
+ context '#motivatedBy?' do
138
+ uri = 'http://www.w3.org/ns/oa#commenting'
139
+ def expect_motivatedBy?(uri)
140
+ expect(g1.motivatedBy? uri).to be_truthy
141
+ expect(g2.motivatedBy? uri).to be_falsy # note g1 and g2 differ here
142
+ expect(g3.motivatedBy? uri).to be_falsy
143
+ end
144
+ it 'returns a boolean' do
145
+ expect(g1.motivatedBy?).to be_truthy
146
+ expect(g2.motivatedBy?).to be_truthy # note g1 and g2 are truthy here
147
+ expect(g3.motivatedBy?).to be_falsy
148
+ end
149
+ it 'accepts a string URI' do
150
+ expect_motivatedBy? uri
151
+ end
152
+ it 'accepts an Addressable::URI' do
153
+ expect_motivatedBy? Addressable::URI.parse(uri)
154
+ end
155
+ it 'accepts an RDF::URI' do
156
+ expect_motivatedBy? RDF::URI.parse(uri)
157
+ end
158
+ end
159
+
160
+ context '#open_annotation?' do
161
+ it 'returns a boolean' do
162
+ expect(g1.open_annotation?).to be_truthy
163
+ expect(g2.open_annotation?).to be_falsy # note g1 and g2 are truthy here
164
+ expect(g3.open_annotation?).to be_falsy
165
+ end
166
+ end
167
+
168
+ context '#is_annotation?' do
169
+ it 'returns a boolean' do
170
+ expect(g1.is_annotation?).to be_truthy
171
+ expect(g2.is_annotation?).to be_truthy
172
+ expect(g3.is_annotation?).to be_truthy
173
+ end
174
+ end
175
+
176
+ end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ module Annotations2triannon
4
+
5
+ describe Resource do
6
+
7
+ before :all do
8
+ @auth_id = 'no99010609'
9
+ @auth_url = 'http://id.loc.gov/authorities/names/no99010609'
10
+ @auth = Resource.new @auth_url
11
+ end
12
+
13
+ before :each do
14
+ end
15
+
16
+ describe '#initialize' do
17
+ it 'should not raise error for a valid iri' do
18
+ # iri_valid = 'http://id.loc.gov/authorities/names/no99010609'
19
+ expect{Resource.new @auth_url}.not_to raise_error
20
+ end
21
+ it 'should raise error for an invalid iri' do
22
+ expect{Resource.new 'This is not a URL'}.to raise_error(RuntimeError)
23
+ end
24
+ end
25
+
26
+ describe '#id' do
27
+ it 'should equal the url basename' do
28
+ expect(@auth.id).to eq(@auth_id)
29
+ end
30
+ end
31
+
32
+ describe '#iri' do
33
+ it 'should equal the auth url' do
34
+ expect(@auth.iri.to_s).to eq(@auth_url)
35
+ end
36
+ it 'should be an instance of Addressable::URI' do
37
+ expect(@auth.iri.instance_of? Addressable::URI).to be_truthy
38
+ end
39
+ end
40
+
41
+ after :each do
42
+ end
43
+
44
+ after :all do
45
+ @auth_url = nil
46
+ @auth = nil
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Annotations2triannon do
4
+
5
+ describe ".configuration" do
6
+ it "should be a configuration object" do
7
+ expect(described_class.configuration).to be_a_kind_of Annotations2triannon::Configuration
8
+ end
9
+ end
10
+
11
+ describe "#configure" do
12
+ before :each do
13
+ Annotations2triannon.configure do |config|
14
+ config.debug = true
15
+ end
16
+ end
17
+ it "returns a hash of options" do
18
+ config = Annotations2triannon.configuration
19
+ expect(config).to be_instance_of Annotations2triannon::Configuration
20
+ expect(config.debug).to be_truthy
21
+ end
22
+ after :each do
23
+ Annotations2triannon.reset
24
+ end
25
+ end
26
+
27
+ describe ".reset" do
28
+ before :each do
29
+ Annotations2triannon.configure do |config|
30
+ config.debug = true
31
+ end
32
+ end
33
+ it "resets the configuration" do
34
+ Annotations2triannon.reset
35
+ config = Annotations2triannon.configuration
36
+ expect(config).to be_instance_of Annotations2triannon::Configuration
37
+ expect(config.debug).to be_falsey
38
+ end
39
+ after :each do
40
+ Annotations2triannon.reset
41
+ end
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,10 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'annotations2triannon'
5
+
6
+ require 'rspec'
7
+
8
+ RSpec.configure do |config|
9
+
10
+ end