roadforest 0.1 → 0.5

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.
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