Moving tests for class proxy and fixing issue with finding first

This commit is contained in:
Sam Lown 2010-06-18 20:07:34 +02:00
parent 5580caf346
commit 061c7a0154
5 changed files with 164 additions and 110 deletions

View file

@ -140,7 +140,7 @@ module CouchRest
elsif m.to_s =~ /^find_(by_.+)/
view_name = $1
if has_view?(view_name)
return find_first_from_view(view_name, *args)
return first_from_view(view_name, *args)
end
end
super

View file

@ -94,9 +94,10 @@ module CouchRest
docs
end
def find_first_from_view(name, *args)
(args[1] ||= {})[:database] = @database
doc = @klass.find_first_from_view(name, args)
def first_from_view(name, *args)
# add to first hash available, or add to end
(args.last.is_a?(Hash) ? args.last : (args << {}).last)[:database] = @database
doc = @klass.first_from_view(name, *args)
doc.database = @database if doc && doc.respond_to?(:database)
doc
end

View file

@ -102,15 +102,24 @@ module CouchRest
fetch_view_with_docs(db, name, query, raw, &block)
end
# Find the first entry that matches the provided key.
# Request like:
# Find the first entry in the view. If the second parameter is a string
# it will be used as the key for the request, for example:
#
# Course.find_first_from_view('teachers', 'Fred')
# Course.first_from_view('by_teacher', 'Fred')
#
def find_first_from_view(name, *args)
key = args[0]
query = args[1] || {}
query.update(:limit => 1, :key => key)
# More advanced requests can be performed by providing a hash:
#
# Course.first_from_view('by_teacher', :startkey => 'bbb', :endkey => 'eee')
#
def first_from_view(name, *args)
query = {:limit => 1}
case args.first
when String, Array
query.update(args[1]) unless args[1].nil?
query[:key] = args.first
when Hash
query.update(args.first)
end
view(name, query).first
end

View file

@ -0,0 +1,128 @@
require File.expand_path("../../spec_helper", __FILE__)
class UnattachedDoc < CouchRest::ExtendedDocument
# Note: no use_database here
property :title
property :questions
property :professor
view_by :title
end
describe "Proxy Class" do
before(:all) do
reset_test_db!
# setup the class default doc to save the design doc
UnattachedDoc.use_database nil # just to be sure it is really unattached
@us = UnattachedDoc.on(DB)
%w{aaa bbb ddd eee}.each do |title|
u = @us.new(:title => title)
u.save
@first_id ||= u.id
end
end
it "should query all" do
rs = @us.all
rs.length.should == 4
end
it "should count" do
@us.count.should == 4
end
it "should make the design doc upon first query" do
@us.by_title
doc = @us.design_doc
doc['views']['all']['map'].should include('UnattachedDoc')
end
it "should merge query params" do
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
rs.length.should == 3
end
it "should query via view" do
view = @us.view :by_title
designed = @us.by_title
view.should == designed
end
it "should query via first_from_view" do
UnattachedDoc.should_receive(:first_from_view).with('by_title', 'bbb', {:database => DB})
@us.first_from_view('by_title', 'bbb')
end
it "should query via first_from_view with complex options" do
UnattachedDoc.should_receive(:first_from_view).with('by_title', {:key => 'bbb', :database => DB})
@us.first_from_view('by_title', :key => 'bbb')
end
it "should query via first_from_view with complex extra options" do
UnattachedDoc.should_receive(:first_from_view).with('by_title', 'bbb', {:limit => 1, :database => DB})
@us.first_from_view('by_title', 'bbb', :limit => 1)
end
it "should yield" do
things = []
@us.view(:by_title) do |thing|
things << thing
end
things[0]["doc"]["title"].should =='aaa'
end
it "should yield with by_key method" do
things = []
@us.by_title do |thing|
things << thing
end
things[0]["doc"]["title"].should =='aaa'
end
it "should get from specific database" do
u = @us.get(@first_id)
u.title.should == "aaa"
end
it "should get first" do
u = @us.first
u.title.should =~ /\A...\z/
end
it "should set database on first retreived document" do
u = @us.first
u.database.should === DB
end
it "should set database on all retreived documents" do
@us.all.each do |u|
u.database.should === DB
end
end
it "should set database on each retreived document" do
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
rs.length.should == 3
rs.each do |u|
u.database.should === DB
end
end
it "should set database on document retreived by id" do
u = @us.get(@first_id)
u.database.should === DB
end
it "should not attempt to set database on raw results using :all" do
@us.all(:raw => true).each do |u|
u.respond_to?(:database).should be_false
end
end
it "should not attempt to set database on raw results using view" do
@us.by_title(:raw => true).each do |u|
u.respond_to?(:database).should be_false
end
end
# Sam Lown 2010-04-07
# Removed as unclear why this should happen as before my changes
# this happend by accident, not explicitly.
# If requested, this feature should be added as a specific method.
#
#it "should clean up design docs left around on specific database" do
# @us.by_title
# original_id = @us.model_design_doc['_rev']
# Unattached.view_by :professor
# @us.by_professor
# @us.model_design_doc['_rev'].should_not == original_id
#end
end

View file

@ -152,6 +152,21 @@ describe "ExtendedDocument views" do
lambda { Course.find_by_foobar('123') }.should raise_error(NoMethodError)
end
it "should perform a search directly with specific key" do
course = Course.first_from_view('by_title', 'bbb')
course.title.should eql('bbb')
end
it "should perform a search directly with specific key with options" do
course = Course.first_from_view('by_title', 'bbb', :reverse => true)
course.title.should eql('bbb')
end
it "should perform a search directly with range" do
course = Course.first_from_view('by_title', :startkey => 'bbb', :endkey => 'eee')
course.title.should eql('bbb')
end
end
describe "a ducktype view" do
@ -255,105 +270,6 @@ describe "ExtendedDocument views" do
end
end
describe "class proxy" do
before(:all) do
reset_test_db!
# setup the class default doc to save the design doc
Unattached.use_database nil # just to be sure it is really unattached
@us = Unattached.on(DB)
%w{aaa bbb ddd eee}.each do |title|
u = @us.new(:title => title)
u.save
@first_id ||= u.id
end
end
it "should query all" do
rs = @us.all
rs.length.should == 4
end
it "should count" do
@us.count.should == 4
end
it "should make the design doc upon first query" do
@us.by_title
doc = @us.design_doc
doc['views']['all']['map'].should include('Unattached')
end
it "should merge query params" do
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
rs.length.should == 3
end
it "should query via view" do
view = @us.view :by_title
designed = @us.by_title
view.should == designed
end
it "should yield" do
things = []
@us.view(:by_title) do |thing|
things << thing
end
things[0]["doc"]["title"].should =='aaa'
end
it "should yield with by_key method" do
things = []
@us.by_title do |thing|
things << thing
end
things[0]["doc"]["title"].should =='aaa'
end
it "should get from specific database" do
u = @us.get(@first_id)
u.title.should == "aaa"
end
it "should get first" do
u = @us.first
u.title.should =~ /\A...\z/
end
it "should set database on first retreived document" do
u = @us.first
u.database.should === DB
end
it "should set database on all retreived documents" do
@us.all.each do |u|
u.database.should === DB
end
end
it "should set database on each retreived document" do
rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
rs.length.should == 3
rs.each do |u|
u.database.should === DB
end
end
it "should set database on document retreived by id" do
u = @us.get(@first_id)
u.database.should === DB
end
it "should not attempt to set database on raw results using :all" do
@us.all(:raw => true).each do |u|
u.respond_to?(:database).should be_false
end
end
it "should not attempt to set database on raw results using view" do
@us.by_title(:raw => true).each do |u|
u.respond_to?(:database).should be_false
end
end
# Sam Lown 2010-04-07
# Removed as unclear why this should happen as before my changes
# this happend by accident, not explicitly.
# If requested, this feature should be added as a specific method.
#
#it "should clean up design docs left around on specific database" do
# @us.by_title
# original_id = @us.model_design_doc['_rev']
# Unattached.view_by :professor
# @us.by_professor
# @us.model_design_doc['_rev'].should_not == original_id
#end
end
describe "a model with a compound key view" do
before(:all) do
Article.by_user_id_and_date.each{|a| a.destroy(true)}