2011-03-30 20:31:39 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
module Ransack
|
2015-02-02 12:23:45 -05:00
|
|
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
|
|
|
|
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
|
|
|
|
|
2011-03-30 20:31:39 -04:00
|
|
|
describe Predicate do
|
|
|
|
|
|
|
|
before do
|
|
|
|
@s = Search.new(Person)
|
|
|
|
end
|
|
|
|
|
2013-02-06 05:26:06 -05:00
|
|
|
shared_examples 'wildcard escaping' do |method, regexp|
|
|
|
|
it 'automatically converts integers to strings' do
|
|
|
|
subject.parent_id_cont = 1
|
|
|
|
expect { subject.result }.to_not raise_error
|
|
|
|
end
|
2013-08-05 18:01:52 -04:00
|
|
|
|
2015-09-08 09:03:15 -04:00
|
|
|
it "escapes '%', '.', '_' and '\\\\' in value" do
|
2013-02-06 08:25:37 -05:00
|
|
|
subject.send(:"#{method}=", '%._\\')
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(subject.result.to_sql).to match(regexp)
|
2013-02-06 05:26:06 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-07-17 10:46:30 -04:00
|
|
|
describe 'eq' do
|
2015-02-02 12:23:45 -05:00
|
|
|
it 'generates an equality condition for boolean true values' do
|
|
|
|
test_boolean_equality_for(true)
|
2011-07-17 10:46:30 -04:00
|
|
|
end
|
|
|
|
|
2015-02-02 12:23:45 -05:00
|
|
|
it 'generates an equality condition for boolean false values' do
|
|
|
|
test_boolean_equality_for(false)
|
2011-07-17 10:46:30 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not generate a condition for nil' do
|
|
|
|
@s.awesome_eq = nil
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).not_to match /WHERE/
|
2011-07-17 10:46:30 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-12 15:48:03 -04:00
|
|
|
describe 'lteq' do
|
|
|
|
it 'generates a <= condition with an integer column' do
|
|
|
|
val = 1000
|
|
|
|
@s.salary_lteq = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} <= #{val}/
|
|
|
|
end
|
|
|
|
|
2014-10-12 17:07:27 -04:00
|
|
|
it 'generates a <= condition with a string column' do
|
|
|
|
val = 'jane@doe.com'
|
|
|
|
@s.email_lteq = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} <= '#{val}'/
|
2014-10-12 15:48:03 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not generate a condition for nil' do
|
|
|
|
@s.salary_lteq = nil
|
|
|
|
expect(@s.result.to_sql).not_to match /WHERE/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'lt' do
|
|
|
|
it 'generates a < condition with an integer column' do
|
|
|
|
val = 2000
|
|
|
|
@s.salary_lt = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} < #{val}/
|
|
|
|
end
|
|
|
|
|
2014-10-12 17:07:27 -04:00
|
|
|
it 'generates a < condition with a string column' do
|
|
|
|
val = 'jane@doe.com'
|
|
|
|
@s.email_lt = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} < '#{val}'/
|
2014-10-12 15:48:03 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not generate a condition for nil' do
|
|
|
|
@s.salary_lt = nil
|
|
|
|
expect(@s.result.to_sql).not_to match /WHERE/
|
|
|
|
end
|
|
|
|
end
|
2014-05-12 10:59:37 -04:00
|
|
|
|
2014-10-12 15:48:03 -04:00
|
|
|
describe 'gteq' do
|
|
|
|
it 'generates a >= condition with an integer column' do
|
|
|
|
val = 300
|
|
|
|
@s.salary_gteq = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} >= #{val}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates a >= condition with a string column' do
|
|
|
|
val = 'jane@doe.com'
|
|
|
|
@s.email_gteq = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} >= '#{val}'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not generate a condition for nil' do
|
|
|
|
@s.salary_gteq = nil
|
|
|
|
expect(@s.result.to_sql).not_to match /WHERE/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'gt' do
|
|
|
|
it 'generates a > condition with an integer column' do
|
|
|
|
val = 400
|
|
|
|
@s.salary_gt = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} > #{val}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates a > condition with a string column' do
|
|
|
|
val = 'jane@doe.com'
|
|
|
|
@s.email_gt = val
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} > '#{val}'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not generate a condition for nil' do
|
|
|
|
@s.salary_gt = nil
|
|
|
|
expect(@s.result.to_sql).not_to match /WHERE/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'cont' do
|
2013-11-06 01:20:51 -05:00
|
|
|
it_has_behavior 'wildcard escaping', :name_cont,
|
|
|
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
2015-09-08 09:03:15 -04:00
|
|
|
/"people"."name" ILIKE '%\\%\\.\\_\\\\%'/
|
2013-11-06 01:43:23 -05:00
|
|
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
2015-09-08 09:03:15 -04:00
|
|
|
/`people`.`name` LIKE '%\\\\%\\\\.\\\\_\\\\\\\\%'/
|
2013-08-05 18:01:52 -04:00
|
|
|
else
|
2013-11-06 01:20:51 -05:00
|
|
|
/"people"."name" LIKE '%%._\\%'/
|
2013-08-05 18:01:52 -04:00
|
|
|
end) do
|
2013-02-06 05:26:06 -05:00
|
|
|
subject { @s }
|
|
|
|
end
|
|
|
|
|
2011-03-30 20:31:39 -04:00
|
|
|
it 'generates a LIKE query with value surrounded by %' do
|
|
|
|
@s.name_cont = 'ric'
|
2013-11-06 01:43:23 -05:00
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE '%ric%'/
|
2011-03-30 20:31:39 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'not_cont' do
|
2013-11-06 01:20:51 -05:00
|
|
|
it_has_behavior 'wildcard escaping', :name_not_cont,
|
|
|
|
(if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
2015-09-08 09:03:15 -04:00
|
|
|
/"people"."name" NOT ILIKE '%\\%\\.\\_\\\\%'/
|
2013-11-06 01:43:23 -05:00
|
|
|
elsif ActiveRecord::Base.connection.adapter_name == "Mysql2"
|
2015-09-08 09:03:15 -04:00
|
|
|
/`people`.`name` NOT LIKE '%\\\\%\\\\.\\\\_\\\\\\\\%'/
|
2013-08-05 18:01:52 -04:00
|
|
|
else
|
2013-11-06 01:20:51 -05:00
|
|
|
/"people"."name" NOT LIKE '%%._\\%'/
|
2013-08-05 18:01:52 -04:00
|
|
|
end) do
|
2013-02-06 05:26:06 -05:00
|
|
|
subject { @s }
|
|
|
|
end
|
|
|
|
|
2011-03-30 20:31:39 -04:00
|
|
|
it 'generates a NOT LIKE query with value surrounded by %' do
|
|
|
|
@s.name_not_cont = 'ric'
|
2013-11-06 01:43:23 -05:00
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%ric%'/
|
2011-03-30 20:31:39 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-25 03:03:43 -04:00
|
|
|
describe 'start' do
|
|
|
|
it 'generates a LIKE query with value followed by %' do
|
|
|
|
@s.name_start = 'Er'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE 'Er%'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_start'" do
|
|
|
|
@s.new_start_start = 'hEy'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE 'hEy%'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_end'" do
|
|
|
|
@s.stop_end_start = 'begin'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE 'begin%'/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'not_start' do
|
|
|
|
it 'generates a NOT LIKE query with value followed by %' do
|
|
|
|
@s.name_not_start = 'Eri'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'Eri%'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_start'" do
|
|
|
|
@s.new_start_not_start = 'hEy'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'hEy%'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_end'" do
|
|
|
|
@s.stop_end_not_start = 'begin'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'begin%'/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'end' do
|
|
|
|
it 'generates a LIKE query with value preceded by %' do
|
|
|
|
@s.name_end = 'Miller'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE '%Miller'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_start'" do
|
|
|
|
@s.new_start_end = 'finish'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE '%finish'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_end'" do
|
|
|
|
@s.stop_end_end = 'Ending'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} I?LIKE '%Ending'/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'not_end' do
|
|
|
|
it 'generates a NOT LIKE query with value preceded by %' do
|
|
|
|
@s.name_not_end = 'Miller'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Miller'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_start'" do
|
|
|
|
@s.new_start_not_end = 'finish'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%finish'/
|
|
|
|
end
|
|
|
|
|
|
|
|
it "works with attribute names ending with '_end'" do
|
|
|
|
@s.stop_end_not_end = 'Ending'
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Ending'/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-06 20:24:04 -04:00
|
|
|
describe 'true' do
|
|
|
|
it 'generates an equality condition for boolean true' do
|
|
|
|
@s.awesome_true = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} = #{
|
|
|
|
ActiveRecord::Base.connection.quoted_true}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates an inequality condition for boolean true' do
|
|
|
|
@s.awesome_true = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} != #{
|
|
|
|
ActiveRecord::Base.connection.quoted_true}/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-26 20:50:47 -04:00
|
|
|
describe 'not_true' do
|
|
|
|
it 'generates an inequality condition for boolean true' do
|
|
|
|
@s.awesome_not_true = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} != #{
|
|
|
|
ActiveRecord::Base.connection.quoted_true}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates an equality condition for boolean true' do
|
|
|
|
@s.awesome_not_true = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} = #{
|
|
|
|
ActiveRecord::Base.connection.quoted_true}/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-06 20:24:04 -04:00
|
|
|
describe 'false' do
|
|
|
|
it 'generates an equality condition for boolean false' do
|
|
|
|
@s.awesome_false = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} = #{
|
|
|
|
ActiveRecord::Base.connection.quoted_false}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates an inequality condition for boolean false' do
|
|
|
|
@s.awesome_false = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} != #{
|
|
|
|
ActiveRecord::Base.connection.quoted_false}/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-26 20:50:47 -04:00
|
|
|
describe 'not_false' do
|
|
|
|
it 'generates an inequality condition for boolean false' do
|
|
|
|
@s.awesome_not_false = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} != #{
|
|
|
|
ActiveRecord::Base.connection.quoted_false}/
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'generates an equality condition for boolean false' do
|
|
|
|
@s.awesome_not_false = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
|
|
|
|
expect(@s.result.to_sql).to match /#{field} = #{
|
|
|
|
ActiveRecord::Base.connection.quoted_false}/
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-07-15 04:06:19 -04:00
|
|
|
describe 'null' do
|
|
|
|
it 'generates a value IS NULL query' do
|
|
|
|
@s.name_null = true
|
2013-11-06 01:43:23 -05:00
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NULL/
|
2011-07-15 04:06:19 -04:00
|
|
|
end
|
2014-05-12 10:59:37 -04:00
|
|
|
|
|
|
|
it 'generates a value IS NOT NULL query when assigned false' do
|
|
|
|
@s.name_null = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NOT NULL/
|
2014-05-12 10:59:37 -04:00
|
|
|
end
|
2011-07-15 04:06:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe 'not_null' do
|
|
|
|
it 'generates a value IS NOT NULL query' do
|
|
|
|
@s.name_not_null = true
|
2013-11-06 01:43:23 -05:00
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NOT NULL/
|
2011-07-15 04:06:19 -04:00
|
|
|
end
|
2014-05-12 10:59:37 -04:00
|
|
|
|
|
|
|
it 'generates a value IS NULL query when assigned false' do
|
|
|
|
@s.name_not_null = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NULL/
|
2014-05-12 10:59:37 -04:00
|
|
|
end
|
2011-07-15 04:06:19 -04:00
|
|
|
end
|
2014-05-12 11:10:52 -04:00
|
|
|
|
|
|
|
describe 'present' do
|
|
|
|
it %q[generates a value IS NOT NULL AND value != '' query] do
|
|
|
|
@s.name_present = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NOT NULL AND #{field} != ''/
|
2014-05-12 11:10:52 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it %q[generates a value IS NULL OR value = '' query when assigned false] do
|
|
|
|
@s.name_present = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NULL OR #{field} = ''/
|
2014-05-12 11:10:52 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'blank' do
|
|
|
|
it %q[generates a value IS NULL OR value = '' query] do
|
|
|
|
@s.name_blank = true
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NULL OR #{field} = ''/
|
2014-05-12 11:10:52 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it %q[generates a value IS NOT NULL AND value != '' query when assigned false] do
|
|
|
|
@s.name_blank = false
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
|
2014-05-15 14:29:46 -04:00
|
|
|
expect(@s.result.to_sql).to match /#{field} IS NOT NULL AND #{field} != ''/
|
2014-05-12 11:10:52 -04:00
|
|
|
end
|
|
|
|
end
|
2015-02-02 12:23:45 -05:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def test_boolean_equality_for(boolean_value)
|
2015-02-02 18:08:21 -05:00
|
|
|
query = expected_query(boolean_value)
|
2015-02-02 12:23:45 -05:00
|
|
|
test_values_for(boolean_value).each do |value|
|
|
|
|
s = Search.new(Person, awesome_eq: value)
|
2015-02-02 18:08:21 -05:00
|
|
|
expect(s.result.to_sql).to match query
|
2015-02-02 12:23:45 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_values_for(boolean_value)
|
|
|
|
case boolean_value
|
|
|
|
when true
|
|
|
|
TRUE_VALUES
|
|
|
|
when false
|
|
|
|
FALSE_VALUES
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-02 18:08:21 -05:00
|
|
|
def expected_query(value, attribute = 'awesome', operator = '=')
|
|
|
|
field = "#{quote_table_name("people")}.#{quote_column_name(attribute)}"
|
|
|
|
quoted_value = ActiveRecord::Base.connection.quote(value)
|
|
|
|
/#{field} #{operator} #{quoted_value}/
|
2015-02-02 12:23:45 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-07-15 04:06:19 -04:00
|
|
|
end
|