wvanbergen-scoped_search 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.rdoc +48 -32
  2. data/Rakefile +1 -3
  3. data/lib/scoped_search.rb +45 -95
  4. data/lib/scoped_search/adapters.rb +41 -0
  5. data/lib/scoped_search/definition.rb +122 -0
  6. data/lib/scoped_search/query_builder.rb +213 -0
  7. data/lib/scoped_search/query_language.rb +30 -0
  8. data/lib/scoped_search/query_language/ast.rb +141 -0
  9. data/lib/scoped_search/query_language/parser.rb +115 -0
  10. data/lib/scoped_search/query_language/tokenizer.rb +62 -0
  11. data/{test → spec}/database.yml +0 -0
  12. data/spec/integration/api_spec.rb +82 -0
  13. data/spec/integration/ordinal_querying_spec.rb +153 -0
  14. data/spec/integration/relation_querying_spec.rb +258 -0
  15. data/spec/integration/string_querying_spec.rb +187 -0
  16. data/spec/lib/database.rb +44 -0
  17. data/spec/lib/matchers.rb +40 -0
  18. data/spec/lib/mocks.rb +19 -0
  19. data/spec/spec_helper.rb +21 -0
  20. data/spec/unit/ast_spec.rb +197 -0
  21. data/spec/unit/definition_spec.rb +24 -0
  22. data/spec/unit/parser_spec.rb +105 -0
  23. data/spec/unit/query_builder_spec.rb +5 -0
  24. data/spec/unit/tokenizer_spec.rb +97 -0
  25. data/tasks/database_tests.rake +5 -5
  26. data/tasks/github-gem.rake +8 -3
  27. metadata +39 -23
  28. data/lib/scoped_search/query_conditions_builder.rb +0 -209
  29. data/lib/scoped_search/query_language_parser.rb +0 -117
  30. data/lib/scoped_search/reg_tokens.rb +0 -51
  31. data/tasks/documentation.rake +0 -33
  32. data/test/integration/api_test.rb +0 -53
  33. data/test/lib/test_models.rb +0 -148
  34. data/test/lib/test_schema.rb +0 -68
  35. data/test/test_helper.rb +0 -44
  36. data/test/unit/query_conditions_builder_test.rb +0 -410
  37. data/test/unit/query_language_test.rb +0 -155
  38. data/test/unit/search_for_test.rb +0 -124
@@ -1,51 +0,0 @@
1
- # Regular expression tokens to be used for parsing.
2
- module RegTokens
3
-
4
- WORD = '[\w-]+'
5
- SPACE = '[ ]'
6
- STRING = '["][\w ]+["]'
7
- OR = 'OR'
8
- POSSIBLY_NEGATED = '[-]?'
9
- MONTH = '[\d]{1,2}'
10
- DAY = '[\d]{1,2}'
11
- FULL_YEAR = '[\d]{4}'
12
- LESS_THAN = '[<][ ]'
13
- GREATER_THAN = '[>][ ]'
14
- LESS_THAN_OR_EQUAL_TO = '[<][=][ ]'
15
- GREATER_THAN_OR_EQUAL_TO = '[>][=][ ]'
16
- TO = 'TO'
17
-
18
- WordOrWord = "(#{WORD}#{SPACE}#{OR}#{SPACE}#{WORD})"
19
- WordOrString = "(#{WORD}#{SPACE}#{OR}#{SPACE}#{STRING})"
20
- StringOrWord = "(#{STRING}#{SPACE}#{OR}#{SPACE}#{WORD})"
21
- StringOrString = "(#{STRING}#{SPACE}#{OR}#{SPACE}#{STRING})"
22
- PossiblyNegatedWord = "(#{POSSIBLY_NEGATED}#{WORD})"
23
- PossiblyNegatedString = "(#{POSSIBLY_NEGATED}#{STRING})"
24
-
25
- DateFormatMMDDYYYY = "(#{MONTH}/#{DAY}/#{FULL_YEAR})" # This would be the same for DD/MM/YYYY
26
- DateFormatYYYYMMDD = "(#{FULL_YEAR}/#{MONTH}/#{DAY})"
27
- DatabaseFormat = "(#{FULL_YEAR}-#{MONTH}-#{DAY})"
28
-
29
- LessThanDateFormatMMDDYYYY = "(#{LESS_THAN}#{MONTH}/#{DAY}/#{FULL_YEAR})"
30
- LessThanDateFormatYYYYMMDD = "(#{LESS_THAN}#{FULL_YEAR}/#{MONTH}/#{DAY})"
31
- LessThanDatabaseFormat = "(#{LESS_THAN}#{FULL_YEAR}-#{MONTH}-#{DAY})"
32
-
33
- GreaterThanDateFormatMMDDYYYY = "(#{GREATER_THAN}#{MONTH}/#{DAY}/#{FULL_YEAR})"
34
- GreaterThanDateFormatYYYYMMDD = "(#{GREATER_THAN}#{FULL_YEAR}/#{MONTH}/#{DAY})"
35
- GreaterThanDatabaseFormat = "(#{GREATER_THAN}#{FULL_YEAR}-#{MONTH}-#{DAY})"
36
-
37
- LessThanOrEqualToDateFormatMMDDYYYY = "(#{LESS_THAN_OR_EQUAL_TO}#{MONTH}/#{DAY}/#{FULL_YEAR})"
38
- LessThanOrEqualToDateFormatYYYYMMDD = "(#{LESS_THAN_OR_EQUAL_TO}#{FULL_YEAR}/#{MONTH}/#{DAY})"
39
- LessThanOrEqualToDatabaseFormat = "(#{LESS_THAN_OR_EQUAL_TO}#{FULL_YEAR}-#{MONTH}-#{DAY})"
40
-
41
- GreaterThanOrEqualToDateFormatMMDDYYYY = "(#{GREATER_THAN_OR_EQUAL_TO}#{MONTH}/#{DAY}/#{FULL_YEAR})"
42
- GreaterThanOrEqualToDateFormatYYYYMMDD = "(#{GREATER_THAN_OR_EQUAL_TO}#{FULL_YEAR}/#{MONTH}/#{DAY})"
43
- GreaterThanOrEqualToDatabaseFormat = "(#{GREATER_THAN_OR_EQUAL_TO}#{FULL_YEAR}-#{MONTH}-#{DAY})"
44
-
45
- BetweenDateFormatMMDDYYYY = "(#{MONTH}/#{DAY}/#{FULL_YEAR}#{SPACE}#{TO}#{SPACE}#{MONTH}/#{DAY}/#{FULL_YEAR})"
46
- BetweenDateFormatYYYYMMDD = "(#{FULL_YEAR}/#{MONTH}/#{DAY}#{SPACE}#{TO}#{SPACE}#{FULL_YEAR}/#{MONTH}/#{DAY})"
47
- BetweenDatabaseFormat = "(#{FULL_YEAR}-#{MONTH}-#{DAY}#{SPACE}#{TO}#{SPACE}#{FULL_YEAR}-#{MONTH}-#{DAY})"
48
- end
49
-
50
-
51
-
@@ -1,33 +0,0 @@
1
- require 'rubygems'
2
- require 'rake/rdoctask'
3
-
4
- desc 'Generate documentation for the acts_as_callback_logger plugin.'
5
- Rake::RDocTask.new do |rdoc|
6
- rdoc.rdoc_dir = 'doc/html'
7
- rdoc.title = 'scoped_search'
8
- rdoc.options << '--line-numbers' << '--inline-source'
9
- rdoc.main = 'README'
10
- rdoc.rdoc_files.include('LICENSE',
11
- 'lib/')
12
- end
13
-
14
-
15
- begin
16
- require 'rcov/rcovtask'
17
- Rcov::RcovTask.new do |t|
18
- t.test_files = Dir[ "test/**/*_test.rb" ]
19
- end
20
- rescue LoadError
21
- nil
22
- end
23
-
24
- begin
25
- require 'rcov/rcovtask'
26
- desc 'Runs spec:rcov and then displays the coverage/index.html file in the browswer.'
27
- task :rcov_display => [:clobber_rcov, :rcov] do
28
- system("open coverage/index.html")
29
- end
30
- rescue LoadError
31
- nil
32
- end
33
-
@@ -1,53 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../test_helper.rb"
2
-
3
- class ScopedSearch::Test::API < Test::Unit::TestCase
4
-
5
- def self.const_missing(const)
6
- ScopedSearch::Test::Models.const_get(const)
7
- end
8
-
9
- def setup
10
- ScopedSearch::Test::establish_connection
11
- ScopedSearch::Test::DatabaseSchema.up
12
- end
13
-
14
- def teardown
15
- ScopedSearch::Test::DatabaseSchema.down
16
- end
17
-
18
- def test_enabling
19
- assert !Foo.respond_to?(:search_for)
20
- Foo.searchable_on :string_field, :text_field, :date_field
21
- assert Foo.respond_to?(:search_for)
22
-
23
- assert_equal ActiveRecord::NamedScope::Scope, Foo.search_for('test').class
24
- end
25
-
26
- def test_search_only_fields
27
- Foo.searchable_on :only => [:string_field, :text_field, :date_field]
28
- assert Foo.respond_to?(:search_for)
29
- assert_equal Foo.scoped_search_fields.size, 3
30
- assert Foo.scoped_search_fields.include?(:string_field)
31
- assert Foo.scoped_search_fields.include?(:text_field)
32
- assert Foo.scoped_search_fields.include?(:date_field)
33
- end
34
-
35
- def test_search_except_fields
36
- Foo.searchable_on :except => [:id, :ignored_field, :created_at, :updated_at]
37
- assert Foo.respond_to?(:search_for)
38
- assert_equal Foo.scoped_search_fields.size, 4
39
- assert Foo.scoped_search_fields.include?(:string_field)
40
- assert Foo.scoped_search_fields.include?(:text_field)
41
- assert Foo.scoped_search_fields.include?(:date_field)
42
- assert Foo.scoped_search_fields.include?(:some_int_field)
43
- end
44
-
45
- def test_search_with_only_and_except
46
- # :except should be ignored if :only is specified.
47
- Foo.searchable_on({:only => [:text_field], :except => [:text_field]})
48
- assert Foo.respond_to?(:search_for)
49
- assert_equal Foo.scoped_search_fields.size, 1
50
- assert Foo.scoped_search_fields.include?(:text_field), ':except should be ignored if :only is specified'
51
- end
52
-
53
- end
@@ -1,148 +0,0 @@
1
- module ScopedSearch::Test::Models
2
-
3
- class Foo < ActiveRecord::Base
4
- def self.create_corpus!
5
- create!(:string_field => "Programmer 123", :text_field => nil, :ignored_field => "123456", :some_int_field => 111, :date_field => '2000-01-01')
6
- create!(:string_field => "Jim", :text_field => "Henson", :ignored_field => "123456a", :some_int_field => 222, :date_field => '2001-04-15')
7
- create!(:string_field => "Jim", :text_field => "Bush", :ignored_field => "123456b", :some_int_field => 333, :date_field => '2001-04-17')
8
- create!(:string_field => "Wes", :text_field => "Hays", :ignored_field => "123456c", :some_int_field => 444, :date_field => '1980-09-27')
9
- create!(:string_field => "Bob", :text_field => "Hays", :ignored_field => "123456d", :some_int_field => 555, :date_field => '2002-11-09')
10
- create!(:string_field => "Dogs", :text_field => "Pit Bull", :ignored_field => "123456e", :some_int_field => 666, :date_field => '2002-12-26')
11
- create!(:string_field => "Dogs", :text_field => "Eskimo", :ignored_field => "123456f", :some_int_field => 777, :date_field => '2003-03-19')
12
- create!(:string_field => "Cows", :text_field => "Farms", :ignored_field => "123456g", :some_int_field => 888, :date_field => '2004-05-01')
13
- create!(:string_field => "Hello World", :text_field => "Hello Moon", :ignored_field => "123456h", :some_int_field => 999, :date_field => '2004-07-11')
14
- create!(:string_field => "Hello World", :text_field => "Goodnight Moon", :ignored_field => "123456i", :some_int_field => 100, :date_field => '2004-09-12')
15
- create!(:string_field => "Happy Cow", :text_field => "Sad Cow", :ignored_field => "123456j", :some_int_field => 200, :date_field => '2005-02-05')
16
- create!(:string_field => "Happy Frog", :text_field => "Sad Frog", :ignored_field => "123456k", :some_int_field => 300, :date_field => '2006-03-09')
17
- create!(:string_field => "Excited Frog", :text_field => "Sad Frog", :ignored_field => "123456l", :some_int_field => 400, :date_field => '2006-07-15')
18
- create!(:string_field => "Man made", :text_field => "Woman made", :ignored_field => "123456m", :some_int_field => 500, :date_field => '2007-06-13')
19
- create!(:string_field => "Cat Toys", :text_field => "Frog Toys", :ignored_field => "123456n", :some_int_field => 600, :date_field => '2008-03-04')
20
- create!(:string_field => "Happy Toys", :text_field => "Sad Toys", :ignored_field => "123456n", :some_int_field => 700, :date_field => '2008-05-12')
21
-
22
- create!(:string_field => "My son was born on 7/15/2006 and weighed 5.5 lbs",
23
- :text_field => "Sad Toys",
24
- :ignored_field => "123456n",
25
- :date_field => '2008-09-22')
26
- end
27
- end
28
-
29
- class User < ActiveRecord::Base
30
- belongs_to :group
31
- belongs_to :address
32
- has_many :notes
33
- has_and_belongs_to_many :locations
34
-
35
- has_many :offices, :dependent => :destroy
36
- has_many :clients, :through => :offices
37
-
38
- def self.create_corpus!
39
- create!(:first_name => 'Willem', :last_name => 'Van Bergen', :login => 'wvanbergen', :age => 25, :group_id => 1, :address_id => 1)
40
- create!(:first_name => 'Wes', :last_name => 'Hays', :login => 'weshays', :age => 26, :group_id => 1, :address_id => 2)
41
- create!(:first_name => 'John', :last_name => 'Dell', :login => 'jdell', :age => 27, :group_id => 2, :address_id => 3)
42
- create!(:first_name => 'Ray', :last_name => 'York', :login => 'ryork', :age => 28, :group_id => 3, :address_id => 4)
43
- create!(:first_name => 'Anna', :last_name => 'Landis', :login => 'alandis', :age => 29, :group_id => 4, :address_id => 5)
44
-
45
- user = self.find_by_first_name('Willem')
46
- user.locations << ScopedSearch::Test::Models::Location.find_by_name('Office')
47
-
48
- user = self.find_by_first_name('Wes')
49
- user.locations << ScopedSearch::Test::Models::Location.find_by_name('Store')
50
-
51
- user = self.find_by_first_name('John')
52
- user.locations << ScopedSearch::Test::Models::Location.find_by_name('Office')
53
-
54
- user = self.find_by_first_name('Ray')
55
- user.locations << ScopedSearch::Test::Models::Location.find_by_name('Home')
56
-
57
- user = self.find_by_first_name('Anna')
58
- user.locations << ScopedSearch::Test::Models::Location.find_by_name('Beach')
59
- end
60
- end
61
-
62
- class Client < ActiveRecord::Base
63
- has_many :offices, :dependent => :destroy
64
- has_many :users, :through => :offices
65
- def self.create_corpus!
66
- create!(:first_name => 'Bob', :last_name => 'Smith')
67
- create!(:first_name => 'Sam', :last_name => 'Lovett')
68
- create!(:first_name => 'Sally', :last_name => 'May')
69
- create!(:first_name => 'Mary', :last_name => 'Smith')
70
- create!(:first_name => 'Darren', :last_name => 'Johnson')
71
- end
72
- end
73
-
74
- class Office < ActiveRecord::Base
75
- belongs_to :client
76
- belongs_to :user
77
- def self.create_corpus!
78
- create!(:name => 'California Office', :user_id => 1, :client_id => 1)
79
- create!(:name => 'California Office', :user_id => 2, :client_id => 2)
80
- create!(:name => 'California Office', :user_id => 3, :client_id => 3)
81
- create!(:name => 'Reno Office', :user_id => 4, :client_id => 4)
82
- create!(:name => 'Reno Office', :user_id => 5, :client_id => 5)
83
- end
84
- end
85
-
86
- class Group < ActiveRecord::Base
87
- has_many :users
88
- def self.create_corpus!
89
- create!(:name => 'System Administrator')
90
- create!(:name => 'Software Managers')
91
- create!(:name => 'Office Managers')
92
- create!(:name => 'Accounting')
93
- end
94
- end
95
-
96
- class Location < ActiveRecord::Base
97
- has_and_belongs_to_many :users
98
- def self.create_corpus!
99
- create!(:name => 'Home')
100
- create!(:name => 'Office')
101
- create!(:name => 'Store')
102
- create!(:name => 'Beach')
103
- end
104
- end
105
-
106
- class Note < ActiveRecord::Base
107
- belongs_to :user
108
- def self.create_corpus!
109
- wes = ScopedSearch::Test::Models::User.find_by_first_name('Wes')
110
- john = ScopedSearch::Test::Models::User.find_by_first_name('John')
111
-
112
- create!(:user_id => wes.id,
113
- :title => 'Purchases',
114
- :content => "1) Linksys Router. 2) Network Cable")
115
-
116
- create!(:user_id => wes.id,
117
- :title => 'Tasks',
118
- :content => 'Clean my car, walk the dog and mow the yard buy milk')
119
-
120
- create!(:user_id => wes.id,
121
- :title => 'Grocery List',
122
- :content => 'milk, gum, apples')
123
-
124
- create!(:user_id => wes.id,
125
- :title => 'Stocks to watch',
126
- :content => 'MA, AAPL, V and SSO. Straddle MA at 200 with JAN 09 options')
127
-
128
- create!(:user_id => john.id,
129
- :title => 'Spec Tests',
130
- :content => 'Spec Tests... Spec Tests... Spec Tests!!')
131
-
132
- create!(:user_id => john.id,
133
- :title => 'Things To Do',
134
- :content => '1) Did I mention Spec Tests!!!, 2) Buy Linksys Router WRT160N')
135
- end
136
- end
137
-
138
- class Address < ActiveRecord::Base
139
- has_one :user
140
- def self.create_corpus!
141
- create!(:street => '800 Haskell St', :city => 'Reno', :state => 'NV', :postal_code => '89509')
142
- create!(:street => '2499 Dorchester Rd', :city => 'Charleston', :state => 'SC', :postal_code => '29414')
143
- create!(:street => '474 Mallard Way', :city => 'Fernley', :state => 'NV', :postal_code => '89408')
144
- create!(:street => '1600 Montero Ct', :city => 'Sparks', :state => 'NV', :postal_code => '89434')
145
- create!(:street => '200 4th St', :city => 'Sparks', :state => 'NV', :postal_code => '89434')
146
- end
147
- end
148
- end
@@ -1,68 +0,0 @@
1
- ActiveRecord::Migration.verbose = false unless ENV.has_key?('DEBUG')
2
-
3
- class ScopedSearch::Test::DatabaseSchema < ActiveRecord::Migration
4
-
5
- def self.up
6
-
7
- create_table :foos do |t|
8
- t.string :string_field
9
- t.text :text_field
10
- t.string :ignored_field
11
- t.integer :some_int_field
12
- t.date :date_field
13
- t.timestamps
14
- end
15
-
16
- create_table :users do |t|
17
- t.string :first_name, :last_name, :login
18
- t.integer :age
19
- t.integer :group_id
20
- t.integer :address_id
21
- end
22
-
23
- create_table :clients do |t|
24
- t.string :first_name, :last_name
25
- end
26
-
27
- create_table :offices do |t|
28
- t.string :name
29
- t.integer :user_id, :client_id
30
- end
31
-
32
- create_table :groups do |t|
33
- t.string :name
34
- end
35
-
36
- create_table :locations do |t|
37
- t.string :name
38
- end
39
-
40
- create_table :locations_users, :id => false, :force => true do |t|
41
- t.integer :user_id
42
- t.integer :location_id
43
- end
44
-
45
- create_table :notes do |t|
46
- t.string :title
47
- t.text :content
48
- t.integer :user_id
49
- end
50
-
51
- create_table :addresses do |t|
52
- t.string :street, :city, :state, :postal_code
53
- end
54
- end
55
-
56
- def self.down
57
- drop_table :foos
58
- drop_table :users
59
- drop_table :clients
60
- drop_table :offices
61
- drop_table :groups
62
- drop_table :locations
63
- drop_table :locations_users
64
- drop_table :notes
65
- drop_table :addresses
66
- end
67
-
68
- end
data/test/test_helper.rb DELETED
@@ -1,44 +0,0 @@
1
- $:.reject! { |e| e.include? 'TextMate' }
2
-
3
- require 'test/unit'
4
- require 'rubygems'
5
- require 'active_record'
6
- require 'ruby-debug'
7
-
8
- require "#{File.dirname(__FILE__)}/../lib/scoped_search"
9
-
10
- module ScopedSearch::Test
11
-
12
- def self.establish_connection
13
- if ENV['DATABASE']
14
- ScopedSearch::Test.establish_named_connection(ENV['DATABASE'])
15
- else
16
- ScopedSearch::Test.establish_default_connection
17
- end
18
- end
19
-
20
- def self.establish_named_connection(name)
21
- @database_connections ||= YAML.load(File.read("#{File.dirname(__FILE__)}/database.yml"))
22
- raise "#{name} database not configured" if @database_connections[name.to_s].nil?
23
- ActiveRecord::Base.establish_connection(@database_connections[name.to_s])
24
- end
25
-
26
- def self.establish_default_connection
27
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
28
- end
29
-
30
- def self.create_corpus!
31
- ScopedSearch::Test::Models::Foo.create_corpus!
32
- ScopedSearch::Test::Models::Location.create_corpus!
33
- ScopedSearch::Test::Models::User.create_corpus!
34
- ScopedSearch::Test::Models::Note.create_corpus!
35
- ScopedSearch::Test::Models::Group.create_corpus!
36
- ScopedSearch::Test::Models::Office.create_corpus!
37
- ScopedSearch::Test::Models::Client.create_corpus!
38
- ScopedSearch::Test::Models::Address.create_corpus!
39
- end
40
- end
41
-
42
- # Load helpers
43
- require "#{File.dirname(__FILE__)}/lib/test_schema"
44
- require "#{File.dirname(__FILE__)}/lib/test_models"
@@ -1,410 +0,0 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
-
3
- class ScopedSearch::Test::QueryConditionsBuilder < Test::Unit::TestCase
4
-
5
- # change this function if you switch to another query language parser
6
- def build_query(search_conditions, query_fields)
7
- ScopedSearch::QueryConditionsBuilder.build_query(search_conditions, query_fields)
8
- end
9
-
10
- # ** Invalid search conditions **
11
- def test_search_with_invalid_search_conditions
12
- search_conditions = ''
13
- query_fields = {'some_table.first_name' => :string}
14
- assert_raise(RuntimeError, 'search_conditions must be a hash') {
15
- build_query(search_conditions, query_fields)
16
- }
17
- end
18
-
19
- def test_search_with_invalid_query_fields
20
- search_conditions = [["Wes", :like]]
21
- query_fields = ''
22
- assert_raise(RuntimeError, 'query_fields must be a hash') {
23
- build_query(search_conditions, query_fields)
24
- }
25
- end
26
-
27
-
28
- # ** Single query search tests **
29
- def test_like_search_condition
30
- search_conditions = [["Wes", :like]]
31
- query_fields = {'some_table.first_name' => :string}
32
- conditions = build_query(search_conditions, query_fields)
33
-
34
- assert_equal '(some_table.first_name LIKE :keyword_0)', conditions.first
35
- assert_equal '%Wes%', conditions.last[:keyword_0]
36
- end
37
-
38
- def test_like_search_condition_with_integer
39
- search_conditions = [["26", :like]]
40
- query_fields = {'some_table.age' => :integer}
41
- conditions = build_query(search_conditions, query_fields)
42
-
43
- assert_equal '(some_table.age = :keyword_0_26)', conditions.first
44
- assert_equal 26, conditions.last[:keyword_0_26]
45
- end
46
-
47
- def test_not_like_search_condition
48
- search_conditions = [["Wes", :not]]
49
- query_fields = {'some_table.first_name' => :string}
50
- conditions = build_query(search_conditions, query_fields)
51
-
52
- assert_equal '((some_table.first_name NOT LIKE :keyword_0 OR some_table.first_name IS NULL))', conditions.first
53
- assert_equal '%Wes%', conditions.last[:keyword_0]
54
- end
55
-
56
- def test_or_search_condition
57
- search_conditions = [["Wes OR Hays", :or]]
58
- query_fields = {'some_table.first_name' => :string}
59
- conditions = build_query(search_conditions, query_fields)
60
- regExs = build_regex_for_or(['first_name'], 'keyword_0')
61
- assert_match /^#{regExs}$/, conditions.first
62
- assert_equal '%Wes%', conditions.last[:keyword_0a]
63
- assert_equal '%Hays%', conditions.last[:keyword_0b]
64
- end
65
-
66
- def test_or_search_condition_with_integer
67
- search_conditions = [["Wes OR 26", :or]]
68
- query_fields = {'some_table.first_name' => :string, 'some_table.age' => :integer}
69
- conditions = build_query(search_conditions, query_fields)
70
- regExs = build_regex_for_or(['first_name', 'age'], 'keyword_0')
71
- assert_match /^#{regExs}$/, conditions.first
72
- assert_equal '%Wes%', conditions.last[:keyword_0a]
73
- assert_equal 26, conditions.last[:keyword_0_26]
74
- end
75
-
76
- # ** less_than_date **
77
- def test_less_than_date_search_condition_with_only_a_date_field_to_search
78
- search_conditions = [['< 09/27/1980', :less_than_date]]
79
- query_fields = {'some_table.event_date' => :datetime}
80
- conditions = build_query(search_conditions, query_fields)
81
-
82
- assert_equal '(some_table.event_date < :keyword_0)', conditions.first
83
- assert_equal '1980-09-27', conditions.last[:keyword_0]
84
- end
85
-
86
- def test_less_than_date_search_condition_with_invalid_date
87
- search_conditions = [['< 2/30/1980', :less_than_date]]
88
- query_fields = {'some_table.event_date' => :datetime}
89
- conditions = build_query(search_conditions, query_fields)
90
-
91
- assert conditions.first.empty?
92
- assert conditions.last.empty?
93
- end
94
-
95
- def test_less_than_date_search_condition_with_a_date_field_and_a_text_field
96
- search_conditions = [['< 09/27/1980', :less_than_date]]
97
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
98
- conditions = build_query(search_conditions, query_fields)
99
-
100
- assert_equal '(some_table.event_date < :keyword_0)', conditions.first
101
- assert_equal '1980-09-27', conditions.last[:keyword_0]
102
- end
103
-
104
- def test_less_than_date_search_condition_with_a_date_field_and_a_text_field
105
- search_conditions = [['< 2/30/1980', :less_than_date]]
106
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
107
- conditions = build_query(search_conditions, query_fields)
108
-
109
- assert conditions.first.empty?
110
- assert conditions.last.empty?
111
- end
112
-
113
-
114
- # ** less_than_or_equal_to_date **
115
- def test_less_than_or_equal_to_date_search_condition_with_only_a_date_field_to_search
116
- search_conditions = [['<= 09/27/1980', :less_than_or_equal_to_date]]
117
- query_fields = {'some_table.event_date' => :datetime}
118
- conditions = build_query(search_conditions, query_fields)
119
-
120
- assert_equal '(some_table.event_date <= :keyword_0)', conditions.first
121
- assert_equal '1980-09-27', conditions.last[:keyword_0]
122
- end
123
-
124
- def test_less_than_or_equal_to_date_search_condition_with_invalid_date
125
- search_conditions = [['<= 2/30/1980', :less_than_or_equal_to_date]]
126
- query_fields = {'some_table.event_date' => :datetime}
127
- conditions = build_query(search_conditions, query_fields)
128
-
129
- assert conditions.first.empty?
130
- assert conditions.last.empty?
131
- end
132
-
133
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
134
- search_conditions = [['<= 09/27/1980', :less_than_or_equal_to_date]]
135
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
136
- conditions = build_query(search_conditions, query_fields)
137
-
138
- assert_equal '(some_table.event_date <= :keyword_0)', conditions.first
139
- assert_equal '1980-09-27', conditions.last[:keyword_0]
140
- end
141
-
142
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
143
- search_conditions = [['<= 2/30/1980', :less_than_or_equal_to_date]]
144
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
145
- conditions = build_query(search_conditions, query_fields)
146
-
147
- assert conditions.first.empty?
148
- assert conditions.last.empty?
149
- end
150
-
151
-
152
- # ** as_of_date **
153
- def test_as_of_date_search_condition_with_only_a_date_field_to_search
154
- search_conditions = [['09/27/1980', :as_of_date]]
155
- query_fields = {'some_table.event_date' => :datetime}
156
- conditions = build_query(search_conditions, query_fields)
157
-
158
- assert_equal '(some_table.event_date = :keyword_0)', conditions.first
159
- assert_equal '1980-09-27', conditions.last[:keyword_0]
160
- end
161
-
162
- def test_as_of_date_search_condition_with_invalid_date
163
- search_conditions = [['2/30/1980', :as_of_date]]
164
- query_fields = {'some_table.event_date' => :datetime}
165
- conditions = build_query(search_conditions, query_fields)
166
-
167
- assert conditions.first.empty?
168
- assert conditions.last.empty?
169
- end
170
-
171
- def test_as_of_date_search_condition_with_a_date_field_and_a_text_field
172
- search_conditions = [['09/27/1980', :as_of_date]]
173
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
174
- conditions = build_query(search_conditions, query_fields)
175
-
176
- assert_equal '(some_table.event_date = :keyword_0 OR some_table.first_name LIKE :keyword_0b)', conditions.first
177
- assert_equal '1980-09-27', conditions.last[:keyword_0]
178
- assert_equal '%09/27/1980%', conditions.last[:keyword_0b]
179
- end
180
-
181
- def test_as_of_date_search_condition_with_a_date_field_and_a_text_field
182
- search_conditions = [['2/30/1980', :as_of_date]]
183
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
184
- conditions = build_query(search_conditions, query_fields)
185
-
186
- assert_equal '(some_table.first_name LIKE :keyword_0b)', conditions.first
187
- assert_equal '%2/30/1980%', conditions.last[:keyword_0b]
188
- end
189
-
190
-
191
- # ** greater_than_date **
192
- def test_less_than_or_equal_to_date_search_condition_with_only_a_date_field_to_search
193
- search_conditions = [['> 09/27/1980', :greater_than_date]]
194
- query_fields = {'some_table.event_date' => :datetime}
195
- conditions = build_query(search_conditions, query_fields)
196
-
197
- assert_equal '(some_table.event_date > :keyword_0)', conditions.first
198
- assert_equal '1980-09-27', conditions.last[:keyword_0]
199
- end
200
-
201
- def test_less_than_or_equal_to_date_search_condition_with_invalid_date
202
- search_conditions = [['> 2/30/1980', :greater_than_date]]
203
- query_fields = {'some_table.event_date' => :datetime}
204
- conditions = build_query(search_conditions, query_fields)
205
-
206
- assert conditions.first.empty?
207
- assert conditions.last.empty?
208
- end
209
-
210
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
211
- search_conditions = [['> 09/27/1980', :greater_than_date]]
212
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
213
- conditions = build_query(search_conditions, query_fields)
214
-
215
- assert_equal '(some_table.event_date > :keyword_0)', conditions.first
216
- assert_equal '1980-09-27', conditions.last[:keyword_0]
217
- end
218
-
219
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
220
- search_conditions = [['> 2/30/1980', :greater_than_date]]
221
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
222
- conditions = build_query(search_conditions, query_fields)
223
-
224
- assert conditions.first.empty?
225
- assert conditions.last.empty?
226
- end
227
-
228
-
229
- # ** greater_than_or_equal_to_date **
230
- def test_less_than_or_equal_to_date_search_condition_with_only_a_date_field_to_search
231
- search_conditions = [['>= 09/27/1980', :greater_than_or_equal_to_date]]
232
- query_fields = {'some_table.event_date' => :datetime}
233
- conditions = build_query(search_conditions, query_fields)
234
-
235
- assert_equal '(some_table.event_date >= :keyword_0)', conditions.first
236
- assert_equal '1980-09-27', conditions.last[:keyword_0]
237
- end
238
-
239
- def test_less_than_or_equal_to_date_search_condition_with_invalid_date
240
- search_conditions = [['>= 2/30/1980', :greater_than_or_equal_to_date]]
241
- query_fields = {'some_table.event_date' => :datetime}
242
- conditions = build_query(search_conditions, query_fields)
243
-
244
- assert conditions.first.empty?
245
- assert conditions.last.empty?
246
- end
247
-
248
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
249
- search_conditions = [['>= 09/27/1980', :greater_than_or_equal_to_date]]
250
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
251
- conditions = build_query(search_conditions, query_fields)
252
-
253
- assert_equal '(some_table.event_date >= :keyword_0)', conditions.first
254
- assert_equal '1980-09-27', conditions.last[:keyword_0]
255
- end
256
-
257
- def test_less_than_or_equal_to_date_search_condition_with_a_date_field_and_a_text_field
258
- search_conditions = [['>= 2/30/1980', :greater_than_or_equal_to_date]]
259
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
260
- conditions = build_query(search_conditions, query_fields)
261
-
262
- assert conditions.first.empty?
263
- assert conditions.last.empty?
264
- end
265
-
266
-
267
-
268
- # ** between_dates **
269
- def test_between_dates_search_condition_two_valid_dates
270
- search_conditions = [['09/27/1980 TO 10/15/1980', :between_dates]]
271
- query_fields = {'some_table.event_date' => :datetime}
272
- conditions = build_query(search_conditions, query_fields)
273
-
274
- assert_equal '((some_table.event_date BETWEEN :keyword_0a AND :keyword_0b))', conditions.first
275
- assert_equal '1980-09-27', conditions.last[:keyword_0a]
276
- assert_equal '1980-10-15', conditions.last[:keyword_0b]
277
- end
278
-
279
- def test_between_dates_search_condition_with_a_valid_date_first_and_an_invalid_date_second
280
- search_conditions = [['09/27/1980 TO 2/30/1981', :between_dates]]
281
- query_fields = {'some_table.event_date' => :datetime}
282
- conditions = build_query(search_conditions, query_fields)
283
-
284
- assert conditions.first.empty?
285
- assert conditions.last.empty?
286
- end
287
-
288
- def test_between_dates_search_condition_with_an_invalid_date_first_and_a_valid_date_second
289
- search_conditions = [['02/30/1980 TO 09/27/1980', :between_dates]]
290
- query_fields = {'some_table.event_date' => :datetime}
291
- conditions = build_query(search_conditions, query_fields)
292
-
293
- assert conditions.first.empty?
294
- assert conditions.last.empty?
295
- end
296
-
297
- def test_between_dates_search_condition_with_two_invalid_dates
298
- search_conditions = [['02/30/1980 TO 02/30/1981', :between_dates]]
299
- query_fields = {'some_table.event_date' => :datetime}
300
- conditions = build_query(search_conditions, query_fields)
301
-
302
- assert conditions.first.empty?
303
- assert conditions.last.empty?
304
- end
305
-
306
-
307
- def test_between_dates_search_condition_two_valid_dates_and_a_text_field
308
- search_conditions = [['09/27/1980 TO 10/15/1980', :between_dates]]
309
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
310
- conditions = build_query(search_conditions, query_fields)
311
-
312
- assert_equal '((some_table.event_date BETWEEN :keyword_0a AND :keyword_0b))', conditions.first
313
- assert_equal '1980-09-27', conditions.last[:keyword_0a]
314
- assert_equal '1980-10-15', conditions.last[:keyword_0b]
315
- end
316
-
317
- def test_between_dates_search_condition_with_a_valid_date_first_and_an_invalid_date_second_and_a_text_field
318
- search_conditions = [['09/27/1980 TO 2/30/1981', :between_dates]]
319
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
320
- conditions = build_query(search_conditions, query_fields)
321
-
322
- assert conditions.first.empty?
323
- assert conditions.last.empty?
324
- end
325
-
326
- def test_between_dates_search_condition_with_an_invalid_date_first_and_a_valid_date_second_and_a_text_field
327
- search_conditions = [['02/30/1980 TO 09/27/1980', :between_dates]]
328
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
329
- conditions = build_query(search_conditions, query_fields)
330
-
331
- assert conditions.first.empty?
332
- assert conditions.last.empty?
333
- end
334
-
335
- def test_between_dates_search_condition_with_two_invalid_dates_and_a_text_field
336
- search_conditions = [['02/30/1980 TO 02/30/1981', :between_dates]]
337
- query_fields = {'some_table.event_date' => :datetime, 'some_table.first_name' => :string}
338
- conditions = build_query(search_conditions, query_fields)
339
-
340
- assert conditions.first.empty?
341
- assert conditions.last.empty?
342
- end
343
-
344
-
345
- # ** Multi query search tests **
346
- def test_like_two_search_condition
347
- search_conditions = [["Wes", :like],["Hays", :like]]
348
- query_fields = {'some_table.first_name' => :string,'some_table.last_name' => :string}
349
- conditions = build_query(search_conditions, query_fields)
350
-
351
- fields = ['first_name','last_name']
352
- regExs = [build_regex_for_like(fields,'keyword_0'),
353
- build_regex_for_like(fields,'keyword_1')].join('[ ]AND[ ]')
354
-
355
- assert_match /^#{regExs}$/, conditions.first
356
- assert_equal '%Wes%', conditions.last[:keyword_0]
357
- assert_equal '%Hays%', conditions.last[:keyword_1]
358
- end
359
-
360
- def test_like_two_search_conditions_with_one_not
361
- search_conditions = [["Wes", :like],["Hays", :not]]
362
- query_fields = {'some_table.first_name' => :string,'some_table.last_name' => :string}
363
- conditions = build_query(search_conditions, query_fields)
364
-
365
- fields = ['first_name','last_name']
366
- regExs = [build_regex_for_like(fields,'keyword_0'),
367
- build_regex_for_not_like(fields,'keyword_1')].join('[ ]AND[ ]')
368
-
369
- assert_match /^#{regExs}$/, conditions.first
370
- assert_equal '%Wes%', conditions.last[:keyword_0]
371
- assert_equal '%Hays%', conditions.last[:keyword_1]
372
- end
373
-
374
-
375
- # ** Helper methods **
376
- def build_regex_for_like(fields,keyword)
377
- orFields = fields.join('|')
378
- regParts = fields.collect { |field|
379
- "some_table.(#{orFields}) LIKE :#{keyword}"
380
- }.join('[ ]OR[ ]')
381
- "[\(]#{regParts}[\)]"
382
- end
383
-
384
- def build_regex_for_not_like(fields,keyword)
385
- orFields = fields.join('|')
386
- regParts = fields.collect { |field|
387
- "[\(]some_table.(#{orFields}) NOT LIKE :#{keyword} OR some_table.(#{orFields}) IS NULL[\)]"
388
- }.join('[ ]AND[ ]')
389
-
390
- "[\(]#{regParts}[\)]"
391
- end
392
-
393
- def build_regex_for_or(fields,keyword)
394
- orFields = fields.join('|')
395
- regParts = fields.collect { |field|
396
- "([(](some_table.(first_name|age) (LIKE|=) :keyword_0[a-zA-Z0-9_]+ OR )?some_table.(first_name|age) (LIKE|=) :keyword_0[a-zA-Z0-9_]+)[)]"
397
- }.join('[ ]OR[ ]')
398
-
399
- "[\(]#{regParts}[\)]"
400
- end
401
-
402
-
403
- def build_regex_for_date(fields,keyword)
404
- orFields = fields.join('|')
405
- regParts = fields.collect { |field|
406
- "some_table.(#{orFields}) = :#{keyword}"
407
- }.join('[ ]OR[ ]')
408
- "[\(]#{regParts}[\)]"
409
- end
410
- end