Skip to content

Instantly share code, notes, and snippets.

@rick
Created November 2, 2008 22:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rick/21755 to your computer and use it in GitHub Desktop.
Save rick/21755 to your computer and use it in GitHub Desktop.
thinking sphinx custom rspec matchers
module ThinkingSphinxIndexMatcher
class HaveIndex
def initialize(expected)
@expected = expected
end
def matches?(target)
@target = target
target.sphinx_indexes.collect(&:fields).flatten.collect(&:columns).flatten.collect(&:__name).include?(@expected)
end
def failure_message
"expected #{@target} to index #{@expected}"
end
def negative_failure_message
"expected #{@target} not to index #{@expected}, but did"
end
end
def have_index(expected)
HaveIndex.new(expected)
end
end
require File.dirname(__FILE__) + '/../spec_helper'
describe ThinkingSphinxIndexMatcher::HaveIndex do
before :each do
@expected = 'some val'
@target = 'some tgt'
@matcher = ThinkingSphinxIndexMatcher::HaveIndex.new(@expected)
end
describe 'when initialized' do
it 'should accept an expected value' do
lambda { ThinkingSphinxIndexMatcher::HaveIndex.new(@expected) }.should_not raise_error(ArgumentError)
end
it 'should require an expected value' do
lambda { ThinkingSphinxIndexMatcher::HaveIndex.new }.should raise_error(ArgumentError)
end
it 'should store the expected value' do
ThinkingSphinxIndexMatcher::HaveIndex.new(@expected).instance_variable_get('@expected').should == @expected
end
end
it 'should have a failure message' do
@matcher.should respond_to(:failure_message)
end
describe 'failure message' do
before :each do
@matcher.instance_variable_set('@target', @target)
end
it 'should explain the problem, containing the target and expected value' do
@matcher.failure_message.should == 'expected some tgt to index some val'
end
end
it 'should have a negative failure message' do
@matcher.should respond_to(:negative_failure_message)
end
describe 'negative failure message' do
before :each do
@matcher.instance_variable_set('@target', @target)
end
it 'should explain the problem, containing the target and expected value' do
@matcher.negative_failure_message.should == 'expected some tgt not to index some val, but did'
end
end
it 'should tell if a target matches the expectation' do
@matcher.should respond_to(:matches?)
end
describe 'telling if a target matches the expectation' do
before :each do
@target.stub!(:sphinx_indexes).and_return([])
end
it 'should accept a target' do
lambda { @matcher.matches?(@target) }.should_not raise_error(ArgumentError)
end
it 'should require a target' do
lambda { @matcher.matches? }.should raise_error(ArgumentError)
end
it 'should set the target' do
@matcher.matches?(@target)
@matcher.instance_variable_get('@target').should == @target
end
it "should go through the target's indexes" do
@target.should_receive(:sphinx_indexes).and_return([])
@matcher.matches?(@target)
end
describe 'when the target has no indexes' do
before :each do
@target.stub!(:sphinx_indexes).and_return([])
end
it 'should return a false value' do
result = @matcher.matches?(@target)
(!!result).should == false
end
end
describe 'when the target has indexes' do
describe 'and an index includes the expected value' do
before :each do
indexes = [
stub('index', :fields => []),
stub('index', :fields => [stub('field', :columns => [])]),
stub('index', :fields => [stub('field', :columns => [stub('column', :__name => 'blah')])]),
stub('index', :fields => [stub('field', :columns => [stub('column', :__name => @expected)])]),
stub('index', :fields => [stub('field', :columns => [stub('column', :__name => 'other'), stub('column', :__name => 'feh')])])
]
@target.stub!(:sphinx_indexes).and_return(indexes)
end
it 'should return a true value' do
result = @matcher.matches?(@target)
(!!result).should == true
end
end
describe 'and no index includes the expected value' do
before :each do
indexes = [
stub('index', :fields => []),
stub('index', :fields => [stub('field', :columns => [])]),
stub('index', :fields => [stub('field', :columns => [stub('column', :__name => 'blah')])]),
stub('index', :fields => [stub('field', :columns => [stub('column', :__name => 'other'), stub('column', :__name => 'feh')])])
]
@target.stub!(:sphinx_indexes).and_return(indexes)
end
it 'should return a false value' do
result = @matcher.matches?(@target)
(!!result).should == false
end
end
end
end
end
describe ThinkingSphinxIndexMatcher do
before :each do
@expected = 'some val'
@helper = Object.new
@helper.extend(ThinkingSphinxIndexMatcher)
@matcher = stub('matcher')
ThinkingSphinxIndexMatcher::HaveIndex.stub!(:new).and_return(@matcher)
end
it "should provide a 'have_index' method" do
@helper.should respond_to(:have_index)
end
describe "'have_index' method" do
it 'should accept an expected value' do
lambda { @helper.have_index(@expected) }.should_not raise_error(ArgumentError)
end
it 'should require an expected value' do
lambda { @helper.have_index }.should raise_error(ArgumentError)
end
it 'should create a matcher for the expected value' do
ThinkingSphinxIndexMatcher::HaveIndex.should_receive(:new).with(@expected)
@helper.have_index(@expected)
end
it 'should return the matcher' do
@helper.have_index(@expected).should == @matcher
end
end
end
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
# from the project root directory.
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'spec'
require 'spec/rails'
Spec::Runner.configure do |config|
# If you're not using ActiveRecord you should remove these
# lines, delete config/database.yml and disable :active_record
# in your config/boot.rb
config.use_transactional_fixtures = true
config.use_instantiated_fixtures = false
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
# == Fixtures
#
# You can declare fixtures for each example_group like this:
# describe "...." do
# fixtures :table_a, :table_b
#
# Alternatively, if you prefer to declare them only once, you can
# do so right here. Just uncomment the next line and replace the fixture
# names with your fixtures.
#
# config.global_fixtures = :table_a, :table_b
#
# If you declare global fixtures, be aware that they will be declared
# for all of your examples, even those that don't use them.
#
# You can also declare which fixtures to use (for example fixtures for test/fixtures):
#
# config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
#
# == Mock Framework
#
# RSpec uses it's own mocking framework by default. If you prefer to
# use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
#
# == Notes
#
# For more information take a look at Spec::Example::Configuration and Spec::Runner
end
require File.expand_path(File.dirname(__FILE__) + '/custom_matchers')
Spec::Runner.configure do |config|
config.include ThinkingSphinxIndexMatcher
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment