require "spec_helper" describe ScopedSearch::Definition do before(:each) do @klass = mock_activerecord_class @definition = ScopedSearch::Definition.new(@klass) @definition.stub(:setup_adapter) @klass.stub(:scoped_search_definition).and_return(@definition) end describe ScopedSearch::Definition::Field do describe '#initialize' do it "should raise an exception with missing field or 'on' keyword" do lambda { @definition.define }.should raise_error(ArgumentError, "Missing field or 'on' keyword argument") end it "should raise an exception with unknown keyword arguments" do lambda { @definition.define(:field, :nonexisting => 'foo') }.should raise_error(ArgumentError, "Unknown arguments to scoped_search: nonexisting") end it "should alias :in to :relation" do ActiveSupport::Deprecation.should_receive(:warn).with("'in' argument deprecated, prefer 'relation' since scoped_search 4.0.0", anything) @definition.define(:field, :in => 'foo').relation.should eq('foo') end it "should accept :relation" do ActiveSupport::Deprecation.should_not_receive(:warn) @definition.define(:field, :relation => 'foo').relation.should eq('foo') end it "should alias :alias to :aliases" do ActiveSupport::Deprecation.should_receive(:warn).with("'alias' argument deprecated, prefer aliases: [..] since scoped_search 4.0.0", anything) @definition.define(:field, :alias => 'foo') @definition.fields.keys.should eq([:field, :foo]) end it "should accept :relation" do ActiveSupport::Deprecation.should_not_receive(:warn) @definition.define(:field, :aliases => ['foo']) @definition.fields.keys.should eq([:field, :foo]) end end describe '#column' do it "should raise an exception when using an unknown field" do lambda { @definition.define(:on => 'nonexisting').column }.should raise_error(ActiveRecord::UnknownAttributeError) end it "should not raise an exception when using an unknown field" do lambda { @definition.define(:on => 'existing').column }.should_not raise_error end end end describe '#initialize' do it "should create the named scope when" do ScopedSearch::Definition.new(@klass) @klass.should respond_to(:search_for) end it "should not create the named scope if it already exists" do @klass.stub(:search_for) @klass.should_not_receive(:define_singleton_method) ScopedSearch::Definition.new(@klass) end end describe '#define_field' do it "should add to fields" do field = instance_double('ScopedSearch::Definition::Field') @definition.define_field('test', field) @definition.fields.should eq(test: field) @definition.unique_fields.should eq([field]) end it "should add aliases" do field = instance_double('ScopedSearch::Definition::Field') @definition.define_field('test', field) @definition.define_field('alias', field) @definition.fields.should eq(test: field, alias: field) @definition.unique_fields.should eq([field]) end it "should ignore duplicate field names" do field1 = instance_double('ScopedSearch::Definition::Field') field2 = instance_double('ScopedSearch::Definition::Field') @definition.define_field('test', field1) @definition.define_field('test', field2) @definition.fields.should eq(test: field1) @definition.unique_fields.should eq([field1, field2]) end end describe '#fields' do before(:each) do @subklass = mock_activerecord_subclass(@klass) @subdefinition = ScopedSearch::Definition.new(@subklass) @subdefinition.stub(:setup_adapter) end it "should return fields from class" do field = @definition.define(on: 'foo') @definition.fields.should eq(foo: field) end it "should return fields from parent class" do field = @definition.define(on: 'foo') @subdefinition.fields.should eq(foo: field) end it "should combine fields from class and parent class" do field1 = @definition.define(on: 'foo') field2 = @subdefinition.define(on: 'foo', only_explicit: true) field3 = @subdefinition.define(on: 'bar') @subdefinition.fields.should eq(foo: field2, bar: field3) end end describe '#default_fields_for' do it "finds fields when there's a field not directly mapped to a DB column" do @definition.define(:on => :custom_flag, :complete_value => { :true => true, :false => false }, :ext_method => :search_by_custom_flag) @definition.default_fields_for("").should eq([]) end end end