roadforest 0.5 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/file-management.rb +70 -58
- data/lib/roadforest/application.rb +9 -17
- data/lib/roadforest/application/dispatcher.rb +76 -9
- data/lib/roadforest/application/parameters.rb +9 -1
- data/lib/roadforest/application/path-provider.rb +30 -3
- data/lib/roadforest/application/route-adapter.rb +96 -14
- data/lib/roadforest/application/services-host.rb +21 -3
- data/lib/roadforest/augment/affordance.rb +82 -11
- data/lib/roadforest/augment/augmentation.rb +24 -6
- data/lib/roadforest/augment/augmenter.rb +12 -3
- data/lib/roadforest/authorization.rb +7 -229
- data/lib/roadforest/authorization/auth-entity.rb +26 -0
- data/lib/roadforest/authorization/authentication-chain.rb +79 -0
- data/lib/roadforest/authorization/default-authentication-store.rb +33 -0
- data/lib/roadforest/authorization/grant-builder.rb +23 -0
- data/lib/roadforest/authorization/grants-holder.rb +58 -0
- data/lib/roadforest/authorization/manager.rb +85 -0
- data/lib/roadforest/authorization/policy.rb +19 -0
- data/lib/roadforest/graph/access-manager.rb +25 -2
- data/lib/roadforest/graph/focus-list.rb +4 -0
- data/lib/roadforest/graph/graph-focus.rb +30 -13
- data/lib/roadforest/graph/nav-affordance-builder.rb +62 -0
- data/lib/roadforest/graph/normalization.rb +3 -3
- data/lib/roadforest/graph/path-vocabulary.rb +64 -0
- data/lib/roadforest/graph/post-focus.rb +5 -0
- data/lib/roadforest/graph/vocabulary.rb +4 -1
- data/lib/roadforest/http/adapters/excon.rb +4 -0
- data/lib/roadforest/http/graph-transfer.rb +17 -1
- data/lib/roadforest/http/keychain.rb +121 -33
- data/lib/roadforest/http/user-agent.rb +5 -3
- data/lib/roadforest/interface/application.rb +25 -8
- data/lib/roadforest/interface/rdf.rb +114 -15
- data/lib/roadforest/interface/utility.rb +3 -0
- data/lib/roadforest/interface/utility/backfill.rb +63 -0
- data/lib/roadforest/interface/utility/grant-list.rb +45 -0
- data/lib/roadforest/interface/utility/grant.rb +22 -0
- data/lib/roadforest/interfaces.rb +1 -0
- data/lib/roadforest/path-matcher.rb +471 -0
- data/lib/roadforest/remote-host.rb +159 -35
- data/lib/roadforest/resource/read-only.rb +23 -4
- data/lib/roadforest/server.rb +32 -3
- data/lib/roadforest/source-rigor/graph-store.rb +0 -2
- data/lib/roadforest/source-rigor/rigorous-access.rb +138 -21
- data/lib/roadforest/templates/affordance-property-values.haml +3 -0
- data/lib/roadforest/templates/rdfpost-curie.haml +1 -1
- data/lib/roadforest/test-support/matchers.rb +41 -12
- data/lib/roadforest/test-support/remote-host.rb +3 -3
- data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +1 -1
- data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +40 -27
- data/lib/roadforest/type-handlers/rdfa.rb +10 -3
- data/lib/roadforest/utility/class-registry.rb +44 -4
- data/spec/affordance-augmenter.rb +46 -19
- data/spec/affordances-flow.rb +46 -30
- data/spec/authorization.rb +16 -4
- data/spec/client.rb +22 -4
- data/spec/focus-list.rb +24 -0
- data/spec/full-integration.rb +8 -3
- data/spec/graph-store.rb +8 -0
- data/spec/keychain.rb +18 -14
- data/spec/rdf-normalization.rb +32 -6
- data/spec/update-focus.rb +36 -39
- metadata +19 -5
@@ -6,6 +6,10 @@ class RDF::Repository
|
|
6
6
|
include RDF::Isomorphic
|
7
7
|
end
|
8
8
|
|
9
|
+
class RDF::Graph
|
10
|
+
include RDF::Isomorphic
|
11
|
+
end
|
12
|
+
|
9
13
|
module RoadForest
|
10
14
|
module Testing
|
11
15
|
module HelperMethods
|
@@ -13,6 +17,23 @@ module RoadForest
|
|
13
17
|
StatementsFromGraph.new(graph)
|
14
18
|
end
|
15
19
|
|
20
|
+
# Heuristically detect the input stream
|
21
|
+
def detect_format(stream)
|
22
|
+
# Got to look into the file to see
|
23
|
+
if stream.is_a?(IO) || stream.is_a?(StringIO)
|
24
|
+
stream.rewind
|
25
|
+
string = stream.read(1000)
|
26
|
+
stream.rewind
|
27
|
+
else
|
28
|
+
string = stream.to_s
|
29
|
+
end
|
30
|
+
case string
|
31
|
+
when /<html/i then RDF::RDFa::Reader
|
32
|
+
when /@prefix/i then RDF::Turtle::Reader
|
33
|
+
else RDF::NTriples::Reader
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
16
37
|
def normalize(graph)
|
17
38
|
case graph
|
18
39
|
when RDF::Queryable then graph
|
@@ -22,7 +43,7 @@ module RoadForest
|
|
22
43
|
# Figure out which parser to use
|
23
44
|
g = RDF::Graph.new
|
24
45
|
reader_class = detect_format(graph)
|
25
|
-
reader_class.new(graph, :base_uri => @info.about).each {|s| g << s}
|
46
|
+
reader_class.new(graph, :base_uri => @info.nil? ? nil : @info.about).each {|s| g << s}
|
26
47
|
g
|
27
48
|
end
|
28
49
|
end
|
@@ -72,7 +93,7 @@ module RoadForest
|
|
72
93
|
"be equivalent to an expected graph" #graphs tend to be too long to use
|
73
94
|
end
|
74
95
|
|
75
|
-
def failure_message_for_should
|
96
|
+
def failure_message_for_should
|
76
97
|
info = @info.respond_to?(:about) ? @info.about : @info.inspect
|
77
98
|
if @expected.is_a?(RDF::Graph) && @actual.size != @expected.size
|
78
99
|
"Graph entry count differs:\nexpected: #{@expected.size}\nactual: #{@actual.size}"
|
@@ -94,12 +115,18 @@ module RoadForest
|
|
94
115
|
def initialize(xpath, value, trace)
|
95
116
|
@xpath, @value, @trace = xpath, value, trace
|
96
117
|
end
|
97
|
-
attr_reader :xpath, :value, :trace
|
118
|
+
attr_reader :xpath, :value, :trace, :actual
|
119
|
+
attr_accessor :found
|
120
|
+
|
121
|
+
def description
|
122
|
+
"should match #{@xpath.inspect}"
|
123
|
+
end
|
98
124
|
|
99
125
|
def matches?(actual)
|
126
|
+
@actual = actual
|
100
127
|
@doc = Nokogiri::HTML.parse(actual)
|
101
128
|
@namespaces = @doc.namespaces.merge("xhtml" => "http://www.w3.org/1999/xhtml", "xml" => "http://www.w3.org/XML/1998/namespace")
|
102
|
-
found = @doc.root.at_xpath(xpath, @namespaces)
|
129
|
+
self.found = @doc.root.at_xpath(xpath, @namespaces)
|
103
130
|
case value
|
104
131
|
when false
|
105
132
|
found.nil?
|
@@ -114,8 +141,7 @@ module RoadForest
|
|
114
141
|
end
|
115
142
|
end
|
116
143
|
|
117
|
-
def failure_message_for_should
|
118
|
-
trace ||= debug
|
144
|
+
def failure_message_for_should
|
119
145
|
msg =
|
120
146
|
case value
|
121
147
|
when true
|
@@ -130,8 +156,7 @@ module RoadForest
|
|
130
156
|
msg
|
131
157
|
end
|
132
158
|
|
133
|
-
def failure_message_for_should_not
|
134
|
-
trace ||= debug
|
159
|
+
def failure_message_for_should_not
|
135
160
|
msg = "expected that #{xpath.inspect} would not be #{value.inspect} in:\n" + actual.to_s
|
136
161
|
msg += "\nDebug:#{trace.join("\n")}" if trace
|
137
162
|
msg
|
@@ -176,13 +201,18 @@ module RoadForest
|
|
176
201
|
not solutions.empty?
|
177
202
|
end
|
178
203
|
|
204
|
+
def indent(string)
|
205
|
+
string.split("\n").map{|line| " " + line}.join("\n")
|
206
|
+
end
|
207
|
+
|
179
208
|
def failure_message_for_should
|
180
|
-
|
209
|
+
require 'pp'
|
210
|
+
"expected: \n#{indent(@query.patterns.pretty_inspect)} \nto return solutions on \n\n#{indent(@actual.dump(:nquads))}\n but didn't"
|
181
211
|
end
|
182
212
|
|
183
213
|
def failure_message_for_should_not
|
184
|
-
|
185
|
-
|
214
|
+
require 'pp'
|
215
|
+
"expected: \n#{indent(@query.patterns.pretty_inspect)} \nnot to return solutions on \n\n#{indent(@actual.dump(:nquads))}\n but does" end
|
186
216
|
end
|
187
217
|
|
188
218
|
class ListEquivalence
|
@@ -191,7 +221,6 @@ module RoadForest
|
|
191
221
|
end
|
192
222
|
|
193
223
|
def subtract(one, other)
|
194
|
-
sorted = one.sort_by{|stmt| stmt.to_a}
|
195
224
|
one.find_all do |expected_stmt|
|
196
225
|
not other.any? do |actual_stmt|
|
197
226
|
actual_stmt.eql? expected_stmt
|
@@ -3,9 +3,9 @@ require 'roadforest/remote-host'
|
|
3
3
|
require 'roadforest/test-support/http-client'
|
4
4
|
module RoadForest::TestSupport
|
5
5
|
class RemoteHost < ::RoadForest::RemoteHost
|
6
|
-
def initialize(
|
7
|
-
@app =
|
8
|
-
super(
|
6
|
+
def initialize(services)
|
7
|
+
@app = RoadForest::Application.new(services)
|
8
|
+
super(services.canonical_host)
|
9
9
|
end
|
10
10
|
|
11
11
|
def build_graph_store
|
@@ -29,7 +29,8 @@ module RoadForest::TypeHandlers
|
|
29
29
|
end.handle_templates do |config|
|
30
30
|
#At some point, should look into using HTML entities to preserve
|
31
31
|
#whitespace in XMLLiterals
|
32
|
-
|
32
|
+
options = {:format => :xhtml}.merge(haml_options || {:ugly => true})
|
33
|
+
config.add_type("haml", { :template_cache => template_cache, :template_options => options })
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -56,10 +57,12 @@ module RoadForest::TypeHandlers
|
|
56
57
|
attr_accessor :prefixes, :base_uri, :lang, :standard_prefixes, :graph, :titles, :doc_title, :graph_name
|
57
58
|
attr_accessor :template_handler
|
58
59
|
attr_reader :debug
|
60
|
+
attr_accessor :debugging_comments
|
59
61
|
|
60
62
|
attr_reader :decoration_set
|
61
63
|
|
62
64
|
def initialize(graph, debug=nil)
|
65
|
+
@debugging_comments = false
|
63
66
|
@debug = debug
|
64
67
|
@graph = graph
|
65
68
|
@graph_name = nil
|
@@ -104,11 +107,18 @@ module RoadForest::TypeHandlers
|
|
104
107
|
|
105
108
|
def add_debug(message = nil)
|
106
109
|
return unless ::RoadForest.debug_io || @debug
|
107
|
-
message ||= ""
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
message ||= " " * @debug_indent
|
111
|
+
begin
|
112
|
+
message = message + yield if block_given?
|
113
|
+
rescue => ex
|
114
|
+
message += ex.inspect
|
115
|
+
message += "\n"
|
116
|
+
message += ex.backtrace[0...10].map do |line|
|
117
|
+
(" " * (@debug_indent + 1)) + line
|
118
|
+
end.join("\n")
|
119
|
+
end
|
120
|
+
RoadForest::debug(message)
|
121
|
+
@debug << message.force_encoding("utf-8") if @debug.is_a?(Array)
|
112
122
|
end
|
113
123
|
|
114
124
|
def setup
|
@@ -171,7 +181,6 @@ module RoadForest::TypeHandlers
|
|
171
181
|
!seen.include?(s)
|
172
182
|
end.each do |class_uri|
|
173
183
|
graph.query(:predicate => RDF.type, :object => class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
|
174
|
-
#add_debug {"order_subjects: #{subject.inspect}"}
|
175
184
|
subjects << subject
|
176
185
|
seen[subject] = true
|
177
186
|
end
|
@@ -184,9 +193,9 @@ module RoadForest::TypeHandlers
|
|
184
193
|
[r.is_a?(RDF::Node) ? 1 : 0, ref_count(r), r]
|
185
194
|
end.sort
|
186
195
|
|
187
|
-
add_debug {"order_subjects: #{recursable.inspect}"}
|
188
|
-
|
189
196
|
subjects += recursable.map{|r| r.last}
|
197
|
+
add_debug {"order_subjects: (final) \n #{subjects.join("\n ")}"}
|
198
|
+
return subjects
|
190
199
|
end
|
191
200
|
|
192
201
|
def order_properties(properties)
|
@@ -231,21 +240,21 @@ module RoadForest::TypeHandlers
|
|
231
240
|
curie =
|
232
241
|
case
|
233
242
|
when @uri_to_term_or_curie.has_key?(uri)
|
234
|
-
add_debug {"get_curie(#{uri}):
|
243
|
+
add_debug {"get_curie(#{uri}): cached: #{@uri_to_term_or_curie[uri].inspect}"}
|
235
244
|
return @uri_to_term_or_curie[uri]
|
236
245
|
when base_uri && uri.index(base_uri.to_s) == 0
|
237
|
-
add_debug {"get_curie(#{uri}): base_uri (#{uri.sub(base_uri.to_s, "")})"}
|
246
|
+
add_debug {"get_curie(#{uri}): base_uri: (#{base_uri} + #{uri.sub(base_uri.to_s, "")})"}
|
238
247
|
uri.sub(base_uri.to_s, "")
|
239
248
|
when @vocabulary && uri.index(@vocabulary) == 0
|
240
|
-
add_debug {"get_curie(#{uri}): vocabulary"}
|
249
|
+
add_debug {"get_curie(#{uri}): vocabulary: #{@vocabulary.inspect}"}
|
241
250
|
uri.sub(@vocabulary, "")
|
242
251
|
when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
|
243
|
-
add_debug {"get_curie(#{uri}): uri_to_prefix"}
|
252
|
+
add_debug {"get_curie(#{uri}): uri_to_prefix: #{@uri_to_prefix[u]}"}
|
244
253
|
prefix = @uri_to_prefix[u]
|
245
254
|
@prefixes[prefix] = u
|
246
255
|
uri.sub(u.to_s, "#{prefix}:")
|
247
256
|
when @standard_prefixes && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
|
248
|
-
add_debug {"get_curie(#{uri}): standard_prefixes"}
|
257
|
+
add_debug {"get_curie(#{uri}): standard_prefixes: #{vocab}"}
|
249
258
|
prefix = vocab.__name__.to_s.split('::').last.downcase
|
250
259
|
@prefixes[prefix] = vocab.to_uri
|
251
260
|
uri.sub(vocab.to_uri.to_s, "#{prefix}:")
|
@@ -288,8 +297,6 @@ module RoadForest::TypeHandlers
|
|
288
297
|
end
|
289
298
|
|
290
299
|
def render(context)
|
291
|
-
#puts "\n#{__FILE__.sub(/^#{Dir.pwd}/,'')}:#{__LINE__} =>
|
292
|
-
##{context.class.inspect}"
|
293
300
|
add_debug "render"
|
294
301
|
if context.render_checked
|
295
302
|
return ""
|
@@ -297,11 +304,17 @@ module RoadForest::TypeHandlers
|
|
297
304
|
template = find_environment_template(context)
|
298
305
|
depth do
|
299
306
|
add_debug{ "template: #{template.file}" }
|
307
|
+
add_debug{ "options: #{template.options}" }
|
300
308
|
add_debug{ "context: #{context.class.name}"}
|
309
|
+
add_debug{ " #{context.attrs}" } if context.respond_to?(:attrs)
|
301
310
|
|
302
311
|
begin
|
303
312
|
@render_stack.push context
|
304
|
-
|
313
|
+
prefix = ""
|
314
|
+
if debugging_comments
|
315
|
+
prefix = "<!-- #{template.file} -->"
|
316
|
+
end
|
317
|
+
prefix + template.render(context) do |item|
|
305
318
|
context.yielded(item)
|
306
319
|
end.sub(/\n\Z/,'')
|
307
320
|
ensure
|
@@ -311,7 +324,7 @@ module RoadForest::TypeHandlers
|
|
311
324
|
end
|
312
325
|
|
313
326
|
def is_list?(object)
|
314
|
-
!(object == RDF.nil || (
|
327
|
+
!(object == RDF.nil || (RDF::List.new(object, @graph)).invalid?)
|
315
328
|
end
|
316
329
|
|
317
330
|
def subject_done(subject)
|
@@ -332,6 +345,15 @@ module RoadForest::TypeHandlers
|
|
332
345
|
properties
|
333
346
|
end
|
334
347
|
|
348
|
+
def build_env(klass)
|
349
|
+
env = klass.new(self)
|
350
|
+
env.heading_predicates = heading_predicates
|
351
|
+
env.lang = lang
|
352
|
+
env.parent = @render_stack.last
|
353
|
+
yield(env)
|
354
|
+
return decoration_set.decoration_for(env)
|
355
|
+
end
|
356
|
+
|
335
357
|
def document_env
|
336
358
|
build_env(DocumentEnvironment) do |env|
|
337
359
|
env.subject_terms = @ordered_subjects
|
@@ -365,15 +387,6 @@ module RoadForest::TypeHandlers
|
|
365
387
|
end
|
366
388
|
end
|
367
389
|
|
368
|
-
def build_env(klass)
|
369
|
-
env = klass.new(self)
|
370
|
-
env.heading_predicates = heading_predicates
|
371
|
-
env.lang = lang
|
372
|
-
env.parent = @render_stack.last
|
373
|
-
yield(env)
|
374
|
-
return decoration_set.decoration_for(env)
|
375
|
-
end
|
376
|
-
|
377
390
|
def object_env(predicate, object)
|
378
391
|
subj = subject_env(object)
|
379
392
|
unless subj.nil?
|
@@ -14,6 +14,7 @@ module RoadForest
|
|
14
14
|
include Graph::Normalization
|
15
15
|
|
16
16
|
attr_writer :valise, :tilt_cache
|
17
|
+
attr_accessor :haml_options
|
17
18
|
|
18
19
|
def valise
|
19
20
|
@valise ||= Valise.define do
|
@@ -33,9 +34,10 @@ module RoadForest
|
|
33
34
|
templates = RDFaWriter::TemplateHandler.new
|
34
35
|
templates.valise = valise
|
35
36
|
templates.template_cache = tilt_cache
|
37
|
+
templates.haml_options = haml_options
|
36
38
|
|
37
39
|
engine = RDFaWriter::RenderEngine.new(rdf, debug) do |engine|
|
38
|
-
engine.graph_name = rdf.context
|
40
|
+
#engine.graph_name = nil #was: rdf.context
|
39
41
|
engine.base_uri = base_uri
|
40
42
|
engine.standard_prefixes = true
|
41
43
|
engine.template_handler = templates
|
@@ -53,10 +55,15 @@ module RoadForest
|
|
53
55
|
prefixes[prefix.to_sym] = prefixes[prefix]
|
54
56
|
end
|
55
57
|
engine.prefixes.merge! prefixes
|
56
|
-
|
57
|
-
|
58
|
+
engine.prefixes.keys.each do |key|
|
59
|
+
if key.is_a? String
|
60
|
+
engine.prefixes[key.to_sym] = engine.prefixes.delete(key)
|
61
|
+
end
|
62
|
+
end
|
58
63
|
|
59
64
|
result = engine.render_document
|
65
|
+
#puts "\n#{__FILE__}:#{__LINE__} => \n#{debug.join("\n")}"
|
66
|
+
return result
|
60
67
|
end
|
61
68
|
|
62
69
|
def network_to_local(base_uri, source)
|
@@ -50,28 +50,68 @@ module RoadForest
|
|
50
50
|
else
|
51
51
|
@purpose = purpose
|
52
52
|
end
|
53
|
+
@sequence = NameSequence.new
|
53
54
|
@classes = {}
|
54
55
|
end
|
55
56
|
|
57
|
+
require 'tsort'
|
58
|
+
class NameSequence
|
59
|
+
include TSort
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
@nodes = Hash.new do |h,k|
|
63
|
+
h[k] = []
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def add(before, after)
|
68
|
+
@nodes[before] << after
|
69
|
+
end
|
70
|
+
|
71
|
+
def exists(node)
|
72
|
+
@nodes[node] ||= []
|
73
|
+
end
|
74
|
+
|
75
|
+
def tsort_each_node(&block)
|
76
|
+
@nodes.each_key(&block)
|
77
|
+
end
|
78
|
+
|
79
|
+
def tsort_each_child(node, &block)
|
80
|
+
@nodes.fetch(node).each(&block)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# @yield each class in name order
|
56
85
|
def map_classes
|
57
86
|
names.map do |name|
|
58
|
-
|
87
|
+
begin
|
88
|
+
yield get(name)
|
89
|
+
rescue UndefinedClass
|
90
|
+
warn "undefined name: #{name} used in sequencing"
|
91
|
+
end
|
59
92
|
end
|
60
93
|
end
|
61
94
|
|
95
|
+
def names
|
96
|
+
@sequence.tsort
|
97
|
+
end
|
98
|
+
|
62
99
|
def add(name, klass)
|
100
|
+
@sequence.exists(name.to_sym)
|
63
101
|
@classes[name.to_sym] = klass
|
64
102
|
@classes[name.to_s] = klass
|
65
103
|
end
|
66
104
|
|
67
|
-
def
|
68
|
-
@
|
105
|
+
def seq(before, after)
|
106
|
+
@sequence.add(before.to_sym, after.to_sym)
|
69
107
|
end
|
70
108
|
|
109
|
+
class UndefinedClass < StandardError; end
|
110
|
+
|
71
111
|
def get(name)
|
72
112
|
@classes.fetch(name)
|
73
113
|
rescue KeyError
|
74
|
-
raise "No #@purpose class registered as name: #{name.inspect} (there are: #{names.inspect})"
|
114
|
+
raise UndefinedClass, "No #@purpose class registered as name: #{name.inspect} (there are: #{names.inspect})"
|
75
115
|
end
|
76
116
|
end
|
77
117
|
end
|
@@ -4,7 +4,24 @@ require 'roadforest/application'
|
|
4
4
|
|
5
5
|
describe RoadForest::Augment::Affordance do
|
6
6
|
let :test_interface do
|
7
|
-
Class.new(RoadForest::Interface::RDF)
|
7
|
+
Class.new(RoadForest::Interface::RDF) do |klass|
|
8
|
+
def update_payload
|
9
|
+
payload_pair do |root_node, graph|
|
10
|
+
seg1 = ::RDF::Node.new
|
11
|
+
graph << [ root_node, Path.forward, seg1 ]
|
12
|
+
graph << [ seg1, Path.predicate, EX.b ]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_payload
|
17
|
+
payload_pair do |root_node, graph|
|
18
|
+
seg1 = ::RDF::Node.new
|
19
|
+
graph << [ root_node, Path.forward, seg1 ]
|
20
|
+
graph << [ seg1, Path.predicate, EX.val ]
|
21
|
+
graph << [ seg1, Path.type, ::RDF::XSD.integer ]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
8
25
|
end
|
9
26
|
|
10
27
|
let :other_test_interface do
|
@@ -12,11 +29,17 @@ describe RoadForest::Augment::Affordance do
|
|
12
29
|
end
|
13
30
|
|
14
31
|
Af = RoadForest::Graph::Af
|
32
|
+
Path = RoadForest::Graph::Path
|
15
33
|
|
16
34
|
class EX < RDF::Vocabulary("http://example.com/"); end
|
17
35
|
|
18
36
|
let :service_host do
|
19
|
-
RoadForest::Application::ServicesHost.new
|
37
|
+
RoadForest::Application::ServicesHost.new.tap do |services|
|
38
|
+
services.root_url = "http://example.com/a"
|
39
|
+
|
40
|
+
services.router.add :test, ["a"], :parent, test_interface
|
41
|
+
services.router.add :nest, ["a", "b", :id], :leaf, other_test_interface
|
42
|
+
end
|
20
43
|
end
|
21
44
|
|
22
45
|
let :content_engine do
|
@@ -24,24 +47,11 @@ describe RoadForest::Augment::Affordance do
|
|
24
47
|
end
|
25
48
|
|
26
49
|
let :application do
|
27
|
-
|
28
|
-
app.stub(:services).and_return(service_host)
|
29
|
-
app.stub(:default_content_engine).and_return(content_engine)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
let :router do
|
34
|
-
RoadForest::Dispatcher.new(application).tap do |router|
|
35
|
-
router.add :test, ["a"], :parent, test_interface
|
36
|
-
router.add :nest, ["a", "b", :id], :leaf, other_test_interface
|
37
|
-
end
|
50
|
+
RoadForest::Application.new(service_host)
|
38
51
|
end
|
39
52
|
|
40
53
|
let :augmenter do
|
41
|
-
RoadForest::Augment::Augmenter.new
|
42
|
-
augmenter.router = router
|
43
|
-
augmenter.canonical_uri = Addressable::URI.parse("http://example.com/a")
|
44
|
-
end
|
54
|
+
RoadForest::Augment::Augmenter.new(service_host)
|
45
55
|
end
|
46
56
|
|
47
57
|
subject :augmented_graph do
|
@@ -59,6 +69,9 @@ describe RoadForest::Augment::Affordance do
|
|
59
69
|
subject.should match_query {
|
60
70
|
pattern [:node, RDF.type, Af.Update]
|
61
71
|
pattern [:node, Af.target, EX.a]
|
72
|
+
pattern [:node, Af.payload, :payload_root ]
|
73
|
+
pattern [:payload_root, Path.forward, :seg1 ]
|
74
|
+
pattern [:seg1, Path.predicate, EX.b ]
|
62
75
|
}
|
63
76
|
end
|
64
77
|
|
@@ -66,10 +79,24 @@ describe RoadForest::Augment::Affordance do
|
|
66
79
|
subject.should match_query {
|
67
80
|
pattern [:node, RDF.type, Af.Create]
|
68
81
|
pattern [:node, Af.target, EX.a]
|
82
|
+
pattern [:node, Af.payload, :payload_root ]
|
83
|
+
pattern [:payload_root, Path.forward, :seg1 ]
|
84
|
+
pattern [:seg1, Path.predicate, EX.val ]
|
69
85
|
}
|
70
86
|
end
|
71
87
|
|
72
|
-
it "should add
|
73
|
-
|
88
|
+
it "should add Remove affordance" do
|
89
|
+
subject.should match_query {
|
90
|
+
pattern [:node, RDF.type, Af.Remove ]
|
91
|
+
pattern [:node, Af.target, EX.a ]
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should add Navigate affordance to child" do
|
96
|
+
subject.should match_query {
|
97
|
+
pattern [:node, RDF.type, Af.Navigate ]
|
98
|
+
pattern [:node, Af.target, EX["a/b/1"] ]
|
99
|
+
}
|
100
|
+
end
|
74
101
|
end
|
75
102
|
end
|