extend filter table to handle soft variable lookup

This commit is contained in:
Dominik Richter 2016-04-29 12:43:16 -04:00 committed by Christoph Hartmann
parent fb91b788a6
commit fc718267c4
2 changed files with 63 additions and 10 deletions

View file

@ -95,15 +95,36 @@ module FilterTable
private private
def matches_float(x, y)
return false if x.nil?
return false if !x.is_a?(Float) && (x =~ /\A[-+]?(\d+\.?\d*|\.\d+)\z/).nil?
x.to_f == y
end
def matches_int(x, y)
return false if x.nil?
return false if !x.is_a?(Integer) && (x =~ /\A[-+]?\d+\z/).nil?
x.to_i == y
end
def matches_regex(x, y)
return x == y if x.is_a?(Regexp)
!x.to_s.match(y).nil?
end
def matches(x, y)
x === y # rubocop:disable Style/CaseEquality
end
def filter_lines(table, field, condition) def filter_lines(table, field, condition)
m = method(:matches)
m = method(:matches_float) if condition.is_a?(Float)
m = method(:matches_int) if condition.is_a?(Integer)
m = method(:matches_regex) if condition.is_a?(Regexp)
table.find_all do |line| table.find_all do |line|
next unless line.key?(field) next unless line.key?(field)
case line[field] m.call(line[field], condition)
when condition
true
else
false
end
end end
end end
end end
@ -134,7 +155,7 @@ module FilterTable
fields.each do |method, field_name| fields.each do |method, field_name|
block = blocks[method] block = blocks[method]
define_method method.to_sym do |condition = Show, &cond_block| define_method method.to_sym do |condition = Show, &cond_block|
return block.call(self) unless block.nil? return block.call(self, condition) unless block.nil?
return where(nil).get_fields(field_name) if condition == Show && !block_given? return where(nil).get_fields(field_name) if condition == Show && !block_given?
where({ field_name => condition }, &cond_block) where({ field_name => condition }, &cond_block)
end end

View file

@ -7,9 +7,9 @@ require 'helper'
describe FilterTable do describe FilterTable do
let (:data) {[ let (:data) {[
{ foo: 3, bar: true, baz: 'yay', num: nil }, { foo: 3, bar: true, baz: 'yay', num: nil, snum: "0" },
{ foo: 2, bar: false, baz: 'noo', num: 1 }, { foo: 2, bar: false, baz: 'noo', num: 1, snum: nil },
{ foo: 2, bar: false, baz: 'whatever', num: 2 }, { foo: 2, bar: false, baz: 'whatever', num: 2, snum: "1.00" },
]} ]}
let (:resource) { let (:resource) {
@ -103,6 +103,38 @@ describe FilterTable do
end end
end end
describe 'with the string-number field' do
before { factory.add(:snum).connect(resource, :data) }
it 'retrieves the number 0' do
instance.snum(0).params.must_equal [data[0]]
end
it 'retrieves the number 1' do
instance.snum(1).params.must_equal []
end
end
describe 'with the string-float field' do
before { factory.add(:snum).connect(resource, :data) }
it 'retrieves the float 0.0' do
instance.snum(0.0).params.must_equal [data[0]]
end
it 'retrieves the float 1.0' do
instance.snum(1.0).params.must_equal [data[2]]
end
end
describe 'with a regex check' do
before { factory.add(:baz).connect(resource, :data) }
it 'retrieves the number 0' do
instance.baz(/ever$/).params.must_equal [data[2]]
end
end
describe 'with the string field' do describe 'with the string field' do
before { factory.add(:baz).connect(resource, :data) } before { factory.add(:baz).connect(resource, :data) }