diff --git a/server/lib/picky/indexed/categories.rb b/server/lib/picky/indexed/categories.rb index e76d2b8d..dad134e8 100644 --- a/server/lib/picky/indexed/categories.rb +++ b/server/lib/picky/indexed/categories.rb @@ -43,9 +43,10 @@ def similar_tokens_for token text = token.text categories.inject([]) do |result, category| next_token = token - # TODO adjust either this or the amount of similar in index + # TODO Adjust either this or the amount of similar in index. + # Also, rename next -> next_similar. # - while next_token = next_token.next(category) + while next_token = next_token.next_similar_token(category) result << next_token if next_token && next_token.text != text end result diff --git a/server/lib/picky/query/token.rb b/server/lib/picky/query/token.rb index a8d51447..356f9780 100644 --- a/server/lib/picky/query/token.rb +++ b/server/lib/picky/query/token.rb @@ -118,37 +118,19 @@ def tokenized tokenizer def possible_combinations_in type type.possible_combinations self end - + + # Returns a token with the next similar text. # + # TODO Rewrite this. It is hard to understand. Also spec performance. # - def from token - new_token = token.dup - new_token.instance_variable_set :@text, @text - new_token.instance_variable_set :@partial, @partial - new_token.instance_variable_set :@original, @original - new_token.instance_variable_set :@qualifier, @qualifier - # TODO - # - # token.instance_variable_set :@similarity, @similarity - new_token - end - - # TODO Rewrite, also next_similar. - # - def next category - token = from self + def next_similar_token category + token = self.dup token if token.next_similar category.bundle_for(token) end - # Sets and returns the next similar word. # - # TODO Use array, shift. - # def next_similar bundle - @text = similarity(bundle).next if similar? - rescue StopIteration => stop_iteration - # reset_similar # TODO - nil # TODO + @text = (similarity(bundle).shift || return) if similar? end # Lazy similar reader. # @@ -157,8 +139,11 @@ def similarity bundle = nil end # Returns an enumerator that traverses over the similar. # + # Note: The dup isn't too nice – since it is needed on account of the shift, above. + # (We avoid a StopIteration exception. Which of both is less evil?) + # def generate_similarity_for bundle - (bundle.similar(@text) || []).each + bundle.similar(@text).dup || [] end # Generates a solr term from this token. diff --git a/server/spec/lib/query/token_spec.rb b/server/spec/lib/query/token_spec.rb index cb595bcc..fdaf3a2f 100644 --- a/server/spec/lib/query/token_spec.rb +++ b/server/spec/lib/query/token_spec.rb @@ -8,6 +8,73 @@ Query::Qualifiers.instance.prepare end + describe 'next_similar_token' do + before(:each) do + @bundle = stub :bundle, :similar => [:array, :of, :similar] + @category = stub :category, :bundle_for => @bundle + + @token = Query::Token.processed 'similar~' + end + it 'returns the right next tokens' do + next_token = @token.next_similar_token @category + next_token.text.should == :array + next_token = next_token.next_similar_token @category + next_token.text.should == :of + next_token = next_token.next_similar_token @category + next_token.text.should == :similar + next_token = next_token.next_similar_token @category + next_token.should == nil + end + end + + describe 'next_similar' do + before(:each) do + @bundle = stub :bundle + end + context 'similar' do + context 'with stub' do + before(:each) do + @bundle.stub! :similar => [:array, :of, :similar] + + @token = Query::Token.processed 'similar~' + end + it 'generates all similar' do + @token.next_similar(@bundle).should == :array + @token.next_similar(@bundle).should == :of + @token.next_similar(@bundle).should == :similar + @token.next_similar(@bundle).should == nil + end + it 'should have a certain text' do + @token.next_similar @bundle + @token.next_similar @bundle + @token.next_similar @bundle + @token.next_similar @bundle + + @token.text.should == :similar + end + end + end + context 'non-similar' do + context 'with stub' do + before(:each) do + @bundle.stub! :similar => [:array, :of, :similar] + + @token = Query::Token.processed 'nonsimilar' + end + it 'generates all similar' do + @token.next_similar(@bundle).should == nil + end + # TODO + # + # it 'should have a certain text' do + # @token.next_similar @bundle + # + # @token.text.should == :nonsimilar + # end + end + end + end + describe "generate_similarity_for" do before(:each) do @bundle = stub :bundle @@ -18,16 +85,16 @@ before(:each) do @bundle.stub! :similar => [:array, :of, :similar] end - it "returns an enumerator" do - @token.generate_similarity_for(@bundle).to_a.size.should == 3 + it "returns an array of the right size" do + @token.generate_similarity_for(@bundle).size.should == 3 end end context "without similar" do before(:each) do - @bundle.stub! :similar => nil + @bundle.stub! :similar => [] end - it "returns an enumerator with 0 entries" do - @token.generate_similarity_for(@bundle).to_a.size.should == 0 + it "returns an array of the right size" do + @token.generate_similarity_for(@bundle).size.should == 0 end end end