123456789_123456789_123456789_123456789_123456789_

Class: Capybara::Selector::RegexpDisassembler Private

Do not use. This class is for internal use only.
Relationships & Source Files
Namespace Children
Classes:
Inherits: Object
Defined in: lib/capybara/selector/regexp_disassembler.rb

Class Method Summary

Instance Method Summary

Constructor Details

.new(regexp) ⇒ RegexpDisassembler

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 9

def initialize(regexp)
  @regexp = regexp
end

Instance Method Details

#alternated_substrings

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 13

def alternated_substrings
  @alternated_substrings ||= begin
    or_strings = process(alternation: true)
    remove_or_covered(or_strings)
    or_strings.any?(&:empty?) ? [] : or_strings
  end
end

#collapse(strs) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 81

def collapse(strs)
  strs.map do |substrings|
    substrings.slice_before(&:nil?).map(&:join).reject(&:empty?).uniq
  end
end

#combine(strs) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 68

def combine(strs)
  suffixes = [[]]
  strs.reverse_each do |str|
    if str.is_a? Set
      prefixes = str.flat_map { |s| combine(s) }
      suffixes = prefixes.product(suffixes).map { |pair| pair.flatten(1) }
    else
      suffixes.each { |arr| arr.unshift str }
    end
  end
  suffixes
end

#extract_strings(expression, alternation: false) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 87

def extract_strings(expression, alternation: false)
  Expression.new(expression).extract_strings(alternation)
end

#process(alternation:) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 61

def process(alternation:)
  strs = extract_strings(Regexp::Parser.parse(@regexp), alternation: alternation)
  strs = collapse(combine(strs).map(&:flatten))
  strs.each { |str| str.map!(&:upcase) } if @regexp.casefold?
  strs
end

#remove_and_covered(strings) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 30

def remove_and_covered(strings)
  # delete_if is documented to modify the array after every block iteration - this doesn't appear to be true
  # uniq the strings to prevent identical strings from removing each other
  strings.uniq!

  # If we have "ab" and "abcd" required - only need to check for "abcd"
  strings.delete_if do |sub_string|
    strings.any? do |cover_string|
      next if sub_string.equal? cover_string

      cover_string.include?(sub_string)
    end
  end
end

#remove_or_covered(or_series) (private)

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 45

def remove_or_covered(or_series)
  # If we are going to match `("a" and "b") or ("ade" and "bce")` it only makes sense to match ("a" and "b")

  # Ensure minimum sets of strings are being or'd
  or_series.each { |strs| remove_and_covered(strs) }

  # Remove any of the alternated string series that fully contain any other string series
  or_series.delete_if do |and_strs|
    or_series.any? do |and_strs2|
      next if and_strs.equal? and_strs2

      remove_and_covered(and_strs + and_strs2) == and_strs
    end
  end
end

#substrings

[ GitHub ]

  
# File 'lib/capybara/selector/regexp_disassembler.rb', line 21

def substrings
  @substrings ||= begin
    strs = process(alternation: false).first
    remove_and_covered(strs)
  end
end