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.
- checksums.yaml +4 -4
- data/.semver +2 -2
- data/README.md +37 -19
- data/lib/ladder.rb +5 -3
- data/lib/ladder/config.rb +73 -0
- data/lib/ladder/configurable.rb +26 -0
- data/lib/ladder/file.rb +10 -1
- data/lib/ladder/resource.rb +130 -60
- data/lib/ladder/resource/dynamic.rb +14 -10
- data/lib/ladder/resource/serializable.rb +22 -10
- data/lib/ladder/version.rb +1 -1
- data/spec/ladder/file_spec.rb +3 -8
- data/spec/ladder/resource/dynamic_spec.rb +19 -17
- data/spec/ladder/resource_spec.rb +43 -12
- data/spec/ladder/searchable/background_spec.rb +23 -13
- data/spec/ladder/searchable/file_spec.rb +2 -8
- data/spec/ladder/searchable/resource_spec.rb +20 -12
- data/spec/shared/file.rb +4 -2
- data/spec/shared/graph.jsonld +51 -6
- data/spec/shared/resource.rb +45 -180
- data/spec/shared/resource/dynamic.rb +149 -0
- data/spec/spec_helper.rb +16 -1
- metadata +6 -2
@@ -58,14 +58,13 @@ module Ladder
|
|
58
58
|
return unless self._context
|
59
59
|
|
60
60
|
self._context.each do |field_name, uri|
|
61
|
-
next if fields
|
61
|
+
next if fields[field_name]
|
62
|
+
next unless RDF::Vocabulary.find_term(uri)
|
62
63
|
|
63
|
-
|
64
|
-
create_accessors field_name
|
64
|
+
create_accessors field_name
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
end
|
66
|
+
# Apply instance properties to resource
|
67
|
+
resource_class.property(field_name.to_sym, predicate: RDF::Vocabulary.find_term(uri))
|
69
68
|
end
|
70
69
|
end
|
71
70
|
|
@@ -113,13 +112,15 @@ module Ladder
|
|
113
112
|
# @see Ladder::Resource#<<
|
114
113
|
#
|
115
114
|
# @param [RDF::Statement, Hash, Array] statement @see RDF::Statement#from
|
116
|
-
# @return [
|
115
|
+
# @return [Object, nil] the value inserted into the object
|
117
116
|
def <<(statement)
|
118
117
|
# ActiveTriples::Resource expects: RDF::Statement, Hash, or Array
|
119
118
|
statement = RDF::Statement.from(statement) unless statement.is_a? RDF::Statement
|
120
119
|
|
121
|
-
|
122
|
-
|
120
|
+
case statement.object
|
121
|
+
when resource_class.type then return # Don't store statically-defined types
|
122
|
+
when RDF::Node then return super # Delegate nodes (relations) to parent
|
123
|
+
end
|
123
124
|
|
124
125
|
if RDF.type == statement.predicate
|
125
126
|
# Store type information
|
@@ -131,9 +132,12 @@ module Ladder
|
|
131
132
|
end
|
132
133
|
|
133
134
|
# If we have an undefined predicate, then dynamically define it
|
134
|
-
return unless statement.predicate.qname
|
135
135
|
property statement.predicate.qname.last, predicate: statement.predicate unless field_from_predicate statement.predicate
|
136
136
|
|
137
|
+
if self._context && self._context.values.include?(statement.predicate.to_s)
|
138
|
+
send("#{self._context.key(statement.predicate.to_s)}=", statement.object.to_s)
|
139
|
+
end
|
140
|
+
|
137
141
|
super
|
138
142
|
end
|
139
143
|
|
@@ -1,17 +1,30 @@
|
|
1
1
|
require 'json/ld'
|
2
|
+
require 'rdf/turtle'
|
2
3
|
|
3
4
|
module Ladder
|
4
5
|
module Resource
|
5
6
|
module Serializable
|
7
|
+
##
|
8
|
+
# Return a Turtle representation for the resource
|
9
|
+
#
|
10
|
+
# @see ActiveTriples::Resource#dump
|
11
|
+
#
|
12
|
+
# @param [Hash] opts options to pass to ActiveTriples
|
13
|
+
# @option opts [Boolean] :related whether to include related resources (default: false)
|
14
|
+
# @return [String] a serialized Turtle version of the resource
|
15
|
+
def as_turtle(opts = { related: false })
|
16
|
+
update_resource(opts.slice :related).dump(:ttl, { standard_prefixes: true }.merge(opts))
|
17
|
+
end
|
18
|
+
|
6
19
|
##
|
7
20
|
# Return a JSON-LD representation for the resource
|
8
21
|
#
|
9
22
|
# @see ActiveTriples::Resource#dump
|
10
23
|
#
|
11
24
|
# @param [Hash] opts options to pass to ActiveTriples
|
12
|
-
# @option opts [Boolean] :related whether to include related resources
|
25
|
+
# @option opts [Boolean] :related whether to include related resources (default: false)
|
13
26
|
# @return [Hash] a serialized JSON-LD version of the resource
|
14
|
-
def as_jsonld(opts = {})
|
27
|
+
def as_jsonld(opts = { related: false })
|
15
28
|
JSON.parse update_resource(opts.slice :related).dump(:jsonld, { standard_prefixes: true }.merge(opts))
|
16
29
|
end
|
17
30
|
|
@@ -46,13 +59,11 @@ module Ladder
|
|
46
59
|
ns, name = property.predicate.qname
|
47
60
|
qname_hash[ns] ||= {}
|
48
61
|
|
49
|
-
if relations
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
elsif fields.keys.include? field_name
|
62
|
+
if relations[field_name]
|
63
|
+
qname_hash[ns][name] = opts[:related] ? send(field_name).to_a.map(&:as_qname) : send(field_name).to_a.map { |obj| "#{obj.class.name.underscore.pluralize}:#{obj.id}" }
|
64
|
+
end
|
65
|
+
|
66
|
+
if fields[field_name]
|
56
67
|
qname_hash[ns][name] = read_attribute(field_name)
|
57
68
|
end
|
58
69
|
|
@@ -60,7 +71,8 @@ module Ladder
|
|
60
71
|
qname_hash[ns].delete_if { |_k, v| v.blank? }
|
61
72
|
end
|
62
73
|
|
63
|
-
|
74
|
+
# Insert labels for boosting search score
|
75
|
+
{ rdfs: { label: update_resource(opts.slice :related).rdf_label } }.merge qname_hash
|
64
76
|
end
|
65
77
|
end
|
66
78
|
end
|
data/lib/ladder/version.rb
CHANGED
data/spec/ladder/file_spec.rb
CHANGED
@@ -2,24 +2,18 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::File do
|
4
4
|
before do
|
5
|
-
Mongoid.load!('mongoid.yml', :development)
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
10
|
-
|
11
5
|
class Datastream
|
12
6
|
include Ladder::File
|
13
7
|
end
|
14
8
|
end
|
15
9
|
|
16
10
|
after do
|
17
|
-
|
11
|
+
Ladder::Config.models.delete Datastream
|
18
12
|
Object.send(:remove_const, 'Datastream') if Object
|
19
13
|
end
|
20
14
|
|
21
15
|
shared_context 'with relations' do
|
22
|
-
let(:thing)
|
16
|
+
let(:thing) { Thing.new }
|
23
17
|
|
24
18
|
before do
|
25
19
|
class Thing
|
@@ -37,6 +31,7 @@ describe Ladder::File do
|
|
37
31
|
end
|
38
32
|
|
39
33
|
after do
|
34
|
+
Ladder::Config.models.delete Thing
|
40
35
|
Object.send(:remove_const, 'Thing') if Object
|
41
36
|
end
|
42
37
|
|
@@ -2,37 +2,39 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::Resource::Dynamic do
|
4
4
|
before do
|
5
|
-
Mongoid.load!('mongoid.yml', :development)
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
10
|
-
|
11
5
|
class Thing
|
12
6
|
include Ladder::Resource::Dynamic
|
7
|
+
|
8
|
+
# FIXME: DRY out this block
|
13
9
|
configure type: RDF::DC.BibliographicResource
|
14
10
|
|
15
|
-
|
16
|
-
property :alt,
|
17
|
-
|
11
|
+
property :title, predicate: RDF::DC.title # localized String
|
12
|
+
property :alt, predicate: RDF::DC.alternative, # non-localized String
|
13
|
+
localize: false
|
14
|
+
property :references, predicate: RDF::DC.references # URI
|
15
|
+
property :referenced, predicate: RDF::DC.isReferencedBy # Array
|
16
|
+
property :is_valid, predicate: RDF::DC.valid # Boolean
|
17
|
+
property :date, predicate: RDF::DC.date # Date
|
18
|
+
property :issued, predicate: RDF::DC.issued # DateTime
|
19
|
+
property :spatial, predicate: RDF::DC.spatial # Float
|
20
|
+
# property :conformsTo, predicate: RDF::DC.conformsTo # Hash
|
21
|
+
property :identifier, predicate: RDF::DC.identifier # Integer
|
22
|
+
# property :license, predicate: RDF::DC.license # Range
|
23
|
+
property :source, predicate: RDF::DC.source # Symbol
|
24
|
+
property :created, predicate: RDF::DC.created # Time
|
25
|
+
###
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
21
29
|
after do
|
22
|
-
|
30
|
+
Ladder::Config.models.delete Thing
|
23
31
|
Object.send(:remove_const, 'Thing') if Object
|
24
32
|
end
|
25
33
|
|
26
34
|
context 'with data' do
|
27
35
|
let(:subject) { Thing.new }
|
28
36
|
|
29
|
-
|
30
|
-
# non-localized literal
|
31
|
-
subject.alt = 'Mumintrollet pa kometjakt'
|
32
|
-
|
33
|
-
# localized literal
|
34
|
-
subject.title = 'Comet in Moominland'
|
35
|
-
end
|
37
|
+
include_context 'with data'
|
36
38
|
|
37
39
|
it_behaves_like 'a Resource'
|
38
40
|
it_behaves_like 'a Dynamic Resource'
|
@@ -2,25 +2,32 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::Resource do
|
4
4
|
before do
|
5
|
-
Mongoid.load!('mongoid.yml', :development)
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
10
|
-
|
11
5
|
class Thing
|
12
6
|
include Ladder::Resource
|
7
|
+
|
8
|
+
# FIXME: DRY out this block
|
13
9
|
configure type: RDF::DC.BibliographicResource
|
14
10
|
|
15
|
-
|
16
|
-
property :alt,
|
17
|
-
|
18
|
-
property :
|
11
|
+
property :title, predicate: RDF::DC.title # localized String
|
12
|
+
property :alt, predicate: RDF::DC.alternative, # non-localized String
|
13
|
+
localize: false
|
14
|
+
property :references, predicate: RDF::DC.references # URI
|
15
|
+
property :referenced, predicate: RDF::DC.isReferencedBy # Array
|
16
|
+
property :is_valid, predicate: RDF::DC.valid # Boolean
|
17
|
+
property :date, predicate: RDF::DC.date # Date
|
18
|
+
property :issued, predicate: RDF::DC.issued # DateTime
|
19
|
+
property :spatial, predicate: RDF::DC.spatial # Float
|
20
|
+
# property :conformsTo, predicate: RDF::DC.conformsTo # Hash
|
21
|
+
property :identifier, predicate: RDF::DC.identifier # Integer
|
22
|
+
# property :license, predicate: RDF::DC.license # Range
|
23
|
+
property :source, predicate: RDF::DC.source # Symbol
|
24
|
+
property :created, predicate: RDF::DC.created # Time
|
25
|
+
###
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
29
|
after do
|
23
|
-
|
30
|
+
Ladder::Config.models.delete Thing
|
24
31
|
Object.send(:remove_const, 'Thing') if Object
|
25
32
|
end
|
26
33
|
|
@@ -47,7 +54,7 @@ describe Ladder::Resource do
|
|
47
54
|
configure type: RDF::DC.PhysicalResource
|
48
55
|
|
49
56
|
embedded_in :thing
|
50
|
-
property :thing, predicate: RDF::DC.
|
57
|
+
property :thing, predicate: RDF::DC.isPartOf, class_name: 'Thing'
|
51
58
|
end
|
52
59
|
|
53
60
|
# many-to-many
|
@@ -63,6 +70,10 @@ describe Ladder::Resource do
|
|
63
70
|
end
|
64
71
|
|
65
72
|
after do
|
73
|
+
Ladder::Config.models.delete Person
|
74
|
+
Ladder::Config.models.delete Concept
|
75
|
+
Ladder::Config.models.delete Part
|
76
|
+
|
66
77
|
Object.send(:remove_const, 'Person') if Object
|
67
78
|
Object.send(:remove_const, 'Concept') if Object
|
68
79
|
Object.send(:remove_const, 'Part') if Object
|
@@ -77,6 +88,26 @@ describe Ladder::Resource do
|
|
77
88
|
it_behaves_like 'a Resource'
|
78
89
|
end
|
79
90
|
|
91
|
+
context 'with subclass' do
|
92
|
+
before do
|
93
|
+
class Subthing < Thing
|
94
|
+
# types are not inherited, so we must set it explicitly
|
95
|
+
configure type: RDF::DC.BibliographicResource
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
after do
|
100
|
+
Ladder::Config.models.delete Subthing
|
101
|
+
Object.send(:remove_const, 'Subthing') if Object
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:subject) { Subthing.new }
|
105
|
+
|
106
|
+
include_context 'with data'
|
107
|
+
|
108
|
+
it_behaves_like 'a Resource'
|
109
|
+
end
|
110
|
+
|
80
111
|
context 'with relations' do
|
81
112
|
let(:subject) { Thing.new }
|
82
113
|
|
@@ -2,23 +2,30 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::Searchable::Background do
|
4
4
|
before do
|
5
|
-
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
|
10
|
-
Elasticsearch::Model.client.indices.delete index: '_all'
|
11
|
-
|
12
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
5
|
+
Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
|
13
6
|
|
14
7
|
class Thing
|
15
8
|
include Ladder::Resource
|
16
9
|
include Ladder::Searchable::Background
|
10
|
+
|
11
|
+
# FIXME: DRY out this block
|
17
12
|
configure type: RDF::DC.BibliographicResource
|
18
13
|
|
19
|
-
|
20
|
-
property :alt,
|
21
|
-
|
14
|
+
property :title, predicate: RDF::DC.title # localized String
|
15
|
+
property :alt, predicate: RDF::DC.alternative, # non-localized String
|
16
|
+
localize: false
|
17
|
+
property :references, predicate: RDF::DC.references # URI
|
18
|
+
property :referenced, predicate: RDF::DC.isReferencedBy # Array
|
19
|
+
property :is_valid, predicate: RDF::DC.valid # Boolean
|
20
|
+
property :date, predicate: RDF::DC.date # Date
|
21
|
+
property :issued, predicate: RDF::DC.issued # DateTime
|
22
|
+
property :spatial, predicate: RDF::DC.spatial # Float
|
23
|
+
# property :conformsTo, predicate: RDF::DC.conformsTo # Hash
|
24
|
+
property :identifier, predicate: RDF::DC.identifier # Integer
|
25
|
+
# property :license, predicate: RDF::DC.license # Range
|
26
|
+
property :source, predicate: RDF::DC.source # Symbol
|
27
|
+
property :created, predicate: RDF::DC.created # Time
|
28
|
+
###
|
22
29
|
end
|
23
30
|
|
24
31
|
class Datastream
|
@@ -28,13 +35,15 @@ describe Ladder::Searchable::Background do
|
|
28
35
|
end
|
29
36
|
|
30
37
|
after do
|
31
|
-
|
38
|
+
Ladder::Config.models.delete Thing
|
39
|
+
Ladder::Config.models.delete Datastream
|
40
|
+
|
32
41
|
Object.send(:remove_const, 'Thing') if Object
|
33
42
|
Object.send(:remove_const, 'Datastream') if Object
|
34
43
|
end
|
35
44
|
|
36
45
|
shared_context 'with relations' do
|
37
|
-
let(:person)
|
46
|
+
let(:person) { Person.new }
|
38
47
|
|
39
48
|
before do
|
40
49
|
class Person
|
@@ -48,6 +57,7 @@ describe Ladder::Searchable::Background do
|
|
48
57
|
end
|
49
58
|
|
50
59
|
after do
|
60
|
+
Ladder::Config.models.delete Person
|
51
61
|
Object.send(:remove_const, 'Person') if Object
|
52
62
|
end
|
53
63
|
end
|
@@ -2,14 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::Searchable::File do
|
4
4
|
before do
|
5
|
-
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
|
10
|
-
Elasticsearch::Model.client.indices.delete index: '_all'
|
11
|
-
|
12
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
5
|
+
Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
|
13
6
|
|
14
7
|
class Datastream
|
15
8
|
include Ladder::File
|
@@ -18,6 +11,7 @@ describe Ladder::Searchable::File do
|
|
18
11
|
end
|
19
12
|
|
20
13
|
after do
|
14
|
+
Ladder::Config.models.delete Datastream
|
21
15
|
Object.send(:remove_const, 'Datastream') if Object
|
22
16
|
end
|
23
17
|
|
@@ -2,28 +2,35 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ladder::Searchable::Resource do
|
4
4
|
before do
|
5
|
-
|
6
|
-
Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
|
7
|
-
Mongoid.purge!
|
8
|
-
|
9
|
-
Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
|
10
|
-
Elasticsearch::Model.client.indices.delete index: '_all'
|
11
|
-
|
12
|
-
LADDER_BASE_URI ||= 'http://example.org'
|
5
|
+
Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
|
13
6
|
|
14
7
|
class Thing
|
15
8
|
include Ladder::Resource
|
16
9
|
include Ladder::Searchable
|
10
|
+
|
11
|
+
# FIXME: DRY out this block
|
17
12
|
configure type: RDF::DC.BibliographicResource
|
18
13
|
|
19
|
-
|
20
|
-
property :alt,
|
21
|
-
|
14
|
+
property :title, predicate: RDF::DC.title # localized String
|
15
|
+
property :alt, predicate: RDF::DC.alternative, # non-localized String
|
16
|
+
localize: false
|
17
|
+
property :references, predicate: RDF::DC.references # URI
|
18
|
+
property :referenced, predicate: RDF::DC.isReferencedBy # Array
|
19
|
+
property :is_valid, predicate: RDF::DC.valid # Boolean
|
20
|
+
property :date, predicate: RDF::DC.date # Date
|
21
|
+
property :issued, predicate: RDF::DC.issued # DateTime
|
22
|
+
property :spatial, predicate: RDF::DC.spatial # Float
|
23
|
+
# property :conformsTo, predicate: RDF::DC.conformsTo # Hash
|
24
|
+
property :identifier, predicate: RDF::DC.identifier # Integer
|
25
|
+
# property :license, predicate: RDF::DC.license # Range
|
26
|
+
property :source, predicate: RDF::DC.source # Symbol
|
27
|
+
property :created, predicate: RDF::DC.created # Time
|
28
|
+
###
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
25
32
|
after do
|
26
|
-
|
33
|
+
Ladder::Config.models.delete Thing
|
27
34
|
Object.send(:remove_const, 'Thing') if Object
|
28
35
|
end
|
29
36
|
|
@@ -42,6 +49,7 @@ describe Ladder::Searchable::Resource do
|
|
42
49
|
end
|
43
50
|
|
44
51
|
after do
|
52
|
+
Ladder::Config.models.delete Person
|
45
53
|
Object.send(:remove_const, 'Person') if Object
|
46
54
|
end
|
47
55
|
end
|