Class: BeHtmlWith

Inherits:
Object
  • Object
show all
Defined in:
lib/assert2/xhtml.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(scope, &block) ⇒ BeHtmlWith

Returns a new instance of BeHtmlWith.



243
244
245
# File 'lib/assert2/xhtml.rb', line 243

def initialize(scope, &block)
  @scope, @block = scope, block
end

Instance Attribute Details

#docObject

Returns the value of attribute doc.



116
117
118
# File 'lib/assert2/xhtml.rb', line 116

def doc
  @doc
end

#failure_messageObject

www.zvon.org/xxl/XPathTutorial/Output/example18.html The preceding axis contains all nodes in the same document as the context node that are before the context node in document order, excluding any ancestors and excluding attribute nodes and namespace nodes



237
238
239
# File 'lib/assert2/xhtml.rb', line 237

def failure_message
  @failure_message
end

#referencesObject (readonly)

Returns the value of attribute references.



161
162
163
# File 'lib/assert2/xhtml.rb', line 161

def references
  @references
end

#scopeObject

Returns the value of attribute scope.



116
117
118
# File 'lib/assert2/xhtml.rb', line 116

def scope
  @scope
end

Class Method Details

.create(stwing) ⇒ Object



247
248
249
250
251
# File 'lib/assert2/xhtml.rb', line 247

def self.create(stwing)
  bhw = BeHtmlWith.new(nil)
  bhw.doc = Nokogiri::HTML(stwing)
  return bhw
end

Instance Method Details

#build_deep_xpath(element) ⇒ Object



151
152
153
154
# File 'lib/assert2/xhtml.rb', line 151

def build_deep_xpath(element)
  @references = []
  return '//' + build_xpath(element)
end

#build_deep_xpath_too(element) ⇒ Object



156
157
158
159
# File 'lib/assert2/xhtml.rb', line 156

def build_deep_xpath_too(element)
  @references = []
  return '//' + build_xpath_too(element)
end

#build_xpath(element) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/assert2/xhtml.rb', line 163

def build_xpath(element)
  path = element.name.sub(/\!$/, '')
  element_kids = element.children.grep(Nokogiri::XML::Element)
  path << '[ '
  count = @references.length
  @references << element

  if element_kids.any?
    path << element_kids.map{|child|
              './descendant::' + build_xpath(child)
            }.join(' and ')
    path << ' and '
  end

  path << "refer(., '#{count}') ]"  #  last so boolean short-circuiting optimizes
  return path
end

#build_xpath_too(element) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/assert2/xhtml.rb', line 181

def build_xpath_too(element)
  path = element.name.sub(/\!$/, '')
  element_kids = element.children.grep(Nokogiri::XML::Element)
  path << '[ '
  count = @references.length
  @references << element
  brackets_owed = 0

  if element_kids.length > 0
    child = element_kids[0]
    path << './descendant::' + build_xpath_too(child)
#               }.join(' and ')
#       path << ' and '
  end

  if element_kids.length > 1
    path << element_kids[1..-1].map{|child|
              '[ ./following-sibling::*[ ./descendant-or-self::' + build_xpath_too(child) + ' ] ]'
             }.join #(' and .')
  end
     path << ' and ' if element_kids.any?

  path << "refer(., '#{count}') ]"  #  last so boolean short-circuiting optimizes
  return path
end

#collect_samples(elements, index) ⇒ Object

end # TODO more “elements” less “nodes”



107
108
109
110
111
112
113
114
# File 'lib/assert2/xhtml.rb', line 107

def collect_samples(elements, index)
  samples = elements.find_all do |element|
    match_attributes_and_text(@references[index], element)
  end

  @first_samples += samples if samples.any? and index == 0
  return samples
end

#complain_about(refered, samples, reason = nil) ⇒ Object

TODO put argumnets in order



207
208
209
210
211
212
213
# File 'lib/assert2/xhtml.rb', line 207

def complain_about(refered, samples, reason = nil)  #  TODO  put argumnets in order
  reason = " (#{reason})" if reason
  "\nCould not find this reference#{reason}...\n\n" +
    refered.to_html +
    "\n\n...in these sample(s)...\n\n" +  #  TODO  how many samples?
    samples.map{|s|s.to_html}.join("\n\n...or...\n\n")
end

#count_elements_to_node(container, element) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/assert2/xhtml.rb', line 215

def count_elements_to_node(container, element)
  return 0 if elements_equal(container, element)
  count = 0
  
  container.children.each do |child|
    sub_count = count_elements_to_node(child, element)
    return count + sub_count if sub_count        
    count += 1
  end
  
  return nil
end

#elements_equal(element_1, element_2) ⇒ Object



100
101
102
103
# File 'lib/assert2/xhtml.rb', line 100

def elements_equal(element_1, element_2)
  raise 'programming error: mismatched elements' unless element_1.document == element_2.document
  element_1.path == element_2.path
end

#get_texts(element) ⇒ Object



82
83
84
# File 'lib/assert2/xhtml.rb', line 82

def get_texts(element)
  element.xpath('text()').map{|x|x.to_s.strip}.reject{|x|x==''}.compact
end

#match_attributes_and_text(reference, sample) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/assert2/xhtml.rb', line 92

def match_attributes_and_text(reference, sample)
  reference.attribute_nodes.each do |attr|
    sample[attr.name] == attr.value or return false
  end

  return match_text(reference, sample)
end

#match_text(ref, sam) ⇒ Object



86
87
88
89
90
# File 'lib/assert2/xhtml.rb', line 86

def match_text(ref, sam)
  ref_text = get_texts(ref)
    #  TODO regices?
  ref_text.empty? or ( ref_text - get_texts(sam) ).empty?
end

#matches?(stwing, &block) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/assert2/xhtml.rb', line 119

def matches?(stwing, &block)
  @scope.wrap_expectation self do  #  TODO  put that back online
    begin
      bwock = block || @block || proc{} #  TODO  what to do with no block? validate?
      builder = Nokogiri::HTML::Builder.new(&bwock)
      @doc = Nokogiri::HTML(stwing)
      @reason = nil

      builder.doc.children.each do |child|
        @first_samples = []
          # TODO warn if child is text
        @path = build_deep_xpath(child)
        next if @path == "//html[ refer(., '0') ]" # CONSIDER wtf is this?

        matchers = @doc.root.xpath_with_callback @path, :refer do |elements, index|
                     collect_samples(elements, index.to_i)
                   end
        
        if matchers.empty?
          @first_samples << @doc.root if @first_samples.empty?  #  TODO  test the first_samples system
          @failure_message = complain_about(builder.doc.root, @first_samples)
          return false
        end  #  TODO  use or lose @reason
      end
      
      # TODO complain if too many matchers

      return true
    end
  end
end

#negative_failure_messageObject



239
240
241
# File 'lib/assert2/xhtml.rb', line 239

def negative_failure_message
  "TODO"
end