Refactor filters

This commit is contained in:
Thomas Walpole 2017-06-19 14:25:21 -07:00
parent 7c88db61b9
commit 0c271dc863
7 changed files with 120 additions and 89 deletions

View File

@ -1,40 +0,0 @@
# frozen_string_literal: true
require 'capybara/selector/filter'
module Capybara
class Selector
class ExpressionFilter < Filter
undef_method :matches?
def apply_filter(expr, value)
return expr if skip?(value)
if !valid_value?(value)
msg = "Invalid value #{value.inspect} passed to expression filter #{@name} - "
if default?
warn msg + "defaulting to #{default}"
value = default
else
warn msg + "skipping"
return expr
end
end
@block.call(expr, value)
end
end
class IdentityExpressionFilter < ExpressionFilter
def initialize
end
def default?
false
end
def apply_filter(expr, _value)
return expr
end
end
end
end

View File

@ -1,47 +1,19 @@
# frozen_string_literal: true
require 'capybara/selector/filters/node_filter'
require 'capybara/selector/filters/expression_filter'
module Capybara
class Selector
class Filter
def initialize(name, block, options={})
@name = name
@block = block
@options = options
@options[:valid_values] = [true,false] if options[:boolean]
end
def default?
@options.has_key?(:default)
end
def default
@options[:default]
end
def matches?(node, value)
return true if skip?(value)
if !valid_value?(value)
msg = "Invalid value #{value.inspect} passed to filter #{@name} - "
if default?
warn msg + "defaulting to #{default}"
value = default
def self.const_missing(const_name)
case const_name
when :Filter
warn "DEPRECATED: Capybara::Selector::Filter is deprecated, please use Capybara::Selector::Filters::NodeFilter instead"
Filters::NodeFilter
when :ExpressionFilter
warn "DEPRECATED: Capybara::Selector::ExpressionFilter is deprecated, please use Capybara::Selector::Filters::ExpressionFilter instead"
Filters::ExpressionFilter
else
warn msg + "skipping"
return true
end
end
@block.call(node, value)
end
def skip?(value)
@options.has_key?(:skip_if) && value == @options[:skip_if]
end
private
def valid_value?(value)
!@options.has_key?(:valid_values) || Array(@options[:valid_values]).include?(value)
super
end
end
end

View File

@ -13,11 +13,11 @@ module Capybara
end
def filter(name, *types_and_options, &block)
add_filter(name, Filter, *types_and_options, &block)
add_filter(name, Filters::NodeFilter, *types_and_options, &block)
end
def expression_filter(name, *types_and_options, &block)
add_filter(name, ExpressionFilter, *types_and_options, &block)
add_filter(name, Filters::ExpressionFilter, *types_and_options, &block)
end
def describe(&block)
@ -40,11 +40,11 @@ module Capybara
end
def node_filters
filters.reject { |_n, f| f.nil? || f.is_a?(ExpressionFilter) }.freeze
filters.reject { |_n, f| f.nil? || f.is_a?(Filters::ExpressionFilter) }.freeze
end
def expression_filters
filters.select { |_n, f| f.nil? || f.is_a?(ExpressionFilter) }.freeze
filters.select { |_n, f| f.nil? || f.is_a?(Filters::ExpressionFilter) }.freeze
end
class << self

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
module Capybara
class Selector
module Filters
class Base
def initialize(name, block, options={})
@name = name
@block = block
@options = options
@options[:valid_values] = [true,false] if options[:boolean]
end
def default?
@options.has_key?(:default)
end
def default
@options[:default]
end
def skip?(value)
@options.has_key?(:skip_if) && value == @options[:skip_if]
end
private
def valid_value?(value)
!@options.has_key?(:valid_values) || Array(@options[:valid_values]).include?(value)
end
end
end
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
require 'capybara/selector/filters/base'
module Capybara
class Selector
module Filters
class ExpressionFilter < Base
def apply_filter(expr, value)
return expr if skip?(value)
if !valid_value?(value)
msg = "Invalid value #{value.inspect} passed to expression filter #{@name} - "
if default?
warn msg + "defaulting to #{default}"
value = default
else
warn msg + "skipping"
return expr
end
end
@block.call(expr, value)
end
end
class IdentityExpressionFilter < ExpressionFilter
def initialize
end
def default?
false
end
def apply_filter(expr, _value)
return expr
end
end
end
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'capybara/selector/filters/base'
module Capybara
class Selector
module Filters
class NodeFilter < Base
def matches?(node, value)
return true if skip?(value)
if !valid_value?(value)
msg = "Invalid value #{value.inspect} passed to filter #{@name} - "
if default?
warn msg + "defaulting to #{default}"
value = default
else
warn msg + "skipping"
return true
end
end
@block.call(node, value)
end
end
end
end
end

View File

@ -1,5 +1,4 @@
# frozen_string_literal: true
require 'capybara/selector/expression_filter'
require 'capybara/selector/filter_set'
require 'capybara/selector/css'
require 'xpath'
@ -85,7 +84,7 @@ module Capybara
def xpath(*expression_filters, &block)
if block
@format, @expression = :xpath, block
expression_filters.flatten.each { |ef| custom_filters[ef] = IdentityExpressionFilter.new }
expression_filters.flatten.each { |ef| custom_filters[ef] = Filters::IdentityExpressionFilter.new }
end
format == :xpath ? @expression : nil
end
@ -188,13 +187,13 @@ module Capybara
def filter(name, *types_and_options, &block)
options = types_and_options.last.is_a?(Hash) ? types_and_options.pop.dup : {}
types_and_options.each { |k| options[k] = true }
custom_filters[name] = Filter.new(name, block, options)
custom_filters[name] = Filters::NodeFilter.new(name, block, options)
end
def expression_filter(name, *types_and_options, &block)
options = types_and_options.last.is_a?(Hash) ? types_and_options.pop.dup : {}
types_and_options.each { |k| options[k] = true }
custom_filters[name] = ExpressionFilter.new(name, block, options)
custom_filters[name] = Filters::ExpressionFilter.new(name, block, options)
end
def filter_set(name, filters_to_use = nil)