annotations2triannon 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.env_example +44 -0
- data/.travis.yml +15 -0
- data/Gemfile +5 -0
- data/LICENSE +202 -0
- data/README.md +31 -0
- data/Rakefile +50 -0
- data/annotations2triannon.gemspec +58 -0
- data/bin/console +5 -0
- data/bin/ctags.rb +8 -0
- data/bin/dms.rb +175 -0
- data/bin/revs.rb +17 -0
- data/bin/revs_annotations2csv.sh +66 -0
- data/lib/annotations2triannon/annotation_list.rb +37 -0
- data/lib/annotations2triannon/configuration.rb +52 -0
- data/lib/annotations2triannon/iiif_annotation_list.rb +17 -0
- data/lib/annotations2triannon/iiif_collection.rb +56 -0
- data/lib/annotations2triannon/iiif_manifest.rb +32 -0
- data/lib/annotations2triannon/iiif_navigator.rb +172 -0
- data/lib/annotations2triannon/manifest.rb +86 -0
- data/lib/annotations2triannon/open_annotation.rb +262 -0
- data/lib/annotations2triannon/open_annotation_harvest.rb +37 -0
- data/lib/annotations2triannon/resource.rb +264 -0
- data/lib/annotations2triannon/revs.rb +263 -0
- data/lib/annotations2triannon/revs_db.rb +69 -0
- data/lib/annotations2triannon/shared_canvas_annotation_list.rb +18 -0
- data/lib/annotations2triannon/shared_canvas_manifest.rb +32 -0
- data/lib/annotations2triannon.rb +27 -0
- data/lib/rdf/vocab/Content.rb +112 -0
- data/lib/rdf/vocab/sc.rb +233 -0
- data/lib/requires.rb +69 -0
- data/log/.gitignore +4 -0
- data/spec/lib/annotations2triannon/configuration_spec.rb +24 -0
- data/spec/lib/annotations2triannon/open_annotation_spec.rb +176 -0
- data/spec/lib/annotations2triannon/resource_spec.rb +53 -0
- data/spec/lib/annotations2triannon_spec.rb +45 -0
- data/spec/spec_helper.rb +10 -0
- metadata +387 -0
data/lib/rdf/vocab/sc.rb
ADDED
@@ -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,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
|
+
|