From 74445d04aa95723d113afbb96577b10f7238b424 Mon Sep 17 00:00:00 2001 From: Alexander Lang Date: Sat, 17 Nov 2012 18:49:26 +0100 Subject: [PATCH] adds removing deleted documents from view results when include_docs=true --- Gemfile.lock | 2 +- lib/couch_potato/view/custom_view_spec.rb | 22 ++++++++++---------- lib/couch_potato/view/model_view_spec.rb | 4 +++- spec/unit/custom_view_spec_spec.rb | 24 ++++++++++++++++++++++ spec/unit/model_view_spec_spec.rb | 25 ++++++++++++++++++++++- spec/views_spec.rb | 11 ++++++++++ 6 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 spec/unit/custom_view_spec_spec.rb diff --git a/Gemfile.lock b/Gemfile.lock index f0b642d7..0ec06cf3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -48,7 +48,7 @@ PLATFORMS DEPENDENCIES couch_potato! rake - rspec (>= 2.0) + rspec (~> 2.11.0) therubyracer timecop tzinfo diff --git a/lib/couch_potato/view/custom_view_spec.rb b/lib/couch_potato/view/custom_view_spec.rb index 59ebaca7..b37151c8 100644 --- a/lib/couch_potato/view/custom_view_spec.rb +++ b/lib/couch_potato/view/custom_view_spec.rb @@ -8,35 +8,35 @@ class CustomViewSpec < BaseViewSpec def map_function options[:map] end - + def reduce_function options[:reduce] end - + def view_parameters {:include_docs => options[:include_docs] || false}.merge(super) end - + def process_results(results) if count? results['rows'].first.try(:[], 'value') || 0 - else + else results['rows'].map do |row| if row['doc'].instance_of?(klass) row['doc'] else - klass.json_create row['doc'] || row['value'].merge(:_id => row['id'] || row['key']) + result = row['doc'] || (row['value'].merge(:_id => row['id'] || row['key']) unless view_parameters[:include_docs]) + klass.json_create result if result end - end + end.compact end end - - private - + + private + def count? view_parameters[:reduce] end - end end -end \ No newline at end of file +end diff --git a/lib/couch_potato/view/model_view_spec.rb b/lib/couch_potato/view/model_view_spec.rb index 6e06c8a3..3ad182d2 100644 --- a/lib/couch_potato/view/model_view_spec.rb +++ b/lib/couch_potato/view/model_view_spec.rb @@ -140,7 +140,9 @@ def process_results(results) if count? results['rows'].first.try(:[], 'value') || 0 else - results['rows'].map { |row| row['doc'] || row['id'] } + results['rows'].map {|row| + row['doc'] || (row['id'] unless view_parameters[:include_docs]) + }.compact end end diff --git a/spec/unit/custom_view_spec_spec.rb b/spec/unit/custom_view_spec_spec.rb new file mode 100644 index 00000000..052fc300 --- /dev/null +++ b/spec/unit/custom_view_spec_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe CouchPotato::View::CustomViewSpec, '#process_results' do + it 'returns the documents' do + spec = CouchPotato::View::CustomViewSpec.new(Child, 'all', {}, {}) + processed_results = spec.process_results('rows' => [{'doc' => {JSON.create_id => 'Child'}}]) + + expect(processed_results.map{|row| row.class}).to eql([Child]) + end + + it 'returns values where there are no documents' do + spec = CouchPotato::View::CustomViewSpec.new(Child, 'all', {}, {:include_docs => false}) + processed_results = spec.process_results('rows' => [{'value' => {JSON.create_id => 'Child'}}]) + + expect(processed_results.map{|row| row.class}).to eql([Child]) + end + + it 'filters out rows without documents when include_docs=true (i.e. doc has been deleted)' do + spec = CouchPotato::View::CustomViewSpec.new(Child, 'all', {}, {:include_docs => true}) + processed_results = spec.process_results('rows' => [{'value' => {JSON.create_id => 'Child'}}]) + + expect(processed_results).to be_empty + end +end diff --git a/spec/unit/model_view_spec_spec.rb b/spec/unit/model_view_spec_spec.rb index fc7c5a43..d28199e6 100644 --- a/spec/unit/model_view_spec_spec.rb +++ b/spec/unit/model_view_spec_spec.rb @@ -1,6 +1,29 @@ require 'spec_helper' -describe CouchPotato::View::ModelViewSpec, 'map_function' do +describe CouchPotato::View::ModelViewSpec, '#process_results' do + it 'returns the documents' do + spec = CouchPotato::View::ModelViewSpec.new(Object, 'all', {}, {}) + processed_results = spec.process_results('rows' => [{'doc' => 'doc-1'}]) + + expect(processed_results).to eql(['doc-1']) + end + + it 'returns ids where there are no documents' do + spec = CouchPotato::View::ModelViewSpec.new(Object, 'all', {}, {:include_docs => false}) + processed_results = spec.process_results('rows' => [{'id' => 'doc-1'}]) + + expect(processed_results).to eql(['doc-1']) + end + + it 'filters out rows without documents when include_docs=true (i.e. doc has been deleted)' do + spec = CouchPotato::View::ModelViewSpec.new(Object, 'all', {}, {:include_docs => true}) + processed_results = spec.process_results('rows' => [{'id' => 'doc-1'}]) + + expect(processed_results).to be_empty + end +end + +describe CouchPotato::View::ModelViewSpec, '#map_function' do it "should include conditions" do spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:conditions => 'doc.closed = true'}, {} spec.map_function.should include('if(doc.ruby_class && doc.ruby_class == \'Object\' && (doc.closed = true))') diff --git a/spec/views_spec.rb b/spec/views_spec.rb index 87787aa1..638b9560 100644 --- a/spec/views_spec.rb +++ b/spec/views_spec.rb @@ -278,4 +278,15 @@ class Coworker @db.view(Coworker.all(:list => :append_doe)).first.name.should == 'joe doe' end end + + describe 'with stale views' do + it 'does not return deleted documents' do + build = Build.new + @db.save_document! build + @db.view(Build.timeline) + @db.destroy build + + expect(@db.view(Build.timeline(:stale => 'ok'))).to be_empty + end + end end