$:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__)) require 'test/unit' require 'rubygems' require 'active_record' require 'global_scope' require 'load_fixtures' class Dummy < ActiveRecord::Base def self.current_scope self.current_scoped_methods end def self.current_scope_hash self.global_scope_hash end def self.reset_global_scope write_inheritable_attribute(:global_scopes, nil); @@subclasses[self].each do |sc| sc.write_inheritable_attribute(:global_scopes, nil); end global_scope(:id1, :find => {:conditions => "zone_id > 0"}, :create => {:zone_id => 1}) global_scope(:id2, :find => {:conditions => "zone_id < 3"}) end end class SubDummy < Dummy end class ScopeQueueTest < Test::Unit::TestCase fixtures :dummies def setup Dummy.reset_global_scope end def test_find_scoping_theoretical assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3"}, :create=>{:zone_id=>1}}, Dummy.current_scope) Dummy.with_scope(:find => {:conditions => "id>1"}) do assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3 AND id>1"}, :create=>{:zone_id=>1}}, Dummy.current_scope) Dummy.with_scope(:find => { :conditions => "id < 5" }) do assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3 AND id>1 AND id<5"}, :create=>{:zone_id=>1}}, Dummy.current_scope) Dummy.without_global_scope(:id1) do assert_equal_scope({:find=>{:conditions=>"zone_id<3 AND id>1 AND id<5"}}, Dummy.current_scope) Dummy.with_scope(:find => { :conditions => "zone_id<2" }) do assert_equal_scope({:find=>{:conditions=>"zone_id<2 AND id>1 AND id<5 AND zone_id<3"}}, Dummy.current_scope) end assert_equal_scope({:find=>{:conditions=>"zone_id<3 AND id>1 AND id<5"}}, Dummy.current_scope) end assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3 AND id>1 AND id<5"}, :create=>{:zone_id=>1}}, Dummy.current_scope) end assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3 AND id>1"}, :create=>{:zone_id=>1}}, Dummy.current_scope) end assert_equal_scope({:find=>{:conditions=>"zone_id>0 AND zone_id<3"}, :create=>{:zone_id=>1}}, Dummy.current_scope) end def test_find_scoping_practical assert_equal(8, Dummy.find(:all).size) result = Dummy.with_scope(:find => { :conditions => "zone_id = 1" }) {Dummy.find(:all).size} assert_equal(3, result) Dummy.class_eval do global_scope(:some_identifier, :find => {:conditions => "id > 1"}) end assert_equal(7, Dummy.find(:all).size) Dummy.with_scope(:find => { :conditions => "zone_id = 1" }) do assert_equal(2, Dummy.find(:all).size) Dummy.with_scope(:find => { :conditions => "id < 3" }) do assert_equal(1, Dummy.find(:all).size) Dummy.without_global_scope(:some_identifier) do assert_equal(2, Dummy.find(:all).size) end assert_equal(1, Dummy.find(:all).size) end assert_equal(2, Dummy.find(:all).size) end end def test_create_scope d = Dummy.new(:name => 'test') assert_equal(nil, d.zone_id) d.save assert_equal(nil, d.zone_id) Dummy.class_eval do global_scope(:zone_restriction, :create => { :zone_id => 2 }) end # remove id1 because it already contains a create-scope Dummy.without_global_scope(:id1) do e = Dummy.create(:name => 'scoped1') assert_equal(2, e.zone_id) e.save assert_equal(2, e.zone_id) f = Dummy.create(:name => 'scoped2') assert_equal(2, f.zone_id) f.zone_id = 1 assert_equal(1, f.zone_id) f.save assert_equal(1, f.zone_id) end end def test_scope_overriding assert_nothing_raised do Dummy.class_eval do global_scope(:id1, {:find => {:conditions => "zone_id > 1"}, :create=>{:zone_id=>2}}, :override => true) end end assert_equal_scope({:find=>{:conditions=>"zone_id>1 AND zone_id<3"}, :create=>{:zone_id=>2}}, Dummy.current_scope) assert_nothing_raised do Dummy.class_eval do global_scope(:id1, {:find => {:conditions => "1 = 1"}}, :override => true) end end assert_equal_scope({:find=>{:conditions=>"zone_id<3 AND 1=1"}}, Dummy.current_scope) end def test_exceptions assert_raise(ActiveRecord::ActiveRecordError) do Dummy.class_eval do global_scope(:id1, :find => {:conditions => "zone_id > 1"}) end end assert_raise(ActiveRecord::ActiveRecordError) do Dummy.without_global_scope(:invalid_identifier) do Dummy.find(:all) end end end def test_scope_inheritance assert_equal_scope(Dummy.current_scope, SubDummy.current_scope) Dummy.class_eval do global_scope(:id1, {:find => {:conditions => "zone_id > 1"}, :create=>{:zone_id=>2}}, :override => true) end assert_equal_scope(Dummy.current_scope, SubDummy.current_scope) SubDummy.class_eval do global_scope(:id1, {:find => {:conditions => "zone_id > 3"}}, :override => true) end assert_not_equal_scope(Dummy.current_scope, SubDummy.current_scope) end private def assert_equal_scope(should, is) assert_equal(normalize(should), normalize(is)) end def assert_not_equal_scope(should, is) assert(normalize(should) != normalize(is)) end def normalize(hash) hash.each_pair do |m,pars| pars.each_pair do |key,vals| hash[m][key] = vals.is_a?(String) ? vals.split(" AND ").collect{|v| v.gsub(%r{[\s\n\(\)]}, '')}.sort : vals end end hash end end