assert2 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/assert2/xhtml.rb +50 -24
  2. data/lib/assert2/xhtml.rb~ +32 -21
  3. metadata +2 -2
data/lib/assert2/xhtml.rb CHANGED
@@ -128,30 +128,45 @@ class BeHtmlWith
128
128
 
129
129
  attr_accessor :doc,
130
130
  :scope
131
+
132
+ def assemble_complaint
133
+ @first_samples << @doc.root if @first_samples.empty? # TODO test the first_samples system
134
+ @failure_message = complain_about(@builder.doc.root, @first_samples)
135
+ end
136
+
137
+ def build_xpaths(&block)
138
+ paths = []
139
+ bwock = block || @block || proc{} # TODO what to do with no block? validate?
140
+ @builder = Nokogiri::HTML::Builder.new(&bwock)
141
+
142
+ @builder.doc.children.each do |child|
143
+ # @first_samples = []
144
+ @path = build_deep_xpath(child)
145
+ next if @path == "//descendant::html[ refer(., '0') ]" # CONSIDER wtf is this?
146
+ paths << @path
147
+ end
148
+
149
+ return paths
150
+ end # TODO refactor more to actually use this
131
151
 
132
152
  def matches?(stwing, &block)
133
153
  @scope.wrap_expectation self do # TODO put that back online
134
154
  begin
135
- bwock = block || @block || proc{} # TODO what to do with no block? validate?
136
- builder = Nokogiri::HTML::Builder.new(&bwock)
155
+ paths = build_xpaths(&block)
137
156
  @doc = Nokogiri::HTML(stwing)
138
157
  @reason = nil
139
158
 
140
- builder.doc.children.each do |child|
159
+ @builder.doc.children.each do |child|
141
160
  @first_samples = []
142
- # TODO warn if child is text
143
161
  @path = build_deep_xpath(child)
144
- next if @path == "//html[ refer(., '0') ]" # CONSIDER wtf is this?
162
+ next if @path == "//descendant::html[ refer(., '0') ]" # CONSIDER wtf is this?
145
163
 
146
164
  matchers = @doc.root.xpath_with_callback @path, :refer do |elements, index|
147
165
  collect_samples(elements, index.to_i)
148
166
  end
149
167
 
150
- if matchers.empty?
151
- @first_samples << @doc.root if @first_samples.empty? # TODO test the first_samples system
152
- @failure_message = complain_about(builder.doc.root, @first_samples)
153
- return false
154
- end # TODO use or lose @reason
168
+ matchers.empty? and assemble_complaint and return false
169
+ # TODO use or lose @reason
155
170
  end
156
171
 
157
172
  # TODO complain if too many matchers
@@ -163,7 +178,11 @@ class BeHtmlWith
163
178
 
164
179
  def build_deep_xpath(element)
165
180
  @references = []
166
- return '//' + build_xpath(element)
181
+ path = build_xpath(element)
182
+ if path.index('not') == 0
183
+ return '/*[ ' + path + ' ]' # ERGO uh, is there a cleaner way?
184
+ end
185
+ return '//' + path
167
186
  end
168
187
 
169
188
  def build_deep_xpath_too(element)
@@ -173,19 +192,20 @@ class BeHtmlWith
173
192
 
174
193
  attr_reader :references
175
194
 
176
- def build_predicate(element)
195
+ def build_predicate(element, conjunction = 'and')
177
196
  path = ''
197
+ conjunction = " #{ conjunction } "
178
198
  element_kids = element.children.grep(Nokogiri::XML::Element)
179
199
 
180
200
  if element_kids.any?
181
201
  path << element_kids.map{|child|
182
- if child.name == 'without' # TODO throw away nested withouts?
183
- 'not( ' + build_predicate(child) + '1=1 )'
184
- else
185
- './descendant::' + build_xpath(child)
186
- end
187
- }.join(' and ')
188
- path << ' and '
202
+ # if child.name == 'without' # TODO throw away nested withouts?
203
+ # 'not( ' + build_predicate(child) + '1=1 )'
204
+ # else
205
+ build_xpath(child)
206
+ # end
207
+ }.join(conjunction)
208
+ path << ' and ' # conjunction
189
209
  end
190
210
 
191
211
  return path
@@ -194,11 +214,17 @@ class BeHtmlWith
194
214
  def build_xpath(element)
195
215
  count = @references.length
196
216
  @references << element # note we skip the without @reference!
197
- path = element.name.sub(/\!$/, '')
198
- path << '[ '
199
- path << build_predicate(element)
200
- path << "refer(., '#{count}') ]" # last so boolean short-circuiting optimizes
201
- return path
217
+
218
+ if element.name == 'without!'
219
+ return 'not( ' + build_predicate(element, 'or') + '1=1 )'
220
+ else
221
+ path = 'descendant::'
222
+ path << element.name.sub(/\!$/, '')
223
+ path << '[ '
224
+ path << build_predicate(element)
225
+ path << "refer(., '#{count}') ]" # last so boolean short-circuiting optimizes
226
+ return path
227
+ end
202
228
  end
203
229
 
204
230
  def build_xpath_too(element)
@@ -128,30 +128,31 @@ class BeHtmlWith
128
128
 
129
129
  attr_accessor :doc,
130
130
  :scope
131
-
131
+
132
+ def assemble_complaint
133
+ @first_samples << @doc.root if @first_samples.empty? # TODO test the first_samples system
134
+ @failure_message = complain_about(@builder.doc.root, @first_samples)
135
+ end
136
+
132
137
  def matches?(stwing, &block)
133
138
  @scope.wrap_expectation self do # TODO put that back online
134
139
  begin
135
140
  bwock = block || @block || proc{} # TODO what to do with no block? validate?
136
- builder = Nokogiri::HTML::Builder.new(&bwock)
141
+ @builder = Nokogiri::HTML::Builder.new(&bwock)
137
142
  @doc = Nokogiri::HTML(stwing)
138
143
  @reason = nil
139
144
 
140
- builder.doc.children.each do |child|
145
+ @builder.doc.children.each do |child|
141
146
  @first_samples = []
142
- # TODO warn if child is text
143
147
  @path = build_deep_xpath(child)
144
- next if @path == "//html[ refer(., '0') ]" # CONSIDER wtf is this?
148
+ next if @path == "//descendant::html[ refer(., '0') ]" # CONSIDER wtf is this?
145
149
 
146
150
  matchers = @doc.root.xpath_with_callback @path, :refer do |elements, index|
147
151
  collect_samples(elements, index.to_i)
148
152
  end
149
153
 
150
- if matchers.empty?
151
- @first_samples << @doc.root if @first_samples.empty? # TODO test the first_samples system
152
- @failure_message = complain_about(builder.doc.root, @first_samples)
153
- return false
154
- end # TODO use or lose @reason
154
+ matchers.empty? and assemble_complaint and return false
155
+ # TODO use or lose @reason
155
156
  end
156
157
 
157
158
  # TODO complain if too many matchers
@@ -163,7 +164,11 @@ class BeHtmlWith
163
164
 
164
165
  def build_deep_xpath(element)
165
166
  @references = []
166
- return '//' + build_xpath(element)
167
+ path = build_xpath(element)
168
+ if path.index('not') == 0
169
+ path = '*[ ' + path + ' ]' # ERGO uh, is there a cleaner way?
170
+ end
171
+ return '//' + path
167
172
  end
168
173
 
169
174
  def build_deep_xpath_too(element)
@@ -179,11 +184,11 @@ class BeHtmlWith
179
184
 
180
185
  if element_kids.any?
181
186
  path << element_kids.map{|child|
182
- if child.name == 'without' # TODO throw away nested withouts?
183
- 'not( ' + build_predicate(child) + ' 1=1 )'
184
- else
185
- './descendant::' + build_xpath(child)
186
- end
187
+ # if child.name == 'without' # TODO throw away nested withouts?
188
+ # 'not( ' + build_predicate(child) + '1=1 )'
189
+ # else
190
+ build_xpath(child)
191
+ # end
187
192
  }.join(' and ')
188
193
  path << ' and '
189
194
  end
@@ -194,11 +199,17 @@ class BeHtmlWith
194
199
  def build_xpath(element)
195
200
  count = @references.length
196
201
  @references << element # note we skip the without @reference!
197
- path = element.name.sub(/\!$/, '')
198
- path << '[ '
199
- path << build_predicate(element)
200
- path << "refer(., '#{count}') ]" # last so boolean short-circuiting optimizes
201
- return path
202
+
203
+ if element.name == 'without!'
204
+ return 'not( ' + build_predicate(element) + '1=1 )'
205
+ else
206
+ path = 'descendant::'
207
+ path << element.name.sub(/\!$/, '')
208
+ path << '[ '
209
+ path << build_predicate(element)
210
+ path << "refer(., '#{count}') ]" # last so boolean short-circuiting optimizes
211
+ return path
212
+ end
202
213
  end
203
214
 
204
215
  def build_xpath_too(element)
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
4
+ version: 0.4.5
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-20 00:00:00 -07:00
12
+ date: 2009-03-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15