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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +8 -1
  3. data/.standard.yml +1 -0
  4. data/Gemfile +5 -5
  5. data/README.md +1 -1
  6. data/Rakefile +4 -2
  7. data/VERSION +1 -1
  8. data/bin/standardrb +16 -0
  9. data/iiif-presentation.gemspec +23 -23
  10. data/lib/iiif/hash_behaviours.rb +29 -33
  11. data/lib/iiif/ordered_hash.rb +33 -33
  12. data/lib/iiif/presentation/abstract_resource.rb +17 -22
  13. data/lib/iiif/presentation/annotation.rb +9 -11
  14. data/lib/iiif/presentation/annotation_list.rb +8 -10
  15. data/lib/iiif/presentation/canvas.rb +11 -13
  16. data/lib/iiif/presentation/collection.rb +7 -9
  17. data/lib/iiif/presentation/image_resource.rb +33 -35
  18. data/lib/iiif/presentation/layer.rb +8 -10
  19. data/lib/iiif/presentation/manifest.rb +9 -12
  20. data/lib/iiif/presentation/range.rb +8 -10
  21. data/lib/iiif/presentation/resource.rb +5 -7
  22. data/lib/iiif/presentation/sequence.rb +8 -11
  23. data/lib/iiif/presentation/service.rb +1 -2
  24. data/lib/iiif/presentation.rb +7 -7
  25. data/lib/iiif/service.rb +121 -102
  26. data/lib/iiif/v3/abstract_resource.rb +132 -144
  27. data/lib/iiif/v3/presentation/annotation.rb +20 -21
  28. data/lib/iiif/v3/presentation/annotation_collection.rb +7 -9
  29. data/lib/iiif/v3/presentation/annotation_page.rb +14 -15
  30. data/lib/iiif/v3/presentation/canvas.rb +21 -22
  31. data/lib/iiif/v3/presentation/choice.rb +14 -15
  32. data/lib/iiif/v3/presentation/collection.rb +7 -8
  33. data/lib/iiif/v3/presentation/image_resource.rb +21 -22
  34. data/lib/iiif/v3/presentation/manifest.rb +18 -19
  35. data/lib/iiif/v3/presentation/nav_place.rb +125 -29
  36. data/lib/iiif/v3/presentation/range.rb +10 -10
  37. data/lib/iiif/v3/presentation/resource.rb +4 -5
  38. data/lib/iiif/v3/presentation/sequence.rb +10 -11
  39. data/lib/iiif/v3/presentation/service.rb +12 -13
  40. data/lib/iiif/v3/presentation.rb +8 -8
  41. data/spec/integration/iiif/presentation/image_resource_spec.rb +54 -58
  42. data/spec/integration/iiif/service_spec.rb +76 -77
  43. data/spec/integration/iiif/v3/abstract_resource_spec.rb +73 -73
  44. data/spec/integration/iiif/v3/presentation/image_resource_spec.rb +53 -56
  45. data/spec/spec_helper.rb +56 -64
  46. data/spec/unit/iiif/hash_behaviours_spec.rb +384 -387
  47. data/spec/unit/iiif/ordered_hash_spec.rb +86 -91
  48. data/spec/unit/iiif/presentation/abstract_resource_spec.rb +64 -70
  49. data/spec/unit/iiif/presentation/annotation_list_spec.rb +1 -3
  50. data/spec/unit/iiif/presentation/annotation_spec.rb +1 -3
  51. data/spec/unit/iiif/presentation/canvas_spec.rb +11 -14
  52. data/spec/unit/iiif/presentation/collection_spec.rb +26 -33
  53. data/spec/unit/iiif/presentation/image_resource_spec.rb +4 -6
  54. data/spec/unit/iiif/presentation/layer_spec.rb +16 -20
  55. data/spec/unit/iiif/presentation/manifest_spec.rb +45 -48
  56. data/spec/unit/iiif/presentation/range_spec.rb +18 -22
  57. data/spec/unit/iiif/presentation/resource_spec.rb +3 -6
  58. data/spec/unit/iiif/presentation/sequence_spec.rb +58 -63
  59. data/spec/unit/iiif/presentation/shared_examples/abstract_resource_only_keys.rb +4 -10
  60. data/spec/unit/iiif/presentation/shared_examples/any_type_keys.rb +5 -9
  61. data/spec/unit/iiif/presentation/shared_examples/array_only_keys.rb +9 -17
  62. data/spec/unit/iiif/presentation/shared_examples/int_only_keys.rb +6 -14
  63. data/spec/unit/iiif/presentation/shared_examples/string_only_keys.rb +6 -13
  64. data/spec/unit/iiif/service_spec.rb +8 -13
  65. data/spec/unit/iiif/v3/abstract_resource_define_methods_for_spec.rb +39 -37
  66. data/spec/unit/iiif/v3/abstract_resource_spec.rb +128 -143
  67. data/spec/unit/iiif/v3/presentation/annotation_collection_spec.rb +14 -17
  68. data/spec/unit/iiif/v3/presentation/annotation_page_spec.rb +71 -69
  69. data/spec/unit/iiif/v3/presentation/annotation_spec.rb +249 -233
  70. data/spec/unit/iiif/v3/presentation/canvas_spec.rb +211 -193
  71. data/spec/unit/iiif/v3/presentation/choice_spec.rb +81 -77
  72. data/spec/unit/iiif/v3/presentation/collection_spec.rb +24 -29
  73. data/spec/unit/iiif/v3/presentation/image_resource_spec.rb +70 -71
  74. data/spec/unit/iiif/v3/presentation/manifest_spec.rb +248 -237
  75. data/spec/unit/iiif/v3/presentation/nav_place_spec.rb +249 -49
  76. data/spec/unit/iiif/v3/presentation/range_spec.rb +28 -29
  77. data/spec/unit/iiif/v3/presentation/resource_spec.rb +83 -82
  78. data/spec/unit/iiif/v3/presentation/sequence_spec.rb +126 -120
  79. data/spec/unit/iiif/v3/presentation/service_spec.rb +123 -124
  80. data/spec/unit/iiif/v3/presentation/shared_examples/abstract_resource_only_keys.rb +4 -8
  81. data/spec/unit/iiif/v3/presentation/shared_examples/any_type_keys.rb +5 -7
  82. data/spec/unit/iiif/v3/presentation/shared_examples/array_only_keys.rb +9 -13
  83. data/spec/unit/iiif/v3/presentation/shared_examples/hash_only_keys.rb +9 -13
  84. data/spec/unit/iiif/v3/presentation/shared_examples/int_only_keys.rb +6 -10
  85. data/spec/unit/iiif/v3/presentation/shared_examples/numeric_only_keys.rb +6 -10
  86. data/spec/unit/iiif/v3/presentation/shared_examples/string_only_keys.rb +6 -10
  87. data/spec/unit/iiif/v3/presentation/shared_examples/uri_only_keys.rb +9 -13
  88. metadata +27 -69
@@ -1,244 +1,254 @@
1
1
  describe IIIF::V3::Presentation::Manifest 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 sequences
5
4
  # see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
6
5
  # %w{ type id label items }.each do |k|
7
- %w{ type id label }.each do |k|
6
+ %w[type id label].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 '#prohibited_keys' do
15
- it 'contains the expected key names' do
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
  start_canvas
20
19
  content_annotation
21
- }
20
+ ]
22
21
  expect(subject.prohibited_keys).to include(*keys)
23
22
  end
24
23
  end
25
24
 
26
- describe '#uri_only_keys' do
27
- it 'id' do
28
- expect(subject.uri_only_keys).to include('id')
25
+ describe "#uri_only_keys" do
26
+ it "id" do
27
+ expect(subject.uri_only_keys).to include("id")
29
28
  end
30
29
  end
31
30
 
32
- describe '#array_only_keys' do
31
+ describe "#array_only_keys" do
33
32
  # NOTE: also allowing sequences as Universal Viewer currently only accepts sequences
34
33
  # see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
35
- %w{ items sequences structures}.each do |k|
34
+ %w[items sequences structures].each do |k|
36
35
  it k do
37
36
  expect(subject.array_only_keys).to include(k)
38
37
  end
39
38
  end
40
39
  end
41
40
 
42
- describe '#legal_viewing_hint_values' do
43
- it 'contains the expected values' do
44
- expect(subject.legal_viewing_hint_values).to contain_exactly('individuals', 'paged', 'continuous', 'auto-advance')
41
+ describe "#legal_viewing_hint_values" do
42
+ it "contains the expected values" do
43
+ expect(subject.legal_viewing_hint_values).to contain_exactly("individuals", "paged", "continuous", "auto-advance")
45
44
  end
46
45
  end
47
46
 
48
- describe '#initialize' do
49
- it 'sets type to Manifest by default' do
50
- expect(subject['type']).to eq 'Manifest'
47
+ describe "#initialize" do
48
+ it "sets type to Manifest by default" do
49
+ expect(subject["type"]).to eq "Manifest"
51
50
  end
52
- it 'allows subclasses to override type' do
51
+ it "allows subclasses to override type" do
53
52
  subclass = Class.new(described_class) do
54
- def initialize(hsh={})
55
- hsh = { 'type' => 'a:SubClass' }
56
- super(hsh)
53
+ def initialize(_hsh = {})
54
+ super({"type" => "a:SubClass"})
57
55
  end
58
56
  end
59
57
  sub = subclass.new
60
- expect(sub['type']).to eq 'a:SubClass'
58
+ expect(sub["type"]).to eq "a:SubClass"
61
59
  end
62
60
  end
63
61
 
64
- let(:manifest_id) { 'http://www.example.org/iiif/book1/manifest' }
62
+ let(:manifest_id) { "http://www.example.org/iiif/book1/manifest" }
65
63
 
66
- describe '#validate' do
67
- it 'raises an IllegalValueError if id is not http' do
68
- subject.label = {'en' => ['Book 1']}
69
- subject['id'] = 'ftp://www.example.org'
70
- subject['items'] = [IIIF::V3::Presentation::Sequence.new]
64
+ describe "#validate" do
65
+ it "raises an IllegalValueError if id is not http" do
66
+ subject.label = {"en" => ["Book 1"]}
67
+ subject["id"] = "ftp://www.example.org"
68
+ subject["items"] = [IIIF::V3::Presentation::Sequence.new]
71
69
  exp_err_msg = "id must be an http(s) URI for #{described_class}"
72
70
  expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
73
71
  end
74
72
 
75
- let(:item_list_err) { 'The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)' }
76
- let(:item_entry_err) { 'All entries in the items list must be a IIIF::V3::Presentation::Canvas' }
73
+ let(:item_list_err) { "The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)" }
74
+ let(:item_entry_err) { "All entries in the items list must be a IIIF::V3::Presentation::Canvas" }
77
75
 
78
- it 'raises MissingRequiredKeyError if no items or sequences key' do
79
- subject['id'] = manifest_id
80
- subject.label = {'en' => ['Book 1']}
76
+ it "raises MissingRequiredKeyError if no items or sequences key" do
77
+ subject["id"] = manifest_id
78
+ subject.label = {"en" => ["Book 1"]}
81
79
  expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, item_list_err)
82
80
  end
83
- describe 'items' do
84
- it 'raises MissingRequiredKeyError for items entry without values' do
85
- subject['id'] = manifest_id
86
- subject.label = {'en' => ['Book 1']}
87
- subject['items'] = []
81
+ describe "items" do
82
+ it "raises MissingRequiredKeyError for items entry without values" do
83
+ subject["id"] = manifest_id
84
+ subject.label = {"en" => ["Book 1"]}
85
+ subject["items"] = []
88
86
  expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, item_list_err)
89
87
  end
90
- it 'raises IllegalValueError for items entry that is not a Sequence' do
91
- subject['id'] = manifest_id
92
- subject.label = {'en' => ['Book 1']}
93
- subject['items'] = [IIIF::V3::Presentation::Sequence.new, IIIF::V3::Presentation::Canvas.new]
88
+ it "raises IllegalValueError for items entry that is not a Sequence" do
89
+ subject["id"] = manifest_id
90
+ subject.label = {"en" => ["Book 1"]}
91
+ subject["items"] = [IIIF::V3::Presentation::Sequence.new, IIIF::V3::Presentation::Canvas.new]
94
92
  expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, item_entry_err)
95
93
  end
96
- it 'raises no error items populated with canvases' do
97
- subject['items'] = [IIIF::V3::Presentation::Canvas.new]
98
- subject['id'] = manifest_id
99
- subject.label = {'en' => ['Book 1']}
94
+ it "raises no error items populated with canvases" do
95
+ subject["items"] = [IIIF::V3::Presentation::Canvas.new]
96
+ subject["id"] = manifest_id
97
+ subject.label = {"en" => ["Book 1"]}
100
98
  expect { subject.validate }.not_to raise_error
101
99
  end
102
100
  end
103
101
 
104
- it 'raises IllegalValueError for structures entry that is not a Range' do
105
- subject['id'] = manifest_id
106
- subject.label = {'en' => ['Book 1']}
107
- subject['items'] = [IIIF::V3::Presentation::Canvas.new]
108
- subject['structures'] = [IIIF::V3::Presentation::Sequence.new]
102
+ it "raises IllegalValueError for structures entry that is not a Range" do
103
+ subject["id"] = manifest_id
104
+ subject.label = {"en" => ["Book 1"]}
105
+ subject["items"] = [IIIF::V3::Presentation::Canvas.new]
106
+ subject["structures"] = [IIIF::V3::Presentation::Sequence.new]
109
107
  exp_err_msg = "All entries in the structures list must be a IIIF::V3::Presentation::Range"
110
108
  expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
111
109
  end
112
- it 'raises no error when structures entry is a Range' do
113
- subject['id'] = manifest_id
114
- subject.label = {'en' => ['Book 1']}
115
- subject['items'] = [IIIF::V3::Presentation::Canvas.new]
116
- subject['structures'] = [IIIF::V3::Presentation::Range.new]
110
+ it "raises no error when structures entry is a Range" do
111
+ subject["id"] = manifest_id
112
+ subject.label = {"en" => ["Book 1"]}
113
+ subject["items"] = [IIIF::V3::Presentation::Canvas.new]
114
+ subject["structures"] = [IIIF::V3::Presentation::Range.new]
117
115
  expect { subject.validate }.not_to raise_error
118
116
  end
119
117
  end
120
118
 
121
- describe 'realistic examples' do
122
- let!(:canvas_object) { IIIF::V3::Presentation::Canvas.new({
123
- "id" => "https://example.org/abc666/iiif3/canvas/0001",
124
- "label" => {'en' => ['image']},
125
- "height" => 7579,
126
- "width" => 10108,
127
- "content" => []
128
- })}
129
- describe 'realistic(?) minimal manifest' do
130
- let!(:manifest_object) { described_class.new({
131
- "@context" => [
132
- "http://www.w3.org/ns/anno.jsonld",
133
- "http://iiif.io/api/presentation/3/context.json"
134
- ],
135
- "id" => "https://example.org/abc666/iiif3/manifest",
136
- "label" => {"en" => ["blah"]},
137
- "requiredStatement" => {
138
- "label": { "en": [ "Attribution" ] },
139
- "value": { "en": [ "bleah" ] },
140
- },
141
- 'summary' => { 'en' => ['blargh'] },
142
- "items" => [canvas_object]
143
- })}
144
- it 'validates' do
145
- expect{manifest_object.validate}.not_to raise_error
119
+ describe "realistic examples" do
120
+ let!(:canvas_object) {
121
+ IIIF::V3::Presentation::Canvas.new({
122
+ "id" => "https://example.org/abc666/iiif3/canvas/0001",
123
+ "label" => {"en" => ["image"]},
124
+ "height" => 7579,
125
+ "width" => 10108,
126
+ "content" => []
127
+ })
128
+ }
129
+ describe "realistic(?) minimal manifest" do
130
+ let!(:manifest_object) {
131
+ described_class.new({
132
+ "@context" => [
133
+ "http://www.w3.org/ns/anno.jsonld",
134
+ "http://iiif.io/api/presentation/3/context.json"
135
+ ],
136
+ "id" => "https://example.org/abc666/iiif3/manifest",
137
+ "label" => {"en" => ["blah"]},
138
+ "requiredStatement" => {
139
+ label: {en: ["Attribution"]},
140
+ value: {en: ["bleah"]}
141
+ },
142
+ "summary" => {"en" => ["blargh"]},
143
+ "items" => [canvas_object]
144
+ })
145
+ }
146
+ it "validates" do
147
+ expect { manifest_object.validate }.not_to raise_error
146
148
  end
147
- it 'has expected required values' do
148
- expect(manifest_object.type).to eq 'Manifest'
149
+ it "has expected required values" do
150
+ expect(manifest_object.type).to eq "Manifest"
149
151
  expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
150
- expect(manifest_object.label['en']).to include "blah"
152
+ expect(manifest_object.label["en"]).to include "blah"
151
153
  expect(manifest_object.items.size).to be 1
152
154
  expect(manifest_object.items.first).to eq canvas_object
153
155
  end
154
- it 'has expected context' do
155
- expect(manifest_object['@context'].size).to be 2
156
- expect(manifest_object['@context']).to include(*IIIF::V3::Presentation::CONTEXT)
156
+ it "has expected context" do
157
+ expect(manifest_object["@context"].size).to be 2
158
+ expect(manifest_object["@context"]).to include(*IIIF::V3::Presentation::CONTEXT)
157
159
  end
158
- it 'has other values' do
159
- expect(manifest_object['required_statement'][:value][:en].first).to eq 'bleah'
160
- expect(manifest_object.summary['en'].first).to eq 'blargh'
160
+ it "has other values" do
161
+ expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
162
+ expect(manifest_object.summary["en"].first).to eq "blargh"
161
163
  end
162
164
  end
163
165
 
164
- describe 'realistic example from Stanford purl manifests' do
165
- let!(:logo_service) { IIIF::V3::Presentation::Service.new({
166
- "@id" => "https://example.org/logo",
167
- "@type" => "ImageService2",
168
- "id" => "https://example.org/logo",
169
- "profile" => "http://iiif.io/api/image/2/level1.json"
170
- })}
171
- let!(:thumbnail_image_service) { IIIF::V3::Presentation::Service.new({
172
- "@id" => "https://example.org/image/iiif/abc666_05_0001",
173
- "id" => "https://example.org/image/iiif/abc666_05_0001",
174
- "profile" => IIIF::V3::Presentation::Service::IIIF_IMAGE_V2_LEVEL1_PROFILE
175
- })}
176
- let!(:thumbnail_image) { IIIF::V3::Presentation::ImageResource.new({
177
- "id" => "https://example.org/image/iiif/abc666_05_0001/full/!400,400/0/default.jpg",
178
- "format" => "image/jpeg",
179
- "service" => [thumbnail_image_service]
180
- })}
181
- let!(:manifest_object) { described_class.new({
182
- "id" => "https://example.org/abc666/iiif3/manifest",
183
- "label" => {"en" => ["blah"]},
184
- "requiredStatement" => {
185
- "label": { "en": [ "Attribution" ] },
186
- "value": { "en": [ "bleah" ] },
187
- },
188
- 'summary' => { 'en' => ['blargh'] },
189
- "items" => [canvas_object],
190
- "logo" => {
191
- "id" => "https://example.org/logo/full/400,/0/default.jpg",
192
- "service" => [logo_service]
193
- },
194
- "seeAlso" => {
195
- "id" => "https://example.org/abc666.mods",
196
- "format" => "application/mods+xml"
197
- },
198
- "viewingHint" => "paged",
199
- "viewingDirection" => "right-to-left",
200
- "metadata" => [
201
- {
202
- "label" => "Type",
203
- "value" => "map"
166
+ describe "realistic example from Stanford purl manifests" do
167
+ let!(:logo_service) {
168
+ IIIF::V3::Presentation::Service.new({
169
+ "@id" => "https://example.org/logo",
170
+ "@type" => "ImageService2",
171
+ "id" => "https://example.org/logo",
172
+ "profile" => "http://iiif.io/api/image/2/level1.json"
173
+ })
174
+ }
175
+ let!(:thumbnail_image_service) {
176
+ IIIF::V3::Presentation::Service.new({
177
+ "@id" => "https://example.org/image/iiif/abc666_05_0001",
178
+ "id" => "https://example.org/image/iiif/abc666_05_0001",
179
+ "profile" => IIIF::V3::Presentation::Service::IIIF_IMAGE_V2_LEVEL1_PROFILE
180
+ })
181
+ }
182
+ let!(:thumbnail_image) {
183
+ IIIF::V3::Presentation::ImageResource.new({
184
+ "id" => "https://example.org/image/iiif/abc666_05_0001/full/!400,400/0/default.jpg",
185
+ "format" => "image/jpeg",
186
+ "service" => [thumbnail_image_service]
187
+ })
188
+ }
189
+ let!(:manifest_object) {
190
+ described_class.new({
191
+ "id" => "https://example.org/abc666/iiif3/manifest",
192
+ "label" => {"en" => ["blah"]},
193
+ "requiredStatement" => {
194
+ label: {en: ["Attribution"]},
195
+ value: {en: ["bleah"]}
204
196
  },
205
- {
206
- "label" => "Rights",
207
- "value" => "stuff"
208
- }
197
+ "summary" => {"en" => ["blargh"]},
198
+ "items" => [canvas_object],
199
+ "logo" => {
200
+ "id" => "https://example.org/logo/full/400,/0/default.jpg",
201
+ "service" => [logo_service]
202
+ },
203
+ "seeAlso" => {
204
+ "id" => "https://example.org/abc666.mods",
205
+ "format" => "application/mods+xml"
206
+ },
207
+ "viewingHint" => "paged",
208
+ "viewingDirection" => "right-to-left",
209
+ "metadata" => [
210
+ {
211
+ "label" => "Type",
212
+ "value" => "map"
213
+ },
214
+ {
215
+ "label" => "Rights",
216
+ "value" => "stuff"
217
+ }
209
218
  ],
210
- "thumbnail" => [thumbnail_image]
211
- })}
212
- it 'thumbnail image object validates' do
213
- expect{thumbnail_image.validate}.not_to raise_error
219
+ "thumbnail" => [thumbnail_image]
220
+ })
221
+ }
222
+ it "thumbnail image object validates" do
223
+ expect { thumbnail_image.validate }.not_to raise_error
214
224
  end
215
- it 'manifest validates' do
216
- expect{manifest_object.validate}.not_to raise_error
225
+ it "manifest validates" do
226
+ expect { manifest_object.validate }.not_to raise_error
217
227
  end
218
- it 'has expected required values' do
219
- expect(manifest_object.type).to eq 'Manifest'
228
+ it "has expected required values" do
229
+ expect(manifest_object.type).to eq "Manifest"
220
230
  expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
221
- expect(manifest_object.label['en']).to include "blah"
231
+ expect(manifest_object.label["en"]).to include "blah"
222
232
  expect(manifest_object.items.size).to be 1
223
233
  expect(manifest_object.items.first).to eq canvas_object
224
234
  end
225
- it 'has expected additional content' do
226
- expect(manifest_object['required_statement'][:value][:en].first).to eq 'bleah'
227
- expect(manifest_object.summary['en'].first).to eq 'blargh'
235
+ it "has expected additional content" do
236
+ expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
237
+ expect(manifest_object.summary["en"].first).to eq "blargh"
228
238
  expect(manifest_object.logo.keys.size).to be 2
229
239
  expect(manifest_object.seeAlso.keys.size).to be 2
230
240
  expect(manifest_object.metadata.size).to be 2
231
241
  expect(manifest_object.thumbnail.size).to be 1
232
242
  end
233
243
 
234
- describe 'from stanford purl CODE' do
244
+ describe "from stanford purl CODE" do
235
245
  let!(:manifest_data) {
236
246
  {
237
247
  "id" => "https://example.org/abc666/iiif3/manifest",
238
248
  "label" => {"en" => ["blah"]},
239
249
  "requiredStatement" => {
240
- "label": { "en": [ "Attribution" ] },
241
- "value": { "en": [ "bleah" ] },
250
+ label: {en: ["Attribution"]},
251
+ value: {en: ["bleah"]}
242
252
  },
243
253
  "logo" => {
244
254
  "id" => "https://example.org/logo/full/400,/0/default.jpg",
@@ -252,29 +262,29 @@ describe IIIF::V3::Presentation::Manifest do
252
262
  }
253
263
  let!(:manifest_object) {
254
264
  m = described_class.new manifest_data
255
- m.viewingHint = 'paged'
265
+ m.viewingHint = "paged"
256
266
  m.metadata = [
257
- { 'label' => 'title', 'value' => 'who wants to know?' },
258
- { 'label' => 'PublishDate', 'value' => 'sometime' }
267
+ {"label" => "title", "value" => "who wants to know?"},
268
+ {"label" => "PublishDate", "value" => "sometime"}
259
269
  ]
260
- m.summary = { 'en' => ['blargh'] }
270
+ m.summary = {"en" => ["blargh"]}
261
271
  m.thumbnail = [thumbnail_image]
262
272
  m.items << canvas_object
263
273
  m
264
274
  }
265
- it 'manifest validates' do
266
- expect{manifest_object.validate}.not_to raise_error
275
+ it "manifest validates" do
276
+ expect { manifest_object.validate }.not_to raise_error
267
277
  end
268
- it 'has expected required values' do
269
- expect(manifest_object.type).to eq 'Manifest'
278
+ it "has expected required values" do
279
+ expect(manifest_object.type).to eq "Manifest"
270
280
  expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
271
- expect(manifest_object.label['en']).to include "blah"
281
+ expect(manifest_object.label["en"]).to include "blah"
272
282
  expect(manifest_object.items.size).to be 1
273
283
  expect(manifest_object.items.first).to eq canvas_object
274
284
  end
275
- it 'has expected additional content' do
276
- expect(manifest_object['required_statement'][:value][:en].first).to eq 'bleah'
277
- expect(manifest_object.summary['en'].first).to eq 'blargh'
285
+ it "has expected additional content" do
286
+ expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
287
+ expect(manifest_object.summary["en"].first).to eq "blargh"
278
288
  expect(manifest_object.logo.keys.size).to be 2
279
289
  expect(manifest_object.seeAlso.keys.size).to be 2
280
290
  expect(manifest_object.metadata.size).to be 2
@@ -282,88 +292,89 @@ describe IIIF::V3::Presentation::Manifest do
282
292
  end
283
293
  end
284
294
  end
285
- describe 'example from http://prezi3.iiif.io/api/presentation/3.0' do
286
- let!(:range_object) { IIIF::V3::Presentation::Range.new({
287
- "id" => "http://example.org/iiif/book1/range/top",
288
- "label" => {"en" => ["home, home on the"]},
289
- "viewingHint" => ["top"]
295
+ describe "example from http://prezi3.iiif.io/api/presentation/3.0" do
296
+ let!(:range_object) {
297
+ IIIF::V3::Presentation::Range.new({
298
+ "id" => "http://example.org/iiif/book1/range/top",
299
+ "label" => {"en" => ["home, home on the"]},
300
+ "viewingHint" => ["top"]
290
301
  })
291
302
  }
292
- let!(:manifest_object) { described_class.new({
293
- "@context" => [
294
- "http://www.w3.org/ns/anno.jsonld",
295
- "http://iiif.io/api/presentation/3/context.json"
303
+ let!(:manifest_object) {
304
+ described_class.new({
305
+ "@context" => [
306
+ "http://www.w3.org/ns/anno.jsonld",
307
+ "http://iiif.io/api/presentation/3/context.json"
308
+ ],
309
+ "id" => "http://example.org/iiif/book1/manifest",
310
+ "label" => {"en" => ["Book 1"]},
311
+ "metadata" => [
312
+ {"label" => {"en" => ["Author"]},
313
+ "value" => {"@none" => ["Anne Author"]}},
314
+ {"label" => {"en" => ["Published"]},
315
+ "value" => {
316
+ "en" => ["Paris, circa 1400"],
317
+ "fr" => ["Paris, environ 1400"]
318
+ }},
319
+ {"label" => {"en" => ["Notes"]},
320
+ "value" => {"en" => ["Text of note 1", "Text of note 2"]}},
321
+ {"label" => {"en" => ["Source"]},
322
+ "value" => {"@none" => ["<span>From: <a href=\"http://example.org/db/1.html\">Some Collection</a></span>"]}}
296
323
  ],
297
- "id" => "http://example.org/iiif/book1/manifest",
298
- "label" => {"en" => ["Book 1"]},
299
- "metadata" => [
300
- {"label" => {"en" => ["Author"]},
301
- "value" => {"@none" => ["Anne Author"]}},
302
- {"label" => {"en" => ["Published"]},
303
- "value" => {
304
- "en" => ["Paris, circa 1400"],
305
- "fr" => ["Paris, environ 1400"]}
324
+ "summary" => {"en" => ["A longer description of this example book. It should give some real information."]},
325
+ "thumbnail" => [{
326
+ "id" => "http://example.org/images/book1-page1/full/80,100/0/default.jpg",
327
+ "type" => "Image",
328
+ "service" => {
329
+ "id" => "http://example.org/images/book1-page1",
330
+ "type" => "ImageService2",
331
+ "profile" => ["http://iiif.io/api/image/2/level1.json"]
332
+ }
333
+ }],
334
+ "viewingDirection" => "right-to-left",
335
+ "viewingHint" => ["paged"],
336
+ "navDate" => "1856-01-01T00:00:00Z",
337
+ "rights" => "http://example.org/license.html",
338
+ "requiredStatement" => {
339
+ label: {en: ["Attribution"]},
340
+ value: {en: ["bleah"]}
306
341
  },
307
- {"label" => {"en" => ["Notes"]},
308
- "value" => {"en" => ["Text of note 1", "Text of note 2"]}},
309
- {"label" => {"en" => ["Source"]},
310
- "value" => {"@none" => ["<span>From: <a href=\"http://example.org/db/1.html\">Some Collection</a></span>"]}}
311
- ],
312
- "summary" => {"en" => ["A longer description of this example book. It should give some real information."]},
313
- "thumbnail" => [{
314
- "id" => "http://example.org/images/book1-page1/full/80,100/0/default.jpg",
315
- "type" => "Image",
316
- "service" => {
317
- "id" => "http://example.org/images/book1-page1",
318
- "type" => "ImageService2",
319
- "profile" => ["http://iiif.io/api/image/2/level1.json"]
320
- }
321
- }],
322
- "viewingDirection" => "right-to-left",
323
- "viewingHint" => ["paged"],
324
- "navDate" => "1856-01-01T00:00:00Z",
325
- "rights" => [{
326
- "id" =>"http://example.org/license.html",
327
- "format" => "text/html"}],
328
- "requiredStatement" => {
329
- "label": { "en": [ "Attribution" ] },
330
- "value": { "en": [ "bleah" ] },
331
- },
332
- "logo" => {
333
- "id" => "http://example.org/logos/institution1.jpg",
334
- "service" => {
342
+ "logo" => {
343
+ "id" => "http://example.org/logos/institution1.jpg",
344
+ "service" => {
335
345
  "id" => "http://example.org/service/inst1",
336
346
  "type" => "ImageService2",
337
347
  "profile" => ["http://iiif.io/api/image/2/profiles/level2.json"]
338
- }
339
- },
340
- "related" => [{
341
- "id" => "http://example.org/videos/video-book1.mpg",
342
- "format" => "video/mpeg"
343
- }],
344
- "service" => [{
345
- "id" => "http://example.org/service/example",
346
- "profile" => ["http://example.org/docs/example-service.html"]
347
- }],
348
- "seeAlso" => [{
349
- "id" => "http://example.org/library/catalog/book1.xml",
350
- "format" => "text/xml",
351
- "profile" => ["http://example.org/profiles/bibliographic"]
352
- }],
353
- "rendering" => [{
354
- "id" => "http://example.org/iiif/book1.pdf",
355
- "label" => {"en" => ["Download as PDF"]},
356
- "format" => "application/pdf"
357
- }],
358
- "within" => [{
359
- "id" => "http://example.org/collections/books/",
360
- "type" => "Collection"
361
- }],
362
- "items" => [canvas_object],
363
- "structures" => [range_object]
364
- })}
365
- it 'validates' do
366
- expect{manifest_object.validate}.not_to raise_error
348
+ }
349
+ },
350
+ "related" => [{
351
+ "id" => "http://example.org/videos/video-book1.mpg",
352
+ "format" => "video/mpeg"
353
+ }],
354
+ "service" => [{
355
+ "id" => "http://example.org/service/example",
356
+ "profile" => ["http://example.org/docs/example-service.html"]
357
+ }],
358
+ "seeAlso" => [{
359
+ "id" => "http://example.org/library/catalog/book1.xml",
360
+ "format" => "text/xml",
361
+ "profile" => ["http://example.org/profiles/bibliographic"]
362
+ }],
363
+ "rendering" => [{
364
+ "id" => "http://example.org/iiif/book1.pdf",
365
+ "label" => {"en" => ["Download as PDF"]},
366
+ "format" => "application/pdf"
367
+ }],
368
+ "within" => [{
369
+ "id" => "http://example.org/collections/books/",
370
+ "type" => "Collection"
371
+ }],
372
+ "items" => [canvas_object],
373
+ "structures" => [range_object]
374
+ })
375
+ }
376
+ it "validates" do
377
+ expect { manifest_object.validate }.not_to raise_error
367
378
  end
368
379
  end
369
380
  end