1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Capybara::Result do
let :string do
Capybara.string <<-STRING
<ul>
<li>Alpha</li>
<li>Beta</li>
<li>Gamma</li>
<li>Delta</li>
</ul>
STRING
end
let :result do
string.all '//li', minimum: 0 # pass minimum: 0 so lazy evaluation doesn't get triggered yet
end
it 'has a length' do
expect(result.length).to eq(4)
end
it 'has a first element' do
result.first.text == 'Alpha'
end
it 'has a last element' do
result.last.text == 'Delta'
end
it 'can supports values_at method' do
expect(result.values_at(0, 2).map(&:text)).to eq(%w[Alpha Gamma])
end
it 'can return an element by its index' do
expect(result.at(1).text).to eq('Beta')
expect(result[2].text).to eq('Gamma')
end
it 'can be mapped' do
expect(result.map(&:text)).to eq(%w[Alpha Beta Gamma Delta])
end
it 'can be selected' do
expect(result.count do |element|
element.text.include? 't'
end).to eq(2)
end
it 'can be reduced' do
expect(result.reduce('') do |memo, element|
memo + element.text[0]
end).to eq('ABGD')
end
it 'can be sampled' do
expect(result).to include(result.sample)
end
it 'can be indexed' do
expect(result.index do |el|
el.text == 'Gamma'
end).to eq(2)
end
def recalc_result
string.all '//li', minimum: 0 # pass minimum: 0 so lazy evaluation doesn't get triggered yet
end
it 'supports all modes of []' do
expect(recalc_result[1].text).to eq 'Beta'
expect(recalc_result[0, 2].map(&:text)).to eq %w[Alpha Beta]
expect(recalc_result[1..3].map(&:text)).to eq %w[Beta Gamma Delta]
expect(recalc_result[-1].text).to eq 'Delta'
expect(recalc_result[-2, 3].map(&:text)).to eq %w[Gamma Delta]
expect(recalc_result[1...3].map(&:text)).to eq %w[Beta Gamma]
expect(recalc_result[1..7].map(&:text)).to eq %w[Beta Gamma Delta]
expect(recalc_result[2...-1].map(&:text)).to eq %w[Gamma]
expect(recalc_result[2..-1].map(&:text)).to eq %w[Gamma Delta] # rubocop:disable Style/SlicingWithRange
expect(recalc_result[2..].map(&:text)).to eq %w[Gamma Delta]
end
it 'supports endless ranges' do
expect(result[2..].map(&:text)).to eq %w[Gamma Delta]
end
eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.6
it 'supports inclusive positive beginless ranges' do
expect(result[..2].map(&:text)).to eq %w[Alpha Beta Gamma]
end
it 'supports inclusive negative beginless ranges' do
expect(result[..-2].map(&:text)).to eq %w[Alpha Beta Gamma]
expect(result[..-1].map(&:text)).to eq %w[Alpha Beta Gamma Delta]
end
it 'supports exclusive positive beginless ranges' do
expect(result[...2].map(&:text)).to eq %w[Alpha Beta]
end
it 'supports exclusive negative beginless ranges' do
expect(result[...-2].map(&:text)).to eq %w[Alpha Beta]
expect(result[...-1].map(&:text)).to eq %w[Alpha Beta Gamma]
end
TEST
it 'works with filter blocks' do
result = string.all('//li') { |node| node.text == 'Alpha' }
expect(result.size).to eq 1
end
# Not a great test but it indirectly tests what is needed
it 'should evaluate filters lazily for idx' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
# Not processed until accessed
expect(result.instance_variable_get('@result_cache').size).to be 0
# Only one retrieved when needed
result.first
expect(result.instance_variable_get('@result_cache').size).to be 1
# works for indexed access
result[0]
expect(result.instance_variable_get('@result_cache').size).to be 1
result[2]
expect(result.instance_variable_get('@result_cache').size).to be 3
# All cached when converted to array
result.to_a
expect(result.instance_variable_get('@result_cache').size).to eq 4
end
it 'should evaluate filters lazily for range' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
result[0..1]
expect(result.instance_variable_get('@result_cache').size).to be 2
expect(result[0..7].size).to eq 4
expect(result.instance_variable_get('@result_cache').size).to be 4
end
it 'should evaluate filters lazily for idx and length' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
result[1, 2]
expect(result.instance_variable_get('@result_cache').size).to be 3
expect(result[2, 5].size).to eq 2
expect(result.instance_variable_get('@result_cache').size).to be 4
end
it 'should only need to evaluate one result for any?' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
result.any?
expect(result.instance_variable_get('@result_cache').size).to be 1
end
it 'should evaluate all elements when #to_a called' do
# All cached when converted to array
result.to_a
expect(result.instance_variable_get('@result_cache').size).to eq 4
end
describe '#each' do
it 'lazily evaluates' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
results = []
result.each do |el|
results << el
expect(result.instance_variable_get('@result_cache').size).to eq results.size
end
expect(results.size).to eq 4
end
context 'without a block' do
it 'returns an iterator' do
expect(result.each).to be_a(Enumerator)
end
it 'lazily evaluates' do
skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
result.each.with_index do |_el, idx|
expect(result.instance_variable_get('@result_cache').size).to eq(idx + 1) # 0 indexing
end
end
end
end
def jruby_lazy_enumerator_workaround?
RUBY_PLATFORM == 'java'
end
end
|