text: require 'spec_helper'
  
  module Bogus
    describe OverwritesMethods do
      let(:method_stringifier) { MethodStringifier.new }
      let(:makes_substitute_methods) { isolate(MakesSubstituteMethods) }
      let(:overwriter) { isolate(OverwritesMethods) }
  
      let(:object) { SampleOfOverwriting.new }
  
      context "with regular objects" do
        class SampleOfOverwriting
          def greet(name)
            "Hello #{name}"
          end
  
          def wave(part_of_body = "hand", speed = "slowly")
            "I'm waving my #{part_of_body} #{speed}"
          end
        end
  
        before do
          overwriter.overwrite(object, :greet)
        end
  
        it "does not change the method signature" do
          expect(object.method(:greet).arity).to eq(1)
        end
  
        it "does not change the method signature" do
          expect {
            object.greet("John", "Paul")
          }.to raise_error(ArgumentError)
        end
  
        it "adds interaction recording to the overwritten object" do
          object.greet("John")
  
          expect(object).to Bogus.have_received.greet("John")
          expect(object).not_to Bogus.have_received.greet("Paul")
        end
  
        it "can reset the overwritten methods" do
          overwriter.reset(object)
  
          expect(object.greet("John")).to eq("Hello John")
        end
  
        it "is imdepotent when overwriting" do
          overwriter.overwrite(object, :greet)
          overwriter.overwrite(object, :greet)
          overwriter.overwrite(object, :greet)
  
          overwriter.reset(object)
  
          expect(object.greet("John")).to eq("Hello John")
        end
      end
  
      context "with objects that use method missing" do
        class UsesMethodMissing
          def respond_to?(name)
            name == :greet
          end
  
          def method_missing(name, *args, &block)
            "the original return value"
          end
        end
  
        let(:object) { UsesMethodMissing.new }
  
        before do
          overwriter.overwrite(object, :greet)
        end
  
        it "can overwrite the non-existent methods" do
          expect(object.methods).to include(:greet)
        end
  
        it "can be reset back to the original state" do
          overwriter.overwrite(object, :greet)
          overwriter.overwrite(object, :greet)
  
          overwriter.reset(object)
  
          expect(object.greet).to eq("the original return value")
        end
      end
  
      context "with fakes" do
        let(:fake) { Samples::FooFake.new }
  
        it "does nothing because fakes methods already work as we need" do
          overwriter.overwrite(fake, :foo_bar)
  
          expect(fake).not_to respond_to(:foo_bar)
        end
  
        it "does not reset fakes, because there is nothing to reset" do
          expect {
            overwriter.reset(fake)
          }.not_to raise_error
        end
      end
    end
  end
  