roadforest 0.1 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/examples/file-management.rb +12 -13
  3. data/lib/roadforest-client.rb +3 -0
  4. data/lib/roadforest-common.rb +2 -0
  5. data/lib/roadforest-server.rb +7 -0
  6. data/lib/roadforest-testing.rb +1 -0
  7. data/lib/roadforest/application.rb +9 -7
  8. data/lib/roadforest/application/dispatcher.rb +39 -63
  9. data/lib/roadforest/application/parameters.rb +1 -1
  10. data/lib/roadforest/application/path-provider.rb +2 -2
  11. data/lib/roadforest/application/route-adapter.rb +130 -18
  12. data/lib/roadforest/application/services-host.rb +0 -4
  13. data/lib/roadforest/augment/affordance.rb +78 -0
  14. data/lib/roadforest/augment/augmentation.rb +97 -0
  15. data/lib/roadforest/augment/augmenter.rb +54 -0
  16. data/lib/roadforest/augmentations.rb +1 -0
  17. data/lib/roadforest/content-handling.rb +1 -0
  18. data/lib/roadforest/content-handling/common-engines.rb +67 -0
  19. data/lib/roadforest/content-handling/engine.rb +2 -14
  20. data/lib/roadforest/content-handling/handler-wrap.rb +29 -31
  21. data/lib/roadforest/content-handling/media-type.rb +6 -0
  22. data/lib/roadforest/{rdf.rb → graph.rb} +1 -1
  23. data/lib/roadforest/{rdf → graph}/access-manager.rb +12 -74
  24. data/lib/roadforest/{rdf → graph}/document.rb +1 -1
  25. data/lib/roadforest/{rdf → graph}/etagging.rb +2 -2
  26. data/lib/roadforest/{rdf → graph}/focus-list.rb +1 -9
  27. data/lib/roadforest/{rdf → graph}/graph-copier.rb +2 -2
  28. data/lib/roadforest/{rdf → graph}/graph-focus.rb +5 -7
  29. data/lib/roadforest/{rdf → graph}/normalization.rb +1 -1
  30. data/lib/roadforest/{rdf → graph}/post-focus.rb +2 -3
  31. data/lib/roadforest/graph/vocabulary.rb +96 -0
  32. data/lib/roadforest/http/graph-transfer.rb +2 -2
  33. data/lib/roadforest/interface/application.rb +145 -0
  34. data/lib/roadforest/interface/blob.rb +38 -0
  35. data/lib/roadforest/interface/rdf.rb +77 -0
  36. data/lib/roadforest/interfaces.rb +2 -0
  37. data/lib/roadforest/remote-host.rb +17 -17
  38. data/lib/roadforest/resource.rb +4 -0
  39. data/lib/roadforest/resource/{rdf/leaf-item.rb → leaf-item.rb} +1 -1
  40. data/lib/roadforest/resource/{rdf/list.rb → list.rb} +1 -1
  41. data/lib/roadforest/resource/{rdf/parent-item.rb → parent-item.rb} +1 -1
  42. data/lib/roadforest/resource/{rdf/read-only.rb → read-only.rb} +18 -18
  43. data/lib/roadforest/resource/role/has-children.rb +1 -1
  44. data/lib/roadforest/resource/role/writable.rb +2 -2
  45. data/lib/roadforest/server.rb +1 -1
  46. data/lib/roadforest/source-rigor.rb +9 -0
  47. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence-annealer.rb +2 -2
  48. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence.rb +5 -5
  49. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/any.rb +1 -1
  50. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/none-if-role-absent.rb +1 -1
  51. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/role-if-available.rb +1 -1
  52. data/lib/roadforest/source-rigor/engine.rb +45 -0
  53. data/lib/roadforest/{rdf → source-rigor}/graph-store.rb +9 -9
  54. data/lib/roadforest/{rdf/source-rigor → source-rigor}/http-investigator.rb +2 -2
  55. data/lib/roadforest/{rdf → source-rigor}/investigation.rb +2 -2
  56. data/lib/roadforest/{rdf/source-rigor → source-rigor}/investigator.rb +3 -3
  57. data/lib/roadforest/{rdf/source-rigor → source-rigor}/null-investigator.rb +3 -2
  58. data/lib/roadforest/{rdf → source-rigor}/parcel.rb +5 -5
  59. data/lib/roadforest/{rdf → source-rigor}/resource-pattern.rb +6 -6
  60. data/lib/roadforest/{rdf → source-rigor}/resource-query.rb +2 -2
  61. data/lib/roadforest/source-rigor/rigorous-access.rb +101 -0
  62. data/lib/roadforest/templates/affordance-doc.haml +23 -0
  63. data/lib/roadforest/templates/affordance-property-values.haml +13 -0
  64. data/lib/roadforest/templates/affordance-subject.haml +9 -0
  65. data/lib/roadforest/templates/affordance-uri-object.haml +2 -0
  66. data/lib/roadforest/templates/base/{property_value.haml → property-value.haml} +0 -0
  67. data/lib/roadforest/templates/base/{property_values.haml → property-values.haml} +0 -0
  68. data/lib/roadforest/templates/distiller/{property_value.haml → property-value.haml} +0 -0
  69. data/lib/roadforest/templates/distiller/{property_values.haml → property-values.haml} +0 -0
  70. data/lib/roadforest/templates/min/{property_values.haml → property-values.haml} +0 -0
  71. data/lib/roadforest/templates/rdfpost-curie.haml +6 -0
  72. data/lib/roadforest/test-support/dispatcher-facade.rb +2 -0
  73. data/lib/roadforest/test-support/matchers.rb +169 -5
  74. data/lib/roadforest/test-support/remote-host.rb +2 -2
  75. data/lib/roadforest/type-handlers/handler.rb +74 -0
  76. data/lib/roadforest/type-handlers/jsonld.rb +34 -0
  77. data/lib/roadforest/type-handlers/rdf-handler.rb +36 -0
  78. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer.rb +2 -2
  79. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/document-environment.rb +9 -8
  80. data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +312 -0
  81. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/object-environment.rb +3 -3
  82. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/property-environment.rb +5 -11
  83. data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +427 -0
  84. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/render-environment.rb +33 -26
  85. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/subject-environment.rb +7 -23
  86. data/lib/roadforest/type-handlers/rdfa.rb +73 -0
  87. data/lib/roadforest/type-handlers/rdfpost.rb +301 -0
  88. data/lib/roadforest/utility/class-registry.rb +23 -5
  89. data/spec/.ctrlp-root +0 -0
  90. data/spec/affordance-augmenter.rb +75 -0
  91. data/spec/affordances-flow.rb +438 -0
  92. data/spec/authorization.rb +34 -0
  93. data/spec/client.rb +13 -12
  94. data/spec/credence-annealer.rb +5 -5
  95. data/spec/focus-list.rb +8 -8
  96. data/spec/full-integration.rb +3 -3
  97. data/spec/graph-copier.rb +4 -4
  98. data/spec/graph-store.rb +19 -31
  99. data/spec/keychain.rb +82 -0
  100. data/spec/rdf-normalization.rb +2 -2
  101. data/spec/rdf-parcel.rb +3 -3
  102. data/spec/rdfa-handler.rb +514 -0
  103. data/spec/rdfpost.rb +96 -0
  104. data/spec/source-rigor.rb +57 -0
  105. data/spec/update-focus.rb +11 -10
  106. metadata +91 -66
  107. data/lib/roadforest/blob-model.rb +0 -53
  108. data/lib/roadforest/content-handling/type-handler.rb +0 -76
  109. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +0 -36
  110. data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +0 -38
  111. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +0 -574
  112. data/lib/roadforest/content-handling/type-handlers/rdfa.rb +0 -175
  113. data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +0 -297
  114. data/lib/roadforest/model.rb +0 -209
  115. data/lib/roadforest/models.rb +0 -2
  116. data/lib/roadforest/rdf/source-rigor.rb +0 -44
  117. data/lib/roadforest/rdf/vocabulary.rb +0 -11
  118. data/lib/roadforest/resource/http/form-parsing.rb +0 -81
  119. data/lib/roadforest/resource/rdf.rb +0 -4
  120. data/spec/form-parsing.rb +0 -1
@@ -21,6 +21,14 @@ module RoadForest
21
21
  end
22
22
  alias [] get
23
23
 
24
+ def all_names
25
+ registrar.registry.names
26
+ end
27
+
28
+ def map_classes(&block)
29
+ registrar.map_classes(&block)
30
+ end
31
+
24
32
  def self.extended(mod)
25
33
  (
26
34
  class << mod; self; end
@@ -32,15 +40,25 @@ module RoadForest
32
40
  end
33
41
  end
34
42
 
35
- def initialize(registrar)
36
- if registrar.respond_to?(:registry_purpose)
37
- @purpose = registrar.registry_purpose
43
+ def initialize(registrar, purpose=nil)
44
+ if purpose.nil?
45
+ if registrar.respond_to?(:registry_purpose)
46
+ @purpose = registrar.registry_purpose
47
+ else
48
+ @purpose = registrar.name
49
+ end
38
50
  else
39
- @purpose = registrar.name
51
+ @purpose = purpose
40
52
  end
41
53
  @classes = {}
42
54
  end
43
55
 
56
+ def map_classes
57
+ names.map do |name|
58
+ yield get(name)
59
+ end
60
+ end
61
+
44
62
  def add(name, klass)
45
63
  @classes[name.to_sym] = klass
46
64
  @classes[name.to_s] = klass
@@ -53,7 +71,7 @@ module RoadForest
53
71
  def get(name)
54
72
  @classes.fetch(name)
55
73
  rescue KeyError
56
- raise "No #@purpose class registered as name: #{name.inspect}"
74
+ raise "No #@purpose class registered as name: #{name.inspect} (there are: #{names.inspect})"
57
75
  end
58
76
  end
59
77
  end
data/spec/.ctrlp-root ADDED
File without changes
@@ -0,0 +1,75 @@
1
+ require 'roadforest/augment/affordance'
2
+ require 'roadforest/interfaces'
3
+ require 'roadforest/application'
4
+
5
+ describe RoadForest::Augment::Affordance do
6
+ let :test_interface do
7
+ Class.new(RoadForest::Interface::RDF)
8
+ end
9
+
10
+ let :other_test_interface do
11
+ Class.new(RoadForest::Interface::RDF)
12
+ end
13
+
14
+ Af = RoadForest::Graph::Af
15
+
16
+ class EX < RDF::Vocabulary("http://example.com/"); end
17
+
18
+ let :service_host do
19
+ RoadForest::Application::ServicesHost.new
20
+ end
21
+
22
+ let :content_engine do
23
+ RoadForest::ContentHandling.rdf_engine
24
+ end
25
+
26
+ 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
38
+ end
39
+
40
+ 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
45
+ end
46
+
47
+ subject :augmented_graph do
48
+ augmenter.augment(graph)
49
+ end
50
+
51
+ describe "simple updateable resource" do
52
+ let :graph do
53
+ RDF::Repository.new.tap do |graph|
54
+ graph << [EX.a, EX.b, EX["a/b/1"]]
55
+ end
56
+ end
57
+
58
+ it "should add Update affordance" do
59
+ subject.should match_query {
60
+ pattern [:node, RDF.type, Af.Update]
61
+ pattern [:node, Af.target, EX.a]
62
+ }
63
+ end
64
+
65
+ it "should add Create affordance" do
66
+ subject.should match_query {
67
+ pattern [:node, RDF.type, Af.Create]
68
+ pattern [:node, Af.target, EX.a]
69
+ }
70
+ end
71
+
72
+ it "should add Delete affordance"
73
+ it "should add Navigable affordance to child"
74
+ end
75
+ end
@@ -0,0 +1,438 @@
1
+ require 'cgi'
2
+ require 'mechanize'
3
+
4
+ require 'rdf'
5
+ require 'rdf/xsd'
6
+ require 'rdf/turtle'
7
+
8
+ require 'roadforest/interfaces'
9
+ require 'roadforest/application'
10
+ require 'roadforest/graph/vocabulary'
11
+ require 'roadforest/augmentations'
12
+ require 'roadforest/content-handling/common-engines'
13
+ require 'roadforest/type-handlers/rdfpost'
14
+ require 'roadforest/type-handlers/rdfa'
15
+
16
+ class EX < RDF::Vocabulary("http://example.com/"); end
17
+
18
+ describe "The full affordances flow" do
19
+ Aff = RoadForest::Graph::Af
20
+
21
+ let :service_host do
22
+ RoadForest::Application::ServicesHost.new
23
+ end
24
+
25
+ let :content_engine do
26
+ RoadForest::ContentHandling.rdf_engine
27
+ end
28
+
29
+ let :application do
30
+ double("RoadForest::Application").tap do |app|
31
+ app.stub(:services).and_return(service_host)
32
+ app.stub(:default_content_engine).and_return(content_engine)
33
+ end
34
+ end
35
+
36
+ let :debug do
37
+ []
38
+ end
39
+
40
+ 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
45
+ end
46
+
47
+ let :rdfa do
48
+ serialize(complete_graph, :haml_options => {:ugly => false})
49
+ end
50
+
51
+ before(:all) do
52
+ @valise = Valise.define do
53
+ ro up_to("spec") + "../lib/roadforest"
54
+ end
55
+
56
+ @tilt_cache = ::Tilt::Cache.new
57
+ end
58
+
59
+ # Heuristically detect the input stream
60
+ def detect_format(stream)
61
+ # Got to look into the file to see
62
+ if stream.is_a?(IO) || stream.is_a?(StringIO)
63
+ stream.rewind
64
+ string = stream.read(1000)
65
+ stream.rewind
66
+ else
67
+ string = stream.to_s
68
+ end
69
+ case string
70
+ when /<html/i then RDF::RDFa::Reader
71
+ when /@prefix/i then RDF::Turtle::Reader
72
+ else RDF::NTriples::Reader
73
+ end
74
+ end
75
+
76
+ def parse(input, options = {})
77
+ reader_class = RDF::Reader.for(options[:format]) if options[:format]
78
+ reader_class ||= options.fetch(:reader, RDF::Reader.for(detect_format(input)))
79
+
80
+ graph = RDF::Repository.new
81
+ reader_class.new(input, options).each do |statement|
82
+ graph << statement
83
+ end
84
+ graph
85
+ end
86
+
87
+ # Serialize @graph to a string and compare against regexps
88
+ def serialize(graph, options = {})
89
+
90
+ options = {:debug => debug, :standard_prefixes => true}.merge(options)
91
+ base_uri =
92
+ if options[:base_uri]
93
+ RDF::URI(options[:base_uri])
94
+ else
95
+ nil
96
+ end
97
+
98
+ templates = RoadForest::TypeHandlers::RDFaWriter::TemplateHandler.new
99
+ templates.valise = @valise
100
+ templates.template_cache = @tilt_cache
101
+ templates.style_name = options[:haml]
102
+ templates.haml_options = options[:haml_options]
103
+
104
+ engine = RoadForest::TypeHandlers::RDFaWriter::RenderEngine.new(graph, options[:debug]) do |engine|
105
+ engine.template_handler = templates
106
+ engine.base_uri = base_uri
107
+ engine.lang = options[:lang]
108
+ engine.standard_prefixes = options[:standard_prefixes]
109
+ engine.top_classes = options[:top_classes] || [RDF::RDFS.Class]
110
+ engine.predicate_order = options[:predicate_order] || [RDF.type, RDF::RDFS.label, RDF::DC.title]
111
+ engine.heading_predicates = options[:heading_predicates] || [RDF::RDFS.label, RDF::DC.title]
112
+ end
113
+
114
+ engine.prefixes.merge! options[:prefixes] unless options[:prefixes].nil?
115
+
116
+ # Generate document
117
+ result = engine.render_document
118
+
119
+ puts CGI.escapeHTML(result) if $verbose
120
+ result
121
+ end
122
+
123
+ let :complete_graph do
124
+ RDF::Repository.new.tap do |graph|
125
+ base_graph.each_statement do |stmt|
126
+ graph << stmt
127
+ end
128
+
129
+ affordance_graph.each_statement do |stmt|
130
+ graph << stmt
131
+ end
132
+ end
133
+ end
134
+
135
+ shared_context "written to RDFa" do
136
+ subject do
137
+ rdfa
138
+ end
139
+
140
+ let :put_uri do
141
+ EX.a.join("put").to_s
142
+ end
143
+
144
+ it "should parse RDFa back to base_graph" do
145
+ #XXX subject isn't right here...
146
+ parse(subject, :format => :rdfa).should be_equivalent_graph(base_graph, :trace => debug)
147
+ end
148
+ end
149
+
150
+ shared_context "affordance augmentation" do
151
+ subject :augmented_graph do
152
+ augmenter.augment(base_graph)
153
+ end
154
+
155
+ it{ should be_equivalent_graph(complete_graph) }
156
+ end
157
+
158
+ shared_context "resubmitted RDFPOST" do
159
+ let :mechanize do
160
+ Mechanize.new
161
+ end
162
+
163
+ let :base_url do
164
+ EX.a
165
+ end
166
+
167
+ let :form do
168
+ Mechanize::Page.new(base_url, nil, rdfa, nil, mechanize).forms.first
169
+ end
170
+
171
+ let :post_data do
172
+ form.request_data
173
+ end
174
+
175
+ subject :received_graph do
176
+ RDF::Repository.new.tap do |graph|
177
+ list = URI::decode_www_form(post_data)
178
+ RoadForest::TypeHandlers::RDFPost::Reader.new(list).each_statement do |stmt|
179
+ graph.insert(stmt)
180
+ end
181
+ end
182
+ end
183
+
184
+ it{ should be_equivalent_graph(base_graph) }
185
+ end
186
+
187
+ #Needed tests
188
+ # 3 levels nesting of subject pred subject pred subject (tricky in terms
189
+ # of RDFPOST repetition) Each subject needs literal terms
190
+ #
191
+ #Non-afforded subject, property with afforded subject
192
+ # (Currently, forms are only produced by document)
193
+
194
+ #Proper affordances on parents and children
195
+ #
196
+ #Affordance payloads
197
+ #
198
+ #Parameterized navigations
199
+ #
200
+ #Embed affordances
201
+ #
202
+ #Re-routing + method support resources (i.e.
203
+ # POST other/route/put -> PUT other/route )
204
+
205
+ describe "a resource that refers to another resource" do
206
+ class TestInterface < RoadForest::Interface::RDF
207
+ end
208
+
209
+ let :router do
210
+ RoadForest::Dispatcher.new(application).tap do |router|
211
+ router.add :test, ["a"], :parent, TestInterface
212
+ router.add :target, ["z"], :parent, TestInterface
213
+ end
214
+ end
215
+
216
+ let :base_graph do
217
+ RDF::Repository.new.tap do |graph|
218
+ graph << [EX.a, EX.b, EX.z]
219
+ end
220
+ end
221
+
222
+ let :affordance_graph do
223
+ caff = ::RDF::Node.new(:caff)
224
+ uaff = ::RDF::Node.new(:uaff)
225
+ naff = ::RDF::Node.new(:naff)
226
+ onaff = ::RDF::Node.new(:onaff)
227
+ daff = ::RDF::Node.new(:daff)
228
+
229
+ RDF::Repository.new.tap do |graph|
230
+ graph << [caff, ::RDF.type, Aff.Update]
231
+ graph << [caff, Aff.target, EX.a]
232
+ graph << [uaff, ::RDF.type, Aff.Create]
233
+ graph << [uaff, Aff.target, EX.a]
234
+ graph << [daff, ::RDF.type, Aff.Remove]
235
+ graph << [daff, Aff.target, EX.a]
236
+ graph << [naff, ::RDF.type, Aff.Navigate]
237
+ graph << [naff, Aff.target, EX.a]
238
+ graph << [onaff, ::RDF.type, Aff.Navigate]
239
+ graph << [onaff, Aff.target, EX.z]
240
+ end
241
+ end
242
+
243
+ it_behaves_like "written to RDFa"
244
+ it_behaves_like "affordance augmentation"
245
+ it_behaves_like "resubmitted RDFPOST"
246
+ end
247
+
248
+ describe "a resource that refers to a foreign IRI" do
249
+ class TestInterface < RoadForest::Interface::RDF
250
+ end
251
+
252
+ let :router do
253
+ RoadForest::Dispatcher.new(application).tap do |router|
254
+ router.add :test, ["a"], :parent, TestInterface
255
+ end
256
+ end
257
+
258
+ let :base_graph do
259
+ RDF::Repository.new.tap do |graph|
260
+ graph << [EX.a, EX.b, RDF::Resource.new("http://google.com/help")]
261
+ end
262
+ end
263
+
264
+ let :affordance_graph do
265
+ caff = ::RDF::Node.new(:caff)
266
+ uaff = ::RDF::Node.new(:uaff)
267
+ naff = ::RDF::Node.new(:naff)
268
+ daff = ::RDF::Node.new(:daff)
269
+ zaff = ::RDF::Node.new(:zaff)
270
+
271
+ RDF::Repository.new.tap do |graph|
272
+ graph << [caff, ::RDF.type, Aff.Update]
273
+ graph << [caff, Aff.target, EX.a]
274
+ graph << [uaff, ::RDF.type, Aff.Create]
275
+ graph << [uaff, Aff.target, EX.a]
276
+ graph << [daff, ::RDF.type, Aff.Remove]
277
+ graph << [daff, Aff.target, EX.a]
278
+ graph << [naff, ::RDF.type, Aff.Navigate]
279
+ graph << [naff, Aff.target, EX.a]
280
+ end
281
+ end
282
+
283
+ it_behaves_like "written to RDFa"
284
+ it_behaves_like "affordance augmentation"
285
+ it_behaves_like "resubmitted RDFPOST"
286
+ end
287
+
288
+ describe "a resource that refers to a unserved IRI" do
289
+ class TestInterface < RoadForest::Interface::RDF
290
+ end
291
+
292
+ let :router do
293
+ RoadForest::Dispatcher.new(application).tap do |router|
294
+ router.add :test, ["a"], :parent, TestInterface
295
+ end
296
+ end
297
+
298
+ let :base_graph do
299
+ RDF::Repository.new.tap do |graph|
300
+ graph << [EX.a, EX.b, EX.z]
301
+ end
302
+ end
303
+
304
+ let :affordance_graph do
305
+ caff = ::RDF::Node.new(:caff)
306
+ uaff = ::RDF::Node.new(:uaff)
307
+ naff = ::RDF::Node.new(:naff)
308
+ daff = ::RDF::Node.new(:daff)
309
+ zaff = ::RDF::Node.new(:zaff)
310
+
311
+ RDF::Repository.new.tap do |graph|
312
+ graph << [caff, ::RDF.type, Aff.Update]
313
+ graph << [caff, Aff.target, EX.a]
314
+ graph << [uaff, ::RDF.type, Aff.Create]
315
+ graph << [uaff, Aff.target, EX.a]
316
+ graph << [daff, ::RDF.type, Aff.Remove]
317
+ graph << [daff, Aff.target, EX.a]
318
+ graph << [naff, ::RDF.type, Aff.Navigate]
319
+ graph << [naff, Aff.target, EX.a]
320
+ graph << [zaff, ::RDF.type, Aff.Null]
321
+ graph << [zaff, Aff.target, EX.z]
322
+ end
323
+ end
324
+
325
+ it_behaves_like "written to RDFa"
326
+ it_behaves_like "affordance augmentation"
327
+ it_behaves_like "resubmitted RDFPOST"
328
+ end
329
+
330
+ describe "a resource that refers to a blob" do
331
+ class TestInterface < RoadForest::Interface::RDF
332
+ end
333
+
334
+ class Blobby < RoadForest::Interface::Blob
335
+ end
336
+
337
+ let :router do
338
+ RoadForest::Dispatcher.new(application).tap do |router|
339
+ router.add :test, ["a"], :parent, TestInterface
340
+ router.add :blob, ["z"], :leaf, RoadForest::Interface::Blob do |route|
341
+ route.content_engine = RoadForest::ContentHandling.images_engine
342
+ end
343
+ end
344
+ end
345
+
346
+ let :base_graph do
347
+ RDF::Repository.new.tap do |graph|
348
+ graph << [EX.a, EX.b, EX.z]
349
+ end
350
+ end
351
+
352
+ let :affordance_graph do
353
+ caff = ::RDF::Node.new(:caff)
354
+ uaff = ::RDF::Node.new(:uaff)
355
+ naff = ::RDF::Node.new(:naff)
356
+ daff = ::RDF::Node.new(:daff)
357
+ eaff = ::RDF::Node.new(:eaff)
358
+
359
+ RDF::Repository.new.tap do |graph|
360
+ graph << [caff, ::RDF.type, Aff.Update]
361
+ graph << [caff, Aff.target, EX.a]
362
+ graph << [uaff, ::RDF.type, Aff.Create]
363
+ graph << [uaff, Aff.target, EX.a]
364
+ graph << [daff, ::RDF.type, Aff.Remove]
365
+ graph << [daff, Aff.target, EX.a]
366
+ graph << [naff, ::RDF.type, Aff.Navigate]
367
+ graph << [naff, Aff.target, EX.a]
368
+ graph << [eaff, ::RDF.type, Aff.Embed]
369
+ graph << [eaff, Aff.target, EX.z]
370
+ end
371
+ end
372
+
373
+ it_behaves_like "written to RDFa"
374
+ it_behaves_like "affordance augmentation"
375
+ it_behaves_like "resubmitted RDFPOST"
376
+ end
377
+
378
+ describe "simple updateable resource" do
379
+ class TestInterface < RoadForest::Interface::RDF
380
+ end
381
+
382
+ let :router do
383
+ RoadForest::Dispatcher.new(application).tap do |router|
384
+ router.add :test, ["a"], :parent, TestInterface
385
+ end
386
+ end
387
+
388
+ let :base_graph do
389
+ RDF::Repository.new.tap do |graph|
390
+ graph << [EX.a, EX.b, 17]
391
+ end
392
+ end
393
+
394
+ let :affordance_graph do
395
+ caff = ::RDF::Node.new(:caff)
396
+ uaff = ::RDF::Node.new(:uaff)
397
+ naff = ::RDF::Node.new(:naff)
398
+ daff = ::RDF::Node.new(:daff)
399
+
400
+ RDF::Repository.new.tap do |graph|
401
+ graph << [caff, ::RDF.type, Aff.Update]
402
+ graph << [caff, Aff.target, EX.a]
403
+ graph << [uaff, ::RDF.type, Aff.Create]
404
+ graph << [uaff, Aff.target, EX.a]
405
+ graph << [daff, ::RDF.type, Aff.Remove]
406
+ graph << [daff, Aff.target, EX.a]
407
+ graph << [naff, ::RDF.type, Aff.Navigate]
408
+ graph << [naff, Aff.target, EX.a]
409
+ end
410
+ end
411
+
412
+ it_behaves_like "written to RDFa" do
413
+ it { should have_xpath('//form/@action', put_uri) }
414
+ it { should have_xpath("//form[@action='#{put_uri}']/@method", "POST") }
415
+ it { should have_xpath("//form[@action='#{put_uri}']/input[@type='hidden']/@name", "rdf") }
416
+ end
417
+
418
+ it_behaves_like "affordance augmentation" do
419
+ it "should add Update affordance" do
420
+ subject.should match_query {
421
+ pattern [:node, RDF.type, Aff.Update]
422
+ pattern [:node, Aff.target, EX.a]
423
+ }
424
+ end
425
+
426
+ it "should add Create affordance" do
427
+ subject.should match_query {
428
+ pattern [:node, RDF.type, Aff.Create]
429
+ pattern [:node, Aff.target, EX.a]
430
+ }
431
+ end
432
+ #it "should add Delete affordance"
433
+ #it "should add Navigable affordance to child"
434
+ end
435
+
436
+ it_behaves_like "resubmitted RDFPOST"
437
+ end
438
+ end