diff --git a/Rakefile b/Rakefile index 07cdd58c..2a09dcdd 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,43 @@ Dir['tasks/*.rake'].each { |file| load(file) } task :default => [:test] + +namespace :test do + + desc "Run tests for all configured databases in test/database.yml" + task :all do + + databases = YAML.load(File.read(File.dirname(__FILE__) + '/test/database.yml')) + databases.each do |database, config| + puts "\nRunning testsuite on #{database} database...\n\n" + sh "rake test DATABASE=#{database}" + end + puts "\nFinished testing for all configured databases!" + puts "(Configure databases by adjusting test/database.yml)" + end + + task :single do + database = ENV['DATABASE'] || 'sqlite3' + puts "Running testsuite on #{database} database...\n" + sh "rake test DATABASE=#{database}" + end + + desc "Run tests on SQLite3 database" + task :sqlite3 do + puts "Running testsuite on SQLite3 database...\n" + sh 'rake test DATABASE=sqlite3' + end + + desc "Run tests on MySQL database" + task :mysql do + puts "Running testsuite on MySQL database...\n" + sh 'rake test DATABASE=mysql' + end + + desc "Run tests on PostgrSQL database" + task :postgresql do + puts "Running testsuite on PostgreSQL database...\n" + sh 'rake test DATABASE=postgresql' + end + +end \ No newline at end of file diff --git a/test/database.yml b/test/database.yml new file mode 100644 index 00000000..f19c7c7f --- /dev/null +++ b/test/database.yml @@ -0,0 +1,17 @@ +sqlite3: + adapter: "sqlite3" + database: ":memory:" + +mysql: + adapter: "mysql" + host: "localhost" + user: "root" + password: + database: "scoped_search_test" + +postgresql: + adapter: "postgresql" + host: "localhost" + username: "sstest" + password: "sstest" + database: "scoped_search_test" diff --git a/test/integration/api_test.rb b/test/integration/api_test.rb new file mode 100644 index 00000000..fc419280 --- /dev/null +++ b/test/integration/api_test.rb @@ -0,0 +1,52 @@ +require "#{File.dirname(__FILE__)}/../test_helper.rb" + +class ScopedSearch::Test::API < Test::Unit::TestCase + + def self.const_missing(const) + ScopedSearch::Test::Models.const_get(const) + end + + def setup + ScopedSearch::Test::establish_connection + ScopedSearch::Test::DatabaseSchema.up + end + + def teardown + ScopedSearch::Test::DatabaseSchema.down + end + + def test_enabling + assert !Foo.respond_to?(:search_for) + Foo.searchable_on :string_field, :text_field, :date_field + assert Foo.respond_to?(:search_for) + + assert_equal ActiveRecord::NamedScope::Scope, Foo.search_for('test').class + end + + def test_search_only_fields + Foo.searchable_on :only => [:string_field, :text_field, :date_field] + assert Foo.respond_to?(:search_for) + assert_equal Foo.scoped_search_fields.size, 3 + assert Foo.scoped_search_fields.include?(:string_field) + assert Foo.scoped_search_fields.include?(:text_field) + assert Foo.scoped_search_fields.include?(:date_field) + end + + def test_search_except_fields + Foo.searchable_on :except => [:id, :ignored_field, :created_at, :updated_at] + assert Foo.respond_to?(:search_for) + assert_equal Foo.scoped_search_fields.size, 3 + assert Foo.scoped_search_fields.include?(:string_field) + assert Foo.scoped_search_fields.include?(:text_field) + assert Foo.scoped_search_fields.include?(:date_field) + end + + def test_search_with_only_and_except + # :except should be ignored if :only is specified. + Foo.searchable_on({:only => [:text_field], :except => [:text_field]}) + assert Foo.respond_to?(:search_for) + assert_equal Foo.scoped_search_fields.size, 1 + assert Foo.scoped_search_fields.include?(:text_field), ':except should be ignored if :only is specified' + end + +end \ No newline at end of file diff --git a/test/lib/test_models.rb b/test/lib/test_models.rb new file mode 100644 index 00000000..ba81c6a0 --- /dev/null +++ b/test/lib/test_models.rb @@ -0,0 +1,148 @@ +module ScopedSearch::Test::Models + + class Foo < ActiveRecord::Base + def self.create_corpus! + create!(:string_field => "Programmer 123", :text_field => nil, :ignored_field => "123456", :date_field => '2000-01-01') + create!(:string_field => "Jim", :text_field => "Henson", :ignored_field => "123456a", :date_field => '2001-04-15') + create!(:string_field => "Jim", :text_field => "Bush", :ignored_field => "123456b", :date_field => '2001-04-17') + create!(:string_field => "Wes", :text_field => "Hays", :ignored_field => "123456c", :date_field => '1980-09-27') + create!(:string_field => "Bob", :text_field => "Hays", :ignored_field => "123456d", :date_field => '2002-11-09') + create!(:string_field => "Dogs", :text_field => "Pit Bull", :ignored_field => "123456e", :date_field => '2002-12-26') + create!(:string_field => "Dogs", :text_field => "Eskimo", :ignored_field => "123456f", :date_field => '2003-03-19') + create!(:string_field => "Cows", :text_field => "Farms", :ignored_field => "123456g", :date_field => '2004-05-01') + create!(:string_field => "Hello World", :text_field => "Hello Moon", :ignored_field => "123456h", :date_field => '2004-07-11') + create!(:string_field => "Hello World", :text_field => "Goodnight Moon", :ignored_field => "123456i", :date_field => '2004-09-12') + create!(:string_field => "Happy Cow", :text_field => "Sad Cow", :ignored_field => "123456j", :date_field => '2005-02-05') + create!(:string_field => "Happy Frog", :text_field => "Sad Frog", :ignored_field => "123456k", :date_field => '2006-03-09') + create!(:string_field => "Excited Frog", :text_field => "Sad Frog", :ignored_field => "123456l", :date_field => '2006-07-15') + create!(:string_field => "Man made", :text_field => "Woman made", :ignored_field => "123456m", :date_field => '2007-06-13') + create!(:string_field => "Cat Toys", :text_field => "Frog Toys", :ignored_field => "123456n", :date_field => '2008-03-04') + create!(:string_field => "Happy Toys", :text_field => "Sad Toys", :ignored_field => "123456n", :date_field => '2008-05-12') + + create!(:string_field => "My son was born on 7/15/2006 and weighed 5.5 lbs", + :text_field => "Sad Toys", + :ignored_field => "123456n", + :date_field => '2008-09-22') + end + end + + class User < ActiveRecord::Base + belongs_to :group + belongs_to :address + has_many :notes + has_and_belongs_to_many :locations + + has_many :offices, :dependent => :destroy + has_many :clients, :through => :offices + + def self.create_corpus! + create!(:first_name => 'Willem', :last_name => 'Van Bergen', :login => 'wvanbergen', :group_id => 1, :address_id => 1) + create!(:first_name => 'Wes', :last_name => 'Hays', :login => 'weshays', :group_id => 1, :address_id => 2) + create!(:first_name => 'John', :last_name => 'Dell', :login => 'jdell', :group_id => 2, :address_id => 3) + create!(:first_name => 'Ray', :last_name => 'York', :login => 'ryork', :group_id => 3, :address_id => 4) + create!(:first_name => 'Anna', :last_name => 'Landis', :login => 'alandis', :group_id => 4, :address_id => 5) + + user = self.find_by_first_name('Willem') + user.locations << ScopedSearch::Test::Models::Location.find_by_name('Office') + + user = self.find_by_first_name('Wes') + user.locations << ScopedSearch::Test::Models::Location.find_by_name('Store') + + user = self.find_by_first_name('John') + user.locations << ScopedSearch::Test::Models::Location.find_by_name('Office') + + user = self.find_by_first_name('Ray') + user.locations << ScopedSearch::Test::Models::Location.find_by_name('Home') + + user = self.find_by_first_name('Anna') + user.locations << ScopedSearch::Test::Models::Location.find_by_name('Beach') + end + end + + class Client < ActiveRecord::Base + has_many :offices, :dependent => :destroy + has_many :users, :through => :offices + def self.create_corpus! + create!(:first_name => 'Bob', :last_name => 'Smith') + create!(:first_name => 'Sam', :last_name => 'Lovett') + create!(:first_name => 'Sally', :last_name => 'May') + create!(:first_name => 'Mary', :last_name => 'Smith') + create!(:first_name => 'Darren', :last_name => 'Johnson') + end + end + + class Office < ActiveRecord::Base + belongs_to :client + belongs_to :user + def self.create_corpus! + create!(:name => 'California Office', :user_id => 1, :client_id => 1) + create!(:name => 'California Office', :user_id => 2, :client_id => 2) + create!(:name => 'California Office', :user_id => 3, :client_id => 3) + create!(:name => 'Reno Office', :user_id => 4, :client_id => 4) + create!(:name => 'Reno Office', :user_id => 5, :client_id => 5) + end + end + + class Group < ActiveRecord::Base + has_many :users + def self.create_corpus! + create!(:name => 'System Administrator') + create!(:name => 'Software Managers') + create!(:name => 'Office Managers') + create!(:name => 'Accounting') + end + end + + class Location < ActiveRecord::Base + has_and_belongs_to_many :users + def self.create_corpus! + create!(:name => 'Home') + create!(:name => 'Office') + create!(:name => 'Store') + create!(:name => 'Beach') + end + end + + class Note < ActiveRecord::Base + belongs_to :user + def self.create_corpus! + wes = ScopedSearch::Test::Models::User.find_by_first_name('Wes') + john = ScopedSearch::Test::Models::User.find_by_first_name('John') + + create!(:user_id => wes.id, + :title => 'Purchases', + :content => "1) Linksys Router. 2) Network Cable") + + create!(:user_id => wes.id, + :title => 'Tasks', + :content => 'Clean my car, walk the dog and mow the yard buy milk') + + create!(:user_id => wes.id, + :title => 'Grocery List', + :content => 'milk, gum, apples') + + create!(:user_id => wes.id, + :title => 'Stocks to watch', + :content => 'MA, AAPL, V and SSO. Straddle MA at 200 with JAN 09 options') + + create!(:user_id => john.id, + :title => 'Spec Tests', + :content => 'Spec Tests... Spec Tests... Spec Tests!!') + + create!(:user_id => john.id, + :title => 'Things To Do', + :content => '1) Did I mention Spec Tests!!!, 2) Buy Linksys Router WRT160N') + end + end + + class Address < ActiveRecord::Base + has_one :user + def self.create_corpus! + create!(:street => '800 Haskell St', :city => 'Reno', :state => 'NV', :postal_code => '89509') + create!(:street => '2499 Dorchester Rd', :city => 'Charleston', :state => 'SC', :postal_code => '29414') + create!(:street => '474 Mallard Way', :city => 'Fernley', :state => 'NV', :postal_code => '89408') + create!(:street => '1600 Montero Ct', :city => 'Sparks', :state => 'NV', :postal_code => '89434') + create!(:street => '200 4th St', :city => 'Sparks', :state => 'NV', :postal_code => '89434') + end + end +end diff --git a/test/lib/test_schema.rb b/test/lib/test_schema.rb new file mode 100644 index 00000000..2dffb862 --- /dev/null +++ b/test/lib/test_schema.rb @@ -0,0 +1,66 @@ +ActiveRecord::Migration.verbose = false unless ENV.has_key?('DEBUG') + +class ScopedSearch::Test::DatabaseSchema < ActiveRecord::Migration + + def self.up + + create_table :foos do |t| + t.string :string_field + t.text :text_field + t.string :ignored_field + t.date :date_field + t.timestamps + end + + create_table :users do |t| + t.string :first_name, :last_name, :login + t.integer :group_id + t.integer :address_id + end + + create_table :clients do |t| + t.string :first_name, :last_name + end + + create_table :offices do |t| + t.string :name + t.integer :user_id, :client_id + end + + create_table :groups do |t| + t.string :name + end + + create_table :locations do |t| + t.string :name + end + + create_table :locations_users, :id => false, :force => true do |t| + t.integer :user_id + t.integer :location_id + end + + create_table :notes do |t| + t.string :title + t.text :content + t.integer :user_id + end + + create_table :addresses do |t| + t.string :street, :city, :state, :postal_code + end + end + + def self.down + drop_table :foos + drop_table :users + drop_table :clients + drop_table :offices + drop_table :groups + drop_table :locations + drop_table :locations_users + drop_table :notes + drop_table :addresses + end + +end \ No newline at end of file diff --git a/test/search_for_test.rb b/test/search_for_test.rb deleted file mode 100644 index 9b876b7f..00000000 --- a/test/search_for_test.rb +++ /dev/null @@ -1,166 +0,0 @@ -require File.dirname(__FILE__) + '/test_helper' - -class ScopedSearchTest < Test::Unit::TestCase - - def setup - case ENV['DATABASE'] - when 'mysql' - create_mysql_connection - when 'postgresql' - create_postgresql_connection - else 'sqlite3' - create_sqlite3_connection - end - InitialSchema.up - SearchTestModel.create_corpus! - Group.create_corpus! - Location.create_corpus! - Address.create_corpus! - User.create_corpus! - Client.create_corpus! - Office.create_corpus! - Note.create_corpus! - end - - def teardown - InitialSchema.down - end - - def test_enabling - assert !SearchTestModel.respond_to?(:search_for) - SearchTestModel.searchable_on :string_field, :text_field, :date_field - assert SearchTestModel.respond_to?(:search_for) - - assert_equal ActiveRecord::NamedScope::Scope, SearchTestModel.search_for('test').class - end - - def test_search_only_fields - SearchTestModel.searchable_on :only => [:string_field, :text_field, :date_field] - assert SearchTestModel.respond_to?(:search_for) - assert_equal SearchTestModel.scoped_search_fields.size, 3 - assert SearchTestModel.scoped_search_fields.include?(:string_field) - assert SearchTestModel.scoped_search_fields.include?(:text_field) - assert SearchTestModel.scoped_search_fields.include?(:date_field) - end - - def test_search_except_fields - SearchTestModel.searchable_on :except => [:id, :ignored_field, :created_at, :updated_at] - assert SearchTestModel.respond_to?(:search_for) - assert_equal SearchTestModel.scoped_search_fields.size, 3 - assert SearchTestModel.scoped_search_fields.include?(:string_field) - assert SearchTestModel.scoped_search_fields.include?(:text_field) - assert SearchTestModel.scoped_search_fields.include?(:date_field) - end - - def test_search_with_only_and_except - # :except should be ignored if :only is specified. - SearchTestModel.searchable_on({:only => [:text_field], :except => [:text_field]}) - assert SearchTestModel.respond_to?(:search_for) - assert_equal SearchTestModel.scoped_search_fields.size, 1 - assert SearchTestModel.scoped_search_fields.include?(:text_field), ':except should be ignored if :only is specified' - end - - def test_search - SearchTestModel.searchable_on :string_field, :text_field, :date_field - - assert_equal SearchTestModel.count, SearchTestModel.search_for('').count - assert_equal 0, SearchTestModel.search_for('456').count - assert_equal 2, SearchTestModel.search_for('hays').count - assert_equal 1, SearchTestModel.search_for('hay ob').count - assert_equal 15, SearchTestModel.search_for('o').count - assert_equal 2, SearchTestModel.search_for('-o').count - assert_equal 15, SearchTestModel.search_for('-Jim').count - assert_equal 1, SearchTestModel.search_for('Jim -Bush').count - assert_equal 1, SearchTestModel.search_for('"Hello World" -"Goodnight Moon"').count - assert_equal 2, SearchTestModel.search_for('Wes OR Bob').count - assert_equal 3, SearchTestModel.search_for('"Happy cow" OR "Sad Frog"').count - assert_equal 3, SearchTestModel.search_for('"Man made" OR Dogs').count - assert_equal 2, SearchTestModel.search_for('Cows OR "Frog Toys"').count - - # ** DATES ** - # - # The next two dates are invalid therefore it will be ignored. - # Since it is just a date being searched for it will also - # be searched for in text fields regardless of whether or - # not it is a valid date. - assert_equal 0, SearchTestModel.search_for('2/30/1980').count - assert_equal 0, SearchTestModel.search_for('99/99/9999').count - - assert_equal 1, SearchTestModel.search_for('9/27/1980').count - assert_equal 1, SearchTestModel.search_for('hays 9/27/1980').count - assert_equal 0, SearchTestModel.search_for('hays 2/30/1980').count - - assert_equal 1, SearchTestModel.search_for('< 12/01/1980').count - assert_equal 6, SearchTestModel.search_for('> 2006/1/1').count - - assert_equal 5, SearchTestModel.search_for('< 12/26/2002').count - assert_equal 6, SearchTestModel.search_for('<= 12/26/2002').count - - assert_equal 6, SearchTestModel.search_for('> 2/5/2005').count - assert_equal 7, SearchTestModel.search_for('>= 2/5/2005').count - - assert_equal 3, SearchTestModel.search_for('1/1/2005 TO 1/1/2007').count - - assert_equal 2, SearchTestModel.search_for('Happy 1/1/2005 TO 1/1/2007').count - - # This should return one with a date of 7/15/2006 found in the text. - assert_equal 2, SearchTestModel.search_for('7/15/2006').count - end - - def test_search_belongs_to_association - User.searchable_on :first_name, :last_name, :group_name - - assert_equal User.count, User.search_for('').count - assert_equal 1, User.search_for('Wes').count - assert_equal 2, User.search_for('System Administrator').count - assert_equal 2, User.search_for('Managers').count - end - - def test_search_has_many_association - User.searchable_on :first_name, :last_name, :notes_title, :notes_content - - assert_equal User.count, User.search_for('').count - assert_equal 2, User.search_for('Router').count - assert_equal 1, User.search_for('milk').count - assert_equal 1, User.search_for('"Spec Tests"').count - assert_equal 0, User.search_for('Wes "Spec Tests"').count - end - - def test_search_has_many_through_association - User.searchable_on :first_name, :last_name, :clients_first_name, :clients_last_name - - assert_equal User.count, User.search_for('').count - assert_equal 2, User.search_for('Smith').count - assert_equal 1, User.search_for('Sam').count - assert_equal 1, User.search_for('Johnson').count - end - - def test_search_has_one_association - User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code - - assert_equal User.count, User.search_for('').count - assert_equal 1, User.search_for('Fernley').count - assert_equal 4, User.search_for('NV').count - assert_equal 1, User.search_for('Haskell').count - assert_equal 2, User.search_for('89434').count - end - - def test_search_has_and_belongs_to_many_association - User.searchable_on :first_name, :last_name, :locations_name - - assert_equal User.count, User.search_for('').count - assert_equal 2, User.search_for('Office').count - assert_equal 1, User.search_for('Store').count - assert_equal 1, User.search_for('John Office').count - end - - def test_search_with_very_long_query - User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code - really_long_string = '' - 10000.times {really_long_string << 'really long string'} - assert_equal 0, User.search_for(really_long_string).count - end - -end - - diff --git a/test/test_helper.rb b/test/test_helper.rb index f7a715b9..fc5a0891 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,3 +1,5 @@ +$:.reject! { |e| e.include? 'TextMate' } + require 'test/unit' require 'rubygems' require 'active_record' @@ -5,245 +7,38 @@ require "#{File.dirname(__FILE__)}/../lib/scoped_search" -ActiveRecord::Migration.verbose = false -class InitialSchema < ActiveRecord::Migration - - def self.up - - create_table :search_test_models do |t| - t.string :string_field - t.text :text_field - t.string :ignored_field - t.date :date_field - t.timestamps - end - - create_table :users do |t| - t.string :first_name, :last_name, :login - t.integer :group_id - t.integer :address_id - end - - create_table :clients do |t| - t.string :first_name, :last_name - end - - create_table :offices do |t| - t.string :name - t.integer :user_id, :client_id - end - - create_table :groups do |t| - t.string :name - end - - create_table :locations do |t| - t.string :name - end - - create_table :locations_users, :id => false, :force => true do |t| - t.integer :user_id - t.integer :location_id - end - - create_table :notes do |t| - t.string :title - t.text :content - t.integer :user_id - end - - create_table :addresses do |t| - t.string :street, :city, :state, :postal_code - end - end - - def self.down - drop_table :search_test_models - drop_table :users - drop_table :clients - drop_table :offices - drop_table :groups - drop_table :locations - drop_table :locations_users - drop_table :notes - drop_table :addresses - end - -end - - -def create_sqlite3_connection - ActiveRecord::Base.establish_connection( - :adapter => "sqlite3", - :dbfile => ":memory:" - ) -end - -def create_postgresql_connection - ActiveRecord::Base.establish_connection( - :adapter => "postgresql", - :host => "localhost", - :username => "sstest", - :password => "sstest", - :database => "scoped_search_test" - ) -end - -def create_mysql_connection - # '/tmp/mysql.sock' is the default location and file rails looks for. - mysql_socket = ENV['MYSQLSOCKET'].nil? ? '/tmp/mysql.sock' : ENV['MYSQLSOCKET'] - ActiveRecord::Base.establish_connection( - :adapter => "mysql", - :host => "localhost", - :username => "sstest", - :password => "sstest", - :database => "scoped_search_test", - :socket => mysql_socket - ) -end - - -class SearchTestModel < ActiveRecord::Base - def self.create_corpus! - create!(:string_field => "Programmer 123", :text_field => nil, :ignored_field => "123456", :date_field => '2000-01-01') - create!(:string_field => "Jim", :text_field => "Henson", :ignored_field => "123456a", :date_field => '2001-04-15') - create!(:string_field => "Jim", :text_field => "Bush", :ignored_field => "123456b", :date_field => '2001-04-17') - create!(:string_field => "Wes", :text_field => "Hays", :ignored_field => "123456c", :date_field => '1980-09-27') - create!(:string_field => "Bob", :text_field => "Hays", :ignored_field => "123456d", :date_field => '2002-11-09') - create!(:string_field => "Dogs", :text_field => "Pit Bull", :ignored_field => "123456e", :date_field => '2002-12-26') - create!(:string_field => "Dogs", :text_field => "Eskimo", :ignored_field => "123456f", :date_field => '2003-03-19') - create!(:string_field => "Cows", :text_field => "Farms", :ignored_field => "123456g", :date_field => '2004-05-01') - create!(:string_field => "Hello World", :text_field => "Hello Moon", :ignored_field => "123456h", :date_field => '2004-07-11') - create!(:string_field => "Hello World", :text_field => "Goodnight Moon", :ignored_field => "123456i", :date_field => '2004-09-12') - create!(:string_field => "Happy Cow", :text_field => "Sad Cow", :ignored_field => "123456j", :date_field => '2005-02-05') - create!(:string_field => "Happy Frog", :text_field => "Sad Frog", :ignored_field => "123456k", :date_field => '2006-03-09') - create!(:string_field => "Excited Frog", :text_field => "Sad Frog", :ignored_field => "123456l", :date_field => '2006-07-15') - create!(:string_field => "Man made", :text_field => "Woman made", :ignored_field => "123456m", :date_field => '2007-06-13') - create!(:string_field => "Cat Toys", :text_field => "Frog Toys", :ignored_field => "123456n", :date_field => '2008-03-04') - create!(:string_field => "Happy Toys", :text_field => "Sad Toys", :ignored_field => "123456n", :date_field => '2008-05-12') - - create!(:string_field => "My son was born on 7/15/2006 and weighed 5.5 lbs", - :text_field => "Sad Toys", - :ignored_field => "123456n", - :date_field => '2008-09-22') - end -end - -class User < ActiveRecord::Base - belongs_to :group - belongs_to :address - has_many :notes - has_and_belongs_to_many :locations +module ScopedSearch::Test - has_many :offices, :dependent => :destroy - has_many :clients, :through => :offices - def self.create_corpus! - create!(:first_name => 'Willem', :last_name => 'Van Bergen', :login => 'wvanbergen', :group_id => 1, :address_id => 1) - create!(:first_name => 'Wes', :last_name => 'Hays', :login => 'weshays', :group_id => 1, :address_id => 2) - create!(:first_name => 'John', :last_name => 'Dell', :login => 'jdell', :group_id => 2, :address_id => 3) - create!(:first_name => 'Ray', :last_name => 'York', :login => 'ryork', :group_id => 3, :address_id => 4) - create!(:first_name => 'Anna', :last_name => 'Landis', :login => 'alandis', :group_id => 4, :address_id => 5) - - user = self.find_by_first_name('Willem') - user.locations << Location.find_by_name('Office') - - user = self.find_by_first_name('Wes') - user.locations << Location.find_by_name('Store') - - user = self.find_by_first_name('John') - user.locations << Location.find_by_name('Office') - - user = self.find_by_first_name('Ray') - user.locations << Location.find_by_name('Home') - - user = self.find_by_first_name('Anna') - user.locations << Location.find_by_name('Beach') + def self.establish_connection + if ENV['DATABASE'] + ScopedSearch::Test.establish_named_connection(ENV['DATABASE']) + else + ScopedSearch::Test.establish_default_connection + end end -end - -class Client < ActiveRecord::Base - has_many :offices, :dependent => :destroy - has_many :users, :through => :offices - def self.create_corpus! - create!(:first_name => 'Bob', :last_name => 'Smith') - create!(:first_name => 'Sam', :last_name => 'Lovett') - create!(:first_name => 'Sally', :last_name => 'May') - create!(:first_name => 'Mary', :last_name => 'Smith') - create!(:first_name => 'Darren', :last_name => 'Johnson') - end -end - -class Office < ActiveRecord::Base - belongs_to :client - belongs_to :user - def self.create_corpus! - create!(:name => 'California Office', :user_id => 1, :client_id => 1) - create!(:name => 'California Office', :user_id => 2, :client_id => 2) - create!(:name => 'California Office', :user_id => 3, :client_id => 3) - create!(:name => 'Reno Office', :user_id => 4, :client_id => 4) - create!(:name => 'Reno Office', :user_id => 5, :client_id => 5) - end -end - -class Group < ActiveRecord::Base - has_many :users - def self.create_corpus! - create!(:name => 'System Administrator') - create!(:name => 'Software Managers') - create!(:name => 'Office Managers') - create!(:name => 'Accounting') + + def self.establish_named_connection(name) + @database_connections ||= YAML.load(File.read("#{File.dirname(__FILE__)}/database.yml")) + raise "#{name} database not configured" if @database_connections[name.to_s].nil? + ActiveRecord::Base.establish_connection(@database_connections[name.to_s]) end -end - -class Location < ActiveRecord::Base - has_and_belongs_to_many :users - def self.create_corpus! - create!(:name => 'Home') - create!(:name => 'Office') - create!(:name => 'Store') - create!(:name => 'Beach') + + def self.establish_default_connection + ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:') end -end - -class Note < ActiveRecord::Base - belongs_to :user + def self.create_corpus! - wes = User.find_by_first_name('Wes') - john = User.find_by_first_name('John') - - create!(:user_id => wes.id, - :title => 'Purchases', - :content => "1) Linksys Router. 2) Network Cable") - - create!(:user_id => wes.id, - :title => 'Tasks', - :content => 'Clean my car, walk the dog and mow the yard buy milk') - - create!(:user_id => wes.id, - :title => 'Grocery List', - :content => 'milk, gum, apples') - - create!(:user_id => wes.id, - :title => 'Stocks to watch', - :content => 'MA, AAPL, V and SSO. Straddle MA at 200 with JAN 09 options') - - create!(:user_id => john.id, - :title => 'Spec Tests', - :content => 'Spec Tests... Spec Tests... Spec Tests!!') - - create!(:user_id => john.id, - :title => 'Things To Do', - :content => '1) Did I mention Spec Tests!!!, 2) Buy Linksys Router WRT160N') - end + ScopedSearch::Test::Models::Foo.create_corpus! + ScopedSearch::Test::Models::Location.create_corpus! + ScopedSearch::Test::Models::User.create_corpus! + ScopedSearch::Test::Models::Note.create_corpus! + ScopedSearch::Test::Models::Group.create_corpus! + ScopedSearch::Test::Models::Office.create_corpus! + ScopedSearch::Test::Models::Client.create_corpus! + ScopedSearch::Test::Models::Address.create_corpus! + end end -class Address < ActiveRecord::Base - has_one :user - def self.create_corpus! - create!(:street => '800 Haskell St', :city => 'Reno', :state => 'NV', :postal_code => '89509') - create!(:street => '2499 Dorchester Rd', :city => 'Charleston', :state => 'SC', :postal_code => '29414') - create!(:street => '474 Mallard Way', :city => 'Fernley', :state => 'NV', :postal_code => '89408') - create!(:street => '1600 Montero Ct', :city => 'Sparks', :state => 'NV', :postal_code => '89434') - create!(:street => '200 4th St', :city => 'Sparks', :state => 'NV', :postal_code => '89434') - end -end \ No newline at end of file +# Load helpers +require "#{File.dirname(__FILE__)}/lib/test_schema" +require "#{File.dirname(__FILE__)}/lib/test_models" diff --git a/test/query_conditions_builder_test.rb b/test/unit/query_conditions_builder_test.rb similarity index 99% rename from test/query_conditions_builder_test.rb rename to test/unit/query_conditions_builder_test.rb index a36e63a9..d8f91fcb 100644 --- a/test/query_conditions_builder_test.rb +++ b/test/unit/query_conditions_builder_test.rb @@ -1,6 +1,6 @@ -require File.dirname(__FILE__) + '/test_helper' +require File.dirname(__FILE__) + '/../test_helper' -class QueryConditionsBuilderTest < Test::Unit::TestCase +class ScopedSearch::Test::QueryConditionsBuilder < Test::Unit::TestCase # change this function if you switch to another query language parser def build_query(search_conditions, query_fields) diff --git a/test/query_language_test.rb b/test/unit/query_language_test.rb similarity index 97% rename from test/query_language_test.rb rename to test/unit/query_language_test.rb index 44bb3cd1..fc4276a8 100644 --- a/test/query_language_test.rb +++ b/test/unit/query_language_test.rb @@ -1,6 +1,6 @@ -require File.dirname(__FILE__) + '/test_helper' +require File.dirname(__FILE__) + '/../test_helper' -class QueryLanguageTest < Test::Unit::TestCase +class ScopedSearch::Test::QueryLanguage < Test::Unit::TestCase # change this function if you switch to another query language parser def parse_query(query) diff --git a/test/unit/search_for_test.rb b/test/unit/search_for_test.rb new file mode 100644 index 00000000..7be3d911 --- /dev/null +++ b/test/unit/search_for_test.rb @@ -0,0 +1,122 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ScopedSearch::Test::SearchFor < Test::Unit::TestCase + + def self.const_missing(const) + ScopedSearch::Test::Models.const_get(const) + end + + def setup + ScopedSearch::Test.establish_connection + ScopedSearch::Test::DatabaseSchema.up + ScopedSearch::Test.create_corpus! + end + + def teardown + ScopedSearch::Test::DatabaseSchema.down + end + + def test_search + Foo.searchable_on :string_field, :text_field, :date_field + + assert_equal Foo.count, Foo.search_for('').count + assert_equal 0, Foo.search_for('456').count + assert_equal 2, Foo.search_for('hays').count + assert_equal 1, Foo.search_for('hay ob').count + assert_equal 15, Foo.search_for('o').count + assert_equal 2, Foo.search_for('-o').count + assert_equal 15, Foo.search_for('-Jim').count + assert_equal 1, Foo.search_for('Jim -Bush').count + assert_equal 1, Foo.search_for('"Hello World" -"Goodnight Moon"').count + assert_equal 2, Foo.search_for('Wes OR Bob').count + assert_equal 3, Foo.search_for('"Happy cow" OR "Sad Frog"').count + assert_equal 3, Foo.search_for('"Man made" OR Dogs').count + assert_equal 2, Foo.search_for('Cows OR "Frog Toys"').count + + # ** DATES ** + # + # The next two dates are invalid therefore it will be ignored. + # Since it is just a date being searched for it will also + # be searched for in text fields regardless of whether or + # not it is a valid date. + assert_equal 0, Foo.search_for('2/30/1980').count + assert_equal 0, Foo.search_for('99/99/9999').count + + assert_equal 1, Foo.search_for('9/27/1980').count + assert_equal 1, Foo.search_for('hays 9/27/1980').count + assert_equal 0, Foo.search_for('hays 2/30/1980').count + + assert_equal 1, Foo.search_for('< 12/01/1980').count + assert_equal 6, Foo.search_for('> 2006/1/1').count + + assert_equal 5, Foo.search_for('< 12/26/2002').count + assert_equal 6, Foo.search_for('<= 12/26/2002').count + + assert_equal 6, Foo.search_for('> 2/5/2005').count + assert_equal 7, Foo.search_for('>= 2/5/2005').count + + assert_equal 3, Foo.search_for('1/1/2005 TO 1/1/2007').count + + assert_equal 2, Foo.search_for('Happy 1/1/2005 TO 1/1/2007').count + + # This should return one with a date of 7/15/2006 found in the text. + assert_equal 2, Foo.search_for('7/15/2006').count + end + + def test_search_belongs_to_association + User.searchable_on :first_name, :last_name, :group_name + + assert_equal User.count, User.search_for('').count + assert_equal 1, User.search_for('Wes').count + assert_equal 2, User.search_for('System Administrator').count + assert_equal 2, User.search_for('Managers').count + end + + def test_search_has_many_association + User.searchable_on :first_name, :last_name, :notes_title, :notes_content + + assert_equal User.count, User.search_for('').count + assert_equal 2, User.search_for('Router').count + assert_equal 1, User.search_for('milk').count + assert_equal 1, User.search_for('"Spec Tests"').count + assert_equal 0, User.search_for('Wes "Spec Tests"').count + end + + def test_search_has_many_through_association + User.searchable_on :first_name, :last_name, :clients_first_name, :clients_last_name + + assert_equal User.count, User.search_for('').count + assert_equal 2, User.search_for('Smith').count + assert_equal 1, User.search_for('Sam').count + assert_equal 1, User.search_for('Johnson').count + end + + def test_search_has_one_association + User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code + + assert_equal User.count, User.search_for('').count + assert_equal 1, User.search_for('Fernley').count + assert_equal 4, User.search_for('NV').count + assert_equal 1, User.search_for('Haskell').count + assert_equal 2, User.search_for('89434').count + end + + def test_search_has_and_belongs_to_many_association + User.searchable_on :first_name, :last_name, :locations_name + + assert_equal User.count, User.search_for('').count + assert_equal 2, User.search_for('Office').count + assert_equal 1, User.search_for('Store').count + assert_equal 1, User.search_for('John Office').count + end + + def test_search_with_very_long_query + User.searchable_on :first_name, :last_name, :address_street, :address_city, :address_state, :address_postal_code + really_long_string = '' + 10000.times {really_long_string << 'really long string'} + assert_equal 0, User.search_for(really_long_string).count + end + +end + +