iiif-presentation 1.4.1 → 1.5.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +8 -1
- data/.standard.yml +1 -0
- data/Gemfile +5 -5
- data/README.md +1 -1
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/bin/standardrb +16 -0
- data/iiif-presentation.gemspec +23 -23
- data/lib/iiif/hash_behaviours.rb +29 -33
- data/lib/iiif/ordered_hash.rb +33 -33
- data/lib/iiif/presentation/abstract_resource.rb +17 -22
- data/lib/iiif/presentation/annotation.rb +9 -11
- data/lib/iiif/presentation/annotation_list.rb +8 -10
- data/lib/iiif/presentation/canvas.rb +11 -13
- data/lib/iiif/presentation/collection.rb +7 -9
- data/lib/iiif/presentation/image_resource.rb +33 -35
- data/lib/iiif/presentation/layer.rb +8 -10
- data/lib/iiif/presentation/manifest.rb +9 -12
- data/lib/iiif/presentation/range.rb +8 -10
- data/lib/iiif/presentation/resource.rb +5 -7
- data/lib/iiif/presentation/sequence.rb +8 -11
- data/lib/iiif/presentation/service.rb +1 -2
- data/lib/iiif/presentation.rb +7 -7
- data/lib/iiif/service.rb +121 -102
- data/lib/iiif/v3/abstract_resource.rb +132 -144
- data/lib/iiif/v3/presentation/annotation.rb +20 -21
- data/lib/iiif/v3/presentation/annotation_collection.rb +7 -9
- data/lib/iiif/v3/presentation/annotation_page.rb +14 -15
- data/lib/iiif/v3/presentation/canvas.rb +21 -22
- data/lib/iiif/v3/presentation/choice.rb +14 -15
- data/lib/iiif/v3/presentation/collection.rb +7 -8
- data/lib/iiif/v3/presentation/image_resource.rb +21 -22
- data/lib/iiif/v3/presentation/manifest.rb +18 -19
- data/lib/iiif/v3/presentation/nav_place.rb +125 -29
- data/lib/iiif/v3/presentation/range.rb +10 -10
- data/lib/iiif/v3/presentation/resource.rb +4 -5
- data/lib/iiif/v3/presentation/sequence.rb +10 -11
- data/lib/iiif/v3/presentation/service.rb +12 -13
- data/lib/iiif/v3/presentation.rb +8 -8
- data/spec/integration/iiif/presentation/image_resource_spec.rb +54 -58
- data/spec/integration/iiif/service_spec.rb +76 -77
- data/spec/integration/iiif/v3/abstract_resource_spec.rb +73 -73
- data/spec/integration/iiif/v3/presentation/image_resource_spec.rb +53 -56
- data/spec/spec_helper.rb +56 -64
- data/spec/unit/iiif/hash_behaviours_spec.rb +384 -387
- data/spec/unit/iiif/ordered_hash_spec.rb +86 -91
- data/spec/unit/iiif/presentation/abstract_resource_spec.rb +64 -70
- data/spec/unit/iiif/presentation/annotation_list_spec.rb +1 -3
- data/spec/unit/iiif/presentation/annotation_spec.rb +1 -3
- data/spec/unit/iiif/presentation/canvas_spec.rb +11 -14
- data/spec/unit/iiif/presentation/collection_spec.rb +26 -33
- data/spec/unit/iiif/presentation/image_resource_spec.rb +4 -6
- data/spec/unit/iiif/presentation/layer_spec.rb +16 -20
- data/spec/unit/iiif/presentation/manifest_spec.rb +45 -48
- data/spec/unit/iiif/presentation/range_spec.rb +18 -22
- data/spec/unit/iiif/presentation/resource_spec.rb +3 -6
- data/spec/unit/iiif/presentation/sequence_spec.rb +58 -63
- data/spec/unit/iiif/presentation/shared_examples/abstract_resource_only_keys.rb +4 -10
- data/spec/unit/iiif/presentation/shared_examples/any_type_keys.rb +5 -9
- data/spec/unit/iiif/presentation/shared_examples/array_only_keys.rb +9 -17
- data/spec/unit/iiif/presentation/shared_examples/int_only_keys.rb +6 -14
- data/spec/unit/iiif/presentation/shared_examples/string_only_keys.rb +6 -13
- data/spec/unit/iiif/service_spec.rb +8 -13
- data/spec/unit/iiif/v3/abstract_resource_define_methods_for_spec.rb +39 -37
- data/spec/unit/iiif/v3/abstract_resource_spec.rb +128 -143
- data/spec/unit/iiif/v3/presentation/annotation_collection_spec.rb +14 -17
- data/spec/unit/iiif/v3/presentation/annotation_page_spec.rb +71 -69
- data/spec/unit/iiif/v3/presentation/annotation_spec.rb +249 -233
- data/spec/unit/iiif/v3/presentation/canvas_spec.rb +211 -193
- data/spec/unit/iiif/v3/presentation/choice_spec.rb +81 -77
- data/spec/unit/iiif/v3/presentation/collection_spec.rb +24 -29
- data/spec/unit/iiif/v3/presentation/image_resource_spec.rb +70 -71
- data/spec/unit/iiif/v3/presentation/manifest_spec.rb +248 -237
- data/spec/unit/iiif/v3/presentation/nav_place_spec.rb +249 -49
- data/spec/unit/iiif/v3/presentation/range_spec.rb +28 -29
- data/spec/unit/iiif/v3/presentation/resource_spec.rb +83 -82
- data/spec/unit/iiif/v3/presentation/sequence_spec.rb +126 -120
- data/spec/unit/iiif/v3/presentation/service_spec.rb +123 -124
- data/spec/unit/iiif/v3/presentation/shared_examples/abstract_resource_only_keys.rb +4 -8
- data/spec/unit/iiif/v3/presentation/shared_examples/any_type_keys.rb +5 -7
- data/spec/unit/iiif/v3/presentation/shared_examples/array_only_keys.rb +9 -13
- data/spec/unit/iiif/v3/presentation/shared_examples/hash_only_keys.rb +9 -13
- data/spec/unit/iiif/v3/presentation/shared_examples/int_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/numeric_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/string_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/uri_only_keys.rb +9 -13
- metadata +27 -69
|
@@ -1,147 +1,149 @@
|
|
|
1
1
|
describe IIIF::V3::Presentation::Resource do
|
|
2
|
-
describe
|
|
3
|
-
it
|
|
4
|
-
expect(subject.required_keys).to include(
|
|
2
|
+
describe "#required_keys" do
|
|
3
|
+
it "id" do
|
|
4
|
+
expect(subject.required_keys).to include("id")
|
|
5
5
|
end
|
|
6
|
-
it
|
|
7
|
-
expect(subject.required_keys).to include(
|
|
6
|
+
it "type" do
|
|
7
|
+
expect(subject.required_keys).to include("type")
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
describe
|
|
12
|
-
it
|
|
11
|
+
describe "#prohibited_keys" do
|
|
12
|
+
it "contains the expected key names" do
|
|
13
13
|
keys = described_class::PAGING_PROPERTIES +
|
|
14
|
-
%w
|
|
14
|
+
%w[
|
|
15
15
|
nav_date
|
|
16
16
|
viewing_direction
|
|
17
17
|
start_canvas
|
|
18
18
|
content_annotations
|
|
19
|
-
|
|
19
|
+
]
|
|
20
20
|
expect(subject.prohibited_keys).to include(*keys)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
describe
|
|
25
|
-
it
|
|
26
|
-
expect(subject.uri_only_keys).to include(
|
|
24
|
+
describe "#uri_only_keys" do
|
|
25
|
+
it "id" do
|
|
26
|
+
expect(subject.uri_only_keys).to include("id")
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
describe
|
|
31
|
-
it
|
|
30
|
+
describe "#initialize" do
|
|
31
|
+
it "allows subclasses to override type" do
|
|
32
32
|
subclass = Class.new(described_class) do
|
|
33
|
-
def initialize(
|
|
34
|
-
|
|
35
|
-
super(hsh)
|
|
33
|
+
def initialize(_hsh = {})
|
|
34
|
+
super({"type" => "a:SubClass"})
|
|
36
35
|
end
|
|
37
36
|
end
|
|
38
37
|
sub = subclass.new
|
|
39
|
-
expect(sub[
|
|
38
|
+
expect(sub["type"]).to eq "a:SubClass"
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
describe
|
|
44
|
-
it
|
|
45
|
-
subject[
|
|
46
|
-
subject[
|
|
42
|
+
describe "#validate" do
|
|
43
|
+
it "raises an IllegalValueError if id is not URI" do
|
|
44
|
+
subject["id"] = "foo"
|
|
45
|
+
subject["type"] = "image/jpeg"
|
|
47
46
|
exp_err_msg = "id value must be a String containing a URI for #{described_class}"
|
|
48
47
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
|
|
49
48
|
end
|
|
50
|
-
it
|
|
51
|
-
subject[
|
|
52
|
-
subject[
|
|
49
|
+
it "raises an IllegalValueError if id is not http" do
|
|
50
|
+
subject["id"] = "ftp://www.example.org"
|
|
51
|
+
subject["type"] = "image/jpeg"
|
|
53
52
|
exp_err_msg = "id must be an http(s) URI for #{described_class}"
|
|
54
53
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
|
|
55
54
|
end
|
|
56
55
|
end
|
|
57
56
|
|
|
58
|
-
describe
|
|
59
|
-
describe
|
|
60
|
-
describe
|
|
61
|
-
let(:file_id) {
|
|
62
|
-
let(:file_type) {
|
|
63
|
-
let(:file_mimetype) {
|
|
64
|
-
let(:resource_object) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
57
|
+
describe "realistic examples" do
|
|
58
|
+
describe "non-image examples from http://prezi3.iiif.io/api/presentation/3.0" do
|
|
59
|
+
describe "audio" do
|
|
60
|
+
let(:file_id) { "http://example.org/iiif/book1/res/music.mp3" }
|
|
61
|
+
let(:file_type) { "dctypes:Sound" }
|
|
62
|
+
let(:file_mimetype) { "audio/mpeg" }
|
|
63
|
+
let(:resource_object) {
|
|
64
|
+
IIIF::V3::Presentation::Resource.new({
|
|
65
|
+
"id" => file_id,
|
|
66
|
+
"type" => file_type,
|
|
67
|
+
"format" => file_mimetype
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
it "validates" do
|
|
71
|
+
expect { resource_object.validate }.not_to raise_error
|
|
71
72
|
end
|
|
72
|
-
it
|
|
73
|
+
it "has expected required values" do
|
|
73
74
|
expect(resource_object.id).to eq file_id
|
|
74
75
|
end
|
|
75
|
-
it
|
|
76
|
+
it "has expected other values" do
|
|
76
77
|
expect(resource_object.type).to eq file_type
|
|
77
78
|
expect(resource_object.format).to eq file_mimetype
|
|
78
79
|
expect(resource_object.service).to eq []
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
|
-
describe
|
|
82
|
-
let(:file_id) {
|
|
83
|
-
let(:file_type) {
|
|
84
|
-
let(:file_mimetype) {
|
|
85
|
-
let(:resource_object) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
describe "text" do
|
|
83
|
+
let(:file_id) { "http://example.org/iiif/book1/res/tei-text-p1.xml" }
|
|
84
|
+
let(:file_type) { "dctypes:Text" }
|
|
85
|
+
let(:file_mimetype) { "application/tei+xml" }
|
|
86
|
+
let(:resource_object) {
|
|
87
|
+
IIIF::V3::Presentation::Resource.new({
|
|
88
|
+
"id" => file_id,
|
|
89
|
+
"type" => file_type,
|
|
90
|
+
"format" => file_mimetype
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
it "validates" do
|
|
94
|
+
expect { resource_object.validate }.not_to raise_error
|
|
92
95
|
end
|
|
93
|
-
it
|
|
96
|
+
it "has expected required values" do
|
|
94
97
|
expect(resource_object.id).to eq file_id
|
|
95
98
|
end
|
|
96
|
-
it
|
|
99
|
+
it "has expected other values" do
|
|
97
100
|
expect(resource_object.type).to eq file_type
|
|
98
101
|
expect(resource_object.format).to eq file_mimetype
|
|
99
102
|
expect(resource_object.service).to eq []
|
|
100
103
|
end
|
|
101
104
|
end
|
|
102
|
-
|
|
103
105
|
end
|
|
104
|
-
describe
|
|
105
|
-
describe
|
|
106
|
-
let(:file_id) {
|
|
107
|
-
let(:file_type) {
|
|
108
|
-
let(:file_mimetype) {
|
|
106
|
+
describe "stanford" do
|
|
107
|
+
describe "non-image resource per purl code" do
|
|
108
|
+
let(:file_id) { "https://example.org/file/abc666/ocr.txt" }
|
|
109
|
+
let(:file_type) { "Document" }
|
|
110
|
+
let(:file_mimetype) { "text/plain" }
|
|
109
111
|
let(:resource_object) {
|
|
110
112
|
resource = IIIF::V3::Presentation::Resource.new
|
|
111
|
-
resource[
|
|
112
|
-
resource[
|
|
113
|
+
resource["id"] = file_id
|
|
114
|
+
resource["type"] = file_type
|
|
113
115
|
resource.format = file_mimetype
|
|
114
116
|
resource
|
|
115
117
|
}
|
|
116
|
-
describe
|
|
117
|
-
it
|
|
118
|
-
expect{resource_object.validate}.not_to raise_error
|
|
118
|
+
describe "world visible" do
|
|
119
|
+
it "validates" do
|
|
120
|
+
expect { resource_object.validate }.not_to raise_error
|
|
119
121
|
end
|
|
120
|
-
it
|
|
122
|
+
it "has expected required values" do
|
|
121
123
|
expect(resource_object.id).to eq file_id
|
|
122
124
|
end
|
|
123
|
-
it
|
|
125
|
+
it "has expected other values" do
|
|
124
126
|
expect(resource_object.type).to eq file_type
|
|
125
127
|
expect(resource_object.format).to eq file_mimetype
|
|
126
128
|
expect(resource_object.service).to eq []
|
|
127
129
|
end
|
|
128
130
|
end
|
|
129
|
-
describe
|
|
131
|
+
describe "requires login" do
|
|
130
132
|
# let(:auth_token_service) {
|
|
131
133
|
# IIIF::V3::Presentation::Service.new({
|
|
132
134
|
# 'id' => 'https://example.org/image/iiif/token',
|
|
133
135
|
# 'profile' => IIIF::V3::Presentation::Service::IIIF_AUTHENTICATION_V1_TOKEN_PROFILE
|
|
134
136
|
# })}
|
|
135
|
-
let(:service_label) {
|
|
136
|
-
let(:token_service_id) {
|
|
137
|
+
let(:service_label) { "login message" }
|
|
138
|
+
let(:token_service_id) { "https://example.org/iiif/token" }
|
|
137
139
|
let(:login_service) {
|
|
138
140
|
IIIF::V3::Presentation::Service.new(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
"id" => "https://example.org/auth/iiif",
|
|
142
|
+
"profile" => "http://iiif.io/api/auth/1/login",
|
|
143
|
+
"label" => service_label,
|
|
144
|
+
"service" => [{
|
|
145
|
+
"id" => token_service_id,
|
|
146
|
+
"profile" => "http://iiif.io/api/auth/1/token"
|
|
145
147
|
}]
|
|
146
148
|
)
|
|
147
149
|
}
|
|
@@ -150,25 +152,24 @@ describe IIIF::V3::Presentation::Resource do
|
|
|
150
152
|
resource.service = [login_service]
|
|
151
153
|
resource
|
|
152
154
|
}
|
|
153
|
-
it
|
|
154
|
-
expect{resource_object_w_login.validate}.not_to raise_error
|
|
155
|
+
it "validates" do
|
|
156
|
+
expect { resource_object_w_login.validate }.not_to raise_error
|
|
155
157
|
end
|
|
156
|
-
it
|
|
158
|
+
it "has expected service value" do
|
|
157
159
|
service_obj = resource_object_w_login.service.first
|
|
158
160
|
expect(service_obj.class).to eq IIIF::V3::Presentation::Service
|
|
159
161
|
expect(service_obj.keys.size).to eq 4
|
|
160
|
-
expect(service_obj.id).to eq
|
|
162
|
+
expect(service_obj.id).to eq "https://example.org/auth/iiif"
|
|
161
163
|
expect(service_obj.profile).to eq IIIF::V3::Presentation::Service::IIIF_AUTHENTICATION_V1_LOGIN_PROFILE
|
|
162
164
|
expect(service_obj.label).to eq service_label
|
|
163
165
|
expect(service_obj.service.class).to eq Array
|
|
164
166
|
expect(service_obj.service.size).to eq 1
|
|
165
167
|
expect(service_obj.service.first.keys.size).to eq 2
|
|
166
|
-
expect(service_obj.service.first[
|
|
167
|
-
expect(service_obj.service.first[
|
|
168
|
+
expect(service_obj.service.first["id"]).to eq token_service_id
|
|
169
|
+
expect(service_obj.service.first["profile"]).to eq IIIF::V3::Presentation::Service::IIIF_AUTHENTICATION_V1_TOKEN_PROFILE
|
|
168
170
|
end
|
|
169
171
|
end
|
|
170
172
|
end
|
|
171
173
|
end
|
|
172
174
|
end
|
|
173
|
-
|
|
174
175
|
end
|
|
@@ -1,212 +1,218 @@
|
|
|
1
1
|
describe IIIF::V3::Presentation::Sequence do
|
|
2
|
-
|
|
3
|
-
describe '#required_keys' do
|
|
2
|
+
describe "#required_keys" do
|
|
4
3
|
# NOTE: relaxing requirement for items as Universal Viewer currently only accepts canvases
|
|
5
4
|
# see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
|
|
6
5
|
# %w{ type items }.each do |k|
|
|
7
|
-
%w
|
|
6
|
+
%w[type].each do |k|
|
|
8
7
|
it k do
|
|
9
8
|
expect(subject.required_keys).to include(k)
|
|
10
9
|
end
|
|
11
10
|
end
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
describe
|
|
15
|
-
it
|
|
13
|
+
describe "#prohibited_keys" do
|
|
14
|
+
it "contains the expected key names" do
|
|
16
15
|
keys = described_class::CONTENT_RESOURCE_PROPERTIES +
|
|
17
16
|
described_class::PAGING_PROPERTIES +
|
|
18
|
-
%w
|
|
17
|
+
%w[
|
|
19
18
|
nav_date
|
|
20
19
|
content_annotations
|
|
21
|
-
|
|
20
|
+
]
|
|
22
21
|
expect(subject.prohibited_keys).to include(*keys)
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
describe
|
|
27
|
-
it
|
|
28
|
-
expect(subject.array_only_keys).to include(
|
|
25
|
+
describe "#array_only_keys" do
|
|
26
|
+
it "items" do
|
|
27
|
+
expect(subject.array_only_keys).to include("items")
|
|
29
28
|
end
|
|
30
29
|
# NOTE: also allowing sequences as Universal Viewer currently only accepts canvases
|
|
31
30
|
# see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
|
|
32
|
-
it
|
|
33
|
-
expect(subject.array_only_keys).to include(
|
|
31
|
+
it "canvases" do
|
|
32
|
+
expect(subject.array_only_keys).to include("canvases")
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
describe
|
|
38
|
-
it
|
|
39
|
-
expect(subject.legal_viewing_hint_values).to contain_exactly(
|
|
36
|
+
describe "#legal_viewing_hint_values" do
|
|
37
|
+
it "contains the expected values" do
|
|
38
|
+
expect(subject.legal_viewing_hint_values).to contain_exactly("individuals", "paged", "continuous", "auto-advance")
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
describe
|
|
44
|
-
it
|
|
45
|
-
expect(subject[
|
|
42
|
+
describe "#initialize" do
|
|
43
|
+
it "sets type to Sequence by default" do
|
|
44
|
+
expect(subject["type"]).to eq "Sequence"
|
|
46
45
|
end
|
|
47
|
-
it
|
|
46
|
+
it "allows subclasses to override type" do
|
|
48
47
|
subclass = Class.new(described_class) do
|
|
49
|
-
def initialize(
|
|
50
|
-
|
|
51
|
-
super(hsh)
|
|
48
|
+
def initialize(_hsh = {})
|
|
49
|
+
super({"type" => "a:SubClass"})
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
52
|
sub = subclass.new
|
|
55
|
-
expect(sub[
|
|
53
|
+
expect(sub["type"]).to eq "a:SubClass"
|
|
56
54
|
end
|
|
57
55
|
end
|
|
58
56
|
|
|
59
|
-
describe
|
|
57
|
+
describe "#validate" do
|
|
60
58
|
let(:req_key_msg) { "The (items or canvases) list must have at least one entry." }
|
|
61
|
-
it
|
|
59
|
+
it "raises MissingRequiredKeyError if no items or canvases key" do
|
|
62
60
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, req_key_msg)
|
|
63
61
|
end
|
|
64
|
-
describe
|
|
65
|
-
it
|
|
66
|
-
subject[
|
|
62
|
+
describe "items" do
|
|
63
|
+
it "raises MissingRequiredKeyError for items as empty Array" do
|
|
64
|
+
subject["items"] = []
|
|
67
65
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, req_key_msg)
|
|
68
66
|
end
|
|
69
67
|
end
|
|
70
|
-
describe
|
|
71
|
-
it
|
|
72
|
-
subject[
|
|
68
|
+
describe "canvases" do
|
|
69
|
+
it "raises MissingRequiredKeyError for canvases as empty Array" do
|
|
70
|
+
subject["items"] = []
|
|
73
71
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, req_key_msg)
|
|
74
72
|
end
|
|
75
73
|
end
|
|
76
74
|
end
|
|
77
75
|
|
|
78
|
-
describe
|
|
79
|
-
let!(:canvas_object) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
describe "realistic examples" do
|
|
77
|
+
let!(:canvas_object) {
|
|
78
|
+
IIIF::V3::Presentation::Canvas.new({
|
|
79
|
+
"id" => "https://example.org/abc666/iiif3/canvas/0001",
|
|
80
|
+
"label" => "p. 1",
|
|
81
|
+
"height" => 7579,
|
|
82
|
+
"width" => 10108,
|
|
83
|
+
"content" => []
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
describe "minimal sequence" do
|
|
87
|
+
let!(:sequence_object) {
|
|
88
|
+
described_class.new({
|
|
89
|
+
"items" => [canvas_object]
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
it "validates" do
|
|
93
|
+
expect { sequence_object.validate }.not_to raise_error
|
|
92
94
|
end
|
|
93
|
-
it
|
|
94
|
-
expect(sequence_object.type).to eq
|
|
95
|
+
it "has expected required values" do
|
|
96
|
+
expect(sequence_object.type).to eq "Sequence"
|
|
95
97
|
expect(sequence_object.items.size).to be 1
|
|
96
98
|
expect(sequence_object.items.first).to eq canvas_object
|
|
97
99
|
end
|
|
98
100
|
end
|
|
99
|
-
|
|
100
|
-
describe
|
|
101
|
-
let(:seq_id) {
|
|
101
|
+
|
|
102
|
+
describe "example from Stanford purl" do
|
|
103
|
+
let(:seq_id) { "https://example.org/abc666#sequence-1" }
|
|
102
104
|
let(:sequence_object) {
|
|
103
105
|
s = described_class.new({
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
"id" => seq_id,
|
|
107
|
+
"label" => "Current order"
|
|
106
108
|
})
|
|
107
109
|
s.canvases << canvas_object
|
|
108
110
|
s
|
|
109
111
|
}
|
|
110
|
-
it
|
|
111
|
-
expect{sequence_object.validate}.not_to raise_error
|
|
112
|
+
it "validates" do
|
|
113
|
+
expect { sequence_object.validate }.not_to raise_error
|
|
112
114
|
end
|
|
113
|
-
it
|
|
114
|
-
expect(sequence_object.type).to eq
|
|
115
|
+
it "has expected required values" do
|
|
116
|
+
expect(sequence_object.type).to eq "Sequence"
|
|
115
117
|
expect(sequence_object.canvases.size).to be 1
|
|
116
118
|
expect(sequence_object.canvases.first).to eq canvas_object
|
|
117
119
|
end
|
|
118
|
-
it
|
|
120
|
+
it "has expected string values" do
|
|
119
121
|
expect(sequence_object.id).to eq seq_id
|
|
120
122
|
expect(sequence_object.label).to eq "Current order"
|
|
121
123
|
end
|
|
122
|
-
describe
|
|
124
|
+
describe "with viewingDirection" do
|
|
123
125
|
let(:sequence_vd) {
|
|
124
|
-
sequence_object.viewingDirection =
|
|
126
|
+
sequence_object.viewingDirection = "left-to-right"
|
|
125
127
|
sequence_object
|
|
126
128
|
}
|
|
127
|
-
it
|
|
128
|
-
expect{sequence_vd.validate}.not_to raise_error
|
|
129
|
+
it "validates" do
|
|
130
|
+
expect { sequence_vd.validate }.not_to raise_error
|
|
129
131
|
end
|
|
130
|
-
it
|
|
131
|
-
expect(sequence_vd.type).to eq
|
|
132
|
+
it "has expected required values" do
|
|
133
|
+
expect(sequence_vd.type).to eq "Sequence"
|
|
132
134
|
expect(sequence_vd.canvases.size).to be 1
|
|
133
135
|
expect(sequence_vd.canvases.first).to eq canvas_object
|
|
134
136
|
end
|
|
135
|
-
it
|
|
137
|
+
it "has expected string values" do
|
|
136
138
|
expect(sequence_vd.id).to eq seq_id
|
|
137
139
|
expect(sequence_vd.label).to eq "Current order"
|
|
138
|
-
expect(sequence_vd.viewing_direction).to eq
|
|
139
|
-
expect(sequence_vd.viewingDirection).to eq
|
|
140
|
+
expect(sequence_vd.viewing_direction).to eq "left-to-right"
|
|
141
|
+
expect(sequence_vd.viewingDirection).to eq "left-to-right"
|
|
140
142
|
end
|
|
141
143
|
end
|
|
142
144
|
end
|
|
143
145
|
|
|
144
|
-
describe
|
|
145
|
-
let!(:sequence_object) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
146
|
+
describe "example from http://prezi3.iiif.io/api/presentation/3.0" do
|
|
147
|
+
let!(:sequence_object) {
|
|
148
|
+
described_class.new({
|
|
149
|
+
"id" => "http://example.org/iiif/book1/sequence/normal",
|
|
150
|
+
"label" => {"en" => "Current Page Order"},
|
|
151
|
+
"viewingDirection" => "left-to-right",
|
|
152
|
+
"viewingHint" => ["paged"],
|
|
153
|
+
"startCanvas" => canvas_object.id,
|
|
154
|
+
"items" => [canvas_object]
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
it "validates" do
|
|
158
|
+
expect { sequence_object.validate }.not_to raise_error
|
|
155
159
|
end
|
|
156
|
-
it
|
|
157
|
-
expect(sequence_object.type).to eq
|
|
160
|
+
it "has expected required values" do
|
|
161
|
+
expect(sequence_object.type).to eq "Sequence"
|
|
158
162
|
expect(sequence_object.items.size).to be 1
|
|
159
163
|
expect(sequence_object.items.first).to eq canvas_object
|
|
160
164
|
end
|
|
161
|
-
it
|
|
165
|
+
it "has expected string values" do
|
|
162
166
|
expect(sequence_object.id).to eq "http://example.org/iiif/book1/sequence/normal"
|
|
163
167
|
expect(sequence_object.viewingDirection).to eq "left-to-right"
|
|
164
168
|
expect(sequence_object.startCanvas).to eq "https://example.org/abc666/iiif3/canvas/0001"
|
|
165
169
|
end
|
|
166
|
-
it
|
|
170
|
+
it "has expected additional content" do
|
|
167
171
|
expect(sequence_object.viewingHint).to eq ["paged"]
|
|
168
|
-
expect(sequence_object.label).to eq
|
|
172
|
+
expect(sequence_object.label).to eq({"en" => "Current Page Order"})
|
|
169
173
|
end
|
|
170
174
|
end
|
|
171
175
|
|
|
172
|
-
describe
|
|
173
|
-
let!(:sequence_object) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
176
|
+
describe "another example" do
|
|
177
|
+
let!(:sequence_object) {
|
|
178
|
+
described_class.new({
|
|
179
|
+
"id" => "http://example.com/prefix/sequence/456",
|
|
180
|
+
"label" => "Book 1",
|
|
181
|
+
"description" => "A longer description of this example book. It should give some real information.",
|
|
182
|
+
"thumbnail" => [{
|
|
183
|
+
"id" => "http://www.example.org/images/book1-page1/full/80,100/0/default.jpg",
|
|
184
|
+
"type" => "Image",
|
|
185
|
+
"service" => [{
|
|
186
|
+
"@context" => "http://iiif.io/api/image/2/context.json",
|
|
187
|
+
"id" => "http://www.example.org/images/book1-page1",
|
|
188
|
+
"profile" => "http://iiif.io/api/image/2/level1.json"
|
|
189
|
+
}]
|
|
190
|
+
}],
|
|
191
|
+
"attribution" => "Provided by Example Organization",
|
|
192
|
+
"rights" => "Sample rights",
|
|
193
|
+
"logo" => "http://www.example.org/logos/institution1.jpg",
|
|
194
|
+
"see_also" => "http://www.example.org/library/catalog/book1.xml",
|
|
195
|
+
"service" => [{
|
|
196
|
+
"@context" => "http://example.org/ns/jsonld/context.json",
|
|
197
|
+
"id" => "http://example.org/service/example",
|
|
198
|
+
"profile" => "http://example.org/docs/example-service.html"
|
|
199
|
+
}],
|
|
200
|
+
"related" => {
|
|
201
|
+
"id" => "http://www.example.org/videos/video-book1.mpg",
|
|
202
|
+
"format" => "video/mpeg"
|
|
203
|
+
},
|
|
204
|
+
"within" => "http://www.example.org/collections/books/",
|
|
205
|
+
# Sequence
|
|
206
|
+
"metadata" => [{"label" => "Author", "value" => "Anne Author"}],
|
|
207
|
+
"items" => [canvas_object],
|
|
208
|
+
"start_canvas" => "http://www.example.org/iiif/book1/canvas/p2",
|
|
209
|
+
"viewingDirection" => "left-to-right",
|
|
210
|
+
"viewingHint" => ["paged"],
|
|
211
|
+
"startCanvas" => canvas_object.id
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
it "validates" do
|
|
215
|
+
expect { sequence_object.validate }.not_to raise_error
|
|
210
216
|
end
|
|
211
217
|
end
|
|
212
218
|
end
|