<commit_before>require File.expand_path(File.dirname(__FILE__) + "/spec_helper")

class SingleObjectPresenter < CachingPresenter
  presents :foo

  delegate :raise_your_hand, :to => :@foo

  def stop!
    @foo.stop
  end

  def last_day?
    @foo.last_day
  end
  
  def talk(&blk)
    if block_given?
      yield @foo
    else
      @foo.speak
    end
  end
  
  def run(*args)
    @foo.run *args
  end
end

class SingleObjectWithConstructorRequirementsPresenter < CachingPresenter
  presents :foo, :requiring => [:bar, :baz]

  def sum
    @bar.amount + @baz.amount
  end
end

class FirstBarPresenter < CachingPresenter
  presents :bar

  def say(what) 
    @bar.say(what)
  end
end

class SecondBarPresenter < CachingPresenter
  presents :bar

  def say(what) 
    @bar.say(what)
  end
end


describe CachingPresenter do
  it "it automatically delegates methods that exist on the object being presented" do
    foo = mock("foo")
    foo.should_receive(:amount).and_return 10
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.amount.should == 10
  end
  
  it "can present on an object with additional constructor requirements" do
    foo, bar, baz = mock("foo"), mock("bar"), mock("baz")
    bar.should_receive(:amount).and_return 100
    baz.should_receive(:amount).and_return 200
    presenter = SingleObjectWithConstructorRequirementsPresenter.new(:foo => foo, :bar => bar, :baz => baz)
    presenter.sum.should == 300
  end
  
  it "raises when the object being presented on isn't passed in" do
    lambda { 
      SingleObjectPresenter.new(:ignored_argument => "here")
    }.should raise_error(ArgumentError, "missing arguments: foo")
  end
  
  it "raises when required constructor arguments aren't passed in" do
    lambda { 
      SingleObjectWithConstructorRequirementsPresenter.new(:foo => mock("foo"))
    }.should raise_error(ArgumentError, "missing arguments: bar, baz")
  end

  it "caches method calls without arguments" do
    foo = mock("foo")
    foo.should_receive(:speak).with().at_most(1).times.and_return "Speaking!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.talk.should == "Speaking!"
    presenter.talk.should == "Speaking!"
  end
  
  it "caches method calls with arguments" do
    foo = mock("foo")
    foo.should_receive(:run).with(:far).at_most(1).times.and_return "Running far!"
    foo.should_receive(:run).with(:near).at_most(1).times.and_return "Running nearby!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.run(:far).should == "Running far!"
    presenter.run(:far).should == "Running far!"
    presenter.run(:near).should == "Running nearby!"
    presenter.run(:near).should == "Running nearby!"
  end
  
  it "caches explicitly delegated methods" do
    foo = mock("foo")
    foo.should_receive(:raise_your_hand).with().at_most(1).times.and_return "raising my hand"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.raise_your_hand.should == "raising my hand"
    presenter.raise_your_hand.should == "raising my hand"    
  end

  it "caches explicitly delegated methods with arguments" do
    foo = mock("foo")
    foo.should_receive(:raise_your_hand).with(1, 2, 3).at_most(1).times.and_return "raising my hand"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.raise_your_hand(1, 2, 3).should == "raising my hand"
    presenter.raise_your_hand(1, 2, 3).should == "raising my hand"    
  end
  
  it "caches implicitly delegated methods" do
    foo = mock("foo")
    foo.should_receive(:turkey).at_most(1).times
    presenter = SingleObjectPresenter.new :foo => foo
    presenter.turkey
    presenter.turkey
  end

  it "doesn't cache method calls with blocks" do
    foo = mock("foo")
    foo.should_receive(:speak).with().exactly(2).times().and_return "Speaking!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.talk { |o| o.speak }.should == "Speaking!"
    presenter.talk { |o| o.speak }.should == "Speaking!"
  end

  it "works with methods suffixed with a question mark" do
    foo = mock("foo")<commit_msg>adds some examples to ensure no method calls with blocks are cached<commit_after>require File.expand_path(File.dirname(__FILE__) + "/spec_helper")

class SingleObjectPresenter < CachingPresenter
  presents :foo

  delegate :raise_your_hand, :to => :@foo

  def stop!
    @foo.stop
  end

  def last_day?
    @foo.last_day
  end
  
  def talk(&blk)
    if block_given?
      yield @foo
    else
      @foo.speak
    end
  end
  
  def run(*args)
    @foo.run *args
  end
end

class SingleObjectWithConstructorRequirementsPresenter < CachingPresenter
  presents :foo, :requiring => [:bar, :baz]

  def sum
    @bar.amount + @baz.amount
  end
end

class FirstBarPresenter < CachingPresenter
  presents :bar

  def say(what) 
    @bar.say(what)
  end
end

class SecondBarPresenter < CachingPresenter
  presents :bar

  def say(what) 
    @bar.say(what)
  end
end


describe CachingPresenter do
  it "it automatically delegates methods that exist on the object being presented" do
    foo = mock("foo")
    foo.should_receive(:amount).and_return 10
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.amount.should == 10
  end
  
  it "can present on an object with additional constructor requirements" do
    foo, bar, baz = mock("foo"), mock("bar"), mock("baz")
    bar.should_receive(:amount).and_return 100
    baz.should_receive(:amount).and_return 200
    presenter = SingleObjectWithConstructorRequirementsPresenter.new(:foo => foo, :bar => bar, :baz => baz)
    presenter.sum.should == 300
  end
  
  it "raises when the object being presented on isn't passed in" do
    lambda { 
      SingleObjectPresenter.new(:ignored_argument => "here")
    }.should raise_error(ArgumentError, "missing arguments: foo")
  end
  
  it "raises when required constructor arguments aren't passed in" do
    lambda { 
      SingleObjectWithConstructorRequirementsPresenter.new(:foo => mock("foo"))
    }.should raise_error(ArgumentError, "missing arguments: bar, baz")
  end

  it "caches method calls without arguments" do
    foo = mock("foo")
    foo.should_receive(:speak).with().at_most(1).times.and_return "Speaking!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.talk.should == "Speaking!"
    presenter.talk.should == "Speaking!"
  end
  
  it "caches method calls with arguments" do
    foo = mock("foo")
    foo.should_receive(:run).with(:far).at_most(1).times.and_return "Running far!"
    foo.should_receive(:run).with(:near).at_most(1).times.and_return "Running nearby!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.run(:far).should == "Running far!"
    presenter.run(:far).should == "Running far!"
    presenter.run(:near).should == "Running nearby!"
    presenter.run(:near).should == "Running nearby!"
  end
  
  it "doesn't cache method calls with blocks" do
    foo = mock("foo")
    foo.should_receive(:speak).with().exactly(2).times().and_return "Speaking!"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.talk { |o| o.speak }.should == "Speaking!"
    presenter.talk { |o| o.speak }.should == "Speaking!"
  end
    
  it "caches explicitly delegated methods" do
    foo = mock("foo")
    foo.should_receive(:raise_your_hand).with().at_most(1).times.and_return "raising my hand"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.raise_your_hand.should == "raising my hand"
    presenter.raise_your_hand.should == "raising my hand"    
  end

  it "doesn't cache explicitly delegated methods with blocks" do
    foo = mock("foo")
    foo.should_receive(:raise_your_hand).with().exactly(2).times.and_return "raising my hand"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.raise_your_hand { }.should == "raising my hand"
    presenter.raise_your_hand { }.should == "raising my hand"
  end

  it "caches explicitly delegated methods with arguments" do
    foo = mock("foo")
    foo.should_receive(:raise_your_hand).with(1, 2, 3).at_most(1).times.and_return "raising my hand"
    presenter = SingleObjectPresenter.new(:foo => foo)
    presenter.raise_your_hand(1, 2, 3).should == "raising my hand"
    presenter.raise_your_hand(1, 2, 3).should == "raising my hand"    
  end
  
  it "caches implicitly delegated methods" do
    foo = mock("foo")
    foo.should_receive(:turkey).at_most(1).times
    presenter = SingleObjectPresenter.new :foo => foo
    presenter.turkey
    presenter.turkey
  end

  it "doesn't cache implicitly delegated methods with blocks" do
    foo = mock("foo")
    foo.should_receive(:turkey).exactly(2).times
    presenter = SingleObjectPresenter.new :foo => foo
    presenter.turkey { }
    presenter.turkey { }
  end

  it "works with methods suffixed with a question mark" do
    foo = mock("foo")
{'fraction_non_alphanumeric': 0.1193117500565995, 'fraction_numerical': 0.006791940230925968, 'mean_word_length': 3.7602370689655173, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6935392', 'n_tokens_mistral': 2919, 'n_tokens_neox': 2773, 'n_words': 714}