ladder 0.2.1 → 0.3.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/.travis.yml +3 -1
- data/README.md +133 -110
- data/ladder.gemspec +6 -5
- data/lib/ladder/file.rb +15 -17
- data/lib/ladder/resource.rb +32 -22
- data/lib/ladder/resource/dynamic.rb +43 -49
- data/lib/ladder/resource/serializable.rb +54 -0
- data/lib/ladder/searchable.rb +5 -4
- data/lib/ladder/searchable/background.rb +43 -0
- data/lib/ladder/searchable/resource.rb +5 -64
- data/lib/ladder/version.rb +1 -1
- data/spec/ladder/file_spec.rb +53 -6
- data/spec/ladder/resource/dynamic_spec.rb +117 -115
- data/spec/ladder/resource_spec.rb +273 -8
- data/spec/ladder/searchable/background_spec.rb +112 -0
- data/spec/ladder/{file/searchable_spec.rb → searchable/file_spec.rb} +6 -26
- data/spec/ladder/searchable/resource_spec.rb +83 -0
- data/spec/shared/file.rb +8 -52
- data/spec/shared/resource.rb +54 -272
- data/spec/shared/searchable/file.rb +50 -0
- data/spec/shared/searchable/resource.rb +223 -0
- data/spec/spec_helper.rb +1 -0
- metadata +55 -33
- data/spec/ladder/resource/searchable_spec.rb +0 -221
@@ -6,170 +6,172 @@ describe Ladder::Resource::Dynamic do
|
|
6
6
|
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
7
|
Mongoid.purge!
|
8
8
|
|
9
|
-
LADDER_BASE_URI
|
9
|
+
LADDER_BASE_URI ||= 'http://example.org'
|
10
10
|
|
11
11
|
class Thing
|
12
12
|
include Ladder::Resource::Dynamic
|
13
13
|
end
|
14
|
-
|
15
|
-
class Person
|
16
|
-
include Ladder::Resource::Dynamic
|
17
|
-
end
|
18
14
|
end
|
19
15
|
|
20
|
-
|
16
|
+
after do
|
17
|
+
Object.send(:remove_const, :LADDER_BASE_URI) if Object
|
18
|
+
Object.send(:remove_const, "Thing") if Object
|
19
|
+
end
|
21
20
|
|
22
|
-
|
21
|
+
context 'with data' do
|
23
22
|
let(:subject) { Thing.new }
|
24
23
|
|
25
24
|
before do
|
26
25
|
# non-localized literal
|
27
26
|
subject.class.field :alt
|
28
|
-
subject.class.property :alt, :
|
27
|
+
subject.class.property :alt, predicate: RDF::DC.alternative
|
29
28
|
subject.alt = 'Mumintrollet pa kometjakt'
|
30
29
|
|
31
30
|
# localized literal
|
32
|
-
subject.class.property :title, :
|
31
|
+
subject.class.property :title, predicate: RDF::DC.title
|
33
32
|
subject.title = 'Comet in Moominland'
|
34
33
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#property' do
|
38
|
-
include_context 'with data'
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
it_behaves_like 'a Resource'
|
36
|
+
|
37
|
+
describe '#property' do
|
38
|
+
context 'with undefined property' do
|
39
|
+
before do
|
40
|
+
subject.property :description, predicate: RDF::DC.description
|
41
|
+
subject.description = "Second in Tove Jansson's series of Moomin books"
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should create a context' do
|
45
|
+
expect(subject._context).to eq({description: RDF::DC.description.to_uri.to_s})
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should build an accessor' do
|
49
|
+
expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
|
50
|
+
end
|
44
51
|
end
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
context 'with conflicting property' do
|
54
|
+
before do
|
55
|
+
subject.property :title, predicate: RDF::DC11.title
|
56
|
+
subject.dc11_title = "Kometjakten"
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should create a context' do
|
60
|
+
expect(subject._context).to eq({dc11_title: RDF::DC11.title.to_uri.to_s})
|
61
|
+
end
|
49
62
|
|
50
|
-
|
51
|
-
|
63
|
+
it 'should build an accessor' do
|
64
|
+
expect(subject.dc11_title).to eq "Kometjakten"
|
65
|
+
end
|
52
66
|
end
|
53
67
|
end
|
54
|
-
|
55
|
-
|
68
|
+
|
69
|
+
describe '#update_resource' do
|
56
70
|
before do
|
57
|
-
|
71
|
+
# undefined property
|
72
|
+
subject.property :description, predicate: RDF::DC.description
|
73
|
+
subject.description = "Second in Tove Jansson's series of Moomin books"
|
74
|
+
|
75
|
+
# conflicting property
|
76
|
+
subject.property :title, predicate: RDF::DC11.title
|
58
77
|
subject.dc11_title = "Kometjakten"
|
59
|
-
end
|
60
78
|
|
61
|
-
|
62
|
-
|
79
|
+
# defined field
|
80
|
+
subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
|
81
|
+
|
82
|
+
# conflicting property
|
83
|
+
subject << RDF::Statement(nil, RDF::DC.alternative, "Kometjakten")
|
84
|
+
|
85
|
+
# URI value
|
86
|
+
subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
|
87
|
+
|
88
|
+
subject.update_resource
|
63
89
|
end
|
64
|
-
|
65
|
-
it 'should
|
66
|
-
expect(subject.
|
90
|
+
|
91
|
+
it 'should have updated values' do
|
92
|
+
expect(subject.resource.statements.count).to eq 5
|
93
|
+
expect(subject.resource.query(predicate: RDF::DC.description, object: "Second in Tove Jansson's series of Moomin books").count).to eq 1
|
94
|
+
expect(subject.resource.query(predicate: RDF::DC11.title, object: "Kometjakten").count).to eq 1
|
95
|
+
expect(subject.resource.query(predicate: RDF::DC.title, object: RDF::Literal.new('Kometen kommer', language: :en)).count).to eq 1
|
96
|
+
expect(subject.resource.query(predicate: RDF::DC.alternative, object: "Kometjakten").count).to eq 1
|
97
|
+
expect(subject.resource.query(predicate: RDF::DC.identifier, object: RDF::URI('http://some.uri')).count).to eq 1
|
67
98
|
end
|
68
99
|
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#<<' do
|
72
|
-
include_context 'with data'
|
73
100
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
101
|
+
describe '#<<' do
|
102
|
+
context 'with defined field' do
|
103
|
+
before do
|
104
|
+
subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
|
105
|
+
end
|
78
106
|
|
79
|
-
|
80
|
-
|
81
|
-
|
107
|
+
it 'should not create a context' do
|
108
|
+
expect(subject._context).to be nil
|
109
|
+
end
|
82
110
|
|
83
|
-
|
84
|
-
|
111
|
+
it 'should update existing values' do
|
112
|
+
expect(subject.title).to eq 'Kometen kommer'
|
113
|
+
end
|
85
114
|
end
|
86
|
-
end
|
87
115
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
116
|
+
context 'with undefined field' do
|
117
|
+
before do
|
118
|
+
subject << RDF::Statement(nil, RDF::DC.description, "Second in Tove Jansson's series of Moomin books")
|
119
|
+
end
|
92
120
|
|
93
|
-
|
94
|
-
|
95
|
-
|
121
|
+
it 'should create a context' do
|
122
|
+
expect(subject._context).to eq({ description: RDF::DC.description.to_uri.to_s })
|
123
|
+
end
|
96
124
|
|
97
|
-
|
98
|
-
|
125
|
+
it 'should build an accessor' do
|
126
|
+
expect(subject.description).to eq "Second in Tove Jansson's series of Moomin books"
|
127
|
+
end
|
99
128
|
end
|
100
|
-
end
|
101
129
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
130
|
+
context 'with conflicting property' do
|
131
|
+
before do
|
132
|
+
subject << RDF::Statement(nil, RDF::DC11.title, "Kometjakten")
|
133
|
+
end
|
106
134
|
|
107
|
-
|
108
|
-
|
109
|
-
|
135
|
+
it 'should create a context' do
|
136
|
+
expect(subject._context).to eq({ dc11_title: RDF::DC11.title.to_uri.to_s })
|
137
|
+
end
|
110
138
|
|
111
|
-
|
112
|
-
|
139
|
+
it 'should build an accessor' do
|
140
|
+
expect(subject.dc11_title).to eq "Kometjakten"
|
141
|
+
end
|
113
142
|
end
|
114
|
-
end
|
115
143
|
|
144
|
+
context 'with a URI value' do
|
145
|
+
before do
|
146
|
+
subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should store the URI as a string' do
|
150
|
+
expect(subject.identifier).to eq 'http://some.uri'
|
151
|
+
end
|
116
152
|
|
117
|
-
|
153
|
+
it 'should cast a URI into the resource' do
|
154
|
+
subject.update_resource
|
155
|
+
query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.identifier)
|
156
|
+
expect(query.first_object).to be_a_kind_of RDF::URI
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#resource_class' do
|
118
162
|
before do
|
119
|
-
subject
|
120
|
-
subject.update_resource
|
163
|
+
subject.property :description, predicate: RDF::DC.description
|
121
164
|
end
|
122
|
-
|
123
|
-
it 'should
|
124
|
-
expect(subject.
|
165
|
+
|
166
|
+
it 'should have modified properties on the instance' do
|
167
|
+
expect(subject.resource.class.properties.keys).to include 'description'
|
125
168
|
end
|
126
169
|
|
127
|
-
it 'should
|
128
|
-
|
129
|
-
expect(
|
130
|
-
expect(query.first_object).to be_a_kind_of RDF::URI
|
170
|
+
it 'should not modify the global class properties' do
|
171
|
+
expect(subject.class.resource_class.properties.keys).to_not include 'description'
|
172
|
+
expect(subject.class.resource_class.properties).to eq subject.class.new.class.resource_class.properties
|
131
173
|
end
|
132
174
|
end
|
133
|
-
|
134
175
|
end
|
135
|
-
|
136
|
-
describe '#update_resource' do
|
137
|
-
include_context 'with data'
|
138
|
-
|
139
|
-
before do
|
140
|
-
# undefined property
|
141
|
-
subject.property :description, :predicate => RDF::DC.description
|
142
|
-
subject.description = "Second in Tove Jansson's series of Moomin books"
|
143
|
-
|
144
|
-
# conflicting property
|
145
|
-
subject.property :title, :predicate => RDF::DC11.title
|
146
|
-
subject.dc11_title = "Kometjakten"
|
147
176
|
|
148
|
-
# defined field
|
149
|
-
subject << RDF::Statement(nil, RDF::DC.title, 'Kometen kommer')
|
150
|
-
|
151
|
-
# conflicting field
|
152
|
-
subject << RDF::Statement(nil, RDF::DC.alternative, "Kometjakten")
|
153
|
-
|
154
|
-
# URI value
|
155
|
-
subject << RDF::Statement(nil, RDF::DC.identifier, RDF::URI('http://some.uri'))
|
156
|
-
|
157
|
-
subject.update_resource
|
158
|
-
end
|
159
|
-
|
160
|
-
it 'should have updated values' do
|
161
|
-
expect(subject.resource.statements.count).to eq 5
|
162
|
-
expect(subject.resource.query(:predicate => RDF::DC.description, :object => "Second in Tove Jansson's series of Moomin books").count).to eq 1
|
163
|
-
expect(subject.resource.query(:predicate => RDF::DC11.title, :object => "Kometjakten").count).to eq 1
|
164
|
-
expect(subject.resource.query(:predicate => RDF::DC.title, :object => RDF::Literal.new('Kometen kommer', :language => :en)).count).to eq 1
|
165
|
-
expect(subject.resource.query(:predicate => RDF::DC.alternative, :object => "Kometjakten").count).to eq 1
|
166
|
-
expect(subject.resource.query(:predicate => RDF::DC.identifier, :object => RDF::URI('http://some.uri')).count).to eq 1
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
after do
|
171
|
-
Object.send(:remove_const, :LADDER_BASE_URI) if Object
|
172
|
-
Object.send(:remove_const, "Thing") if Object
|
173
|
-
Object.send(:remove_const, "Person") if Object
|
174
|
-
end
|
175
177
|
end
|
@@ -6,22 +6,287 @@ describe Ladder::Resource do
|
|
6
6
|
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
7
|
Mongoid.purge!
|
8
8
|
|
9
|
-
LADDER_BASE_URI
|
9
|
+
LADDER_BASE_URI ||= 'http://example.org'
|
10
10
|
|
11
11
|
class Thing
|
12
12
|
include Ladder::Resource
|
13
13
|
end
|
14
|
-
|
15
|
-
class Person
|
16
|
-
include Ladder::Resource
|
17
|
-
end
|
18
14
|
end
|
19
15
|
|
20
|
-
it_behaves_like 'a Resource'
|
21
|
-
|
22
16
|
after do
|
23
17
|
Object.send(:remove_const, :LADDER_BASE_URI) if Object
|
24
18
|
Object.send(:remove_const, "Thing") if Object
|
25
|
-
Object.send(:remove_const, "Person") if Object
|
26
19
|
end
|
20
|
+
|
21
|
+
shared_context 'with data' do
|
22
|
+
before do
|
23
|
+
subject.class.configure type: RDF::DC.BibliographicResource
|
24
|
+
|
25
|
+
# non-localized literal
|
26
|
+
subject.class.field :alt
|
27
|
+
subject.class.property :alt, predicate: RDF::DC.alternative
|
28
|
+
subject.alt = 'Mumintrollet pa kometjakt'
|
29
|
+
|
30
|
+
# localized literal
|
31
|
+
subject.class.property :title, predicate: RDF::DC.title
|
32
|
+
subject.title = 'Comet in Moominland'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
shared_context 'with relations' do
|
37
|
+
let(:person) { Person.new }
|
38
|
+
let(:concept) { Concept.new }
|
39
|
+
let(:part) { Part.new }
|
40
|
+
|
41
|
+
before do
|
42
|
+
class Person
|
43
|
+
include Ladder::Resource
|
44
|
+
end
|
45
|
+
|
46
|
+
class Concept
|
47
|
+
include Ladder::Resource
|
48
|
+
end
|
49
|
+
|
50
|
+
class Part
|
51
|
+
include Ladder::Resource
|
52
|
+
end
|
53
|
+
|
54
|
+
person.class.configure type: RDF::DC.AgentClass
|
55
|
+
concept.class.configure type: RDF::SKOS.Concept
|
56
|
+
part.class.configure type: RDF::DC.PhysicalResource
|
57
|
+
|
58
|
+
# many-to-many
|
59
|
+
person.class.property :things, predicate: RDF::DC.relation, class_name: 'Thing'
|
60
|
+
subject.class.property :people, predicate: RDF::DC.creator, class_name: 'Person'
|
61
|
+
subject.people << person
|
62
|
+
|
63
|
+
# one-sided has-many
|
64
|
+
subject.class.has_and_belongs_to_many :concepts, inverse_of: nil
|
65
|
+
subject.class.property :concepts, predicate: RDF::DC.subject, class_name: 'Concept'
|
66
|
+
subject.concepts << concept
|
67
|
+
|
68
|
+
# embedded one
|
69
|
+
part.class.embedded_in :thing
|
70
|
+
part.class.property :thing, predicate: RDF::DC.relation, class_name: 'Thing'
|
71
|
+
subject.class.embeds_one :part, cascade_callbacks: true
|
72
|
+
subject.class.property :part, predicate: RDF::DC.hasPart, class_name: 'Part'
|
73
|
+
subject.part = part
|
74
|
+
subject.save
|
75
|
+
end
|
76
|
+
|
77
|
+
after do
|
78
|
+
Object.send(:remove_const, "Person") if Object
|
79
|
+
Object.send(:remove_const, 'Concept') if Object
|
80
|
+
Object.send(:remove_const, 'Part') if Object
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should have relations' do
|
84
|
+
expect(subject.people.to_a).to include person
|
85
|
+
expect(subject.concepts.to_a).to include concept
|
86
|
+
expect(subject.part).to eq part
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have inverse relations' do
|
90
|
+
expect(person.things.to_a).to include subject
|
91
|
+
expect(concept.relations).to be_empty
|
92
|
+
expect(part.thing).to eq subject
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'with many-to-many' do
|
96
|
+
it 'should have a relation' do
|
97
|
+
expect(subject.relations['people'].relation).to eq (Mongoid::Relations::Referenced::ManyToMany)
|
98
|
+
expect(subject.people.to_a).to include person
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should have an inverse relation' do
|
102
|
+
expect(person.relations['things'].relation).to eq (Mongoid::Relations::Referenced::ManyToMany)
|
103
|
+
expect(person.things.to_a).to include subject
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should have a valid predicate' do
|
107
|
+
expect(subject.class.properties['people'].predicate).to eq RDF::DC.creator
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should have a valid inverse predicate' do
|
111
|
+
expect(person.class.properties['things'].predicate).to eq RDF::DC.relation
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'with one-sided has-many' do
|
116
|
+
it 'should have a relation' do
|
117
|
+
expect(subject.relations['concepts'].relation).to eq (Mongoid::Relations::Referenced::ManyToMany)
|
118
|
+
expect(subject.concepts.to_a).to include concept
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should not have an inverse relation' do
|
122
|
+
expect(subject.relations['concepts'].inverse_of).to be nil
|
123
|
+
expect(concept.relations).to be_empty
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should have a valid predicate' do
|
127
|
+
expect(subject.class.properties['concepts'].predicate).to eq RDF::DC.subject
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should not have an inverse predicate' do
|
131
|
+
expect(concept.class.properties).to be_empty
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'with embedded-one' do
|
136
|
+
it 'should have a relation' do
|
137
|
+
expect(subject.relations['part'].relation).to eq (Mongoid::Relations::Embedded::One)
|
138
|
+
expect(subject.part).to eq part
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should have an inverse relation' do
|
142
|
+
expect(part.relations['thing'].relation).to eq (Mongoid::Relations::Embedded::In)
|
143
|
+
expect(part.thing).to eq subject
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should have a valid predicate' do
|
147
|
+
expect(subject.class.properties['part'].predicate).to eq RDF::DC.hasPart
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should have a valid inverse predicate' do
|
151
|
+
expect(part.class.properties['thing'].predicate).to eq RDF::DC.relation
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context '#update_resource with related' do
|
156
|
+
# TODO add tests for autosaved relations
|
157
|
+
before do
|
158
|
+
subject.update_resource(related: true)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should have a literal object' do
|
162
|
+
query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.title)
|
163
|
+
expect(query.first_object.to_s).to eq 'Comet in Moominland'
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should have an embedded object' do
|
167
|
+
query = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.hasPart)
|
168
|
+
expect(query.count).to eq 1
|
169
|
+
expect(query.first_object).to eq part.rdf_subject
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should have an embedded object relation' do
|
173
|
+
query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
|
174
|
+
expect(query.count).to eq 1
|
175
|
+
expect(query.first_object).to eq subject.rdf_subject
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should have related objects' do
|
179
|
+
# many-to-many
|
180
|
+
query_creator = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.creator)
|
181
|
+
expect(query_creator.count).to eq 1
|
182
|
+
expect(query_creator.first_object).to eq person.rdf_subject
|
183
|
+
|
184
|
+
# one-sided has-many
|
185
|
+
query_subject = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.subject)
|
186
|
+
expect(query_subject.count).to eq 1
|
187
|
+
expect(query_subject.first_object).to eq concept.rdf_subject
|
188
|
+
|
189
|
+
# embedded-one
|
190
|
+
query_part = subject.resource.query(subject: subject.rdf_subject, predicate: RDF::DC.hasPart)
|
191
|
+
expect(query_part.count).to eq 1
|
192
|
+
expect(query_part.first_object).to eq part.rdf_subject
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should have related object relations' do
|
196
|
+
# many-to-many
|
197
|
+
query = person.resource.query(subject: person.rdf_subject, predicate: RDF::DC.relation)
|
198
|
+
expect(query.count).to eq 1
|
199
|
+
expect(query.first_object).to eq subject.rdf_subject
|
200
|
+
|
201
|
+
# one-sided has-many
|
202
|
+
expect(concept.resource.query(object: subject.rdf_subject)).to be_empty
|
203
|
+
|
204
|
+
# embedded-one
|
205
|
+
query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
|
206
|
+
expect(query.count).to eq 1
|
207
|
+
expect(query.first_object).to eq subject.rdf_subject
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context '#update_resource with related and then without related' do
|
212
|
+
# TODO add tests for autosaved relations
|
213
|
+
before do
|
214
|
+
subject.update_resource(related: true)
|
215
|
+
subject.update_resource # implicit false
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should not have related objects' do
|
219
|
+
expect(subject.resource.query(subject: person.rdf_subject)).to be_empty
|
220
|
+
expect(subject.resource.query(subject: concept.rdf_subject)).to be_empty
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should have embedded object relations' do
|
224
|
+
query = subject.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
|
225
|
+
expect(query.count).to eq 1
|
226
|
+
expect(query.first_object).to eq subject.rdf_subject
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should have related object relations' do
|
230
|
+
# many-to-many
|
231
|
+
query = person.resource.query(subject: person.rdf_subject, predicate: RDF::DC.relation)
|
232
|
+
expect(query.count).to eq 1
|
233
|
+
expect(query.first_object).to eq subject.rdf_subject
|
234
|
+
|
235
|
+
# one-sided has-many
|
236
|
+
expect(concept.resource.query(object: subject.rdf_subject)).to be_empty
|
237
|
+
|
238
|
+
# embedded-one
|
239
|
+
query = part.resource.query(subject: part.rdf_subject, predicate: RDF::DC.relation)
|
240
|
+
expect(query.count).to eq 1
|
241
|
+
expect(query.first_object).to eq subject.rdf_subject
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'serializable' do
|
246
|
+
# TODO: contexts with relations and without
|
247
|
+
# expect(subject.as_jsonld(related: true)).to eq subject.as_jsonld
|
248
|
+
# expect(subject.as_qname(related: true)).to eq subject.as_qname
|
249
|
+
# expect(subject.as_framed_jsonld).to eq subject.as_jsonld
|
250
|
+
|
251
|
+
describe '#as_jsonld related: true' do
|
252
|
+
it 'should output a valid jsonld representation of itself and related' do
|
253
|
+
graph = RDF::Graph.new << JSON::LD::API.toRdf(subject.as_jsonld related: true)
|
254
|
+
expect(subject.update_resource(related: true).to_hash).to eq graph.to_hash
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe '#as_qname related: true' do
|
259
|
+
it 'should output a valid qname representation of itself and related' do
|
260
|
+
# TODO
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe '#as_framed_jsonld' do
|
265
|
+
it 'should output a valid framed jsonld representation of itself and related' do
|
266
|
+
framed_graph = RDF::Graph.new << JSON::LD::API.toRdf(subject.as_framed_jsonld)
|
267
|
+
related_graph = RDF::Graph.new << JSON::LD::API.toRdf(subject.as_jsonld related: true)
|
268
|
+
expect(framed_graph.to_hash).to eq related_graph.to_hash
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
context 'with data' do
|
276
|
+
let(:subject) { Thing.new }
|
277
|
+
|
278
|
+
include_context 'with data'
|
279
|
+
|
280
|
+
it_behaves_like 'a Resource'
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'with relations' do
|
284
|
+
let(:subject) { Thing.new }
|
285
|
+
|
286
|
+
include_context 'with data'
|
287
|
+
include_context 'with relations'
|
288
|
+
|
289
|
+
it_behaves_like 'a Resource'
|
290
|
+
end
|
291
|
+
|
27
292
|
end
|