ladder 0.3.2 → 0.4.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.
@@ -1,10 +1,12 @@
1
1
  require 'mimemagic'
2
2
 
3
3
  shared_examples 'a File' do
4
- describe 'LADDER_BASE_URI' do
4
+ describe '#configure_model' do
5
5
  it 'should automatically have a base URI' do
6
- expect(subject.rdf_subject.parent).to eq RDF::URI('http://example.org/datastreams/')
6
+ expect([RDF::URI('http://example.org/datastreams/')]).to include subject.rdf_subject.parent
7
7
  end
8
+
9
+ # TODO: it should be registered in Ladder::Config
8
10
  end
9
11
 
10
12
  describe '#initialize' do
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "@context": {
3
3
  "dc": "http://purl.org/dc/terms/",
4
- "skos": "http://www.w3.org/2004/02/skos/core#"
4
+ "skos": "http://www.w3.org/2004/02/skos/core#",
5
+ "xsd": "http://www.w3.org/2001/XMLSchema#"
5
6
  },
6
7
  "@id": "_:b1",
7
8
  "@type": "dc:BibliographicResource",
@@ -13,10 +14,48 @@
13
14
  "@id": "_:b1"
14
15
  }
15
16
  },
17
+ "dc:created": {
18
+ "@type": "xsd:dateTime",
19
+ "@value": "2015-03-06T16:00:00Z"
20
+ },
21
+ "dc:date": {
22
+ "@type": "xsd:date",
23
+ "@value": "1946-01-01"
24
+ },
25
+ "dc:identifier": {
26
+ "@type": "xsd:integer",
27
+ "@value": "16589991"
28
+ },
29
+ "dc:isReferencedBy": [
30
+ {
31
+ "@value":"something",
32
+ "@language":"en"
33
+ },
34
+ {
35
+ "@value":"another",
36
+ "@language":"en"
37
+ }
38
+ ],
39
+ "dc:issued": {
40
+ "@type": "xsd:date",
41
+ "@value": "1951-01-01"
42
+ },
43
+ "dc:source": {
44
+ "@type": "xsd:token",
45
+ "@value": "something"
46
+ },
47
+ "dc:spatial": {
48
+ "@type": "xsd:double",
49
+ "@value": "1.2345E1"
50
+ },
51
+ "dc:valid": {
52
+ "@type": "xsd:boolean",
53
+ "@value": "true"
54
+ },
16
55
  "dc:hasPart": {
17
56
  "@id": "_:b3",
18
57
  "@type": "dc:PhysicalResource",
19
- "dc:relation": {
58
+ "dc:isPartOf": {
20
59
  "@id": "_:b1"
21
60
  }
22
61
  },
@@ -24,8 +63,14 @@
24
63
  "@id": "_:b4",
25
64
  "@type": "skos:Concept"
26
65
  },
27
- "dc:title": {
28
- "@value": "Comet in Moominland",
29
- "@language": "en"
30
- }
66
+ "dc:title": [
67
+ {
68
+ "@value": "Comet in Moominland",
69
+ "@language": "en"
70
+ },
71
+ {
72
+ "@value": "Kometen kommer",
73
+ "@language": "sv"
74
+ }
75
+ ]
31
76
  }
@@ -1,165 +1,30 @@
1
1
  shared_context 'with data' do
2
2
  before do
3
- subject.alt = 'Mumintrollet pa kometjakt' # non-localized literal
4
- subject.title = 'Comet in Moominland' # localized literal
5
- end
6
- end
7
-
8
- shared_examples 'a Dynamic Resource' do
9
- describe '#property' do
10
- context 'with undefined property' do
11
- before do
12
- subject.property :description, predicate: RDF::DC.description
13
- subject.description = "Second in Tove Jansson's series of Moomin books"
14
- end
15
-
16
- it 'should create a context' do
17
- expect(subject._context).to eq(description: RDF::DC.description.to_uri.to_s)
18
- end
19
-
20
- it 'should build an accessor' do
21
- expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
22
- end
23
- end
24
-
25
- context 'with conflicting property' do
26
- before do
27
- subject.property :title, predicate: RDF::DC11.title
28
- subject.dc11_title = 'Kometjakten'
29
- end
30
-
31
- it 'should create a context' do
32
- expect(subject._context).to eq(dc11_title: RDF::DC11.title.to_uri.to_s)
33
- end
34
-
35
- it 'should build an accessor' do
36
- expect(subject.dc11_title).to eq 'Kometjakten'
37
- end
38
- end
39
- end
40
-
41
- describe '#update_resource' do
42
- before do
43
- # undefined property
44
- subject.property :description, predicate: RDF::DC.description
45
- subject.description = "Second in Tove Jansson's series of Moomin books"
46
-
47
- # conflicting property
48
- subject.property :title, predicate: RDF::DC11.title
49
- subject.dc11_title = 'Kometjakten'
50
-
51
- # defined field
52
- subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
53
-
54
- # conflicting property
55
- subject << RDF::Statement(nil, RDF::DC.alternative, 'Kometjakten')
56
-
57
- # URI value
58
- subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
59
-
60
- # RDF type
61
- subject << RDF::Statement(nil, RDF.type, RDF::DC.PhysicalResource)
62
-
63
- subject.update_resource
64
- end
65
-
66
- it 'should have updated values' do
67
- expect(subject.resource.statements.count).to eq 7
68
- expect(subject.resource.query(predicate: RDF::DC.description, object: "Second in Tove Jansson's series of Moomin books").count).to eq 1
69
- expect(subject.resource.query(predicate: RDF::DC11.title, object: 'Kometjakten').count).to eq 1
70
- expect(subject.resource.query(predicate: RDF::DC.title, object: RDF::Literal.new('Kometen kommer', language: :en)).count).to eq 1
71
- expect(subject.resource.query(predicate: RDF::DC.alternative, object: 'Kometjakten').count).to eq 1
72
- expect(subject.resource.query(predicate: RDF::DC.identifier, object: RDF::URI('http://some.uri')).count).to eq 1
73
- end
74
-
75
- it 'should contain both class and dynamic types' do
76
- expect(subject.type.count).to eq 2
77
- expect(subject.type).to include RDF::DC.BibliographicResource
78
- expect(subject.type).to include RDF::DC.PhysicalResource
79
- end
80
- end
81
-
82
- describe '#<<' do
83
- context 'with defined field' do
84
- before do
85
- subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
86
- end
87
-
88
- it 'should not create a context' do
89
- expect(subject._context).to be nil
90
- end
91
-
92
- it 'should update existing values' do
93
- expect(subject.title).to eq 'Kometen kommer'
94
- end
95
- end
96
-
97
- context 'with undefined field' do
98
- before do
99
- subject << RDF::Statement(nil, RDF::DC.description, "Second in Tove Jansson's series of Moomin books")
100
- end
101
-
102
- it 'should create a context' do
103
- expect(subject._context).to eq(description: RDF::DC.description.to_uri.to_s)
104
- end
105
-
106
- it 'should build an accessor' do
107
- expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
108
- end
109
- end
110
-
111
- context 'with conflicting property' do
112
- before do
113
- subject << RDF::Statement(nil, RDF::DC11.title, 'Kometjakten')
114
- end
115
-
116
- it 'should create a context' do
117
- expect(subject._context).to eq(dc11_title: RDF::DC11.title.to_uri.to_s)
118
- end
119
-
120
- it 'should build an accessor' do
121
- expect(subject.dc11_title).to eq 'Kometjakten'
122
- end
123
- end
124
-
125
- context 'with a URI value' do
126
- before do
127
- subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
128
- end
129
-
130
- it 'should store the URI as a string' do
131
- expect(subject.identifier).to eq 'http://some.uri'
132
- end
133
-
134
- it 'should cast a URI into the resource' do
135
- subject.update_resource
136
- query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.identifier)
137
- expect(query.first_object).to be_a_kind_of RDF::URI
138
- end
139
- end
140
- end
141
-
142
- describe '#resource_class' do
143
- before do
144
- subject.property :description, predicate: RDF::DC.description
145
- end
146
-
147
- it 'should have modified properties on the instance' do
148
- expect(subject.resource.class.properties.keys).to include 'description'
149
- end
150
-
151
- it 'should not modify the global class properties' do
152
- expect(subject.class.resource_class.properties.keys).to_not include 'description'
153
- expect(subject.class.resource_class.properties).to eq subject.class.new.class.resource_class.properties
154
- end
3
+ subject.title_translations = { 'en' => 'Comet in Moominland', # localized String
4
+ 'sv' => 'Kometen kommer' }
5
+ subject.alt = 'Mumintrollet pa kometjakt' # non-localized String
6
+ subject.references = 'http://foo.com' # URI
7
+ subject.referenced = %w(something another) # Array
8
+ subject.is_valid = true # Boolean -> xsd:boolean
9
+ subject.date = Date.new(1946) # Date -> xsd:date
10
+ subject.issued = DateTime.new(1951) # DateTime -> xsd:date
11
+ subject.spatial = 12.345 # Float -> xsd:double
12
+ # subject.conformsTo = { 'key' => 'value' } # Hash
13
+ subject.identifier = 16_589_991 # Integer -> xsd:integer
14
+ # subject.license = 1..10 # Range
15
+ subject.source = :something # Symbol -> xsd:token
16
+ subject.created = Time.new.beginning_of_hour # Time
155
17
  end
156
18
  end
157
19
 
158
20
  shared_examples 'a Resource' do
159
- describe 'LADDER_BASE_URI' do
21
+ describe '#configure_model' do
160
22
  it 'should automatically have a base URI' do
161
- expect(subject.resource.rdf_subject.parent).to eq RDF::URI('http://example.org/things/')
23
+ expect([RDF::URI('http://example.org/things/'),
24
+ RDF::URI('http://example.org/subthings/')]).to include subject.rdf_subject.parent
162
25
  end
26
+
27
+ # TODO: it should be registered in Ladder::Config
163
28
  end
164
29
 
165
30
  describe '#property' do
@@ -184,11 +49,11 @@ shared_examples 'a Resource' do
184
49
 
185
50
  context 'with localized literal' do
186
51
  it 'should return localized value' do
187
- expect(subject.title).to eq 'Comet in Moominland'
52
+ expect(['Comet in Moominland', 'Kometen kommer']).to include(subject.title).or eq(subject.title)
188
53
  end
189
54
 
190
55
  it 'should return all locales' do
191
- expect(subject.attributes['title']).to eq('en' => 'Comet in Moominland')
56
+ expect('en' => 'Comet in Moominland', 'sv' => 'Kometen kommer').to include(subject.attributes['title']).or eq(subject.attributes['title'])
192
57
  end
193
58
 
194
59
  it 'should have a valid predicate' do
@@ -209,7 +74,7 @@ shared_examples 'a Resource' do
209
74
 
210
75
  it 'should have a non-localized literal object' do
211
76
  subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.title).each_statement do |s|
212
- expect(s.object.to_s).to eq 'Comet in Moominland'
77
+ expect(['Comet in Moominland', 'Kometen kommer']).to include s.object.to_s
213
78
  end
214
79
  end
215
80
 
@@ -227,11 +92,11 @@ shared_examples 'a Resource' do
227
92
  describe '#<<' do
228
93
  context 'with defined field' do
229
94
  before do
230
- subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
95
+ subject << RDF::Statement(nil, RDF::DC.title, RDF::Literal.new('Kometen kommer', language: :sv))
231
96
  end
232
97
 
233
98
  it 'should update existing values' do
234
- expect(subject.title).to eq 'Kometen kommer'
99
+ expect(subject.title_translations).to eq('sv' => 'Kometen kommer')
235
100
  end
236
101
  end
237
102
 
@@ -259,16 +124,16 @@ shared_examples 'a Resource' do
259
124
 
260
125
  context 'with a URI value' do
261
126
  before do
262
- subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
127
+ subject << RDF::Statement(nil, RDF::DC.references, RDF::URI('http://some.uri'))
263
128
  end
264
129
 
265
130
  it 'should store the URI as a string' do
266
- expect(subject.identifier).to eq 'http://some.uri'
131
+ expect(subject.references).to eq 'http://some.uri'
267
132
  end
268
133
 
269
134
  it 'should cast a URI into the resource' do
270
135
  subject.update_resource
271
- query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.identifier)
136
+ query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.references)
272
137
  expect(query.first_object).to be_a_kind_of RDF::URI
273
138
  end
274
139
  end
@@ -276,11 +141,18 @@ shared_examples 'a Resource' do
276
141
 
277
142
  describe '#rdf_label' do
278
143
  it 'should return the default label' do
279
- expect(subject.rdf_label.to_a).to eq ['Comet in Moominland']
144
+ expect(['Comet in Moominland', 'Kometen kommer']).to include subject.rdf_label.first
280
145
  end
281
146
  end
282
147
 
283
148
  context 'a serializable' do
149
+ describe '#as_turtle' do
150
+ it 'should output a valid turtle representation of itself' do
151
+ graph = RDF::Graph.new << RDF::Turtle::Reader.new(subject.as_turtle)
152
+ expect(subject.update_resource.to_hash).to eq graph.to_hash
153
+ end
154
+ end
155
+
284
156
  describe '#as_jsonld' do
285
157
  it 'should output a valid jsonld representation of itself' do
286
158
  graph = RDF::Graph.new << JSON::LD::API.toRdf(subject.as_jsonld)
@@ -290,7 +162,7 @@ shared_examples 'a Resource' do
290
162
 
291
163
  describe '#as_qname' do
292
164
  it 'should output a valid qname representation of itself' do
293
- # TODO
165
+ # TODO: check rdfs:label
294
166
  end
295
167
  end
296
168
  end
@@ -307,16 +179,9 @@ shared_examples 'a Resource' do
307
179
  end
308
180
 
309
181
  it 'should populate the same properties' do
310
- # TODO: clean this up
311
- def remove_ids(x)
312
- if x.is_a?(Hash)
313
- x.reduce({}) do |m, (k, v)|
314
- m[k] = remove_ids(v) unless k == '@id'
315
- m
316
- end
317
- else
318
- x
319
- end
182
+ def remove_ids(hash)
183
+ hash.delete '@id'
184
+ hash.each_value { |value| remove_ids(value) if value.is_a? Hash }
320
185
  end
321
186
 
322
187
  expect(remove_ids(new_subject.as_framed_jsonld)).to eq remove_ids(subject.as_framed_jsonld)
@@ -421,7 +286,7 @@ shared_examples 'a Resource with relations' do
421
286
  end
422
287
 
423
288
  it 'should have a valid inverse predicate' do
424
- expect(part.class.properties['thing'].predicate).to eq RDF::DC.relation
289
+ expect(part.class.properties['thing'].predicate).to eq RDF::DC.isPartOf
425
290
  end
426
291
  end
427
292
 
@@ -433,7 +298,7 @@ shared_examples 'a Resource with relations' do
433
298
 
434
299
  it 'should have a literal object' do
435
300
  query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.title)
436
- expect(query.first_object.to_s).to eq 'Comet in Moominland'
301
+ expect(['Comet in Moominland', 'Kometen kommer']).to include query.first_object.to_s
437
302
  end
438
303
 
439
304
  it 'should have an embedded object' do
@@ -443,7 +308,7 @@ shared_examples 'a Resource with relations' do
443
308
  end
444
309
 
445
310
  it 'should have an embedded object relation' do
446
- query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
311
+ query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.isPartOf)
447
312
  expect(query.count).to eq 1
448
313
  expect(query.first_object).to eq subject.rdf_subject
449
314
  end
@@ -475,7 +340,7 @@ shared_examples 'a Resource with relations' do
475
340
  expect(concept.resource.query(object: subject.rdf_subject)).to be_empty
476
341
 
477
342
  # embedded-one
478
- query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
343
+ query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.isPartOf)
479
344
  expect(query.count).to eq 1
480
345
  expect(query.first_object).to eq subject.rdf_subject
481
346
  end
@@ -494,7 +359,7 @@ shared_examples 'a Resource with relations' do
494
359
  end
495
360
 
496
361
  it 'should have embedded object relations' do
497
- query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
362
+ query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.isPartOf)
498
363
  expect(query.count).to eq 1
499
364
  expect(query.first_object).to eq subject.rdf_subject
500
365
  end
@@ -509,7 +374,7 @@ shared_examples 'a Resource with relations' do
509
374
  expect(concept.resource.query(object: subject.rdf_subject)).to be_empty
510
375
 
511
376
  # embedded-one
512
- query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
377
+ query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.isPartOf)
513
378
  expect(query.count).to eq 1
514
379
  expect(query.first_object).to eq subject.rdf_subject
515
380
  end
@@ -0,0 +1,149 @@
1
+ shared_examples 'a Dynamic Resource' do
2
+ describe '#property' do
3
+ context 'with undefined property' do
4
+ before do
5
+ subject.property :description, predicate: RDF::DC.description
6
+ subject.description = "Second in Tove Jansson's series of Moomin books"
7
+ end
8
+
9
+ it 'should create a context' do
10
+ expect(subject._context).to eq(description: RDF::DC.description.to_uri.to_s)
11
+ end
12
+
13
+ it 'should build an accessor' do
14
+ expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
15
+ end
16
+ end
17
+
18
+ context 'with conflicting property' do
19
+ before do
20
+ subject.property :title, predicate: RDF::DC11.title
21
+ subject.dc11_title = 'Kometjakten'
22
+ end
23
+
24
+ it 'should create a context' do
25
+ expect(subject._context).to eq(dc11_title: RDF::DC11.title.to_uri.to_s)
26
+ end
27
+
28
+ it 'should build an accessor' do
29
+ expect(subject.dc11_title).to eq 'Kometjakten'
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#update_resource' do
35
+ before do
36
+ # undefined property
37
+ subject.property :description, predicate: RDF::DC.description
38
+ subject.description = "Second in Tove Jansson's series of Moomin books"
39
+
40
+ # conflicting property
41
+ subject.property :title, predicate: RDF::DC11.title
42
+ subject.dc11_title = 'Kometjakten'
43
+
44
+ # defined field
45
+ subject << RDF::Statement(nil, RDF::DC.title, RDF::Literal.new('Kometen kommer', language: :sv))
46
+
47
+ # conflicting property
48
+ subject << RDF::Statement(nil, RDF::DC.alternative, 'Kometjakten')
49
+
50
+ # URI value
51
+ subject << RDF::Statement(nil, RDF::DC.references, RDF::URI('http://some.uri'))
52
+
53
+ # RDF type
54
+ subject << RDF::Statement(nil, RDF.type, RDF::DC.PhysicalResource)
55
+
56
+ subject.update_resource
57
+ end
58
+
59
+ it 'should have updated values' do
60
+ # expect(subject.resource.statements.count).to eq 7
61
+ expect(subject.resource.query(predicate: RDF::DC.description, object: "Second in Tove Jansson's series of Moomin books").count).to eq 1
62
+ expect(subject.resource.query(predicate: RDF::DC11.title, object: 'Kometjakten').count).to eq 1
63
+ expect(subject.resource.query(predicate: RDF::DC.title, object: RDF::Literal.new('Kometen kommer', language: :sv)).count).to eq 1
64
+ expect(subject.resource.query(predicate: RDF::DC.alternative, object: 'Kometjakten').count).to eq 1
65
+ expect(subject.resource.query(predicate: RDF::DC.references, object: RDF::URI('http://some.uri')).count).to eq 1
66
+ end
67
+
68
+ it 'should contain both class and dynamic types' do
69
+ expect(subject.type.count).to eq 2
70
+ expect(subject.type).to include RDF::DC.BibliographicResource
71
+ expect(subject.type).to include RDF::DC.PhysicalResource
72
+ end
73
+ end
74
+
75
+ describe '#<<' do
76
+ context 'with defined field' do
77
+ before do
78
+ subject << RDF::Statement(nil, RDF::DC.title, RDF::Literal.new('Kometen kommer', language: :sv))
79
+ end
80
+
81
+ it 'should not create a context' do
82
+ expect(subject._context).to be nil
83
+ end
84
+
85
+ it 'should update existing values' do
86
+ expect(subject.title).to eq 'Kometen kommer'
87
+ end
88
+ end
89
+
90
+ context 'with undefined field' do
91
+ before do
92
+ subject << RDF::Statement(nil, RDF::DC.description, "Second in Tove Jansson's series of Moomin books")
93
+ end
94
+
95
+ it 'should create a context' do
96
+ expect(subject._context).to eq(description: RDF::DC.description.to_uri.to_s)
97
+ end
98
+
99
+ it 'should build an accessor' do
100
+ expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
101
+ end
102
+ end
103
+
104
+ context 'with conflicting property' do
105
+ before do
106
+ subject << RDF::Statement(nil, RDF::DC11.title, 'Kometjakten')
107
+ end
108
+
109
+ it 'should create a context' do
110
+ expect(subject._context).to eq(dc11_title: RDF::DC11.title.to_uri.to_s)
111
+ end
112
+
113
+ it 'should build an accessor' do
114
+ expect(subject.dc11_title).to eq 'Kometjakten'
115
+ end
116
+ end
117
+
118
+ context 'with a URI value' do
119
+ before do
120
+ subject << RDF::Statement(nil, RDF::DC.references, RDF::URI('http://some.uri'))
121
+ end
122
+
123
+ it 'should store the URI as a string' do
124
+ expect(subject.references).to eq 'http://some.uri'
125
+ end
126
+
127
+ it 'should cast a URI into the resource' do
128
+ subject.update_resource
129
+ query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.references)
130
+ expect(query.first_object).to be_a_kind_of RDF::URI
131
+ end
132
+ end
133
+ end
134
+
135
+ describe '#resource_class' do
136
+ before do
137
+ subject.property :description, predicate: RDF::DC.description
138
+ end
139
+
140
+ it 'should have modified properties on the instance' do
141
+ expect(subject.resource.class.properties.keys).to include 'description'
142
+ end
143
+
144
+ it 'should not modify the global class properties' do
145
+ expect(subject.class.resource_class.properties.keys).to_not include 'description'
146
+ expect(subject.class.resource_class.properties).to eq subject.class.new.class.resource_class.properties
147
+ end
148
+ end
149
+ end