require 'spec_helper' describe Picky::Query::Allocation do before(:each) do @backend = stub :backend @index = stub :index, :result_identifier => :some_result_identifier, :backend => @backend @combinations = stub :combinations, :empty? => false @allocation = described_class.new @index, @combinations end describe "hash" do it "delegates to the combinations" do @combinations.should_receive(:hash).once.with @allocation.hash end end describe "to_s" do before(:each) do @combinations.stub! :to_result => 'combinations_result' end context "allocation.count > 0" do before(:each) do @allocation.stub! :count => 10 @allocation.stub! :score => :score @allocation.stub! :ids => :ids end it "represents correctly" do @allocation.to_s.should == "Allocation([:some_result_identifier, :score, 10, \"combinations_result\", :ids])" end end end describe 'remove' do it 'should delegate to the combinations' do @combinations.should_receive(:remove).once.with [:some_categories] @allocation.remove [:some_categories] end end describe 'process!' do context 'no ids' do before(:each) do @allocation.stub! :calculate_ids => [] end it 'should process right' do @allocation.process!(0, 0).should == [] end it 'should process right' do @allocation.process!(0, 10).should == [] end it 'should process right' do @allocation.process!(20, 0).should == [] end it 'should process right' do @allocation.process!(20, 10).should == [] end end context 'with ids' do before(:each) do @allocation.stub! :calculate_ids => [1,2,3,4,5,6,7,8,9,10] end it 'should process right' do @allocation.process!(0, 0).should == [] end it 'should process right' do @allocation.process!(0, 10).should == [] end it 'should process right' do @allocation.process!(5, 0).should == [1,2,3,4,5] end it 'should process right' do @allocation.process!(5, 5).should == [6,7,8,9,10] end it 'should process right' do @allocation.process!(20, 0).should == [1,2,3,4,5,6,7,8,9,10] end it 'should process right' do @allocation.process!(20, 5).should == [6,7,8,9,10] end it 'should process right' do @allocation.process!(20, 10).should == [] end end context 'with symbol ids' do before(:each) do @allocation.stub! :calculate_ids => [:a,:b,:c,:d,:e,:f,:g,:h,:i,:j] end it 'should process right' do @allocation.process!(0, 0).should == [] end it 'should process right' do @allocation.process!(0, 10).should == [] end it 'should process right' do @allocation.process!(5, 0).should == [:a,:b,:c,:d,:e] end it 'should process right' do @allocation.process!(5, 5).should == [:f,:g,:h,:i,:j] end it 'should process right' do @allocation.process!(20, 0).should == [:a,:b,:c,:d,:e,:f,:g,:h,:i,:j] end it 'should process right' do @allocation.process!(20, 5).should == [:f,:g,:h,:i,:j] end it 'should process right' do @allocation.process!(20, 10).should == [] end end context 'with ids & illegal ids' do before(:each) do @allocation.stub! :calculate_ids => [1,2,3,4,5,6,7,8,9,10] end it 'should process right' do @allocation.process!(0, 0, [1,3,7]).should == [] end it 'should process right' do @allocation.process!(0, 10, [1,3,7]).should == [] end it 'should process right' do @allocation.process!(5, 0, [1,3,7]).should == [2,4,5,6,8] end it 'should process right' do @allocation.process!(5, 5, [1,3,7]).should == [9,10] end it 'should process right' do @allocation.process!(20, 0, [1,3,7]).should == [2,4,5,6,8,9,10] end it 'should process right' do @allocation.process!(20, 5, [1,3,7]).should == [9,10] end it 'should process right' do @allocation.process!(20, 10, [1,3,7]).should == [] end end end describe 'to_result' do context 'with few combinations' do before(:each) do @allocation = described_class.new @index, stub(:combinations, :empty? => false, :to_result => [:some_result]) @allocation.instance_variable_set :@score, :some_score end context 'with ids' do it 'should output an array of information' do @backend.stub! :ids => [1,2,3] @allocation.process! 20, 0 @allocation.to_result.should == [:some_result_identifier, :some_score, 3, [:some_result], [1, 2, 3]] end end end context 'with results' do before(:each) do combinations = stub :combinations, :empty? => false, :to_result => [:some_result1, :some_result2] @allocation = described_class.new @index, combinations @allocation.instance_variable_set :@score, :some_score end context 'with ids' do it 'should output an array of information' do @backend.stub! :ids => [1,2,3] @allocation.process! 20, 0 @allocation.to_result.should == [:some_result_identifier, :some_score, 3, [:some_result1, :some_result2], [1, 2, 3]] end end end context 'without results' do before(:each) do @allocation = described_class.new @index, stub(:combinations, :empty? => true) @allocation.instance_variable_set :@score, :some_score end it 'should return nil' do @backend.stub! :ids => [] @allocation.process! 20, 0 @allocation.to_result.should == nil end end end describe 'to_json' do before(:each) do @allocation = described_class.new @index, stub(:combination, :empty? => false, :to_result => [:some_result1, :some_result2]) @allocation.instance_variable_set :@score, :some_score end it 'should output the correct json string' do @backend.stub! :ids => [1,2,3,4,5,6,7] @allocation.process! 20, 0 @allocation.to_json.should == '["some_result_identifier","some_score",7,["some_result1","some_result2"],[1,2,3,4,5,6,7]]' end end describe "calculate_score" do context 'non-empty combinations' do it 'should delegate to backend and combinations' do @backend.should_receive(:weight).once.with(@combinations).and_return 1 @combinations.should_receive(:boost_for).once.with(:some_boosts).and_return 2 @allocation.calculate_score(:some_boosts).should == 3 end end context 'empty combinations' do before(:each) do @combinations.stub! :empty? => true end it 'should just be zero' do @allocation.calculate_score(:some_weights).should == 0 end end end describe "<=>" do it "should sort higher first" do first = described_class.new @index, [] first.instance_variable_set :@score, 20 second = described_class.new @index, [] second.instance_variable_set :@score, 10 first.<=>(second).should == -1 end end describe "sort!" do it "should sort correctly" do first = described_class.new @index, :whatever first.instance_variable_set :@score, 20 second = described_class.new @index, :whatever second.instance_variable_set :@score, 10 third = described_class.new @index, :whatever third.instance_variable_set :@score, 5 allocations = [second, third, first] allocations.sort!.should == [first, second, third] end end describe "process!" do before(:each) do @amount = stub :amount @offset = stub :offset @ids = stub :ids, :size => :some_original_size, :slice! => :some_sliced_ids @allocation.stub! :calculate_ids => @ids end it 'should calculate_ids' do @allocation.should_receive(:calculate_ids).once.with(@amount, @offset).and_return @ids @allocation.process! @amount, @offset end it 'should get the original ids count' do @allocation.process! @amount, @offset @allocation.count.should == :some_original_size end it 'should slice! the ids down' do @ids.should_receive(:slice!).once.with @offset, @amount @allocation.process! @amount, @offset end it 'should return the sliced ids' do @allocation.process!(@amount, @offset).should == :some_sliced_ids end it 'should assign the sliced ids correctly' do @allocation.process! @amount, @offset @allocation.ids.should == :some_sliced_ids end end end