Skip to content

Commit

Permalink
UnionCollection uses lazy loading of collection data; UnionCollection…
Browse files Browse the repository at this point in the history
… properly handles blocks
  • Loading branch information
sjlombardo committed Jun 1, 2008
1 parent 5b555b9 commit b79c599
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 22 deletions.
20 changes: 13 additions & 7 deletions lib/zetetic/acts/network.rb
Expand Up @@ -60,7 +60,7 @@ module Acts #:nodoc:
# * <tt>find_by_*</tt> - works as expected, behaving like <tt>find :first</tt>
# * <tt>find_all_by_*</tt> - works as expected like <tt>find :all</tt>
#
class UnionCollection < Array
class UnionCollection

# UnionCollection should be initialized with a list of ActiveRecord collections
#
Expand All @@ -72,8 +72,6 @@ class UnionCollection < Array
def initialize(*sets)
@sets = sets || []
@sets.compact! # remove nil elements
@sets.each{|set| self.concat set unless set.nil?} unless @sets.nil?
uniq!
end

# Emulates the ActiveRecord::base.find method.
Expand All @@ -91,6 +89,12 @@ def find(*args)

private

def load_sets
@arr = []
@sets.each{|set| @arr.concat set unless set.nil?} unless @sets.nil?
@arr.uniq!
end

# start by passing the find to set 0. If no results are returned
# pass the find on to set 1, and so on.
def find_initial(method_id, *args)
Expand Down Expand Up @@ -142,13 +146,15 @@ def find_from_ids(method_id, *args)
end

# Handle find_by convienince methods
def method_missing(method_id, *args)
def method_missing(method_id, *args, &block)
if method_id.to_s =~ /^find_all_by/
find_all method_id, *args
find_all method_id, *args, &block
elsif method_id.to_s =~ /^find_by/
find_initial method_id, *args
find_initial method_id, *args, &block
else
super
debugger
load_sets
@arr.send method_id, *args, &block
end
end
end
Expand Down
43 changes: 28 additions & 15 deletions test/network_test.rb
Expand Up @@ -43,15 +43,6 @@ def ids
end
end

class ActsAsUntionTest < Test::Unit::TestCase
fixtures :shows, :channels

def test_union_method
assert_equal 0, channels(:abc).pay_shows.length
assert_equal 3, channels(:discovery).pay_shows.length
end
end

class UnionCollectionTest < Test::Unit::TestCase
fixtures :shows, :channels

Expand Down Expand Up @@ -131,13 +122,13 @@ def test_find_with_scope

def test_empty_sets
assert_equal Zetetic::Acts::UnionCollection.new().size, 0
assert_equal Zetetic::Acts::UnionCollection.new(), []
assert_equal Zetetic::Acts::UnionCollection.new().to_ary, []
assert_equal Zetetic::Acts::UnionCollection.new([],[]).size, 0
assert_equal Zetetic::Acts::UnionCollection.new([],[]), []
assert_equal Zetetic::Acts::UnionCollection.new([],[]).to_ary, []
assert_equal Zetetic::Acts::UnionCollection.new(nil,nil).size, 0
assert_equal Zetetic::Acts::UnionCollection.new(nil,nil), []
assert_equal Zetetic::Acts::UnionCollection.new(nil,nil).to_ary, []
assert_equal Zetetic::Acts::UnionCollection.new([],nil).size, 0
assert_equal Zetetic::Acts::UnionCollection.new([],nil), []
assert_equal Zetetic::Acts::UnionCollection.new([],nil).to_ary, []
end

def test_mixed_sets
Expand All @@ -163,9 +154,31 @@ def test_unique
assert_equal channels(:discovery).shows.size, union.size
assert_equal channels(:discovery).shows.size, union.find(:all).size
end

def test_lazy_load
# internal array should start out nil
assert_nil @union.instance_variable_get(:@arr)

# finder operations shouldn't affect state
@union.find(0)
assert_nil @union.instance_variable_get(:@arr)

# array operations should cause data load
@union.collect{|a| a}
assert !@union.instance_variable_get(:@arr).empty?
end
end

class ActsAsUntionTest < Test::Unit::TestCase
fixtures :shows, :channels

def test_union_method
assert_equal 0, channels(:abc).pay_shows.length
assert_equal 3, channels(:discovery).pay_shows.length
end
end

class NetworkTest < Test::Unit::TestCase
class ActsAsNetworkTest < Test::Unit::TestCase
fixtures :people, :people_people, :invites

def test_habtm_assignments
Expand Down Expand Up @@ -230,7 +243,7 @@ def test_assigments_conditions

jane.reload and jack.reload and alex.reload

assert_equal [alex], jack.colleagues.find(:all, :conditions => { :name => "Alex" })
assert_equal [alex].to_ary, jack.colleagues.find(:all, :conditions => { :name => "Alex" }).to_ary
end

def test_outbound_habtm
Expand Down

0 comments on commit b79c599

Please sign in to comment.