Skip to content

Commit

Permalink
Switched back to rspec
Browse files Browse the repository at this point in the history
Switched back to rspec. It's for real this time. I liked matchy/context
but I got tired of my tests breaking every time I updated one of them.
  • Loading branch information
Mat Brown committed Jan 13, 2009
1 parent 8851120 commit 6794991
Show file tree
Hide file tree
Showing 23 changed files with 451 additions and 436 deletions.
7 changes: 2 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
coverage
README.txt
.*.swp
/doc/
pkg
sunspot-solr.pid
*.swp
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ end

require 'newgem/tasks' # load /tasks/*.rake
Dir['tasks/**/*.rake'].each { |t| load t }

task :default => :spec
218 changes: 218 additions & 0 deletions spec/api/build_search_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
require File.join(File.dirname(__FILE__), 'spec_helper')

describe 'Search' do
it 'should search by keywords' do
connection.should_receive(:query).with('(keyword search) AND (type:Post)', :filter_queries => [], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :keywords => 'keyword search'
session.search Post do
keywords 'keyword search'
end
end

it 'should scope by exact match with a string' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['title_s:My\ Pet\ Post'], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :conditions => { :title => 'My Pet Post' }
session.search Post do
with.title 'My Pet Post'
end
end

it 'should ignore nonexistant fields in hash scope' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => [], :start => 0, :rows => config.pagination.default_per_page)
session.search Post, :conditions => { :bogus => 'Field' }
end

it 'should raise an ArgumentError for nonexistant fields in block scope' do
lambda do
session.search Post do
with.bogus 'Field'
end
end.should raise_error(ArgumentError)
end

it 'should scope by exact match with time' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['published_at_d:1983\-07\-08T09\:00\:00Z'], :start => 0, :rows => config.pagination.default_per_page).twice
time = Time.parse('1983-07-08 05:00:00 -0400')
session.search Post, :conditions => { :published_at => time }
session.search Post do
with.published_at time
end
end

it 'should scope by less than match with float' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[* TO 3\.0]'], :start => 0, :rows => config.pagination.default_per_page).twice

session.search Post, :conditions => { :average_rating => 3.0 } do
conditions.interpret :average_rating, :less_than
end

session.search Post do
with.average_rating.less_than 3.0
end
end

it 'should scope by greater than match with float' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[3\.0 TO *]'], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :conditions => { :average_rating => 3.0 } do
conditions.interpret :average_rating, :greater_than
end
session.search Post do
with.average_rating.greater_than 3.0
end
end

it 'should scope by between match with float' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['average_rating_f:[2\.0 TO 4\.0]'], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :conditions => { :average_rating => [2.0, 4.0] } do
conditions.interpret :average_rating, :between
end
session.search Post do
with.average_rating.between 2.0..4.0
end
end

it 'should scope by any match with integer' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['category_ids_im:(2 OR 7 OR 12)'], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :conditions => { :category_ids => [2, 7, 12] }
session.search Post do
with.category_ids.any_of [2, 7, 12]
end
end

it 'should scope by all match with integer' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['category_ids_im:(2 AND 7 AND 12)'], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :conditions => { :category_ids => [2, 7, 12] } do
conditions.interpret :category_ids, :all_of
end
session.search Post do
with.category_ids.all_of [2, 7, 12]
end
end

it 'should allow setting of default conditions' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['average_rating_f:2\.0'], :start => 0, :rows => config.pagination.default_per_page)
session.search Post do
conditions.default :average_rating, 2.0
end
end

it 'should not use default condition value if condition provided' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => ['average_rating_f:3\.0'], :start => 0, :rows => config.pagination.default_per_page)
session.search Post, :conditions => { :average_rating => 3.0 } do
conditions.default :average_rating, 2.0
end
end

it 'should paginate using default per_page' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => [], :rows => 30, :start => 30).twice
session.search Post, :page => 2
session.search Post do
paginate :page => 2
end
end

it 'should paginate using provided per_page' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => [], :rows => 15, :start => 45).twice
session.search Post, :page => 4, :per_page => 15
session.search Post do
paginate :page => 4, :per_page => 15
end
end

it 'should order' do
connection.should_receive(:query).with('(type:Post)', :filter_queries => [], :sort => [{ :average_rating_f => :descending }], :start => 0, :rows => config.pagination.default_per_page).twice
session.search Post, :order => 'average_rating desc'
session.search Post do
order_by :average_rating, :desc
end
end

it 'should build search for multiple types' do
connection.should_receive(:query).with('(type:(Post OR Comment))', :filter_queries => [], :start => 0, :rows => config.pagination.default_per_page)
session.search(Post, Comment)
end

it 'should allow search on fields common to all types' do
connection.should_receive(:query).with('(type:(Post OR Comment))', :filter_queries => ['published_at_d:1983\-07\-08T09\:00\:00Z'], :start => 0, :rows => config.pagination.default_per_page).twice
time = Time.parse('1983-07-08 05:00:00 -0400')
session.search Post, Comment, :conditions => { :published_at => time }
session.search Post, Comment do
with.published_at time
end
end

it 'should raise exception if search scoped to field not common to all types' do
lambda do
session.search Post, Comment do
with.blog_id 1
end
end.should raise_error(ArgumentError)
end

it 'should raise exception if search scoped to field configured differently between types' do
lambda do
session.search Post, Comment do
with.average_rating 2.2 # this is a float in Post but an integer in Comment
end
end.should raise_error(ArgumentError)
end

it 'should ignore condition if field is not common to all types' do
connection.should_receive(:query).with('(type:(Post OR Comment))', :filter_queries => [], :start => 0, :rows => config.pagination.default_per_page)
session.search Post, Comment, :conditions => { :blog_id => 1 }
end

it 'should raise ArgumentError if bogus field scoped' do
lambda do
session.search Post do
with.bogus.equal_to :field
end
end.should raise_error(ArgumentError)
end

it 'should raise NoMethodError if bogus operator referenced' do
lambda do
session.search Post do
with.category_ids.resembling :bogus_condition
end
end.should raise_error(NoMethodError)
end

it 'should raise ArgumentError if no :page argument given to paginate' do
lambda do
session.search Post do
paginate
end
end.should raise_error(ArgumentError)
end

it 'should raise ArgumentError if bogus argument given to paginate' do
lambda do
session.search Post do
paginate :page => 4, :ugly => :puppy
end
end.should raise_error(ArgumentError)
end

it 'should raise NoMethodError if more than one argument passed to scope method' do # or should it?
lambda do
session.search Post do
with.category_ids 4, 5
end
end.should raise_error(NoMethodError)
end

private

def config
@config ||= Sunspot::Configuration.build
end

def connection
@connection ||= mock('connection')
end

def session
@session ||= Sunspot::Session.new(config, connection)
end
end
112 changes: 112 additions & 0 deletions spec/api/indexer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
require File.join(File.dirname(__FILE__), 'spec_helper')

describe 'indexer' do
describe 'when indexing an object' do
it 'should index id and type' do
connection.should_receive(:add).with(hash_including(:id => "Post #{post.id}", :type => ['Post', 'BaseClass']))
session.index post
end

it 'should index text' do
post :title => 'A Title', :body => 'A Post'
connection.should_receive(:add).with(hash_including(:title_text => 'A Title', :body_text => 'A Post'))
session.index post
end

it 'should correctly index a string attribute field' do
post :title => 'A Title'
connection.should_receive(:add).with(hash_including(:title_s => 'A Title'))
session.index post
end

it 'should correctly index an integer attribute field' do
post :blog_id => 4
connection.should_receive(:add).with(hash_including(:blog_id_i => '4'))
session.index post
end

it 'should correctly index a float attribute field' do
post :average_rating => 2.23
connection.should_receive(:add).with(hash_including(:average_rating_f => '2.23'))
session.index post
end

it 'should allow indexing by a multiple-value field' do
post :category_ids => [3, 14]
connection.should_receive(:add).with(hash_including(:category_ids_im => ['3', '14']))
session.index post
end

it 'should correctly index a time field' do
post :published_at => Time.parse('1983-07-08 05:00:00 -0400')
connection.should_receive(:add).with(hash_including(:published_at_d => '1983-07-08T09:00:00Z'))
session.index post
end

it 'should correctly index a virtual field' do
post :title => 'The Blog Post'
connection.should_receive(:add).with(hash_including(:sort_title_s => 'blog post'))
session.index post
end

it 'should correctly index a field that is defined on a superclass' do
Sunspot.setup(BaseClass) { string :author_name }
post :author_name => 'Mat Brown'
connection.should_receive(:add).with(hash_including(:author_name_s => 'Mat Brown'))
session.index post
end

it 'should remove an object from the index' do
connection.should_receive(:delete).with("Post #{post.id}")
session.remove(post)
end

it 'should be able to remove everything from the index' do
connection.should_receive(:delete_by_query).with("type:[* TO *]")
session.remove_all
end

it 'should be able to remove everything of a given class from the index' do
connection.should_receive(:delete_by_query).with("type:Post")
session.remove_all(Post)
end
end

it 'should throw a NoMethodError only if a nonexistent type is defined' do
lambda { Sunspot.setup(Post) { string :author_name }}.should_not raise_error
lambda { Sunspot.setup(Post) { bogus :journey }}.should raise_error(NoMethodError)
end

it 'should throw a NoMethodError if a nonexistent field argument is passed' do
lambda { Sunspot.setup(Post) { string :author_name, :bogus => :argument }}.should raise_error(ArgumentError)
end

it 'should throw an ArgumentError if an attempt is made to index an object that has no configuration' do
lambda { session.index(Time.now) }.should raise_error(ArgumentError)
end

it 'should throw an ArgumentError if single-value field tries to index multiple values' do
lambda do
Sunspot.setup(Post) { string :author_name }
session.index(post(:author_name => ['Mat Brown', 'Matthew Brown']))
end.should raise_error(ArgumentError)
end

private

def config
Sunspot::Configuration.build
end

def connection
@connection ||= mock('connection')
end

def session
@session ||= Sunspot::Session.new(config, connection)
end

def post(attrs = {})
@post ||= Post.new(attrs)
end
end
Loading

0 comments on commit 6794991

Please sign in to comment.