roadforest 0.5 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/examples/file-management.rb +70 -58
  3. data/lib/roadforest/application.rb +9 -17
  4. data/lib/roadforest/application/dispatcher.rb +76 -9
  5. data/lib/roadforest/application/parameters.rb +9 -1
  6. data/lib/roadforest/application/path-provider.rb +30 -3
  7. data/lib/roadforest/application/route-adapter.rb +96 -14
  8. data/lib/roadforest/application/services-host.rb +21 -3
  9. data/lib/roadforest/augment/affordance.rb +82 -11
  10. data/lib/roadforest/augment/augmentation.rb +24 -6
  11. data/lib/roadforest/augment/augmenter.rb +12 -3
  12. data/lib/roadforest/authorization.rb +7 -229
  13. data/lib/roadforest/authorization/auth-entity.rb +26 -0
  14. data/lib/roadforest/authorization/authentication-chain.rb +79 -0
  15. data/lib/roadforest/authorization/default-authentication-store.rb +33 -0
  16. data/lib/roadforest/authorization/grant-builder.rb +23 -0
  17. data/lib/roadforest/authorization/grants-holder.rb +58 -0
  18. data/lib/roadforest/authorization/manager.rb +85 -0
  19. data/lib/roadforest/authorization/policy.rb +19 -0
  20. data/lib/roadforest/graph/access-manager.rb +25 -2
  21. data/lib/roadforest/graph/focus-list.rb +4 -0
  22. data/lib/roadforest/graph/graph-focus.rb +30 -13
  23. data/lib/roadforest/graph/nav-affordance-builder.rb +62 -0
  24. data/lib/roadforest/graph/normalization.rb +3 -3
  25. data/lib/roadforest/graph/path-vocabulary.rb +64 -0
  26. data/lib/roadforest/graph/post-focus.rb +5 -0
  27. data/lib/roadforest/graph/vocabulary.rb +4 -1
  28. data/lib/roadforest/http/adapters/excon.rb +4 -0
  29. data/lib/roadforest/http/graph-transfer.rb +17 -1
  30. data/lib/roadforest/http/keychain.rb +121 -33
  31. data/lib/roadforest/http/user-agent.rb +5 -3
  32. data/lib/roadforest/interface/application.rb +25 -8
  33. data/lib/roadforest/interface/rdf.rb +114 -15
  34. data/lib/roadforest/interface/utility.rb +3 -0
  35. data/lib/roadforest/interface/utility/backfill.rb +63 -0
  36. data/lib/roadforest/interface/utility/grant-list.rb +45 -0
  37. data/lib/roadforest/interface/utility/grant.rb +22 -0
  38. data/lib/roadforest/interfaces.rb +1 -0
  39. data/lib/roadforest/path-matcher.rb +471 -0
  40. data/lib/roadforest/remote-host.rb +159 -35
  41. data/lib/roadforest/resource/read-only.rb +23 -4
  42. data/lib/roadforest/server.rb +32 -3
  43. data/lib/roadforest/source-rigor/graph-store.rb +0 -2
  44. data/lib/roadforest/source-rigor/rigorous-access.rb +138 -21
  45. data/lib/roadforest/templates/affordance-property-values.haml +3 -0
  46. data/lib/roadforest/templates/rdfpost-curie.haml +1 -1
  47. data/lib/roadforest/test-support/matchers.rb +41 -12
  48. data/lib/roadforest/test-support/remote-host.rb +3 -3
  49. data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +1 -1
  50. data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +40 -27
  51. data/lib/roadforest/type-handlers/rdfa.rb +10 -3
  52. data/lib/roadforest/utility/class-registry.rb +44 -4
  53. data/spec/affordance-augmenter.rb +46 -19
  54. data/spec/affordances-flow.rb +46 -30
  55. data/spec/authorization.rb +16 -4
  56. data/spec/client.rb +22 -4
  57. data/spec/focus-list.rb +24 -0
  58. data/spec/full-integration.rb +8 -3
  59. data/spec/graph-store.rb +8 -0
  60. data/spec/keychain.rb +18 -14
  61. data/spec/rdf-normalization.rb +32 -6
  62. data/spec/update-focus.rb +36 -39
  63. metadata +19 -5
@@ -3,6 +3,9 @@
3
3
  - objects.each do |object|
4
4
  - if object.is_subject?
5
5
  = rdfpost_curie("o", object.subject)
6
+ %label{}
7
+ %span= get_predicate_name(predicate)
8
+ %input{object.attrs.merge(:readonly => true)}
6
9
  - elsif object.attrs.empty?
7
10
  = yield(object)
8
11
  - else
@@ -1,5 +1,5 @@
1
1
  - if reduced?
2
- - unless prefix.empty?
2
+ - unless prefix.nil? or prefix.empty?
3
3
  %input{type: "hidden", name: "#{kind}n", value: prefix}
4
4
  %input{type: "hidden", name: "#{kind}v", value: suffix}
5
5
  - else
@@ -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(actual)
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(actual)
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(actual)
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
- "expected #{@query.patterns.inspect} to return solutions on \n#{@actual.dump(:nquads)}\n but didn't"
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
- "expected #{@query.patterns.inspect} not to return solutions on \n#{@actual.dump(:nquads)}\n but does"
185
- end
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(app)
7
- @app = app
8
- super(app.canonical_host)
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
@@ -264,7 +264,7 @@ module RoadForest
264
264
 
265
265
  def attrs
266
266
  _decorated_.attrs.merge(
267
- :method => "POST", :action => subject.join("put")
267
+ :method => "POST", :action => subject / "put"
268
268
  )
269
269
  end
270
270
  end
@@ -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
- config.add_type("haml", { :template_cache => template_cache, :template_options => haml_options || {:ugly => true} })
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
- message = message + yield if block_given?
109
- msg = "#{' ' * @debug_indent}#{message}"
110
- RoadForest::debug(msg)
111
- @debug << msg.force_encoding("utf-8") if @debug.is_a?(Array)
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}): uri_to_term_or_curie #{@uri_to_term_or_curie[uri].inspect}"}
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
- template.render(context) do |item|
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 || (l = RDF::List.new(object, @graph)).invalid?)
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
- #$stderr.puts debug
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
- yield get(name)
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 names
68
- @classes.keys.select{|key| key.is_a? Symbol}
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
- double("RoadForest::Application").tap do |app|
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.tap do |augmenter|
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 Delete affordance"
73
- it "should add Navigable affordance to child"
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