ldpath 0.3.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -4
- data/.rubocop_todo.yml +2 -33
- data/.travis.yml +4 -1
- data/CHANGELOG.md +98 -0
- data/CODE_OF_CONDUCT.md +36 -0
- data/CONTRIBUTING.md +161 -0
- data/Gemfile +6 -2
- data/README.md +31 -7
- data/SUPPORT.md +6 -0
- data/bin/ldpath +20 -12
- data/ldpath.gemspec +9 -4
- data/lib/ldpath/field_mapping.rb +43 -1
- data/lib/ldpath/functions.rb +84 -72
- data/lib/ldpath/parser.rb +31 -36
- data/lib/ldpath/program.rb +7 -62
- data/lib/ldpath/result.rb +83 -0
- data/lib/ldpath/selectors.rb +105 -28
- data/lib/ldpath/tests.rb +11 -13
- data/lib/ldpath/transform.rb +28 -27
- data/lib/ldpath/version.rb +1 -1
- data/lib/ldpath.rb +3 -4
- data/spec/fixtures/bbc_b0081dq5.nt +4 -0
- data/spec/fixtures/loc_n79021164.nt +3 -0
- data/spec/ldpath_parser_spec.rb +19 -1
- data/spec/ldpath_program_spec.rb +87 -32
- data/spec/ldpath_transform_spec.rb +10 -0
- data/spec/lib/functions/list_spec.rb +1 -1
- data/spec/spec_helper.rb +31 -1
- metadata +73 -9
- data/.rubocop_hound.yml +0 -1063
data/lib/ldpath/selectors.rb
CHANGED
@@ -1,19 +1,48 @@
|
|
1
1
|
module Ldpath
|
2
2
|
class Selector
|
3
3
|
def evaluate(program, uris, context)
|
4
|
-
|
4
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
5
|
+
enum_wrap(uris).map do |uri|
|
5
6
|
loading program, uri, context
|
6
|
-
evaluate_one
|
7
|
-
|
7
|
+
enum_flatten_one(evaluate_one(uri, context)).each do |x|
|
8
|
+
yield x unless x.nil?
|
9
|
+
end
|
10
|
+
end
|
8
11
|
end
|
9
12
|
|
10
13
|
def loading(program, uri, context)
|
11
14
|
program.loading uri, context
|
12
15
|
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def enum_wrap(object)
|
20
|
+
if object.nil?
|
21
|
+
[]
|
22
|
+
elsif object.respond_to?(:to_ary)
|
23
|
+
object.to_ary || [object]
|
24
|
+
elsif object.is_a? Hash
|
25
|
+
[object]
|
26
|
+
elsif object.is_a? Enumerable
|
27
|
+
object
|
28
|
+
else
|
29
|
+
[object]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def enum_flatten_one(object)
|
34
|
+
return to_enum(:enum_flatten_one, object) unless block_given?
|
35
|
+
|
36
|
+
enum_wrap(object).each do |e|
|
37
|
+
enum_wrap(e).each do |v|
|
38
|
+
yield v
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
13
42
|
end
|
14
43
|
|
15
44
|
class SelfSelector < Selector
|
16
|
-
def evaluate_one(uri,
|
45
|
+
def evaluate_one(uri, _context)
|
17
46
|
uri
|
18
47
|
end
|
19
48
|
end
|
@@ -27,7 +56,9 @@ module Ldpath
|
|
27
56
|
end
|
28
57
|
|
29
58
|
def evaluate(program, uris, context)
|
30
|
-
|
59
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
60
|
+
|
61
|
+
enum_wrap(uris).map do |uri|
|
31
62
|
loading program, uri, context
|
32
63
|
args = arguments.map do |i|
|
33
64
|
case i
|
@@ -37,8 +68,10 @@ module Ldpath
|
|
37
68
|
i
|
38
69
|
end
|
39
70
|
end
|
40
|
-
program.func_call
|
41
|
-
|
71
|
+
enum_flatten_one(program.func_call(fname, uri, context, *args)).each do |x|
|
72
|
+
yield x unless x.nil?
|
73
|
+
end
|
74
|
+
end
|
42
75
|
end
|
43
76
|
end
|
44
77
|
|
@@ -49,7 +82,7 @@ module Ldpath
|
|
49
82
|
end
|
50
83
|
|
51
84
|
def evaluate_one(uri, context)
|
52
|
-
context.query([uri, property, nil]).map(&:object)
|
85
|
+
context.query([uri, property, nil]).lazy.map(&:object)
|
53
86
|
end
|
54
87
|
end
|
55
88
|
|
@@ -62,15 +95,28 @@ module Ldpath
|
|
62
95
|
def evaluate_one(uri, context)
|
63
96
|
return PropertySelector.new(property).evaluate_one(uri_context) unless defined? RDF::Reasoner
|
64
97
|
|
65
|
-
context.query([uri, nil, nil]).select do |result|
|
98
|
+
context.query([uri, nil, nil]).lazy.select do |result|
|
66
99
|
result.predicate.entail(:subPropertyOf).include? property
|
67
100
|
end.map(&:object)
|
68
101
|
end
|
69
102
|
end
|
70
103
|
|
104
|
+
class NegatedPropertySelector < Selector
|
105
|
+
attr_reader :properties
|
106
|
+
def initialize(*properties)
|
107
|
+
@properties = properties
|
108
|
+
end
|
109
|
+
|
110
|
+
def evaluate_one(uri, context)
|
111
|
+
context.query([uri, nil, nil]).lazy.reject do |result|
|
112
|
+
properties.include? result.predicate
|
113
|
+
end.map(&:object)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
71
117
|
class WildcardSelector < Selector
|
72
118
|
def evaluate_one(uri, context)
|
73
|
-
context.query([uri, nil, nil]).map(&:object)
|
119
|
+
context.query([uri, nil, nil]).lazy.map(&:object)
|
74
120
|
end
|
75
121
|
end
|
76
122
|
|
@@ -81,7 +127,7 @@ module Ldpath
|
|
81
127
|
end
|
82
128
|
|
83
129
|
def evaluate_one(uri, context)
|
84
|
-
context.query([nil, property, uri]).map(&:subject)
|
130
|
+
context.query([nil, property, uri]).lazy.map(&:subject)
|
85
131
|
end
|
86
132
|
end
|
87
133
|
|
@@ -93,19 +139,20 @@ module Ldpath
|
|
93
139
|
end
|
94
140
|
|
95
141
|
def evaluate(program, uris, context)
|
96
|
-
|
97
|
-
input = Array(uris)
|
142
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
98
143
|
|
99
|
-
|
100
|
-
input = property.evaluate program, input, context
|
101
|
-
end
|
144
|
+
input = enum_wrap(uris)
|
102
145
|
|
103
|
-
repeat.each_with_index do |i, idx|
|
104
|
-
break if input.
|
146
|
+
(0..repeat.max).each_with_index do |i, idx|
|
147
|
+
break if input.none? || (repeat.max == Ldpath::Transform::Infinity && idx > 25) # we're probably lost..
|
105
148
|
input = property.evaluate program, input, context
|
106
|
-
|
149
|
+
|
150
|
+
next unless idx >= repeat.min
|
151
|
+
|
152
|
+
enum_wrap(input).each do |x|
|
153
|
+
yield x
|
154
|
+
end
|
107
155
|
end
|
108
|
-
result.flatten.compact
|
109
156
|
end
|
110
157
|
end
|
111
158
|
|
@@ -118,21 +165,47 @@ module Ldpath
|
|
118
165
|
end
|
119
166
|
|
120
167
|
class PathSelector < CompoundSelector
|
121
|
-
def evaluate(program, uris, context)
|
168
|
+
def evaluate(program, uris, context, &block)
|
169
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
170
|
+
|
122
171
|
output = left.evaluate(program, uris, context)
|
123
|
-
right.evaluate(program, output, context)
|
172
|
+
right.evaluate(program, output, context, &block)
|
124
173
|
end
|
125
174
|
end
|
126
175
|
|
127
176
|
class UnionSelector < CompoundSelector
|
128
177
|
def evaluate(program, uris, context)
|
129
|
-
|
178
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
179
|
+
|
180
|
+
enum_union(left.evaluate(program, uris, context), right.evaluate(program, uris, context)).each do |x|
|
181
|
+
yield x
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def enum_union(left, right)
|
188
|
+
return to_enum(:enum_union, left, right) unless block_given?
|
189
|
+
|
190
|
+
enum_wrap(left).each do |e|
|
191
|
+
yield e
|
192
|
+
end
|
193
|
+
|
194
|
+
enum_wrap(right).each do |e|
|
195
|
+
yield e
|
196
|
+
end
|
130
197
|
end
|
131
198
|
end
|
132
199
|
|
133
200
|
class IntersectionSelector < CompoundSelector
|
134
201
|
def evaluate(program, uris, context)
|
135
|
-
|
202
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
203
|
+
|
204
|
+
result = left.evaluate(program, uris, context).to_a & right.evaluate(program, uris, context).to_a
|
205
|
+
|
206
|
+
result.each do |x|
|
207
|
+
yield x
|
208
|
+
end
|
136
209
|
end
|
137
210
|
end
|
138
211
|
|
@@ -144,15 +217,19 @@ module Ldpath
|
|
144
217
|
end
|
145
218
|
|
146
219
|
def evaluate(program, uris, context)
|
220
|
+
return to_enum(:evaluate, program, uris, context) unless block_given?
|
221
|
+
|
147
222
|
program.meta[identifier] = tap.evaluate(program, uris, context).map { |x| RDF::Literal.new(x.to_s).canonicalize.object }
|
148
223
|
|
149
|
-
|
224
|
+
enum_wrap(uris).map do |uri|
|
150
225
|
loading program, uri, context
|
151
|
-
evaluate_one
|
152
|
-
|
226
|
+
enum_flatten_one(evaluate_one(uri, context)).each do |x|
|
227
|
+
yield x unless x.nil?
|
228
|
+
end
|
229
|
+
end
|
153
230
|
end
|
154
231
|
|
155
|
-
def evaluate_one(uri,
|
232
|
+
def evaluate_one(uri, _context)
|
156
233
|
uri
|
157
234
|
end
|
158
235
|
end
|
data/lib/ldpath/tests.rb
CHANGED
@@ -10,7 +10,7 @@ module Ldpath
|
|
10
10
|
def evaluate(program, uris, context)
|
11
11
|
entries = delegate.evaluate program, uris, context
|
12
12
|
entries.select do |uri|
|
13
|
-
|
13
|
+
enum_wrap(test.evaluate(program, uri, context)).any? do |x|
|
14
14
|
x
|
15
15
|
end
|
16
16
|
end
|
@@ -23,11 +23,10 @@ module Ldpath
|
|
23
23
|
@lang = lang
|
24
24
|
end
|
25
25
|
|
26
|
-
def evaluate(
|
26
|
+
def evaluate(_program, uri, _context)
|
27
27
|
return unless uri.literal?
|
28
|
-
|
29
|
-
|
30
|
-
end
|
28
|
+
|
29
|
+
uri if (lang == "none" && !uri.has_language?) || uri.language == lang
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
@@ -37,11 +36,10 @@ module Ldpath
|
|
37
36
|
@type = type
|
38
37
|
end
|
39
38
|
|
40
|
-
def evaluate(program, uri,
|
39
|
+
def evaluate(program, uri, _context)
|
41
40
|
return unless uri.literal?
|
42
|
-
|
43
|
-
|
44
|
-
end
|
41
|
+
|
42
|
+
uri if uri.has_datatype? && uri.datatype == type
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
@@ -53,7 +51,7 @@ module Ldpath
|
|
53
51
|
end
|
54
52
|
|
55
53
|
def evaluate(program, uri, context)
|
56
|
-
!
|
54
|
+
!enum_wrap(delegate.evaluate(program, uri, context)).any? { |x| x }
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
@@ -79,8 +77,8 @@ module Ldpath
|
|
79
77
|
end
|
80
78
|
|
81
79
|
def evaluate(program, uri, context)
|
82
|
-
left.evaluate(program, uri, context).
|
83
|
-
right.evaluate(program, uri, context).
|
80
|
+
left.evaluate(program, uri, context).any? &&
|
81
|
+
right.evaluate(program, uri, context).any?
|
84
82
|
end
|
85
83
|
end
|
86
84
|
|
@@ -93,7 +91,7 @@ module Ldpath
|
|
93
91
|
end
|
94
92
|
|
95
93
|
def evaluate(program, uri, context)
|
96
|
-
left.evaluate(program, uri, context).
|
94
|
+
left.evaluate(program, uri, context).include?(right)
|
97
95
|
end
|
98
96
|
end
|
99
97
|
end
|
data/lib/ldpath/transform.rb
CHANGED
@@ -15,7 +15,7 @@ module Ldpath
|
|
15
15
|
"fn" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/functions/1.0/"), # (LMF index functions)
|
16
16
|
"foaf" => RDF::Vocabulary.new("http://xmlns.com/foaf/0.1/"),
|
17
17
|
"info" => RDF::Vocabulary.new("info:"),
|
18
|
-
"urn" => RDF::Vocabulary.new("urn:")
|
18
|
+
"urn" => RDF::Vocabulary.new("urn:")
|
19
19
|
}
|
20
20
|
end
|
21
21
|
end
|
@@ -71,7 +71,7 @@ module Ldpath
|
|
71
71
|
# Mappings
|
72
72
|
|
73
73
|
rule(mapping: subtree(:mapping)) do
|
74
|
-
FieldMapping.new mapping
|
74
|
+
FieldMapping.new mapping
|
75
75
|
end
|
76
76
|
|
77
77
|
## Selectors
|
@@ -106,18 +106,13 @@ module Ldpath
|
|
106
106
|
end
|
107
107
|
|
108
108
|
rule(range: subtree(:range)) do
|
109
|
-
|
110
|
-
when "*"
|
111
|
-
0..Infinity
|
112
|
-
when "+"
|
113
|
-
1..Infinity
|
114
|
-
when "?"
|
115
|
-
0..1
|
116
|
-
else
|
117
|
-
range.fetch(:min, 0).to_i..range.fetch(:max, Infinity).to_f
|
118
|
-
end
|
109
|
+
range.fetch(:min, 0).to_i..range.fetch(:max, Infinity).to_f
|
119
110
|
end
|
120
111
|
|
112
|
+
rule(range: '*') { 0..Infinity }
|
113
|
+
rule(range: '+') { 1..Infinity }
|
114
|
+
rule(range: '?') { 0..1 }
|
115
|
+
|
121
116
|
rule(delegate: subtree(:delegate), repeat: simple(:repeat)) do
|
122
117
|
RecursivePathSelector.new delegate, repeat
|
123
118
|
end
|
@@ -126,6 +121,10 @@ module Ldpath
|
|
126
121
|
TapSelector.new identifier.to_s, tap
|
127
122
|
end
|
128
123
|
|
124
|
+
rule(not: simple(:not), property: sequence(:property)) do
|
125
|
+
NegatedPropertySelector.new(*property)
|
126
|
+
end
|
127
|
+
|
129
128
|
### Test Selectors
|
130
129
|
|
131
130
|
rule(delegate: subtree(:delegate), test: subtree(:test)) do
|
@@ -144,16 +143,16 @@ module Ldpath
|
|
144
143
|
TypeTest.new type
|
145
144
|
end
|
146
145
|
|
147
|
-
rule(not:
|
148
|
-
NotTest.new
|
146
|
+
rule(not: simple(:not_op), delegate: simple(:delegate)) do
|
147
|
+
NotTest.new delegate
|
149
148
|
end
|
150
149
|
|
151
|
-
rule(
|
152
|
-
|
150
|
+
rule(op: '|', left_test: subtree(:left_test), right_test: subtree(:right_test)) do
|
151
|
+
OrTest.new left_test, right_test
|
153
152
|
end
|
154
153
|
|
155
|
-
rule(
|
156
|
-
|
154
|
+
rule(op: '&', left_test: subtree(:left_test), right_test: subtree(:right_test)) do
|
155
|
+
AndTest.new left_test, right_test
|
157
156
|
end
|
158
157
|
|
159
158
|
rule(is: subtree(:is)) do
|
@@ -165,15 +164,17 @@ module Ldpath
|
|
165
164
|
end
|
166
165
|
|
167
166
|
### Compound Selectors
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
167
|
+
|
168
|
+
rule(op: '/', left: subtree(:left), right: subtree(:right)) do
|
169
|
+
PathSelector.new left, right
|
170
|
+
end
|
171
|
+
|
172
|
+
rule(op: '|', left: subtree(:left), right: subtree(:right)) do
|
173
|
+
UnionSelector.new left, right
|
174
|
+
end
|
175
|
+
|
176
|
+
rule(op: '&', left: subtree(:left), right: subtree(:right)) do
|
177
|
+
IntersectionSelector.new left, right
|
177
178
|
end
|
178
179
|
|
179
180
|
Infinity = 1.0 / 0.0
|
data/lib/ldpath/version.rb
CHANGED
data/lib/ldpath.rb
CHANGED
@@ -10,8 +10,11 @@ module Ldpath
|
|
10
10
|
require 'ldpath/transform'
|
11
11
|
require 'ldpath/functions'
|
12
12
|
require 'ldpath/program'
|
13
|
+
require 'ldpath/result'
|
13
14
|
|
14
15
|
class << self
|
16
|
+
attr_writer :logger
|
17
|
+
|
15
18
|
def evaluate(program, uri, context)
|
16
19
|
Ldpath::Program.parse(program).evaluate(uri, context)
|
17
20
|
end
|
@@ -25,9 +28,5 @@ module Ldpath
|
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
28
|
-
|
29
|
-
def logger=(logger)
|
30
|
-
@logger = logger
|
31
|
-
end
|
32
31
|
end
|
33
32
|
end
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<http://www.bbc.co.uk/programmes/b0081dq5> <http://xmlns.com/foaf/0.1/primaryTopic> <_:b0> .
|
2
|
+
<_:b0> <http://purl.org/ontology/po/pid> "b0081dq5" .
|
3
|
+
<_:b0> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/primaryTopic> .
|
4
|
+
<_:b0> <http://purl.org/dc/elements/1.1/title> "Huw Stephens" .
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<http://id.loc.gov/authorities/names/n79021164> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.loc.gov/mads/rdf/v1#PersonalName> .
|
2
|
+
<http://id.loc.gov/authorities/names/n79021164> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.loc.gov/mads/rdf/v1#Authority> .
|
3
|
+
<http://id.loc.gov/authorities/names/n79021164> <http://www.loc.gov/mads/rdf/v1#authoritativeLabel> "Twain, Mark, 1835-1910 (network call to LOC)"@en .
|
data/spec/ldpath_parser_spec.rb
CHANGED
@@ -200,12 +200,30 @@ describe Ldpath::Parser do
|
|
200
200
|
end
|
201
201
|
|
202
202
|
it "tap_selector" do
|
203
|
-
subject.selector.parse('?<
|
203
|
+
subject.selector.parse('?<__autocomplete>fn:predicates()')
|
204
204
|
end
|
205
205
|
|
206
206
|
it "loose_selector" do
|
207
207
|
subject.selector.parse('~<info:a>')
|
208
208
|
end
|
209
|
+
|
210
|
+
it "negated property selector" do
|
211
|
+
subject.selector.parse('!<info:a>')
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "tests" do
|
216
|
+
it "should pass a simple property test" do
|
217
|
+
subject.selector.parse('.[info:a]')
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should pass a property test with '&'" do
|
221
|
+
subject.selector.parse('.[info:a & info:b]')
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should pass a property test with '|'" do
|
225
|
+
subject.selector.parse('.[info:a | info:b]')
|
226
|
+
end
|
209
227
|
end
|
210
228
|
|
211
229
|
describe "integration tests" do
|
data/spec/ldpath_program_spec.rb
CHANGED
@@ -36,19 +36,19 @@ EOF
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should work" do
|
39
|
-
graph << [object, RDF::DC.title, "Hello, world!"]
|
40
|
-
graph << [object, RDF::DC.isPartOf, parent]
|
41
|
-
graph << [object, RDF::DC.description, RDF::Literal.new("English!", language: "en")]
|
42
|
-
graph << [object, RDF::DC.description, RDF::Literal.new("French!", language: "fr")]
|
39
|
+
graph << [object, RDF::Vocab::DC.title, "Hello, world!"]
|
40
|
+
graph << [object, RDF::Vocab::DC.isPartOf, parent]
|
41
|
+
graph << [object, RDF::Vocab::DC.description, RDF::Literal.new("English!", language: "en")]
|
42
|
+
graph << [object, RDF::Vocab::DC.description, RDF::Literal.new("French!", language: "fr")]
|
43
43
|
graph << [object, RDF::URI.new("info:intProperty"), 1]
|
44
44
|
graph << [object, RDF::URI.new("info:intProperty"), "garbage"]
|
45
45
|
graph << [object, RDF::URI.new("info:numericProperty"), "1"]
|
46
|
-
graph << [parent, RDF::DC.title, "Parent title"]
|
47
|
-
graph << [child, RDF::DC.isPartOf, object]
|
48
|
-
graph << [child, RDF::DC.title, "Child title"]
|
49
|
-
graph << [parent, RDF::DC.isPartOf, grandparent]
|
46
|
+
graph << [parent, RDF::Vocab::DC.title, "Parent title"]
|
47
|
+
graph << [child, RDF::Vocab::DC.isPartOf, object]
|
48
|
+
graph << [child, RDF::Vocab::DC.title, "Child title"]
|
49
|
+
graph << [parent, RDF::Vocab::DC.isPartOf, grandparent]
|
50
50
|
|
51
|
-
result = subject.evaluate object, graph
|
51
|
+
result = subject.evaluate object, context: graph
|
52
52
|
|
53
53
|
expect(result["title"]).to match_array "Hello, world!"
|
54
54
|
expect(result["parent_title"]).to match_array "Parent title"
|
@@ -97,17 +97,17 @@ EOF
|
|
97
97
|
|
98
98
|
let(:graph) do
|
99
99
|
graph = RDF::Graph.new
|
100
|
-
graph << [object, RDF::DC.title, "Hello, world!"]
|
101
|
-
graph << [object, RDF::DC.description, "Description"]
|
102
|
-
graph << [object, RDF::DC.hasPart, "a"]
|
103
|
-
graph << [object, RDF::DC.hasPart, "b"]
|
104
|
-
graph << [object, RDF::DC.hasPart, "c"]
|
100
|
+
graph << [object, RDF::Vocab::DC.title, "Hello, world!"]
|
101
|
+
graph << [object, RDF::Vocab::DC.description, "Description"]
|
102
|
+
graph << [object, RDF::Vocab::DC.hasPart, "a"]
|
103
|
+
graph << [object, RDF::Vocab::DC.hasPart, "b"]
|
104
|
+
graph << [object, RDF::Vocab::DC.hasPart, "c"]
|
105
105
|
|
106
106
|
graph
|
107
107
|
end
|
108
108
|
|
109
109
|
subject do
|
110
|
-
program.evaluate object, graph
|
110
|
+
program.evaluate object, context: graph
|
111
111
|
end
|
112
112
|
|
113
113
|
describe "concat" do
|
@@ -191,8 +191,13 @@ title = foaf:primaryTopic / dc:title :: xsd:string ;
|
|
191
191
|
EOF
|
192
192
|
end
|
193
193
|
|
194
|
+
before do
|
195
|
+
stub_request(:get, 'http://www.bbc.co.uk/programmes/b0081dq5')
|
196
|
+
.to_return(status: 200, body: webmock_fixture('bbc_b0081dq5.nt'), headers: { 'Content-Type' => 'application/n-triples' })
|
197
|
+
end
|
198
|
+
|
194
199
|
it "should work" do
|
195
|
-
result = subject.evaluate RDF::URI.new("http://www.bbc.co.uk/programmes/b0081dq5
|
200
|
+
result = subject.evaluate RDF::URI.new("http://www.bbc.co.uk/programmes/b0081dq5")
|
196
201
|
expect(result["title"]).to match_array "Huw Stephens"
|
197
202
|
end
|
198
203
|
end
|
@@ -205,9 +210,16 @@ predicates = <http://xmlns.com/foaf/0.1/primaryTopic> / fn:predicates() :: xsd:s
|
|
205
210
|
EOF
|
206
211
|
end
|
207
212
|
|
213
|
+
before do
|
214
|
+
stub_request(:get, 'http://www.bbc.co.uk/programmes/b0081dq5')
|
215
|
+
.to_return(status: 200, body: webmock_fixture('bbc_b0081dq5.nt'), headers: { 'Content-Type' => 'application/n-triples' })
|
216
|
+
end
|
217
|
+
|
208
218
|
it "should work" do
|
209
|
-
result = subject.evaluate RDF::URI.new("http://www.bbc.co.uk/programmes/b0081dq5
|
210
|
-
expect(result["predicates"]).to include "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
|
219
|
+
result = subject.evaluate RDF::URI.new("http://www.bbc.co.uk/programmes/b0081dq5")
|
220
|
+
expect(result["predicates"]).to include "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
|
221
|
+
"http://purl.org/ontology/po/pid",
|
222
|
+
"http://purl.org/dc/elements/1.1/title"
|
211
223
|
end
|
212
224
|
end
|
213
225
|
|
@@ -219,9 +231,9 @@ EOF
|
|
219
231
|
let(:graph) do
|
220
232
|
graph = RDF::Graph.new
|
221
233
|
|
222
|
-
graph << [object, RDF::DC.title, "Object"]
|
223
|
-
graph << [child, RDF::DC.title, "Child"]
|
224
|
-
graph << [object, RDF::DC.hasPart, child]
|
234
|
+
graph << [object, RDF::Vocab::DC.title, "Object"]
|
235
|
+
graph << [child, RDF::Vocab::DC.title, "Child"]
|
236
|
+
graph << [object, RDF::Vocab::DC.hasPart, child]
|
225
237
|
|
226
238
|
graph
|
227
239
|
end
|
@@ -236,7 +248,7 @@ child_title_with_tap = dcterms:hasPart / ?<tap>fn:predicates() / dcterms:title :
|
|
236
248
|
end
|
237
249
|
|
238
250
|
it "should work" do
|
239
|
-
result = subject.evaluate object, graph
|
251
|
+
result = subject.evaluate object, context: graph
|
240
252
|
expect(result["child_title_with_tap"]).to eq result["child_title"]
|
241
253
|
expect(result["tap"]).to eq ["http://purl.org/dc/terms/title"]
|
242
254
|
end
|
@@ -250,9 +262,9 @@ child_title_with_tap = dcterms:hasPart / ?<tap>fn:predicates() / dcterms:title :
|
|
250
262
|
let(:graph) do
|
251
263
|
graph = RDF::Graph.new
|
252
264
|
|
253
|
-
graph << [object, RDF::DC.title, "Object"]
|
254
|
-
graph << [child, RDF::DC.title, "Child"]
|
255
|
-
graph << [object, RDF::DC.hasPart, child]
|
265
|
+
graph << [object, RDF::Vocab::DC.title, "Object"]
|
266
|
+
graph << [child, RDF::Vocab::DC.title, "Child"]
|
267
|
+
graph << [object, RDF::Vocab::DC.hasPart, child]
|
256
268
|
|
257
269
|
graph
|
258
270
|
end
|
@@ -267,7 +279,7 @@ title_with_loose = ~dc:title :: xsd:string ;
|
|
267
279
|
end
|
268
280
|
|
269
281
|
it "should work" do
|
270
|
-
result = subject.evaluate object, graph
|
282
|
+
result = subject.evaluate object, context: graph
|
271
283
|
expect(result["title_with_loose"]).to eq result["title"]
|
272
284
|
end
|
273
285
|
end
|
@@ -288,27 +300,70 @@ title_with_loose = ~dc:title :: xsd:string ;
|
|
288
300
|
let(:graph) do
|
289
301
|
graph = RDF::Graph.new
|
290
302
|
|
291
|
-
graph << [object, RDF.type, RDF::DC.Agent]
|
292
|
-
graph << [object, RDF::DC.title, "Title"]
|
293
|
-
graph << [other_object, RDF::DC.title, "Other Title"]
|
303
|
+
graph << [object, RDF.type, RDF::Vocab::DC.Agent]
|
304
|
+
graph << [object, RDF::Vocab::DC.title, "Title"]
|
305
|
+
graph << [other_object, RDF::Vocab::DC.title, "Other Title"]
|
294
306
|
|
295
307
|
graph
|
296
308
|
end
|
297
309
|
|
298
310
|
it "should work" do
|
299
|
-
result = subject.evaluate object, graph
|
311
|
+
result = subject.evaluate object, context: graph
|
300
312
|
expect(result["title"]).to eq ["Title"]
|
301
313
|
end
|
302
314
|
|
303
315
|
it "filters objects that don't match" do
|
304
|
-
result = subject.evaluate other_object, graph
|
316
|
+
result = subject.evaluate other_object, context: graph
|
305
317
|
expect(result).to be_empty
|
306
318
|
end
|
307
319
|
end
|
308
320
|
|
309
321
|
describe "error handling" do
|
310
322
|
it "should provide a reasonable exception" do
|
311
|
-
expect { Ldpath::Program.parse "title .= <oops> ;" }.to raise_error
|
323
|
+
expect { Ldpath::Program.parse "title .= <oops> ;" }.to raise_error(/Expected "=", but got "."/)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe '#evaluate' do
|
328
|
+
context 'when passing limit_to_context' do
|
329
|
+
subject do
|
330
|
+
Ldpath::Program.parse <<-EOF
|
331
|
+
@prefix madsrdf : <http://www.loc.gov/mads/rdf/v1#> ;
|
332
|
+
@prefix schema: <http://www.w3.org/2000/01/rdf-schema#> ;
|
333
|
+
property = madsrdf:authoritativeLabel :: xsd:string ;
|
334
|
+
EOF
|
335
|
+
end
|
336
|
+
|
337
|
+
let(:subject_uri) { RDF::URI('http://id.loc.gov/authorities/names/n79021164') }
|
338
|
+
|
339
|
+
let(:graph) do
|
340
|
+
graph = RDF::Graph.new
|
341
|
+
graph << [subject_uri, RDF::Vocab::MADS.authoritativeLabel, 'Mark Twain (passed in context)']
|
342
|
+
graph
|
343
|
+
end
|
344
|
+
|
345
|
+
before do
|
346
|
+
stub_request(:get, 'http://id.loc.gov/authorities/names/n79021164')
|
347
|
+
.to_return(status: 200, body: webmock_fixture('loc_n79021164.nt'), headers: { 'Content-Type' => 'application/n-triples' })
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'as false' do
|
351
|
+
let(:expected_values) { ['Mark Twain (passed in context)', 'Twain, Mark, 1835-1910 (network call to LOC)'] }
|
352
|
+
|
353
|
+
it 'returns values from context and network call' do
|
354
|
+
result = subject.evaluate subject_uri, context: graph
|
355
|
+
expect(result['property']).to match_array expected_values
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
context 'as true' do
|
360
|
+
let(:expected_values) { ['Mark Twain (passed in context)'] }
|
361
|
+
|
362
|
+
it 'returns values from context only' do
|
363
|
+
result = subject.evaluate(subject_uri, context: graph, limit_to_context: true)
|
364
|
+
expect(result['property']).to match_array expected_values
|
365
|
+
end
|
366
|
+
end
|
312
367
|
end
|
313
368
|
end
|
314
369
|
end
|