ladder 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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