assert2 0.4.5 → 0.4.6
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.
- data/lib/assert2/xhtml.rb +71 -34
- metadata +2 -2
data/lib/assert2/xhtml.rb
CHANGED
@@ -89,45 +89,90 @@ class BeHtmlWith
|
|
89
89
|
|
90
90
|
def match_regexp(reference, sample)
|
91
91
|
reference =~ /^\(\?/ and
|
92
|
-
|
92
|
+
Regexp.new(reference) =~ sample
|
93
93
|
end
|
94
94
|
|
95
95
|
def match_text(ref, sam)
|
96
96
|
ref_text = get_texts(ref)
|
97
|
-
|
97
|
+
|
98
98
|
ref_text.empty? or ( ref_text - (sam_text = get_texts(sam)) ).empty? or
|
99
99
|
(ref_text.length == 1 and
|
100
100
|
match_regexp(ref_text.first, sam_text.join) )
|
101
101
|
end # The irony _is_ lost on us
|
102
102
|
|
103
|
-
def
|
103
|
+
def verbose_spew(reference, sample)
|
104
|
+
if reference['verbose!'] == 'true' and
|
105
|
+
@spewed[yo_path = sample.path] == nil
|
106
|
+
puts
|
107
|
+
puts '-' * 60
|
108
|
+
p yo_path
|
109
|
+
puts sample.to_xhtml
|
110
|
+
@spewed[yo_path] = true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def match_class(attr_name, ref, sam)
|
115
|
+
return false unless attr_name == 'class'
|
116
|
+
return " #{sam} ".index(" #{ref} ")
|
117
|
+
end # NOTE if you call it a class, but ref contains
|
118
|
+
# something fruity, you are on your own!
|
119
|
+
|
120
|
+
def match_attributes(reference, sample)
|
104
121
|
reference.attribute_nodes.each do |attr|
|
105
|
-
|
106
|
-
|
107
|
-
|
122
|
+
unless %w( xpath! verbose! ).include? attr.name
|
123
|
+
ref, sam = deAmpAmp(attr.value),
|
124
|
+
deAmpAmp(sample[attr.name])
|
125
|
+
|
126
|
+
ref == sam or
|
127
|
+
match_regexp(ref, sam) or
|
128
|
+
match_class(attr.name, ref, sam) or
|
129
|
+
return false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
return true
|
134
|
+
end
|
135
|
+
|
136
|
+
def match_xpath(reference, sample)
|
137
|
+
if value = reference['xpath!']
|
138
|
+
matches = sample.parent.xpath("*[ #{value} ]")
|
139
|
+
match_paths = matches.map{|m| m.path }
|
140
|
+
return match_paths.include? sample.path
|
108
141
|
end
|
109
142
|
|
110
|
-
return
|
143
|
+
return true
|
144
|
+
end
|
145
|
+
|
146
|
+
def match_attributes_and_text(reference, sample)
|
147
|
+
if match_attributes(reference, sample) and
|
148
|
+
match_text(reference, sample) and
|
149
|
+
match_xpath(reference, sample)
|
150
|
+
|
151
|
+
verbose_spew(reference, sample)
|
152
|
+
return true
|
153
|
+
end
|
154
|
+
|
155
|
+
return false
|
111
156
|
end
|
112
157
|
|
113
158
|
def elements_equal(element_1, element_2)
|
114
159
|
raise 'programming error: mismatched elements' unless element_1.document == element_2.document
|
115
160
|
element_1.path == element_2.path
|
116
161
|
end
|
117
|
-
|
118
|
-
# end # TODO more "elements" less "nodes"
|
119
162
|
|
120
163
|
def collect_samples(elements, index)
|
121
164
|
samples = elements.find_all do |element|
|
122
165
|
match_attributes_and_text(@references[index], element)
|
123
166
|
end
|
124
167
|
|
125
|
-
@first_samples +=
|
168
|
+
@first_samples += elements # if index == 0
|
169
|
+
# TODO this could use more testage, and it could enforce a link to the parent
|
126
170
|
return samples
|
127
171
|
end
|
128
172
|
|
129
173
|
attr_accessor :doc,
|
130
|
-
:scope
|
174
|
+
:scope,
|
175
|
+
:builder
|
131
176
|
|
132
177
|
def assemble_complaint
|
133
178
|
@first_samples << @doc.root if @first_samples.empty? # TODO test the first_samples system
|
@@ -140,7 +185,6 @@ class BeHtmlWith
|
|
140
185
|
@builder = Nokogiri::HTML::Builder.new(&bwock)
|
141
186
|
|
142
187
|
@builder.doc.children.each do |child|
|
143
|
-
# @first_samples = []
|
144
188
|
@path = build_deep_xpath(child)
|
145
189
|
next if @path == "//descendant::html[ refer(., '0') ]" # CONSIDER wtf is this?
|
146
190
|
paths << @path
|
@@ -150,7 +194,7 @@ class BeHtmlWith
|
|
150
194
|
end # TODO refactor more to actually use this
|
151
195
|
|
152
196
|
def matches?(stwing, &block)
|
153
|
-
@scope.wrap_expectation self do
|
197
|
+
@scope.wrap_expectation self do
|
154
198
|
begin
|
155
199
|
paths = build_xpaths(&block)
|
156
200
|
@doc = Nokogiri::HTML(stwing)
|
@@ -158,6 +202,7 @@ class BeHtmlWith
|
|
158
202
|
|
159
203
|
@builder.doc.children.each do |child|
|
160
204
|
@first_samples = []
|
205
|
+
@spewed = {}
|
161
206
|
@path = build_deep_xpath(child)
|
162
207
|
next if @path == "//descendant::html[ refer(., '0') ]" # CONSIDER wtf is this?
|
163
208
|
|
@@ -180,7 +225,7 @@ class BeHtmlWith
|
|
180
225
|
@references = []
|
181
226
|
path = build_xpath(element)
|
182
227
|
if path.index('not') == 0
|
183
|
-
return '/*[ ' + path + ' ]'
|
228
|
+
return '/*[ ' + path + ' ]' # ERGO uh, is there a cleaner way?
|
184
229
|
end
|
185
230
|
return '//' + path
|
186
231
|
end
|
@@ -198,14 +243,8 @@ class BeHtmlWith
|
|
198
243
|
element_kids = element.children.grep(Nokogiri::XML::Element)
|
199
244
|
|
200
245
|
if element_kids.any?
|
201
|
-
path << element_kids.map{|child|
|
202
|
-
|
203
|
-
# 'not( ' + build_predicate(child) + '1=1 )'
|
204
|
-
# else
|
205
|
-
build_xpath(child)
|
206
|
-
# end
|
207
|
-
}.join(conjunction)
|
208
|
-
path << ' and ' # conjunction
|
246
|
+
path << element_kids.map{|child| build_xpath(child) }.join(conjunction)
|
247
|
+
path << ' and '
|
209
248
|
end
|
210
249
|
|
211
250
|
return path
|
@@ -223,6 +262,8 @@ class BeHtmlWith
|
|
223
262
|
path << '[ '
|
224
263
|
path << build_predicate(element)
|
225
264
|
path << "refer(., '#{count}') ]" # last so boolean short-circuiting optimizes
|
265
|
+
# xpath = element['xpath!']
|
266
|
+
# path << "[ #{ xpath } ]" if xpath
|
226
267
|
return path
|
227
268
|
end
|
228
269
|
end
|
@@ -238,8 +279,6 @@ class BeHtmlWith
|
|
238
279
|
if element_kids.length > 0
|
239
280
|
child = element_kids[0]
|
240
281
|
path << './descendant::' + build_xpath_too(child)
|
241
|
-
# }.join(' and ')
|
242
|
-
# path << ' and '
|
243
282
|
end
|
244
283
|
|
245
284
|
if element_kids.length > 1
|
@@ -274,15 +313,6 @@ class BeHtmlWith
|
|
274
313
|
return nil
|
275
314
|
end # TODO use or lose these
|
276
315
|
|
277
|
-
# TODO does a multi-modal top axis work?
|
278
|
-
# TODO this_match = node.xpath('preceding::*').length
|
279
|
-
|
280
|
-
# http://www.zvon.org/xxl/XPathTutorial/Output/example18.html
|
281
|
-
# The preceding axis contains all nodes in the same document
|
282
|
-
# as the context node that are before the context node in
|
283
|
-
# document order, excluding any ancestors and excluding
|
284
|
-
# attribute nodes and namespace nodes
|
285
|
-
|
286
316
|
attr_accessor :failure_message
|
287
317
|
|
288
318
|
def negative_failure_message
|
@@ -331,4 +361,11 @@ class Nokogiri::XML::Node
|
|
331
361
|
def content= string
|
332
362
|
self.native_content = encode_special_chars(string.to_s)
|
333
363
|
end
|
334
|
-
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class Nokogiri::XML::Builder
|
367
|
+
def text(string)
|
368
|
+
node = Nokogiri::XML::Text.new(string.to_s, @doc)
|
369
|
+
insert(node)
|
370
|
+
end
|
371
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assert2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phlip
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-03-
|
12
|
+
date: 2009-03-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|