roadforest 0.1 → 0.5
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 +12 -13
- data/lib/roadforest-client.rb +3 -0
- data/lib/roadforest-common.rb +2 -0
- data/lib/roadforest-server.rb +7 -0
- data/lib/roadforest-testing.rb +1 -0
- data/lib/roadforest/application.rb +9 -7
- data/lib/roadforest/application/dispatcher.rb +39 -63
- data/lib/roadforest/application/parameters.rb +1 -1
- data/lib/roadforest/application/path-provider.rb +2 -2
- data/lib/roadforest/application/route-adapter.rb +130 -18
- data/lib/roadforest/application/services-host.rb +0 -4
- data/lib/roadforest/augment/affordance.rb +78 -0
- data/lib/roadforest/augment/augmentation.rb +97 -0
- data/lib/roadforest/augment/augmenter.rb +54 -0
- data/lib/roadforest/augmentations.rb +1 -0
- data/lib/roadforest/content-handling.rb +1 -0
- data/lib/roadforest/content-handling/common-engines.rb +67 -0
- data/lib/roadforest/content-handling/engine.rb +2 -14
- data/lib/roadforest/content-handling/handler-wrap.rb +29 -31
- data/lib/roadforest/content-handling/media-type.rb +6 -0
- data/lib/roadforest/{rdf.rb → graph.rb} +1 -1
- data/lib/roadforest/{rdf → graph}/access-manager.rb +12 -74
- data/lib/roadforest/{rdf → graph}/document.rb +1 -1
- data/lib/roadforest/{rdf → graph}/etagging.rb +2 -2
- data/lib/roadforest/{rdf → graph}/focus-list.rb +1 -9
- data/lib/roadforest/{rdf → graph}/graph-copier.rb +2 -2
- data/lib/roadforest/{rdf → graph}/graph-focus.rb +5 -7
- data/lib/roadforest/{rdf → graph}/normalization.rb +1 -1
- data/lib/roadforest/{rdf → graph}/post-focus.rb +2 -3
- data/lib/roadforest/graph/vocabulary.rb +96 -0
- data/lib/roadforest/http/graph-transfer.rb +2 -2
- data/lib/roadforest/interface/application.rb +145 -0
- data/lib/roadforest/interface/blob.rb +38 -0
- data/lib/roadforest/interface/rdf.rb +77 -0
- data/lib/roadforest/interfaces.rb +2 -0
- data/lib/roadforest/remote-host.rb +17 -17
- data/lib/roadforest/resource.rb +4 -0
- data/lib/roadforest/resource/{rdf/leaf-item.rb → leaf-item.rb} +1 -1
- data/lib/roadforest/resource/{rdf/list.rb → list.rb} +1 -1
- data/lib/roadforest/resource/{rdf/parent-item.rb → parent-item.rb} +1 -1
- data/lib/roadforest/resource/{rdf/read-only.rb → read-only.rb} +18 -18
- data/lib/roadforest/resource/role/has-children.rb +1 -1
- data/lib/roadforest/resource/role/writable.rb +2 -2
- data/lib/roadforest/server.rb +1 -1
- data/lib/roadforest/source-rigor.rb +9 -0
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence-annealer.rb +2 -2
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence.rb +5 -5
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/any.rb +1 -1
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/none-if-role-absent.rb +1 -1
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/role-if-available.rb +1 -1
- data/lib/roadforest/source-rigor/engine.rb +45 -0
- data/lib/roadforest/{rdf → source-rigor}/graph-store.rb +9 -9
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/http-investigator.rb +2 -2
- data/lib/roadforest/{rdf → source-rigor}/investigation.rb +2 -2
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/investigator.rb +3 -3
- data/lib/roadforest/{rdf/source-rigor → source-rigor}/null-investigator.rb +3 -2
- data/lib/roadforest/{rdf → source-rigor}/parcel.rb +5 -5
- data/lib/roadforest/{rdf → source-rigor}/resource-pattern.rb +6 -6
- data/lib/roadforest/{rdf → source-rigor}/resource-query.rb +2 -2
- data/lib/roadforest/source-rigor/rigorous-access.rb +101 -0
- data/lib/roadforest/templates/affordance-doc.haml +23 -0
- data/lib/roadforest/templates/affordance-property-values.haml +13 -0
- data/lib/roadforest/templates/affordance-subject.haml +9 -0
- data/lib/roadforest/templates/affordance-uri-object.haml +2 -0
- data/lib/roadforest/templates/base/{property_value.haml → property-value.haml} +0 -0
- data/lib/roadforest/templates/base/{property_values.haml → property-values.haml} +0 -0
- data/lib/roadforest/templates/distiller/{property_value.haml → property-value.haml} +0 -0
- data/lib/roadforest/templates/distiller/{property_values.haml → property-values.haml} +0 -0
- data/lib/roadforest/templates/min/{property_values.haml → property-values.haml} +0 -0
- data/lib/roadforest/templates/rdfpost-curie.haml +6 -0
- data/lib/roadforest/test-support/dispatcher-facade.rb +2 -0
- data/lib/roadforest/test-support/matchers.rb +169 -5
- data/lib/roadforest/test-support/remote-host.rb +2 -2
- data/lib/roadforest/type-handlers/handler.rb +74 -0
- data/lib/roadforest/type-handlers/jsonld.rb +34 -0
- data/lib/roadforest/type-handlers/rdf-handler.rb +36 -0
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer.rb +2 -2
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/document-environment.rb +9 -8
- data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +312 -0
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/object-environment.rb +3 -3
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/property-environment.rb +5 -11
- data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +427 -0
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/render-environment.rb +33 -26
- data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/subject-environment.rb +7 -23
- data/lib/roadforest/type-handlers/rdfa.rb +73 -0
- data/lib/roadforest/type-handlers/rdfpost.rb +301 -0
- data/lib/roadforest/utility/class-registry.rb +23 -5
- data/spec/.ctrlp-root +0 -0
- data/spec/affordance-augmenter.rb +75 -0
- data/spec/affordances-flow.rb +438 -0
- data/spec/authorization.rb +34 -0
- data/spec/client.rb +13 -12
- data/spec/credence-annealer.rb +5 -5
- data/spec/focus-list.rb +8 -8
- data/spec/full-integration.rb +3 -3
- data/spec/graph-copier.rb +4 -4
- data/spec/graph-store.rb +19 -31
- data/spec/keychain.rb +82 -0
- data/spec/rdf-normalization.rb +2 -2
- data/spec/rdf-parcel.rb +3 -3
- data/spec/rdfa-handler.rb +514 -0
- data/spec/rdfpost.rb +96 -0
- data/spec/source-rigor.rb +57 -0
- data/spec/update-focus.rb +11 -10
- metadata +91 -66
- data/lib/roadforest/blob-model.rb +0 -53
- data/lib/roadforest/content-handling/type-handler.rb +0 -76
- data/lib/roadforest/content-handling/type-handlers/jsonld.rb +0 -36
- data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +0 -38
- data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +0 -574
- data/lib/roadforest/content-handling/type-handlers/rdfa.rb +0 -175
- data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +0 -297
- data/lib/roadforest/model.rb +0 -209
- data/lib/roadforest/models.rb +0 -2
- data/lib/roadforest/rdf/source-rigor.rb +0 -44
- data/lib/roadforest/rdf/vocabulary.rb +0 -11
- data/lib/roadforest/resource/http/form-parsing.rb +0 -81
- data/lib/roadforest/resource/rdf.rb +0 -4
- data/spec/form-parsing.rb +0 -1
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'rdf'
|
2
2
|
require 'roadforest/debug'
|
3
|
-
require 'roadforest/
|
4
|
-
require 'roadforest/
|
3
|
+
require 'roadforest/graph/vocabulary'
|
4
|
+
require 'roadforest/graph/normalization'
|
5
5
|
|
6
|
-
require 'roadforest/
|
7
|
-
require 'roadforest/
|
6
|
+
require 'roadforest/source-rigor/resource-query'
|
7
|
+
require 'roadforest/source-rigor/resource-pattern'
|
8
8
|
|
9
|
-
module RoadForest
|
10
|
-
class GraphStore
|
11
|
-
include Normalization
|
9
|
+
module RoadForest
|
10
|
+
class SourceRigor::GraphStore
|
11
|
+
include Graph::Normalization
|
12
12
|
|
13
13
|
#The interface supported by ::RDF::Graph
|
14
14
|
include ::RDF::Countable
|
@@ -183,7 +183,7 @@ module RoadForest::RDF
|
|
183
183
|
def query_execute(query, &block)
|
184
184
|
#XXX Weird edge case of GM getting queried with a vanilla RDF::Query...
|
185
185
|
#needs tests, thought
|
186
|
-
query = ResourceQuery.from(query)
|
186
|
+
query = RoadForest::SourceRigor::ResourceQuery.from(query)
|
187
187
|
query.execute(self).filter do |solution|
|
188
188
|
solution.respond_to?(:context) and not solution.context.nil?
|
189
189
|
end.each(&block)
|
@@ -191,7 +191,7 @@ module RoadForest::RDF
|
|
191
191
|
|
192
192
|
def query_pattern(pattern, &block)
|
193
193
|
case pattern
|
194
|
-
when ResourcePattern
|
194
|
+
when RoadForest::SourceRigor::ResourcePattern
|
195
195
|
pattern.execute(@repository, {}, :context_roles => {:local => local_context_node}) do |statement|
|
196
196
|
next if statement.context.nil?
|
197
197
|
yield statement if block_given?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'roadforest/utility/class-registry'
|
2
2
|
|
3
|
-
|
3
|
+
module RoadForest::SourceRigor
|
4
4
|
class NotCredible < StandardError; end
|
5
5
|
class NoCredibleResults < StandardError; end
|
6
6
|
|
@@ -13,5 +13,5 @@ class RoadForest::RDF::SourceRigor
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
|
-
require 'roadforest/
|
17
|
-
require 'roadforest/
|
16
|
+
require 'roadforest/source-rigor/null-investigator'
|
17
|
+
require 'roadforest/source-rigor/http-investigator'
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'roadforest/
|
2
|
-
require 'roadforest/
|
1
|
+
require 'roadforest/graph'
|
2
|
+
require 'roadforest/graph/normalization'
|
3
3
|
|
4
|
-
module RoadForest
|
5
|
-
class Parcel
|
6
|
-
include Normalization
|
4
|
+
module RoadForest
|
5
|
+
class SourceRigor::Parcel
|
6
|
+
include Graph::Normalization
|
7
7
|
|
8
8
|
attr_accessor :graph
|
9
9
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'rdf/query/pattern'
|
2
|
-
require 'roadforest/
|
3
|
-
require 'roadforest/
|
4
|
-
require 'roadforest/
|
2
|
+
require 'roadforest/graph'
|
3
|
+
require 'roadforest/source-rigor/graph-store'
|
4
|
+
require 'roadforest/source-rigor/investigation'
|
5
5
|
|
6
|
-
module RoadForest::
|
6
|
+
module RoadForest::SourceRigor
|
7
7
|
class ResourcePattern < ::RDF::Query::Pattern
|
8
8
|
def self.from(pattern, options)
|
9
9
|
pattern = case pattern
|
@@ -19,7 +19,7 @@ module RoadForest::RDF
|
|
19
19
|
options ||= {}
|
20
20
|
self.new(options.merge(pattern))
|
21
21
|
else
|
22
|
-
raise ArgumentError, "expected RoadForest::
|
22
|
+
raise ArgumentError, "expected RoadForest::SourceRigor::ResourcePattern, RDF::Query::Pattern, RDF::Statement, Hash, or Array, but got #{pattern.inspect}"
|
23
23
|
end
|
24
24
|
|
25
25
|
unless options.nil?
|
@@ -35,7 +35,7 @@ module RoadForest::RDF
|
|
35
35
|
attr_accessor :context_roles, :source_rigor
|
36
36
|
|
37
37
|
def execute(queryable, bindings = nil, query_context_roles = nil, &block)
|
38
|
-
unless queryable.is_a? RoadForest::
|
38
|
+
unless queryable.is_a? RoadForest::SourceRigor::GraphStore
|
39
39
|
return super(queryable, bindings || {}, &block)
|
40
40
|
end
|
41
41
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'roadforest/
|
1
|
+
require 'roadforest/graph'
|
2
2
|
require 'rdf/query'
|
3
3
|
|
4
|
-
module RoadForest::
|
4
|
+
module RoadForest::SourceRigor
|
5
5
|
class ResourceQuery < ::RDF::Query
|
6
6
|
def initialize(patterns = [], options = {}, &block)
|
7
7
|
@subject_context = options[:subject_context]
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'roadforest/graph/access-manager'
|
2
|
+
require 'roadforest/source-rigor/resource-query'
|
3
|
+
require 'roadforest/source-rigor/resource-pattern'
|
4
|
+
require 'roadforest/source-rigor/parcel'
|
5
|
+
|
6
|
+
module RoadForest
|
7
|
+
module SourceRigor
|
8
|
+
module Rigorous
|
9
|
+
attr_accessor :rigor
|
10
|
+
|
11
|
+
def dup
|
12
|
+
other = self.class.allocate
|
13
|
+
other.resource = self.resource
|
14
|
+
other.rigor = self.rigor
|
15
|
+
other.source_graph = self.source_graph
|
16
|
+
|
17
|
+
return other
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_query
|
21
|
+
ResourceQuery.new([], {}) do |query|
|
22
|
+
query.subject_context = resource
|
23
|
+
query.source_rigor = rigor
|
24
|
+
yield query
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def query_execute(query, &block)
|
29
|
+
query = ResourceQuery.from(query, resource, rigor)
|
30
|
+
execute_search(query, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def query_pattern(pattern, &block)
|
34
|
+
pattern = ResourcePattern.from(pattern, {:context_roles => {:subject => resource}, :source_rigor => rigor})
|
35
|
+
execute_search(pattern, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class RetrieveManager < Graph::ReadOnlyManager
|
40
|
+
include Rigorous
|
41
|
+
end
|
42
|
+
|
43
|
+
class PostManager < Graph::WriteManager
|
44
|
+
include Rigorous
|
45
|
+
end
|
46
|
+
|
47
|
+
class UpdateManager < Graph::SplitManager
|
48
|
+
include Rigorous
|
49
|
+
|
50
|
+
def initialize
|
51
|
+
@copied_contexts = {}
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_accessor :copied_contexts
|
55
|
+
|
56
|
+
def dup
|
57
|
+
other = super
|
58
|
+
other.copied_contexts = self.copied_contexts
|
59
|
+
other.target_graph = self.target_graph
|
60
|
+
return other
|
61
|
+
end
|
62
|
+
|
63
|
+
def execute_search(search, &block)
|
64
|
+
enum = search.execute(destination_graph)
|
65
|
+
if enum.any?{ true }
|
66
|
+
enum.each(&block)
|
67
|
+
return enum
|
68
|
+
end
|
69
|
+
search.execute(origin_graph, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def insert(statement)
|
73
|
+
copy_context
|
74
|
+
super
|
75
|
+
end
|
76
|
+
|
77
|
+
def delete(statement)
|
78
|
+
copy_context
|
79
|
+
super
|
80
|
+
end
|
81
|
+
|
82
|
+
def parceller
|
83
|
+
@parceller ||=
|
84
|
+
begin
|
85
|
+
parceller = Parcel.new
|
86
|
+
parceller.graph = source_graph
|
87
|
+
parceller
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def copy_context
|
92
|
+
return if copied_contexts[resource]
|
93
|
+
parceller.graph_for(resource).each_statement do |statement|
|
94
|
+
statement.context = resource
|
95
|
+
destination_graph << statement
|
96
|
+
end
|
97
|
+
copied_contexts[resource] = true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
!!! XML
|
2
|
+
!!! 5
|
3
|
+
%html{:xmlns => "http://www.w3.org/1999/xhtml", :lang => lang, :prefix => prefix}
|
4
|
+
- if base || title
|
5
|
+
%head
|
6
|
+
- if base
|
7
|
+
%base{:href => base}
|
8
|
+
- if title
|
9
|
+
%title= title
|
10
|
+
%body
|
11
|
+
- subjects.each do |subject|
|
12
|
+
- if subject.respond_to? :affordance?
|
13
|
+
%form{subject.attrs}
|
14
|
+
%input{type: "hidden", name: "rdf"}
|
15
|
+
- prefixes.each do |name, target|
|
16
|
+
- unless name.nil? or name.empty?
|
17
|
+
%input{type: "hidden", name: "n", value: name}
|
18
|
+
%input{type: "hidden", name: "v", value: target}
|
19
|
+
|
20
|
+
!= yield(subject)
|
21
|
+
- else
|
22
|
+
%div{subject.attrs}
|
23
|
+
!= yield(subject)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
%div.property
|
2
|
+
= rdfpost_curie("p", predicate)
|
3
|
+
- objects.each do |object|
|
4
|
+
- if object.is_subject?
|
5
|
+
= rdfpost_curie("o", object.subject)
|
6
|
+
- elsif object.attrs.empty?
|
7
|
+
= yield(object)
|
8
|
+
- else
|
9
|
+
%label{object.label_attrs}
|
10
|
+
%span= get_predicate_name(predicate)
|
11
|
+
%input{object.input_attrs(yield(object))}
|
12
|
+
- if(object.type_uri)
|
13
|
+
%input{type: "hidden", name: "lt", value: object.type_uri}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,7 +1,165 @@
|
|
1
|
+
require 'rdf/isomorphic'
|
2
|
+
require 'rspec/matchers'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
class RDF::Repository
|
6
|
+
include RDF::Isomorphic
|
7
|
+
end
|
8
|
+
|
1
9
|
module RoadForest
|
2
10
|
module Testing
|
11
|
+
module HelperMethods
|
12
|
+
def statements_from_graph(graph)
|
13
|
+
StatementsFromGraph.new(graph)
|
14
|
+
end
|
15
|
+
|
16
|
+
def normalize(graph)
|
17
|
+
case graph
|
18
|
+
when RDF::Queryable then graph
|
19
|
+
when IO, StringIO
|
20
|
+
RDF::Graph.new.load(graph, :base_uri => @info.about)
|
21
|
+
else
|
22
|
+
# Figure out which parser to use
|
23
|
+
g = RDF::Graph.new
|
24
|
+
reader_class = detect_format(graph)
|
25
|
+
reader_class.new(graph, :base_uri => @info.about).each {|s| g << s}
|
26
|
+
g
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class BeEquivalentGraph
|
32
|
+
include HelperMethods
|
33
|
+
Info = Struct.new(:about, :num, :trace, :compare, :inputDocument, :outputDocument, :expectedResults, :format, :title)
|
34
|
+
|
35
|
+
def initialize(expected, info)
|
36
|
+
@expected = normalize(expected)
|
37
|
+
|
38
|
+
@info =
|
39
|
+
if info.respond_to?(:about)
|
40
|
+
info
|
41
|
+
elsif info.is_a?(Hash)
|
42
|
+
identifier = expected.is_a?(RDF::Graph) ? expected.context : info[:about]
|
43
|
+
trace = info[:trace]
|
44
|
+
trace = trace.join("\n") if trace.is_a?(Array)
|
45
|
+
i = Info.new(identifier, "0000", trace, info[:compare])
|
46
|
+
i.format = info[:format]
|
47
|
+
i
|
48
|
+
else
|
49
|
+
Info.new(expected.is_a?(RDF::Graph) ? expected.context : info, "0000", info.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
@info.format ||= :ttl
|
53
|
+
end
|
54
|
+
attr_reader :expected, :info
|
55
|
+
|
56
|
+
def matches?(actual)
|
57
|
+
@actual = normalize(actual)
|
58
|
+
@actual.isomorphic_with?(@expected)# rescue false
|
59
|
+
end
|
60
|
+
|
61
|
+
def dump_graph(graph)
|
62
|
+
graph.dump(@info.format, :standard_prefixes => true)
|
63
|
+
rescue
|
64
|
+
begin
|
65
|
+
graph.dump(:nquads, :standard_prefixes => true)
|
66
|
+
rescue
|
67
|
+
graph.inspect
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def description
|
72
|
+
"be equivalent to an expected graph" #graphs tend to be too long to use
|
73
|
+
end
|
74
|
+
|
75
|
+
def failure_message_for_should(actual)
|
76
|
+
info = @info.respond_to?(:about) ? @info.about : @info.inspect
|
77
|
+
if @expected.is_a?(RDF::Graph) && @actual.size != @expected.size
|
78
|
+
"Graph entry count differs:\nexpected: #{@expected.size}\nactual: #{@actual.size}"
|
79
|
+
elsif @expected.is_a?(Array) && @actual.size != @expected.length
|
80
|
+
"Graph entry count differs:\nexpected: #{@expected.length}\nactual: #{@actual.size}"
|
81
|
+
else
|
82
|
+
"Graph differs"
|
83
|
+
end +
|
84
|
+
"\n#{info + "\n" unless info.to_s.empty?}" +
|
85
|
+
(@info.inputDocument ? "Input file: #{@info.inputDocument}\n" : "") +
|
86
|
+
(@info.outputDocument ? "Output file: #{@info.outputDocument}\n" : "") +
|
87
|
+
"\nExpected:\n#{dump_graph(@expected)}" +
|
88
|
+
"\nResults:\n#{dump_graph(@actual)}" +
|
89
|
+
(@info.trace ? "\nDebug:\n#{@info.trace}" : "")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class HaveXpath
|
94
|
+
def initialize(xpath, value, trace)
|
95
|
+
@xpath, @value, @trace = xpath, value, trace
|
96
|
+
end
|
97
|
+
attr_reader :xpath, :value, :trace
|
98
|
+
|
99
|
+
def matches?(actual)
|
100
|
+
@doc = Nokogiri::HTML.parse(actual)
|
101
|
+
@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)
|
103
|
+
case value
|
104
|
+
when false
|
105
|
+
found.nil?
|
106
|
+
when true
|
107
|
+
!found.nil?
|
108
|
+
when Array
|
109
|
+
found.to_s.split(" ").include?(*value)
|
110
|
+
when Regexp
|
111
|
+
found.to_s =~ value
|
112
|
+
else
|
113
|
+
found.to_s == value
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def failure_message_for_should(actual)
|
118
|
+
trace ||= debug
|
119
|
+
msg =
|
120
|
+
case value
|
121
|
+
when true
|
122
|
+
"expected that #{xpath.inspect} would be present\nwas:\n #{found.inspect}\n"
|
123
|
+
when false
|
124
|
+
"expected that #{xpath.inspect} would be absent\nwas:\n #{found.inspect}\n"
|
125
|
+
else
|
126
|
+
"expected that #{xpath.inspect} would be\n #{value.inspect}\nwas:\n #{found.inspect}\n"
|
127
|
+
end
|
128
|
+
msg += "in:\n" + actual.to_s
|
129
|
+
msg += "\nDebug:#{trace.join("\n")}" if trace
|
130
|
+
msg
|
131
|
+
end
|
132
|
+
|
133
|
+
def failure_message_for_should_not(actual)
|
134
|
+
trace ||= debug
|
135
|
+
msg = "expected that #{xpath.inspect} would not be #{value.inspect} in:\n" + actual.to_s
|
136
|
+
msg += "\nDebug:#{trace.join("\n")}" if trace
|
137
|
+
msg
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class Produces
|
142
|
+
def initialize(expected, info)
|
143
|
+
@expected, @info = expected, info
|
144
|
+
end
|
145
|
+
attr_reader :expected, :info
|
146
|
+
|
147
|
+
def matches?(actual)
|
148
|
+
actual == expected
|
149
|
+
end
|
150
|
+
|
151
|
+
def failure_message_for_should(actual)
|
152
|
+
"Expected: #{expected.inspect}\n" +
|
153
|
+
"Actual : #{actual.inspect}\n" +
|
154
|
+
"Processing results:\n#{info.join("\n")}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
3
158
|
class MatchesQuery
|
4
159
|
def initialize(pattern = nil, &block)
|
160
|
+
if pattern.nil? and block.nil?
|
161
|
+
raise "Matches query (e.g. should match_query) created with no patterns: probably used a do block..."
|
162
|
+
end
|
5
163
|
pattern ||= []
|
6
164
|
if Hash === pattern
|
7
165
|
pattern = [pattern]
|
@@ -74,17 +232,23 @@ module RoadForest
|
|
74
232
|
alias that_match_pattern that_match_query
|
75
233
|
end
|
76
234
|
|
77
|
-
module
|
78
|
-
def
|
79
|
-
|
235
|
+
module MatcherMethods
|
236
|
+
def produce(expected, info)
|
237
|
+
Produces.new(expected, info)
|
238
|
+
end
|
239
|
+
|
240
|
+
def have_xpath(xpath, value = true, trace = nil)
|
241
|
+
HaveXpath.new(xpath, value, trace || debug)
|
80
242
|
end
|
81
|
-
end
|
82
243
|
|
83
|
-
module MatcherMethods
|
84
244
|
def match_query(pattern = nil, &block)
|
85
245
|
MatchesQuery.new(pattern, &block)
|
86
246
|
end
|
87
247
|
|
248
|
+
def be_equivalent_graph(graph, info = nil)
|
249
|
+
BeEquivalentGraph.new(graph, info)
|
250
|
+
end
|
251
|
+
|
88
252
|
def be_equivalent_to(list)
|
89
253
|
ListEquivalence.new(list)
|
90
254
|
end
|