iiif-presentation 1.4.2 → 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 +127 -130
- 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 +72 -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 +124 -131
- 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 -235
- 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 +125 -119
- 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 +26 -65
|
@@ -1,155 +1,150 @@
|
|
|
1
1
|
describe IIIF::OrderedHash do
|
|
2
|
-
|
|
3
|
-
describe '#camelize_keys' do
|
|
2
|
+
describe "#camelize_keys" do
|
|
4
3
|
before(:each) do
|
|
5
|
-
@uri =
|
|
6
|
-
@within_uri =
|
|
7
|
-
subject[
|
|
8
|
-
subject[
|
|
4
|
+
@uri = "http://www.example.org/descriptions/book1.xml"
|
|
5
|
+
@within_uri = "http://www.example.org/collections/books/"
|
|
6
|
+
subject["see_also"] = @uri
|
|
7
|
+
subject["within"] = @within_uri
|
|
9
8
|
end
|
|
10
|
-
it
|
|
9
|
+
it "changes snake_case keys to camelCase" do
|
|
11
10
|
subject.camelize_keys # #send gets past protection
|
|
12
|
-
expect(subject.
|
|
13
|
-
expect(subject.
|
|
11
|
+
expect(subject.key?("seeAlso")).to be_truthy
|
|
12
|
+
expect(subject.key?("see_also")).to be_falsey
|
|
14
13
|
end
|
|
15
|
-
it
|
|
14
|
+
it "keeps the right values" do
|
|
16
15
|
subject.camelize_keys
|
|
17
|
-
expect(subject[
|
|
18
|
-
expect(subject[
|
|
16
|
+
expect(subject["seeAlso"]).to eq @uri
|
|
17
|
+
expect(subject["within"]).to eq @within_uri
|
|
19
18
|
end
|
|
20
|
-
it
|
|
21
|
-
see_also_position = subject.keys.index(
|
|
22
|
-
within_position = subject.keys.index(
|
|
19
|
+
it "keeps things in the same position" do
|
|
20
|
+
see_also_position = subject.keys.index("see_also")
|
|
21
|
+
within_position = subject.keys.index("within")
|
|
23
22
|
subject.camelize_keys
|
|
24
|
-
expect(subject.keys[see_also_position]).to eq
|
|
25
|
-
expect(subject.keys[within_position]).to eq
|
|
23
|
+
expect(subject.keys[see_also_position]).to eq "seeAlso"
|
|
24
|
+
expect(subject.keys[within_position]).to eq "within"
|
|
26
25
|
end
|
|
27
|
-
|
|
28
26
|
end
|
|
29
27
|
|
|
30
|
-
describe
|
|
28
|
+
describe "#snakeize_keys" do
|
|
31
29
|
before(:each) do
|
|
32
|
-
@uri =
|
|
33
|
-
@within_uri =
|
|
34
|
-
subject[
|
|
35
|
-
subject[
|
|
30
|
+
@uri = "http://www.example.org/descriptions/book1.xml"
|
|
31
|
+
@within_uri = "http://www.example.org/collections/books/"
|
|
32
|
+
subject["seeAlso"] = @uri
|
|
33
|
+
subject["within"] = @within_uri
|
|
36
34
|
end
|
|
37
|
-
it
|
|
35
|
+
it "changes camelCase keys to snake_case" do
|
|
38
36
|
subject.snakeize_keys
|
|
39
|
-
expect(subject.
|
|
40
|
-
expect(subject.
|
|
37
|
+
expect(subject.key?("see_also")).to be_truthy
|
|
38
|
+
expect(subject.key?("seeAlso")).to be_falsey
|
|
41
39
|
end
|
|
42
|
-
it
|
|
40
|
+
it "keeps the right values" do
|
|
43
41
|
subject.snakeize_keys
|
|
44
|
-
expect(subject[
|
|
45
|
-
expect(subject[
|
|
42
|
+
expect(subject["see_also"]).to eq @uri
|
|
43
|
+
expect(subject["within"]).to eq @within_uri
|
|
46
44
|
end
|
|
47
|
-
it
|
|
48
|
-
see_also_position = subject.keys.index(
|
|
49
|
-
within_position = subject.keys.index(
|
|
45
|
+
it "keeps things in the same position" do
|
|
46
|
+
see_also_position = subject.keys.index("seeAlso")
|
|
47
|
+
within_position = subject.keys.index("within")
|
|
50
48
|
subject.snakeize_keys
|
|
51
|
-
expect(subject.keys[see_also_position]).to eq
|
|
52
|
-
expect(subject.keys[within_position]).to eq
|
|
49
|
+
expect(subject.keys[see_also_position]).to eq "see_also"
|
|
50
|
+
expect(subject.keys[within_position]).to eq "within"
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
|
-
describe
|
|
54
|
+
describe "insertion patches" do
|
|
55
|
+
let(:init_data) { [["wubble", "fred"], ["baz", "qux"], ["grault", "garply"]] }
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
subject do
|
|
57
|
+
subject do
|
|
61
58
|
hsh = described_class.new
|
|
62
59
|
init_data.each { |e| hsh[e[0]] = e[1] }
|
|
63
60
|
hsh
|
|
64
61
|
end
|
|
65
62
|
|
|
66
|
-
describe
|
|
67
|
-
it
|
|
68
|
-
subject.insert(2,
|
|
69
|
-
expect(subject[subject.keys[0]]).to eq
|
|
70
|
-
expect(subject[subject.keys[1]]).to eq
|
|
71
|
-
expect(subject[subject.keys[2]]).to eq
|
|
72
|
-
expect(subject[subject.keys[3]]).to eq
|
|
63
|
+
describe "#insert" do
|
|
64
|
+
it "inserts as expected" do
|
|
65
|
+
subject.insert(2, "quux", "corge")
|
|
66
|
+
expect(subject[subject.keys[0]]).to eq "fred"
|
|
67
|
+
expect(subject[subject.keys[1]]).to eq "qux"
|
|
68
|
+
expect(subject[subject.keys[2]]).to eq "corge"
|
|
69
|
+
expect(subject[subject.keys[3]]).to eq "garply"
|
|
73
70
|
end
|
|
74
|
-
it
|
|
75
|
-
expect(subject.insert(1,
|
|
71
|
+
it "returns the instance" do
|
|
72
|
+
expect(subject.insert(1, "quux", "corge")).to eq subject
|
|
76
73
|
end
|
|
77
|
-
it
|
|
78
|
-
expect { subject.insert(-5,
|
|
74
|
+
it "raises IndexError if a negative index is too small" do
|
|
75
|
+
expect { subject.insert(-5, "quux", "corge") }.to raise_error IndexError
|
|
79
76
|
end
|
|
80
|
-
it
|
|
81
|
-
subject.insert(-1,
|
|
82
|
-
expect(subject[subject.keys.last]).to eq
|
|
77
|
+
it "puts index -1 on the end" do
|
|
78
|
+
subject.insert(-1, "thud", "wibble")
|
|
79
|
+
expect(subject[subject.keys.last]).to eq "wibble"
|
|
83
80
|
end
|
|
84
81
|
end
|
|
85
82
|
|
|
86
|
-
describe
|
|
87
|
-
it
|
|
88
|
-
subject.insert_before(existing_key:
|
|
89
|
-
expect(subject.keys).to eq [
|
|
83
|
+
describe "#insert_before" do
|
|
84
|
+
it "inserts in the expected place with a supplied key" do
|
|
85
|
+
subject.insert_before(existing_key: "grault", new_key: "quux", value: "corge")
|
|
86
|
+
expect(subject.keys).to eq ["wubble", "baz", "quux", "grault"]
|
|
90
87
|
end
|
|
91
|
-
it
|
|
92
|
-
subject.insert_before(new_key:
|
|
93
|
-
expect(subject.keys).to eq [
|
|
88
|
+
it "inserts in the expected place with a supplied block" do
|
|
89
|
+
subject.insert_before(new_key: "quux", value: "corge") { |k, v| k.start_with?("g") }
|
|
90
|
+
expect(subject.keys).to eq ["wubble", "baz", "quux", "grault"]
|
|
94
91
|
end
|
|
95
|
-
it
|
|
96
|
-
expect(subject.insert_before(existing_key:
|
|
92
|
+
it "returns the instance" do
|
|
93
|
+
expect(subject.insert_before(existing_key: "grault", new_key: "quux", value: "corge")).to be subject
|
|
97
94
|
end
|
|
98
|
-
describe
|
|
99
|
-
it
|
|
100
|
-
expect { subject.insert_before(existing_key:
|
|
95
|
+
describe "raises KeyError" do
|
|
96
|
+
it "when the supplied existing key is not found" do
|
|
97
|
+
expect { subject.insert_before(existing_key: "foo", new_key: "quux", value: "corge") }.to raise_error KeyError
|
|
101
98
|
end
|
|
102
|
-
it
|
|
103
|
-
expect { subject.insert_before(existing_key:
|
|
99
|
+
it "when the supplied new key already exists" do
|
|
100
|
+
expect { subject.insert_before(existing_key: "grault", new_key: "wubble", value: "corge") }.to raise_error KeyError
|
|
104
101
|
end
|
|
105
102
|
end
|
|
106
103
|
end
|
|
107
104
|
|
|
108
|
-
describe
|
|
109
|
-
it
|
|
110
|
-
subject.insert_after(existing_key:
|
|
111
|
-
expect(subject.keys).to eq [
|
|
105
|
+
describe "#insert_after" do
|
|
106
|
+
it "inserts in the expected place with a supplied key" do
|
|
107
|
+
subject.insert_after(existing_key: "baz", new_key: "quux", value: "corge")
|
|
108
|
+
expect(subject.keys).to eq ["wubble", "baz", "quux", "grault"]
|
|
112
109
|
end
|
|
113
|
-
it
|
|
114
|
-
subject.insert_after(new_key:
|
|
115
|
-
expect(subject.keys).to eq [
|
|
110
|
+
it "inserts in the expected place with a supplied block" do
|
|
111
|
+
subject.insert_after(new_key: "quux", value: "corge") { |k, v| k.start_with?("g") }
|
|
112
|
+
expect(subject.keys).to eq ["wubble", "baz", "quux", "grault"]
|
|
116
113
|
end
|
|
117
|
-
it
|
|
118
|
-
expect(subject.insert_after(existing_key:
|
|
114
|
+
it "returns the instance" do
|
|
115
|
+
expect(subject.insert_after(existing_key: "baz", new_key: "quux", value: "corge")).to be subject
|
|
119
116
|
end
|
|
120
|
-
describe
|
|
121
|
-
it
|
|
122
|
-
expect { subject.insert_after(existing_key:
|
|
117
|
+
describe "raises KeyError" do
|
|
118
|
+
it "when the supplied existing key is not found" do
|
|
119
|
+
expect { subject.insert_after(existing_key: "foo", new_key: "quux", value: "corge") }.to raise_error KeyError
|
|
123
120
|
end
|
|
124
|
-
it
|
|
125
|
-
expect { subject.insert_after(existing_key:
|
|
121
|
+
it "when the supplied new key already exists" do
|
|
122
|
+
expect { subject.insert_after(existing_key: "grault", new_key: "wubble", value: "corge") }.to raise_error KeyError
|
|
126
123
|
end
|
|
127
124
|
end
|
|
128
125
|
end
|
|
129
126
|
|
|
130
|
-
describe
|
|
131
|
-
it
|
|
132
|
-
subject.unshift(
|
|
133
|
-
expect(subject[subject.keys[0]]).to eq
|
|
127
|
+
describe "#unshift" do
|
|
128
|
+
it "adds an entry to the front of the object" do
|
|
129
|
+
subject.unshift("thud", "wibble")
|
|
130
|
+
expect(subject[subject.keys[0]]).to eq "wibble"
|
|
134
131
|
end
|
|
135
|
-
it
|
|
136
|
-
expect(subject.unshift(
|
|
132
|
+
it "returns the instance" do
|
|
133
|
+
expect(subject.unshift("thud", "wibble")).to be subject
|
|
137
134
|
end
|
|
138
135
|
end
|
|
139
136
|
|
|
140
|
-
describe
|
|
141
|
-
it
|
|
137
|
+
describe "#remove_empties" do
|
|
138
|
+
it "if they're arrays" do
|
|
142
139
|
subject[:wubble] = []
|
|
143
140
|
subject.remove_empties
|
|
144
141
|
expect(subject.has_key?(:wubble)).to be_falsey
|
|
145
142
|
end
|
|
146
|
-
it
|
|
143
|
+
it "if they're nil" do
|
|
147
144
|
subject[:wubble] = nil
|
|
148
145
|
subject.remove_empties
|
|
149
146
|
expect(subject.has_key?(:wubble)).to be_falsey
|
|
150
147
|
end
|
|
151
148
|
end
|
|
152
|
-
|
|
153
149
|
end
|
|
154
150
|
end
|
|
155
|
-
|
|
@@ -1,133 +1,127 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require File.join(File.dirname(__FILE__),
|
|
4
|
-
|
|
1
|
+
require "active_support/inflector"
|
|
2
|
+
require "json"
|
|
3
|
+
require File.join(File.dirname(__FILE__), "../../../../lib/iiif/hash_behaviours")
|
|
5
4
|
|
|
6
5
|
describe IIIF::Presentation::AbstractResource do
|
|
7
|
-
|
|
8
|
-
let(:
|
|
9
|
-
let(:manifest_from_spec_path) { File.join(fixtures_dir, 'manifests/complete_from_spec.json') }
|
|
6
|
+
let(:fixtures_dir) { File.join(File.dirname(__FILE__), "../../../fixtures") }
|
|
7
|
+
let(:manifest_from_spec_path) { File.join(fixtures_dir, "manifests/complete_from_spec.json") }
|
|
10
8
|
let(:abstract_resource_subclass) do
|
|
11
9
|
Class.new(IIIF::Presentation::AbstractResource) do
|
|
12
10
|
include IIIF::HashBehaviours
|
|
13
11
|
|
|
14
|
-
def initialize(hsh={})
|
|
15
|
-
hsh[
|
|
16
|
-
super
|
|
12
|
+
def initialize(hsh = {})
|
|
13
|
+
hsh["@type"] = "a:SubClass" unless hsh.has_key?("@type")
|
|
14
|
+
super
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
def required_keys
|
|
20
|
-
super + %w
|
|
18
|
+
super + %w[@id]
|
|
21
19
|
end
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
subject do
|
|
26
|
-
instance = abstract_resource_subclass.new
|
|
27
|
-
instance[
|
|
24
|
+
instance = abstract_resource_subclass.new
|
|
25
|
+
instance["@id"] = "http://example.com/prefix/manifest/123"
|
|
28
26
|
instance
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
describe
|
|
32
|
-
it
|
|
29
|
+
describe "#initialize" do
|
|
30
|
+
it "raises an error if you try to instantiate AbstractResource" do
|
|
33
31
|
expect { IIIF::Presentation::AbstractResource.new }.to raise_error(RuntimeError)
|
|
34
32
|
end
|
|
35
|
-
it
|
|
36
|
-
expect(subject[
|
|
33
|
+
it "sets @type" do
|
|
34
|
+
expect(subject["@type"]).to eq "a:SubClass"
|
|
37
35
|
end
|
|
38
|
-
it
|
|
36
|
+
it "can take any old hash" do
|
|
39
37
|
hsh = JSON.parse(IO.read(manifest_from_spec_path))
|
|
40
38
|
new_instance = abstract_resource_subclass.new(hsh)
|
|
41
|
-
expect(new_instance[
|
|
39
|
+
expect(new_instance["label"]).to eq "Book 1"
|
|
42
40
|
end
|
|
43
41
|
end
|
|
44
42
|
|
|
45
|
-
describe
|
|
46
|
-
it
|
|
43
|
+
describe "A nested object (e.g. self['metdata'])" do
|
|
44
|
+
it "returns [] if not set" do
|
|
47
45
|
expect(subject.metadata).to eq([])
|
|
48
46
|
end
|
|
49
|
-
it
|
|
47
|
+
it "is not in #to_ordered_hash at all if we access it but do not append to it" do
|
|
50
48
|
subject.metadata # touch it
|
|
51
49
|
expect(subject.metadata).to eq([])
|
|
52
|
-
expect(subject.to_ordered_hash.has_key?(
|
|
50
|
+
expect(subject.to_ordered_hash.has_key?("metadata")).to be_falsey
|
|
53
51
|
end
|
|
54
|
-
it
|
|
52
|
+
it "gets structured as we'd expect" do
|
|
55
53
|
subject.metadata << {
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
"label" => "Author",
|
|
55
|
+
"value" => "Anne Author"
|
|
58
56
|
}
|
|
59
57
|
subject.metadata << {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
{
|
|
58
|
+
"label" => "Published",
|
|
59
|
+
"value" => [
|
|
60
|
+
{"@value" => "Paris, circa 1400", "@language" => "en"},
|
|
61
|
+
{"@value" => "Paris, environ 14eme siecle", "@language" => "fr"}
|
|
64
62
|
]
|
|
65
63
|
}
|
|
66
|
-
expect(subject.metadata[0][
|
|
67
|
-
expect(subject.metadata[1][
|
|
68
|
-
expect(subject.metadata[1][
|
|
64
|
+
expect(subject.metadata[0]["label"]).to eq("Author")
|
|
65
|
+
expect(subject.metadata[1]["value"].length).to eq(2)
|
|
66
|
+
expect(subject.metadata[1]["value"].reverse.find { |e| e["@language"] == "fr" }["@value"]).to eq("Paris, environ 14eme siecle")
|
|
69
67
|
end
|
|
70
68
|
|
|
71
|
-
it
|
|
69
|
+
it "roundtrips" do
|
|
72
70
|
subject.metadata << {
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
"label" => "Author",
|
|
72
|
+
"value" => "Anne Author"
|
|
75
73
|
}
|
|
76
74
|
subject.metadata << {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
{
|
|
80
|
-
{
|
|
75
|
+
"label" => "Published",
|
|
76
|
+
"value" => [
|
|
77
|
+
{"@value" => "Paris, circa 1400", "@language" => "en"},
|
|
78
|
+
{"@value" => "Paris, environ 14eme siecle", "@language" => "fr"}
|
|
81
79
|
]
|
|
82
80
|
}
|
|
83
|
-
File.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
parsed
|
|
87
|
-
expect(parsed[
|
|
88
|
-
|
|
89
|
-
expect(parsed['metadata'][1]['value'].select { |e| e['@language'] == 'fr'}.last['@value']).to eq('Paris, environ 14eme siecle')
|
|
90
|
-
File.delete('/tmp/osullivan-spec.json')
|
|
81
|
+
File.write("/tmp/osullivan-spec.json", subject.to_json)
|
|
82
|
+
parsed = subject.class.parse("/tmp/osullivan-spec.json")
|
|
83
|
+
expect(parsed["metadata"][0]["label"]).to eq("Author")
|
|
84
|
+
expect(parsed["metadata"][1]["value"].length).to eq(2)
|
|
85
|
+
expect(parsed["metadata"][1]["value"].reverse.find { |e| e["@language"] == "fr" }["@value"]).to eq("Paris, environ 14eme siecle")
|
|
86
|
+
File.delete("/tmp/osullivan-spec.json")
|
|
91
87
|
end
|
|
92
88
|
end
|
|
93
89
|
|
|
94
|
-
describe
|
|
95
|
-
it
|
|
96
|
-
expect(subject.required_keys).to eq %w
|
|
90
|
+
describe "#required_keys" do
|
|
91
|
+
it "accumulates" do
|
|
92
|
+
expect(subject.required_keys).to eq %w[@type @id]
|
|
97
93
|
end
|
|
98
94
|
end
|
|
99
95
|
|
|
100
|
-
describe
|
|
101
|
-
describe
|
|
102
|
-
before(:each) { subject.delete(
|
|
103
|
-
it
|
|
104
|
-
expect(subject.has_key?(
|
|
105
|
-
expect(subject.to_ordered_hash.has_key?(
|
|
96
|
+
describe "#to_ordered_hash" do
|
|
97
|
+
describe "adds the @context" do
|
|
98
|
+
before(:each) { subject.delete("@context") }
|
|
99
|
+
it "by default" do
|
|
100
|
+
expect(subject.has_key?("@context")).to be_falsey
|
|
101
|
+
expect(subject.to_ordered_hash.has_key?("@context")).to be_truthy
|
|
106
102
|
end
|
|
107
|
-
it
|
|
108
|
-
expect(subject.has_key?(
|
|
109
|
-
expect(subject.to_ordered_hash(include_context: false).has_key?(
|
|
103
|
+
it "unless you say not to" do
|
|
104
|
+
expect(subject.has_key?("@context")).to be_falsey
|
|
105
|
+
expect(subject.to_ordered_hash(include_context: false).has_key?("@context")).to be_falsey
|
|
110
106
|
end
|
|
111
|
-
it
|
|
112
|
-
different_ctxt =
|
|
113
|
-
subject[
|
|
107
|
+
it "or it's already there" do
|
|
108
|
+
different_ctxt = "http://example.org/context"
|
|
109
|
+
subject["@context"] = different_ctxt
|
|
114
110
|
oh = subject.to_ordered_hash
|
|
115
|
-
expect(oh[
|
|
111
|
+
expect(oh["@context"]).to eq different_ctxt
|
|
116
112
|
end
|
|
117
113
|
end
|
|
118
114
|
|
|
119
|
-
describe
|
|
115
|
+
describe "runs the validations" do
|
|
120
116
|
# Test this here because there's nothing to validate on the superclass (Subject)
|
|
121
117
|
let(:error) { IIIF::Presentation::MissingRequiredKeyError }
|
|
122
|
-
before(:each) { subject.delete(
|
|
123
|
-
it
|
|
118
|
+
before(:each) { subject.delete("@id") }
|
|
119
|
+
it "raises exceptions" do
|
|
124
120
|
expect { subject.to_ordered_hash }.to raise_error error
|
|
125
121
|
end
|
|
126
|
-
it
|
|
122
|
+
it "unless you tell it not to" do
|
|
127
123
|
expect { subject.to_ordered_hash(force: true) }.to_not raise_error
|
|
128
124
|
end
|
|
129
125
|
end
|
|
130
126
|
end
|
|
131
|
-
|
|
132
127
|
end
|
|
133
|
-
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
describe IIIF::Presentation::AnnotationList do
|
|
2
|
-
|
|
3
2
|
describe "#{described_class}.define_methods_for_array_only_keys" do
|
|
4
|
-
it_behaves_like
|
|
3
|
+
it_behaves_like "it has the appropriate methods for array-only keys"
|
|
5
4
|
end
|
|
6
|
-
|
|
7
5
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
describe IIIF::Presentation::Annotation do
|
|
2
|
-
|
|
3
2
|
describe "#{described_class}.define_methods_for_abstract_resource_only_keys" do
|
|
4
|
-
it_behaves_like
|
|
3
|
+
it_behaves_like "it has the appropriate methods for abstract_resource_only_keys"
|
|
5
4
|
end
|
|
6
|
-
|
|
7
5
|
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
describe IIIF::Presentation::Canvas do
|
|
2
|
-
|
|
3
2
|
let(:fixed_values) do
|
|
4
3
|
{
|
|
5
4
|
"@context" => "http://iiif.io/api/presentation/2/context.json",
|
|
@@ -8,38 +7,36 @@ describe IIIF::Presentation::Canvas do
|
|
|
8
7
|
"label" => "p. 1",
|
|
9
8
|
"height" => 1000,
|
|
10
9
|
"width" => 750,
|
|
11
|
-
"images" =>
|
|
12
|
-
"otherContent" =>
|
|
10
|
+
"images" => [],
|
|
11
|
+
"otherContent" => []
|
|
13
12
|
}
|
|
14
13
|
end
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
expect(subject['@type']).to eq 'sc:Canvas'
|
|
15
|
+
describe "#initialize" do
|
|
16
|
+
it "sets @type" do
|
|
17
|
+
expect(subject["@type"]).to eq "sc:Canvas"
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
describe "#{described_class}.int_only_keys" do
|
|
24
|
-
it_behaves_like
|
|
22
|
+
it_behaves_like "it has the appropriate methods for integer-only keys"
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
describe "#{described_class}.define_methods_for_string_only_keys" do
|
|
28
|
-
it_behaves_like
|
|
26
|
+
it_behaves_like "it has the appropriate methods for string-only keys"
|
|
29
27
|
end
|
|
30
|
-
|
|
28
|
+
|
|
31
29
|
describe "#{described_class}.define_methods_for_array_only_keys" do
|
|
32
|
-
it_behaves_like
|
|
30
|
+
it_behaves_like "it has the appropriate methods for array-only keys"
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
describe "#{described_class}.define_methods_for_any_type_keys" do
|
|
36
|
-
it_behaves_like
|
|
34
|
+
it_behaves_like "it has the appropriate methods for any-type keys"
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
describe "#legal_viewing_hint_values" do
|
|
40
38
|
it "should not error" do
|
|
41
|
-
expect{subject.legal_viewing_hint_values}.not_to raise_error
|
|
39
|
+
expect { subject.legal_viewing_hint_values }.not_to raise_error
|
|
42
40
|
end
|
|
43
41
|
end
|
|
44
|
-
|
|
45
42
|
end
|
|
@@ -1,54 +1,47 @@
|
|
|
1
1
|
describe IIIF::Presentation::Collection do
|
|
2
|
-
|
|
3
|
-
let(:fixed_values) do
|
|
2
|
+
let(:fixed_values) do
|
|
4
3
|
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'label' => 'Sub Collection 2'
|
|
20
|
-
}
|
|
4
|
+
"@context" => "http://iiif.io/api/presentation/2/context.json",
|
|
5
|
+
"@id" => "http://example.org/iiif/collection/top",
|
|
6
|
+
"@type" => "sc:Collection",
|
|
7
|
+
"label" => "Top Level Collection for Example Organization",
|
|
8
|
+
"description" => "Description of Collection",
|
|
9
|
+
"attribution" => "Provided by Example Organization",
|
|
10
|
+
|
|
11
|
+
"collections" => [
|
|
12
|
+
{"@id" => "http://example.org/iiif/collection/part1",
|
|
13
|
+
"@type" => "sc:Collection",
|
|
14
|
+
"label" => "Sub Collection 1"},
|
|
15
|
+
{"@id" => "http://example.org/iiif/collection/part2",
|
|
16
|
+
"@type" => "sc:Collection",
|
|
17
|
+
"label" => "Sub Collection 2"}
|
|
21
18
|
],
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
19
|
+
"manifests" => [
|
|
20
|
+
{"@id" => "http://example.org/iiif/book1/manifest",
|
|
21
|
+
"@type" => "sc:Manifest",
|
|
22
|
+
"label" => "Book 1"}
|
|
27
23
|
]
|
|
28
24
|
}
|
|
29
25
|
end
|
|
30
26
|
|
|
31
|
-
describe
|
|
32
|
-
it
|
|
33
|
-
expect(subject[
|
|
27
|
+
describe "#initialize" do
|
|
28
|
+
it "sets @type to sc:Collection by default" do
|
|
29
|
+
expect(subject["@type"]).to eq "sc:Collection"
|
|
34
30
|
end
|
|
35
31
|
end
|
|
36
32
|
|
|
37
33
|
describe "#{described_class}.define_methods_for_array_only_keys" do
|
|
38
|
-
it_behaves_like
|
|
34
|
+
it_behaves_like "it has the appropriate methods for array-only keys"
|
|
39
35
|
end
|
|
40
36
|
|
|
41
37
|
describe "#{described_class}.define_methods_for_string_only_keys" do
|
|
42
|
-
it_behaves_like
|
|
38
|
+
it_behaves_like "it has the appropriate methods for string-only keys"
|
|
43
39
|
end
|
|
44
40
|
|
|
45
41
|
describe "#{described_class}.define_methods_for_any_type_keys" do
|
|
46
|
-
it_behaves_like
|
|
42
|
+
it_behaves_like "it has the appropriate methods for any-type keys"
|
|
47
43
|
end
|
|
48
44
|
|
|
49
|
-
describe
|
|
45
|
+
describe "#validate" do
|
|
50
46
|
end
|
|
51
|
-
|
|
52
47
|
end
|
|
53
|
-
|
|
54
|
-
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
describe IIIF::Presentation::ImageResource do
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
expect(subject['@type']).to eq 'dctypes:Image'
|
|
2
|
+
describe "#initialize" do
|
|
3
|
+
it "sets @type to dctypes:Image" do
|
|
4
|
+
expect(subject["@type"]).to eq "dctypes:Image"
|
|
6
5
|
end
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
describe "#{described_class}.int_only_keys" do
|
|
10
|
-
it_behaves_like
|
|
9
|
+
it_behaves_like "it has the appropriate methods for integer-only keys"
|
|
11
10
|
end
|
|
12
|
-
|
|
13
11
|
end
|