wvanbergen-scoped_search 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,65 +1,78 @@
1
1
  = scoped_search
2
2
 
3
- This simple plugin will make it easy to search your ActiveRecord models. Searching is performed using a query string, which should be passed to the named_scope *search_for* that uses SQL %LIKE% conditions for searching (ILIKE for Postgres). You can specify what fields should be used for searching.
3
+ The <b>scoped_search</b> Rails plugin makes it easy to search your ActiveRecord models. Searching is
4
+ performed using a query string, which should be passed to the named_scope *search_for* that uses SQL
5
+ <tt>LIKE %keyword%</tt> conditions for searching (ILIKE for Postgres). You can specify what fields
6
+ should be used for searching.
4
7
 
5
8
  == Installing
6
9
 
7
- gem install wvanbergen-scoped_search -s http://gems.github.com
10
+ The recommended method to enable scoped_search in your project is adding the scoped_search gem to your environment. Add the following code to your Rails configuration in <tt>config/environment.rb</tt>:
11
+
12
+ Rails::Initializer.run do |config|
13
+ ...
14
+ config.gem 'wvanbergen-scoped_search', :lib => 'scoped_search',
15
+ source => 'http://gems.github.com/'
16
+ end
17
+
18
+ Run <tt>sudo rake gems:install</tt> to install the gem.
19
+
20
+ Another alternative is to install scoped_search as a Rails plugin:
21
+
22
+ script/plugin install git://github.com/wvanbergen/scoped_search.git
8
23
 
9
24
  == Usage
10
25
 
11
26
  First, you have to specify in what columns should be searched:
12
27
 
13
- class User < ActiveRecord::Base
14
- searchable_on :first_name, :last_name
15
- end
28
+ class User < ActiveRecord::Base
29
+ searchable_on :first_name, :last_name
30
+ end
16
31
 
17
32
 
18
33
  Now, the <b>search_for</b> scope is available for queries. You should pass a query string to the scope.
19
34
  This can be empty or nil, in which case all no search conditions are set (and all records will be returned).
20
35
 
21
- User.search_for(params[:q]).each { |project| ... }
36
+ User.search_for(params[:q]).each { |project| ... }
22
37
 
23
38
 
24
39
  You can also search on associate models. This works with <b>belongs_to</b>, <b>has_one</b>, <b>has_many</b>,
25
40
  <b>has_many :through</b>, and <b>HABTM</b>. For example if a User <b>has_many</b> Notes (title, content, created_at, updated_at)
26
41
 
27
- class User < ActiveRecord::Base
28
- has_many: notes
29
- searchable_on :first_name, :last_name, :notes_title, :notes_content
30
- end
31
-
42
+ class User < ActiveRecord::Base
43
+ has_many: notes
44
+ searchable_on :first_name, :last_name, :notes_title, :notes_content
45
+ end
32
46
 
33
47
  The search query language is simple. It supports these constructs:
34
- * <b>words:</b> some search keywords
35
- * <b>phrases:</b> "a single search phrase"
36
- * <b>negation:</b> "look for this" -"but do not look for this phrase and this" -word
37
- * <b>OR words/phrases:</b> word/phrase OR word/phrase. Example: "Hello World" OR "Hello Moon"
48
+ * <b>words:</b> <tt>some search keywords</tt>
49
+ * <b>phrases:</b> <tt>"a single search phrase"</tt>
50
+ * <b>negation:</b> <tt>"look for this" -"but do not look for this phrase and this" -word</tt>
51
+ * <b>OR words/phrases:</b> word/phrase OR word/phrase. Example: <tt>"Hello World" OR "Hello Moon"</tt>
38
52
  * <b>dates:</b> mm/dd/yyyy, dd/mm/yyyy, yyyy/mm/dd, yyyy-mm-dd
39
- * <b>date ranges:</b> > date, >= date, < date, <= date, date TO date. Examples: > mm/dd/yyyy, < yyyy-mm-dd
53
+ * <b>date ranges:</b> > date, >= date, < date, <= date, date TO date. Examples: <tt>> 30/05/1983</tt>, <tt>< 2009-01-30</tt>
40
54
 
41
- This functionality is build on named_scope. The searchable_on statement creates
55
+ This functionality is build on <tt>named_scope</tt>. The searchable_on statement creates
42
56
  a named_scope *search_for*. Because of this, you can actually chain the call with
43
57
  other scopes. For example, this can be very useful if you only want to search in
44
58
  projects that are accessible by a given user.
45
59
 
46
- class Project < ActiveRecord::Base
47
- searchable_on :name, :description
48
- named_scope :accessible_by, lambda { |user| ... }
49
- end
50
-
51
- # using chained named_scopes and will_paginate
52
- Project.accessible_by(current_user).search_for(params[:q]).paginate(:page => params[:page], :include => :tasks)
60
+ class Project < ActiveRecord::Base
61
+ searchable_on :name, :description
62
+ named_scope :accessible_by, lambda { |user| ... }
63
+ end
53
64
 
65
+ # using chained named_scopes and will_paginate
66
+ Project.accessible_by(current_user).search_for(params[:q]).paginate(:page => params[:page], :include => :tasks)
54
67
 
55
68
  == Additional resources
56
69
 
57
- * Source code: http://github.com/wvanbergen/scoped_search
70
+ * Source code: http://github.com/wvanbergen/scoped_search/tree/master
58
71
  * Project wiki: http://wiki.github.com/wvanbergen/scoped_search
59
72
  * RDoc documentation: http://wvanbergen.github.com/scoped_search
60
- * wvanbergen's blog posts: http://techblog.floorplanner.com/tag/scoped_search/
73
+ * wvanbergen's blog posts: http://techblog.floorplanner.com/tag/scoped_search
61
74
 
62
75
  == License
63
76
 
64
- This plugin is released under the MIT license. Please contact (willem AT vanbergen DOT org) if you have any suggestions or remarks.
65
-
77
+ This plugin is released under the MIT license. Please contact weshays (http://github.com/weshays)
78
+ or wvanbergen (http://github.com/wvanbergen) for any questions.
data/Rakefile CHANGED
@@ -1,43 +1,5 @@
1
1
  Dir['tasks/*.rake'].each { |file| load(file) }
2
2
 
3
+ desc 'Default: run unit tests for only sqlite.'
3
4
  task :default => [:test]
4
5
 
5
- namespace :test do
6
-
7
- desc "Run tests for all configured databases in test/database.yml"
8
- task :all do
9
-
10
- databases = YAML.load(File.read(File.dirname(__FILE__) + '/test/database.yml'))
11
- databases.each do |database, config|
12
- puts "\nRunning testsuite on #{database} database...\n\n"
13
- sh "rake test DATABASE=#{database}"
14
- end
15
- puts "\nFinished testing for all configured databases!"
16
- puts "(Configure databases by adjusting test/database.yml)"
17
- end
18
-
19
- task :single do
20
- database = ENV['DATABASE'] || 'sqlite3'
21
- puts "Running testsuite on #{database} database...\n"
22
- sh "rake test DATABASE=#{database}"
23
- end
24
-
25
- desc "Run tests on SQLite3 database"
26
- task :sqlite3 do
27
- puts "Running testsuite on SQLite3 database...\n"
28
- sh 'rake test DATABASE=sqlite3'
29
- end
30
-
31
- desc "Run tests on MySQL database"
32
- task :mysql do
33
- puts "Running testsuite on MySQL database...\n"
34
- sh 'rake test DATABASE=mysql'
35
- end
36
-
37
- desc "Run tests on PostgrSQL database"
38
- task :postgresql do
39
- puts "Running testsuite on PostgreSQL database...\n"
40
- sh 'rake test DATABASE=postgresql'
41
- end
42
-
43
- end
@@ -44,9 +44,7 @@ module ScopedSearch
44
44
  search_conditions.each_with_index do |search_condition, index|
45
45
  keyword_name = "keyword_#{index}".to_sym
46
46
  conditions << case search_condition.last
47
- # Still thinking about this one
48
- # when :integer: integer_conditions(keyword_name, search_condition.first)
49
-
47
+ # :like also handles integers
50
48
  when :like: like_condition(keyword_name, search_condition.first)
51
49
  when :not: not_like_condition(keyword_name, search_condition.first)
52
50
 
@@ -68,17 +66,18 @@ module ScopedSearch
68
66
 
69
67
  private
70
68
 
71
- # def integer_condition(keyword_name, value)
72
- # Still thinking about this one
73
- # end
74
-
75
- def like_condition(keyword_name, value)
76
- @query_params[keyword_name] = "%#{value}%"
69
+ def like_condition(keyword_name, value)
77
70
  retVal = []
78
71
  @query_fields.each do |field, field_type| #|key,value|
79
72
  if field_type == :string or field_type == :text
73
+ @query_params[keyword_name] = "%#{value}%"
80
74
  retVal << "#{field} #{@sql_like} :#{keyword_name.to_s}"
81
75
  end
76
+ if value.strip =~ /^[0-9]+$/ and (field_type == :int or field_type == :integer)
77
+ qkey = "#{keyword_name}_#{value.strip}"
78
+ @query_params[qkey.to_sym] = value.strip.to_i
79
+ retVal << "#{field} = :#{qkey}"
80
+ end
82
81
  end
83
82
  "(#{retVal.join(' OR ')})"
84
83
  end
@@ -101,10 +100,22 @@ module ScopedSearch
101
100
  keyword_name_b = "#{keyword_name.to_s}b".to_sym
102
101
  @query_params[keyword_name_a] = "%#{word1}%"
103
102
  @query_params[keyword_name_b] = "%#{word2}%"
104
- @query_fields.each do |field, field_type| #|key,value|
103
+ @query_fields.each do |field, field_type| #|key,value|
105
104
  if field_type == :string or field_type == :text
106
105
  retVal << "(#{field} #{@sql_like} :#{keyword_name_a.to_s} OR #{field} #{@sql_like} :#{keyword_name_b.to_s})"
107
106
  end
107
+ if (word1.strip =~ /^[0-9]+$/ and word2.strip =~ /^[0-9]+$/) and (field_type == :int or field_type == :integer)
108
+ qkeya = "#{keyword_name}_a_#{word1.strip}"
109
+ qkeyb = "#{keyword_name}_b_#{word2.strip}"
110
+ @query_params[qkeya] = word1.strip.to_i
111
+ @query_params[qkeyb] = word2.strip.to_i
112
+ retVal << "(#{field} = :#{qkeya} OR #{field} = :#{qkeyb})"
113
+ elsif (word1.strip =~ /^[0-9]+$/ or word2.strip =~ /^[0-9]+$/) and (field_type == :int or field_type == :integer)
114
+ num_word = word1.strip =~ /^[0-9]+$/ ? word1.strip.to_i : word2.strip.to_i
115
+ qkey = "#{keyword_name}_#{num_word}"
116
+ @query_params[qkey.to_sym] = num_word
117
+ retVal << "(#{field} = :#{qkey})"
118
+ end
108
119
  end
109
120
  "(#{retVal.join(' OR ')})"
110
121
  end
@@ -69,7 +69,7 @@ module ScopedSearch
69
69
  end
70
70
  end
71
71
  end
72
-
72
+
73
73
  return conditions_tree
74
74
  end
75
75
 
@@ -0,0 +1,20 @@
1
+ require 'yaml' unless Object::const_defined?('YAML')
2
+
3
+ namespace :test do
4
+
5
+ databases = YAML.load(File.read(File.dirname(__FILE__) + '/../test/database.yml'))
6
+
7
+ desc "Run testsuite on all configured databases in test/database.yml"
8
+ task(:all => databases.keys.map { |db| db.to_sym }) do
9
+ puts "\nFinished testing on all configured databases!"
10
+ puts "(Configure databases by adjusting test/database.yml)"
11
+ end
12
+
13
+ databases.each do |database, config|
14
+ desc "Run testsuite on #{database} database."
15
+ task database.to_sym do
16
+ puts "Running testsuite on #{database} database...\n\n"
17
+ sh "rake test DATABASE=#{database}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
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
+
@@ -35,10 +35,11 @@ class ScopedSearch::Test::API < Test::Unit::TestCase
35
35
  def test_search_except_fields
36
36
  Foo.searchable_on :except => [:id, :ignored_field, :created_at, :updated_at]
37
37
  assert Foo.respond_to?(:search_for)
38
- assert_equal Foo.scoped_search_fields.size, 3
38
+ assert_equal Foo.scoped_search_fields.size, 4
39
39
  assert Foo.scoped_search_fields.include?(:string_field)
40
40
  assert Foo.scoped_search_fields.include?(:text_field)
41
41
  assert Foo.scoped_search_fields.include?(:date_field)
42
+ assert Foo.scoped_search_fields.include?(:some_int_field)
42
43
  end
43
44
 
44
45
  def test_search_with_only_and_except
@@ -2,22 +2,22 @@ module ScopedSearch::Test::Models
2
2
 
3
3
  class Foo < ActiveRecord::Base
4
4
  def self.create_corpus!
5
- create!(:string_field => "Programmer 123", :text_field => nil, :ignored_field => "123456", :date_field => '2000-01-01')
6
- create!(:string_field => "Jim", :text_field => "Henson", :ignored_field => "123456a", :date_field => '2001-04-15')
7
- create!(:string_field => "Jim", :text_field => "Bush", :ignored_field => "123456b", :date_field => '2001-04-17')
8
- create!(:string_field => "Wes", :text_field => "Hays", :ignored_field => "123456c", :date_field => '1980-09-27')
9
- create!(:string_field => "Bob", :text_field => "Hays", :ignored_field => "123456d", :date_field => '2002-11-09')
10
- create!(:string_field => "Dogs", :text_field => "Pit Bull", :ignored_field => "123456e", :date_field => '2002-12-26')
11
- create!(:string_field => "Dogs", :text_field => "Eskimo", :ignored_field => "123456f", :date_field => '2003-03-19')
12
- create!(:string_field => "Cows", :text_field => "Farms", :ignored_field => "123456g", :date_field => '2004-05-01')
13
- create!(:string_field => "Hello World", :text_field => "Hello Moon", :ignored_field => "123456h", :date_field => '2004-07-11')
14
- create!(:string_field => "Hello World", :text_field => "Goodnight Moon", :ignored_field => "123456i", :date_field => '2004-09-12')
15
- create!(:string_field => "Happy Cow", :text_field => "Sad Cow", :ignored_field => "123456j", :date_field => '2005-02-05')
16
- create!(:string_field => "Happy Frog", :text_field => "Sad Frog", :ignored_field => "123456k", :date_field => '2006-03-09')
17
- create!(:string_field => "Excited Frog", :text_field => "Sad Frog", :ignored_field => "123456l", :date_field => '2006-07-15')
18
- create!(:string_field => "Man made", :text_field => "Woman made", :ignored_field => "123456m", :date_field => '2007-06-13')
19
- create!(:string_field => "Cat Toys", :text_field => "Frog Toys", :ignored_field => "123456n", :date_field => '2008-03-04')
20
- create!(:string_field => "Happy Toys", :text_field => "Sad Toys", :ignored_field => "123456n", :date_field => '2008-05-12')
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
21
 
22
22
  create!(:string_field => "My son was born on 7/15/2006 and weighed 5.5 lbs",
23
23
  :text_field => "Sad Toys",
@@ -36,11 +36,11 @@ module ScopedSearch::Test::Models
36
36
  has_many :clients, :through => :offices
37
37
 
38
38
  def self.create_corpus!
39
- create!(:first_name => 'Willem', :last_name => 'Van Bergen', :login => 'wvanbergen', :group_id => 1, :address_id => 1)
40
- create!(:first_name => 'Wes', :last_name => 'Hays', :login => 'weshays', :group_id => 1, :address_id => 2)
41
- create!(:first_name => 'John', :last_name => 'Dell', :login => 'jdell', :group_id => 2, :address_id => 3)
42
- create!(:first_name => 'Ray', :last_name => 'York', :login => 'ryork', :group_id => 3, :address_id => 4)
43
- create!(:first_name => 'Anna', :last_name => 'Landis', :login => 'alandis', :group_id => 4, :address_id => 5)
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
44
 
45
45
  user = self.find_by_first_name('Willem')
46
46
  user.locations << ScopedSearch::Test::Models::Location.find_by_name('Office')
@@ -8,12 +8,14 @@ class ScopedSearch::Test::DatabaseSchema < ActiveRecord::Migration
8
8
  t.string :string_field
9
9
  t.text :text_field
10
10
  t.string :ignored_field
11
+ t.integer :some_int_field
11
12
  t.date :date_field
12
13
  t.timestamps
13
14
  end
14
15
 
15
16
  create_table :users do |t|
16
17
  t.string :first_name, :last_name, :login
18
+ t.integer :age
17
19
  t.integer :group_id
18
20
  t.integer :address_id
19
21
  end
@@ -35,6 +35,15 @@ class ScopedSearch::Test::QueryConditionsBuilder < Test::Unit::TestCase
35
35
  assert_equal '%Wes%', conditions.last[:keyword_0]
36
36
  end
37
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
+
38
47
  def test_not_like_search_condition
39
48
  search_conditions = [["Wes", :not]]
40
49
  query_fields = {'some_table.first_name' => :string}
@@ -54,6 +63,16 @@ class ScopedSearch::Test::QueryConditionsBuilder < Test::Unit::TestCase
54
63
  assert_equal '%Hays%', conditions.last[:keyword_0b]
55
64
  end
56
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
+
57
76
  # ** less_than_date **
58
77
  def test_less_than_date_search_condition_with_only_a_date_field_to_search
59
78
  search_conditions = [['< 09/27/1980', :less_than_date]]
@@ -374,12 +393,13 @@ class ScopedSearch::Test::QueryConditionsBuilder < Test::Unit::TestCase
374
393
  def build_regex_for_or(fields,keyword)
375
394
  orFields = fields.join('|')
376
395
  regParts = fields.collect { |field|
377
- "[\(]some_table.(#{orFields}) LIKE :#{keyword}a OR some_table.(#{orFields}) LIKE :#{keyword}b[\)]"
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_]+)[)]"
378
397
  }.join('[ ]OR[ ]')
379
398
 
380
399
  "[\(]#{regParts}[\)]"
381
400
  end
382
401
 
402
+
383
403
  def build_regex_for_date(fields,keyword)
384
404
  orFields = fields.join('|')
385
405
  regParts = fields.collect { |field|
@@ -30,12 +30,13 @@ class ScopedSearch::Test::QueryLanguage < Test::Unit::TestCase
30
30
  assert_equal 2, parsed.length
31
31
  assert_equal 'willem', parsed.last.first
32
32
 
33
- parsed = parse_query(" hallo willem van\tbergen ")
34
- assert_equal 4, parsed.length
33
+ parsed = parse_query(" hallo willem van\tbergen 25")
34
+ assert_equal 5, parsed.length
35
35
  assert_equal 'hallo', parsed[0].first
36
36
  assert_equal 'willem', parsed[1].first
37
37
  assert_equal 'van', parsed[2].first
38
38
  assert_equal 'bergen', parsed[3].first
39
+ assert_equal '25', parsed[4].first
39
40
  end
40
41
 
41
42
  def test_quoted_keywords
@@ -56,6 +57,10 @@ class ScopedSearch::Test::QueryLanguage < Test::Unit::TestCase
56
57
  assert_equal 2, parsed.length
57
58
  assert_equal 'hallo wi', parsed[0].first
58
59
  assert_equal 'llem', parsed[1].first
60
+
61
+ parsed = parse_query('"hays 25"')
62
+ assert_equal 1, parsed.length
63
+ assert_equal 'hays 25', parsed[0].first
59
64
  end
60
65
 
61
66
  def test_quote_escaping
@@ -17,7 +17,7 @@ class ScopedSearch::Test::SearchFor < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_search
20
- Foo.searchable_on :string_field, :text_field, :date_field
20
+ Foo.searchable_on :string_field, :text_field, :date_field, :some_int_field
21
21
 
22
22
  assert_equal Foo.count, Foo.search_for('').count
23
23
  assert_equal 0, Foo.search_for('456').count
@@ -32,6 +32,7 @@ class ScopedSearch::Test::SearchFor < Test::Unit::TestCase
32
32
  assert_equal 3, Foo.search_for('"Happy cow" OR "Sad Frog"').count
33
33
  assert_equal 3, Foo.search_for('"Man made" OR Dogs').count
34
34
  assert_equal 2, Foo.search_for('Cows OR "Frog Toys"').count
35
+ assert_equal 1, Foo.search_for('700').count
35
36
 
36
37
  # ** DATES **
37
38
  #
@@ -83,12 +84,13 @@ class ScopedSearch::Test::SearchFor < Test::Unit::TestCase
83
84
  end
84
85
 
85
86
  def test_search_has_many_through_association
86
- User.searchable_on :first_name, :last_name, :clients_first_name, :clients_last_name
87
+ User.searchable_on :first_name, :last_name, :age, :clients_first_name, :clients_last_name
87
88
 
88
89
  assert_equal User.count, User.search_for('').count
89
90
  assert_equal 2, User.search_for('Smith').count
90
91
  assert_equal 1, User.search_for('Sam').count
91
92
  assert_equal 1, User.search_for('Johnson').count
93
+ assert_equal 1, User.search_for('28').count
92
94
  end
93
95
 
94
96
  def test_search_has_one_association
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wvanbergen-scoped_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Bergen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-01-29 00:00:00 -08:00
13
+ date: 2009-02-23 00:00:00 -08:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -24,14 +24,10 @@ extensions: []
24
24
 
25
25
  extra_rdoc_files:
26
26
  - README.rdoc
27
- - CHANGELOG.rdoc
28
- - TODO.rdoc
29
27
  files:
30
- - CHANGELOG.rdoc
31
28
  - LICENSE
32
29
  - README.rdoc
33
30
  - Rakefile
34
- - TODO.rdoc
35
31
  - init.rb
36
32
  - lib
37
33
  - lib/scoped_search
@@ -40,6 +36,8 @@ files:
40
36
  - lib/scoped_search/query_language_parser.rb
41
37
  - lib/scoped_search/reg_tokens.rb
42
38
  - tasks
39
+ - tasks/database_tests.rake
40
+ - tasks/documentation.rake
43
41
  - tasks/github-gem.rake
44
42
  - test
45
43
  - test/database.yml
data/CHANGELOG.rdoc DELETED
@@ -1,13 +0,0 @@
1
- = Changelog for scoped_search
2
-
3
- The following changes were incorporated in each scoped_search release.
4
-
5
- == scoped_search 0.3.0
6
- - Detection of column types so they can be handled properly
7
- - Date based queries supported on date and time fields
8
-
9
- == scoped_search 0.2.0
10
- - OR keyword supported in query language
11
-
12
- == scoped_search 0.1.0
13
- - Initial version
data/TODO.rdoc DELETED
@@ -1,6 +0,0 @@
1
- = TODO items for scoped_search
2
-
3
- Contact me at my GitHub account (http://github.com/wvanbergen) if you want to help out.
4
-
5
- == Documentation & testing
6
- - Add rdoc and comments to code