From 431116a0ce35562826980bee15f6f13c79009750 Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Sun, 7 Mar 2010 23:28:47 -0800 Subject: [PATCH 1/7] Removed duplicative unit specs. Extracted DoubleInjection.create, .exists?, .reset, .verify, .verify_double, .reset_double, and .instances from Space. --- .../strategies/scope/instance.rb | 2 +- .../strategies/scope/instance_of_class.rb | 2 +- lib/rr/injections/double_injection.rb | 63 +- lib/rr/injections/injection.rb | 6 + lib/rr/injections/method_missing_injection.rb | 14 +- .../singleton_method_added_injection.rb | 17 +- .../method_missing_dispatch.rb | 4 +- lib/rr/recorded_calls.rb | 2 +- lib/rr/space.rb | 79 +- spec/rr/adapters/rr_methods_creator_spec.rb | 12 - spec/rr/adapters/rr_methods_space_spec.rb | 35 +- ...uble_definition_create_blank_slate_spec.rb | 71 +- .../double_definition_create_spec.rb | 22 +- .../double_definition_spec.rb | 1168 ----------------- .../double_injection_verify_spec.rb | 2 +- spec/rr/double_spec.rb | 361 ----- ...times_called_expectation_any_times_spec.rb | 34 +- .../times_called_expectation_at_least_spec.rb | 46 +- .../times_called_expectation_at_most_spec.rb | 66 +- .../times_called_expectation_helper.rb | 9 +- .../times_called_expectation_integer_spec.rb | 82 +- .../times_called_expectation_proc_spec.rb | 60 +- .../times_called_expectation_range_spec.rb | 68 +- .../times_called_expectation_spec.rb | 38 - spec/rr/rspec/rspec_adapter_spec.rb | 19 +- spec/rr/space/space_spec.rb | 284 +--- spec/spec_helper.rb | 76 -- spec/spy_verification_spec.rb | 2 +- 28 files changed, 293 insertions(+), 2351 deletions(-) delete mode 100644 spec/rr/double_definitions/double_definition_spec.rb delete mode 100644 spec/rr/double_spec.rb delete mode 100644 spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb diff --git a/lib/rr/double_definitions/strategies/scope/instance.rb b/lib/rr/double_definitions/strategies/scope/instance.rb index 1b9eb7bd..86c3c896 100644 --- a/lib/rr/double_definitions/strategies/scope/instance.rb +++ b/lib/rr/double_definitions/strategies/scope/instance.rb @@ -5,7 +5,7 @@ module Scope class Instance < ScopeStrategy protected def do_call - double_injection = space.double_injection(subject, method_name) + double_injection = Injections::DoubleInjection.create(subject, method_name) Double.new(double_injection, definition) end end diff --git a/lib/rr/double_definitions/strategies/scope/instance_of_class.rb b/lib/rr/double_definitions/strategies/scope/instance_of_class.rb index 95d4903b..2c44a8e0 100644 --- a/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +++ b/lib/rr/double_definitions/strategies/scope/instance_of_class.rb @@ -32,7 +32,7 @@ def do_call instance_of_subject_double_definition_create.call(:new) do |*args| ##### instance = subject.allocate - double_injection = space.double_injection(instance, method_name) + double_injection = Injections::DoubleInjection.create(instance, method_name) Double.new(double_injection, definition) ##### if args.last.is_a?(ProcFromBlock) diff --git a/lib/rr/injections/double_injection.rb b/lib/rr/injections/double_injection.rb index ab67e66c..acff2941 100644 --- a/lib/rr/injections/double_injection.rb +++ b/lib/rr/injections/double_injection.rb @@ -4,6 +4,57 @@ module Injections # A double_injection has 0 to many Double objects. Each Double # has Argument Expectations and Times called Expectations. class DoubleInjection < Injection + class << self + def create(subject, method_name) + instances[subject][method_name.to_sym] ||= begin + new(subject, method_name.to_sym, (class << subject; self; end)).bind + end + end + + def exists?(subject, method_name) + instances.include?(subject) && instances[subject].include?(method_name.to_sym) + end + + def reset + instances.each do |subject, method_double_map| + method_double_map.keys.each do |method_name| + reset_double(subject, method_name) + end + end + end + + def verify(*subjects) + subjects = Injections::DoubleInjection.instances.keys if subjects.empty? + subjects.each do |subject| + instances.include?(subject) && + instances[subject].keys.each do |method_name| + verify_double(subject, method_name) + end && + instances.delete(subject) + end + end + + # Verifies the DoubleInjection for the passed in subject and method_name. + def verify_double(subject, method_name) + Injections::DoubleInjection.instances[subject][method_name].verify + ensure + reset_double subject, method_name + end + + # Resets the DoubleInjection for the passed in subject and method_name. + def reset_double(subject, method_name) + double_injection = Injections::DoubleInjection.instances[subject].delete(method_name) + Injections::DoubleInjection.instances.delete(subject) if Injections::DoubleInjection.instances[subject].empty? + double_injection.reset + end + + def instances + @instances ||= HashWithObjectIdKey.new do |hash, subject_object| + hash.set_with_object_id(subject_object, {}) + end + end + end + attr_reader :subject_class, :method_name, :doubles MethodArguments = Struct.new(:arguments, :block) @@ -34,8 +85,8 @@ def bind bind_method_with_alias end else - space.method_missing_injection(subject) - space.singleton_method_added_injection(subject) + Injections::MethodMissingInjection.create(subject) + Injections::SingletonMethodAddedInjection.create(subject) end else bind_method @@ -50,6 +101,7 @@ def verify double.verify end end + # RR::DoubleInjection#reset removes the injected dispatcher method. # It binds the original method implementation on the subject @@ -100,7 +152,10 @@ def bypass_bound_method protected def subject_is_proxy_for_method?(method_name_in_question) - !(class << @subject; self; end). + !( + class << @subject; + self; + end). instance_methods. detect {|method_name| method_name.to_sym == method_name_in_question.to_sym} end @@ -122,7 +177,7 @@ def bind_method subject_class.class_eval(<<-METHOD, __FILE__, __LINE__ + 1) def #{@method_name}(*args, &block) arguments = MethodArguments.new(args, block) - RR::Space.double_injection(#{subject}, :#{@method_name}).dispatch_method(arguments.arguments, arguments.block) + RR::Injections::DoubleInjection.create(#{subject}, :#{@method_name}).dispatch_method(arguments.arguments, arguments.block) end METHOD end diff --git a/lib/rr/injections/injection.rb b/lib/rr/injections/injection.rb index 15e5b051..136824b3 100644 --- a/lib/rr/injections/injection.rb +++ b/lib/rr/injections/injection.rb @@ -1,6 +1,12 @@ module RR module Injections class Injection + class << self + def instances + @instances ||= HashWithObjectIdKey.new + end + end + include Space::Reader attr_reader :subject diff --git a/lib/rr/injections/method_missing_injection.rb b/lib/rr/injections/method_missing_injection.rb index 71d7217a..63504660 100644 --- a/lib/rr/injections/method_missing_injection.rb +++ b/lib/rr/injections/method_missing_injection.rb @@ -1,6 +1,18 @@ module RR module Injections class MethodMissingInjection < Injection + class << self + def create(subject) + instances[subject] ||= begin + new(subject).bind + end + end + + def exists?(subject) + instances.include?(subject) + end + end + def initialize(subject) @subject = subject @placeholder_method_defined = false @@ -48,7 +60,7 @@ class << subject; self; end def bind_method returns_method = <<-METHOD def method_missing(method_name, *args, &block) - RR::Space.method_missing_injection(self).dispatch_method(method_name, args, block) + RR::Injections::MethodMissingInjection.create(self).dispatch_method(method_name, args, block) end METHOD subject_class.class_eval(returns_method, __FILE__, __LINE__ - 4) diff --git a/lib/rr/injections/singleton_method_added_injection.rb b/lib/rr/injections/singleton_method_added_injection.rb index 9cb5ad88..1773ac2f 100644 --- a/lib/rr/injections/singleton_method_added_injection.rb +++ b/lib/rr/injections/singleton_method_added_injection.rb @@ -1,6 +1,18 @@ module RR module Injections class SingletonMethodAddedInjection < Injection + class << self + def create(subject) + instances[subject] ||= begin + new(subject).bind + end + end + + def exists?(subject) + instances.include?(subject) + end + end + def initialize(subject) @subject = subject @placeholder_method_defined = false @@ -18,12 +30,11 @@ def singleton_method_added(method_name) end memoized_subject = subject - memoized_space = space memoized_original_method_alias_name = original_method_alias_name subject_class.__send__(:alias_method, original_method_alias_name, :singleton_method_added) subject_class.__send__(:define_method, :singleton_method_added) do |method_name_arg| - if memoized_space.double_injection_exists?(memoized_subject, method_name_arg) - memoized_space.double_injection(memoized_subject, method_name_arg).send(:deferred_bind_method) + if Injections::DoubleInjection.exists?(memoized_subject, method_name_arg) + Injections::DoubleInjection.create(memoized_subject, method_name_arg).send(:deferred_bind_method) end send(memoized_original_method_alias_name, method_name_arg) end diff --git a/lib/rr/method_dispatches/method_missing_dispatch.rb b/lib/rr/method_dispatches/method_missing_dispatch.rb index 3039d419..9c173cd9 100644 --- a/lib/rr/method_dispatches/method_missing_dispatch.rb +++ b/lib/rr/method_dispatches/method_missing_dispatch.rb @@ -13,7 +13,7 @@ def initialize(subject, method_name, args, block) end def call - if space.double_injection_exists?(subject, method_name) + if Injections::DoubleInjection.exists?(subject, method_name) space.record_call(subject, method_name, args, block) @double = find_double_to_attempt @@ -50,7 +50,7 @@ def call_implementation end def double_injection - space.double_injection(subject, method_name) + Injections::DoubleInjection.create(subject, method_name) end def_delegators 'self.class', :original_method_missing_alias_name diff --git a/lib/rr/recorded_calls.rb b/lib/rr/recorded_calls.rb index 98fa6e40..3040978f 100644 --- a/lib/rr/recorded_calls.rb +++ b/lib/rr/recorded_calls.rb @@ -40,7 +40,7 @@ def match_error(spy_verification) attr_accessor :ordered_index def double_injection_exists_error(spy_verification) - unless space.double_injection_exists?(spy_verification.subject, spy_verification.method_name) + unless Injections::DoubleInjection.exists?(spy_verification.subject, spy_verification.method_name) RR::Errors::SpyVerificationErrors::DoubleInjectionNotFoundError.new( "A Double Injection for the subject and method call:\n" << "#{spy_verification.subject.inspect}\n" << diff --git a/lib/rr/space.rb b/lib/rr/space.rb index 9655ca9d..13fb3a62 100644 --- a/lib/rr/space.rb +++ b/lib/rr/space.rb @@ -19,53 +19,14 @@ def method_missing(method_name, *args, &block) end end - attr_reader :double_injections, :method_missing_injections, :ordered_doubles, :recorded_calls + attr_reader :ordered_doubles, :recorded_calls attr_accessor :trim_backtrace def initialize - @double_injections = HashWithObjectIdKey.new do |hash, subject_object| - hash.set_with_object_id(subject_object, {}) - end - @method_missing_injections = HashWithObjectIdKey.new - @singleton_method_added_injections = HashWithObjectIdKey.new @ordered_doubles = [] @trim_backtrace = false @recorded_calls = RR::RecordedCalls.new end - # Reuses or creates, if none exists, a DoubleInjection for the passed - # in subject and method_name. - # When a DoubleInjection is created, it binds the dispatcher to the - # subject. - def double_injection(subject, method_name) - @double_injections[subject][method_name.to_sym] ||= begin - Injections::DoubleInjection.new(subject, method_name.to_sym, (class << subject; self; end)).bind - end - end - - def double_injection_exists?(subject, method_name) - @double_injections.include?(subject) && @double_injections[subject].include?(method_name.to_sym) - end - - def method_missing_injection(subject) - @method_missing_injections[subject] ||= begin - Injections::MethodMissingInjection.new(subject).bind - end - end - - def method_missing_injection_exists?(subject) - @method_missing_injections.include?(subject) - end - - def singleton_method_added_injection(subject) - @singleton_method_added_injections[subject] ||= begin - Injections::SingletonMethodAddedInjection.new(subject).bind - end - end - - def singleton_method_added_injection_exists?(subject) - @singleton_method_added_injections.include?(subject) - end - # Registers the ordered Double to be verified. def register_ordered_double(double) @ordered_doubles << double unless ordered_doubles.include?(double) @@ -90,20 +51,15 @@ def verify_ordered_double(double) # Verifies all the DoubleInjection objects have met their # TimesCalledExpectations. - def verify_doubles(*objects) - objects = @double_injections.keys if objects.empty? - objects.each do |subject| - @double_injections[subject].keys.each do |method_name| - verify_double(subject, method_name) - end - end + def verify_doubles(*subjects) + Injections::DoubleInjection.verify(*subjects) end alias_method :verify, :verify_doubles # Resets the registered Doubles and ordered Doubles def reset reset_ordered_doubles - reset_double_injections + Injections::DoubleInjection.reset reset_method_missing_injections reset_singleton_method_added_injections reset_recorded_calls @@ -111,18 +67,14 @@ def reset # Verifies the DoubleInjection for the passed in subject and method_name. def verify_double(subject, method_name) - @double_injections[subject][method_name].verify - ensure - reset_double subject, method_name + Injections::DoubleInjection.verify_double(subject, method_name) end # Resets the DoubleInjection for the passed in subject and method_name. def reset_double(subject, method_name) - double_injection = @double_injections[subject].delete(method_name) - @double_injections.delete(subject) if @double_injections[subject].empty? - double_injection.reset + Injections::DoubleInjection.reset_double(subject, method_name) end - + def record_call(subject, method_name, arguments, block) @recorded_calls << [subject, method_name, arguments, block] end @@ -133,27 +85,18 @@ def reset_ordered_doubles @ordered_doubles.clear end - # Resets the registered Doubles for the next test run. - def reset_double_injections - @double_injections.each do |subject, method_double_map| - method_double_map.keys.each do |method_name| - reset_double(subject, method_name) - end - end - end - def reset_method_missing_injections - @method_missing_injections.each do |subject, injection| + Injections::MethodMissingInjection.instances.each do |subject, injection| injection.reset end - @method_missing_injections.clear + Injections::MethodMissingInjection.instances.clear end def reset_singleton_method_added_injections - @singleton_method_added_injections.each do |subject, injection| + Injections::SingletonMethodAddedInjection.instances.each do |subject, injection| injection.reset end - @singleton_method_added_injections.clear + Injections::SingletonMethodAddedInjection.instances.clear end def reset_recorded_calls diff --git a/spec/rr/adapters/rr_methods_creator_spec.rb b/spec/rr/adapters/rr_methods_creator_spec.rb index 1d17d168..1172e954 100644 --- a/spec/rr/adapters/rr_methods_creator_spec.rb +++ b/spec/rr/adapters/rr_methods_creator_spec.rb @@ -23,8 +23,6 @@ def call_strategy(*args, &block) @strategy_method_name = :mock end - send("normal strategy definition") - context "when passing no args" do it "returns a DoubleDefinitionCreate" do call_strategy.class.should == RR::DoubleDefinitions::DoubleDefinitionCreate @@ -47,8 +45,6 @@ def call_strategy(*args, &block) @strategy_method_name = :stub end - send("normal strategy definition") - context "when passing no args" do it "returns a DoubleDefinitionCreate" do call_strategy.class.should == RR::DoubleDefinitions::DoubleDefinitionCreate @@ -70,8 +66,6 @@ def call_strategy(*args, &block) @strategy_method_name = :dont_allow end - send("normal strategy definition") - context "when passing no args" do it "returns a DoubleDefinitionCreate" do call_strategy.class.should == RR::DoubleDefinitions::DoubleDefinitionCreate @@ -104,8 +98,6 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :mock! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to Mock" do proxy = mock!(:foobar) @@ -119,8 +111,6 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :stub! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to Stub" do proxy = stub!(:foobar) @@ -134,8 +124,6 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :dont_allow! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to DontAllow" do proxy = dont_allow!(:foobar) diff --git a/spec/rr/adapters/rr_methods_space_spec.rb b/spec/rr/adapters/rr_methods_space_spec.rb index 8c1556a7..4b5a2204 100644 --- a/spec/rr/adapters/rr_methods_space_spec.rb +++ b/spec/rr/adapters/rr_methods_space_spec.rb @@ -20,7 +20,7 @@ module Adapters describe "#rr_verify" do it "verifies and deletes the double_injections" do - double_1 = space.double_injection(subject_1, method_name) + double_1 = Injections::DoubleInjection.create(subject_1, method_name) double_1_verify_calls = 0 double_1_reset_calls = 0 ( @@ -34,7 +34,7 @@ class << double_1; double_1_reset_calls += 1 end end - double_2 = space.double_injection(subject_2, method_name) + double_2 = Injections::DoubleInjection.create(subject_2, method_name) double_2_verify_calls = 0 double_2_reset_calls = 0 ( @@ -65,41 +65,26 @@ class << double_2; describe "#rr_reset" do it "removes the ordered doubles" do - double_1 = new_double( - space.double_injection(subject_1, :foobar1), - RR::DoubleDefinitions::DoubleDefinition.new(creator = RR::DoubleDefinitions::DoubleDefinitionCreate.new) - ) - double_2 = new_double( - space.double_injection(subject_2, :foobar2), - RR::DoubleDefinitions::DoubleDefinition.new(creator = RR::DoubleDefinitions::DoubleDefinitionCreate.new) - ) + mock(subject_1).foobar1.ordered + mock(subject_2).foobar2.ordered - double_1.definition.ordered - double_2.definition.ordered - - space.ordered_doubles.should_not be_empty + Injections::DoubleInjection.instances.should_not be_empty rr_reset - space.ordered_doubles.should be_empty + Injections::DoubleInjection.instances.should be_empty end it "resets all double_injections" do - double_1 = space.double_injection(subject_1, method_name) + double_1 = Injections::DoubleInjection.create(subject_1, method_name) double_1_reset_calls = 0 - ( - class << double_1; - self; - end).class_eval do + ( class << double_1; self; end).class_eval do define_method(:reset) do || double_1_reset_calls += 1 end end - double_2 = space.double_injection(subject_2, method_name) + double_2 = Injections::DoubleInjection.create(subject_2, method_name) double_2_reset_calls = 0 - ( - class << double_2; - self; - end).class_eval do + ( class << double_2; self; end).class_eval do define_method(:reset) do || double_2_reset_calls += 1 end diff --git a/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb b/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb index b62bd580..604ae04f 100644 --- a/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb +++ b/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb @@ -12,15 +12,6 @@ module DoubleDefinitions double_definition_create.mock(subject) end - macro("initializes proxy with passed in double_definition_create") do - it "initializes proxy with passed in double_definition_create" do - class << blank_slate - attr_reader :double_definition_create - end - blank_slate.double_definition_create.should === double_definition_create - end - end - describe ".new" do it "does not undefine object_id" do blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create) @@ -32,65 +23,35 @@ class << blank_slate @blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create) end - send "initializes proxy with passed in double_definition_create" - it "clears out all methods from proxy" do - proxy_subclass = Class.new(DoubleDefinitionCreateBlankSlate) do - def i_should_be_a_double - end - end - proxy_subclass.instance_methods.map {|m| m.to_s}.should include('i_should_be_a_double') - - proxy = proxy_subclass.new(double_definition_create) - proxy.i_should_be_a_double.should be_instance_of(DoubleDefinition) + stub(subject).i_should_be_a_double.should be_instance_of(DoubleDefinition) end end context "when passed a block" do - macro("calls the block to define the Doubles") do - send "initializes proxy with passed in double_definition_create" - - it "creates double_injections" do - subject.foobar(1, 2).should == :one_two - subject.foobar(1).should == :one - subject.foobar(:something).should == :default - subject.baz.should == :baz_result - end - - it "clears out all methods from proxy" do - proxy_subclass = Class.new(DoubleDefinitionCreateBlankSlate) do - def i_should_be_a_double - end - end - proxy_subclass.instance_methods.map {|m| m.to_s}.should include('i_should_be_a_double') - - proxy_subclass.new(double_definition_create) do |m| - m.i_should_be_a_double.should be_instance_of(DoubleDefinition) - end - end - end - context "when the block has an arity of 1" do attr_reader :passed_in_argument before do passed_in_argument = nil - block = lambda do |b| + stub(subject) do |b| passed_in_argument = b b.foobar(1, 2) {:one_two} b.foobar(1) {:one} b.foobar.with_any_args {:default} b.baz() {:baz_result} end - block.arity.should == 1 - - @blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create, &block) @passed_in_argument = passed_in_argument end - send("calls the block to define the Doubles") + it "creates double_injections" do + subject.foobar(1, 2).should == :one_two + subject.foobar(1).should == :one + subject.foobar(:something).should == :default + subject.baz.should == :baz_result + end it "passes the self into the block" do - passed_in_argument.__double_definition_create__.should == double_definition_create + passed_in_argument.__double_definition_create__.should be_instance_of(DoubleDefinitions::DoubleDefinitionCreate) end end @@ -98,23 +59,25 @@ def i_should_be_a_double attr_reader :self_value before do self_value = nil - block = lambda do || + stub(subject) do || self_value = self foobar(1, 2) {:one_two} foobar(1) {:one} foobar.with_any_args {:default} baz() {:baz_result} end - block.arity.should == 0 - - @blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create, &block) @self_value = self_value end - send("calls the block to define the Doubles") + it "creates double_injections" do + subject.foobar(1, 2).should == :one_two + subject.foobar(1).should == :one + subject.foobar(:something).should == :default + subject.baz.should == :baz_result + end it "evaluates the block with the context of self" do - self_value.__double_definition_create__.should == double_definition_create + self_value.__double_definition_create__.should be_instance_of(DoubleDefinitions::DoubleDefinitionCreate) end end end diff --git a/spec/rr/double_definitions/double_definition_create_spec.rb b/spec/rr/double_definitions/double_definition_create_spec.rb index 7acb6eb8..b86c7976 100644 --- a/spec/rr/double_definitions/double_definition_create_spec.rb +++ b/spec/rr/double_definitions/double_definition_create_spec.rb @@ -28,8 +28,6 @@ def call_strategy(*args, &block) @strategy_method_name = :mock end - send("normal strategy definition") - context "when passing no args" do it "returns self" do call_strategy.should === double_definition_create @@ -61,8 +59,6 @@ def call_strategy(*args, &block) @strategy_method_name = :stub end - send("normal strategy definition") - context "when passing no args" do it "returns self" do call_strategy.should === double_definition_create @@ -93,8 +89,6 @@ def call_strategy(*args, &block) @strategy_method_name = :dont_allow end - send("normal strategy definition") - context "when passing no args" do it "returns self" do call_strategy.should === double_definition_create @@ -143,12 +137,11 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :mock! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to Mock" do double_definition_create.mock!(:foobar) double_definition_create.verification_strategy.class.should == Strategies::Verification::Mock + lambda {RR.verify}.should raise_error(::RR::Errors::TimesCalledError) end end end @@ -158,8 +151,6 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :stub! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to Stub" do double_definition_create.stub!(:foobar) @@ -173,8 +164,6 @@ def call_strategy(*args, &definition_eval_block) @strategy_method_name = :dont_allow! end - send("! strategy definition") - context "when passed a method_name argument" do it "sets #verification_strategy to DontAllow" do double_definition_create.dont_allow!(:foobar) @@ -274,9 +263,10 @@ def foobar(*args) end it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do - double_definition_create.call(:foobar, 1, 2) + mock(subject).foobar(1, 2) subject.foobar(1, 2) lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError) + lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError) end describe "#subject.method_name being called" do @@ -295,11 +285,13 @@ def foobar(*args) it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do def subject.foobar(*args) - :baz; + :baz end - double_definition_create.call(:foobar, 1, 2) + mock(subject).foobar(1, 2) + subject.foobar(1, 2) lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError) + lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError) end describe "#subject.method_name being called" do diff --git a/spec/rr/double_definitions/double_definition_spec.rb b/spec/rr/double_definitions/double_definition_spec.rb deleted file mode 100644 index ccbb2f6b..00000000 --- a/spec/rr/double_definitions/double_definition_spec.rb +++ /dev/null @@ -1,1168 +0,0 @@ -require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper") - -module RR - module DoubleDefinitions - describe DoubleDefinition do - attr_reader :subject, :double_definition_create, :double, :definition - - it_should_behave_like "Swapped Space" - - before do - @subject = Object.new - add_original_method - @double_definition_create = DoubleDefinitionCreate.new - @definition = double_definition_create.stub(subject).foobar - @double = definition.double - end - - def add_original_method - def subject.foobar(a, b) - :original_return_value - end - end - - describe "#root_subject" do - it "returns #double_definition_create.root_subject" do - definition.root_subject.should == definition.double_definition_create.root_subject - definition.root_subject.should == subject - end - end - - describe "DefinitionConstructionMethods" do - macro("DoubleDefinition where #double_definition_create is a Reimplementation") do - before do - definition.double_definition_create.implementation_strategy.class.should == Strategies::Implementation::Reimplementation - call_double_injection - end - end - - macro("DoubleDefinition where #double_definition_create is a Proxy") do - before do - definition.double_definition_create.proxy - definition.double_definition_create.implementation_strategy.class.should == Strategies::Implementation::Proxy - call_double_injection - end - end - - describe "#with" do - macro("#with") do - it "returns DoubleDefinition" do - definition.with(1).should === definition - end - - it "sets an ArgumentEqualityExpectation" do - definition.should be_exact_match(1, 2) - definition.should_not be_exact_match(2) - end - end - - context "when not passed a block" do - before do - definition.with(1, 2) - subject.foobar(1, 2) - end - - send "#with" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with(1, 2) do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "when #double_definition_create.implementation_strategy is a Reimplementation" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#with" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "when #double_definition_create.implementation_strategy is a Proxy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#with" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#with_any_args" do - macro "#with_any_args" do - it "returns DoubleDefinition" do - definition.with_no_args.should === definition - end - - it "sets an AnyArgumentExpectation" do - definition.should_not be_exact_match(1) - definition.should be_wildcard_match(1) - end - end - - context "when not passed a block" do - before do - definition.with_any_args - end - - send "#with_any_args" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_any_args do |*args| - actual_args = args - :new_return_value - end - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "when #double_definition_create.implementation_strategy is a Reimplementation" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#with_any_args" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "when #double_definition_create.implementation_strategy is a Proxy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#with_any_args" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#with_no_args" do - macro "#with_no_args" do - it "returns DoubleDefinition" do - definition.with_no_args.should === definition - end - - it "sets an ArgumentEqualityExpectation with no arguments" do - definition.argument_expectation.should == RR::Expectations::ArgumentEqualityExpectation.new() - end - end - - def add_original_method - def subject.foobar() - :original_return_value - end - end - - context "when not passed a block" do - before do - definition.with_no_args - end - - send "#with_no_args" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_no_args do |*args| - actual_args = args - :new_return_value - end - @return_value = subject.foobar - @args = actual_args - end - - context "when #double_definition_create.implementation_strategy is a Reimplementation" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#with_no_args" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [] - end - end - end - - context "when #double_definition_create.implementation_strategy is a Proxy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#with_no_args" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#never" do - it "returns DoubleDefinition" do - definition.never.should === definition - end - - it "sets up a Times Called Expectation with 0" do - definition.with_any_args - definition.never - lambda {subject.foobar}.should raise_error(RR::Errors::TimesCalledError) - end - - describe "#subject.method_name being called" do - it "raises a TimesCalledError" do - definition.with_any_args.never - lambda {subject.foobar}.should raise_error(RR::Errors::TimesCalledError) - end - end - end - - describe "#once" do - macro "#once" do - it "returns DoubleDefinition" do - definition.once.should === definition - end - - it "sets up a Times Called Expectation with 1" do - lambda {subject.foobar}.should raise_error(RR::Errors::TimesCalledError) - end - end - - context "when not passed a block" do - before do - definition.with_any_args.once - subject.foobar(1, 2) - end - - send "#once" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_any_args.once do |*args| - actual_args = args - :new_return_value - end - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#once" - - describe "#subject.method_name being called with any arguments" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#once" - - describe "#subject.method_name being called with any arguments" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#twice" do - macro "#twice" do - it "returns DoubleDefinition" do - definition.twice.should === definition - end - - it "sets up a Times Called Expectation with 2" do - definition.twice.with_any_args - lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError) - end - end - - context "when not passed a block" do - before do - definition.with_any_args.twice - subject.foobar(1, 2) - subject.foobar(1, 2) - end - - send "#twice" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_any_args.twice do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#twice" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#twice" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#at_least" do - macro "#at_least" do - it "returns DoubleDefinition" do - definition.with_any_args.at_least(2).should === definition - end - - it "sets up a Times Called Expectation with 1" do - definition.times_matcher.should == RR::TimesCalledMatchers::AtLeastMatcher.new(2) - end - end - - context "when not passed a block" do - before do - definition.with_any_args.at_least(2) - subject.foobar(1, 2) - end - - send "#at_least" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_any_args.at_least(2) do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#at_least" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#at_least" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#at_most" do - macro "#at_most" do - it "returns DoubleDefinition" do - definition.with_any_args.at_most(2).should === definition - end - - it "sets up a Times Called Expectation with 1" do - lambda do - subject.foobar - end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected at most 2 times.") - end - end - - context "when not passed a block" do - before do - definition.with_any_args.at_most(2) - subject.foobar(1, 2) - subject.foobar(1, 2) - end - - send "#at_most" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with_any_args.at_most(2) do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#at_most" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#at_most" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#times" do - macro "#times" do - it "returns DoubleDefinition" do - definition.times(3).should === definition - end - - it "sets up a Times Called Expectation with passed in times" do - lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError) - end - end - - context "when not passed a block" do - before do - definition.with(1, 2).times(3) - subject.foobar(1, 2) - subject.foobar(1, 2) - subject.foobar(1, 2) - end - - send "#times" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with(1, 2).times(3) do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#times" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#times" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#any_number_of_times" do - macro "#any_number_of_times" do - it "returns DoubleDefinition" do - definition.any_number_of_times.should === definition - end - - it "sets up a Times Called Expectation with AnyTimes matcher" do - definition.times_matcher.should == RR::TimesCalledMatchers::AnyTimesMatcher.new - end - end - - context "when not passed a block" do - before do - definition.with(1, 2).any_number_of_times - subject.foobar(1, 2) - end - - send "#any_number_of_times" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with(1, 2).any_number_of_times do |*args| - actual_args = args - :new_return_value - end - subject.foobar(1, 2) - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#any_number_of_times" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#any_number_of_times" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#ordered" do - macro "#ordered" do - it "adds itself to the ordered doubles list" do - definition.ordered - RR::Space.instance.ordered_doubles.should include(double) - end - - it "does not double_injection add itself" do - definition.ordered - RR::Space.instance.ordered_doubles.should == [double] - end - - it "sets ordered? to true" do - definition.should be_ordered - end - - context "when there is no Double" do - it "raises a DoubleDefinitionError" do - definition.double = nil - lambda do - definition.ordered - end.should raise_error( - RR::Errors::DoubleDefinitionError, - "Double Definitions must have a dedicated Double to be ordered. " << - "For example, using instance_of does not allow ordered to be used. " << - "proxy the class's #new method instead." - ) - end - end - end - - context "when not passed a block" do - before do - definition.with(1, 2).once.ordered - subject.foobar(1, 2) - end - - send "#ordered" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with(1, 2).once.ordered do |*args| - actual_args = args - :new_return_value - end - @return_value = subject.foobar(1, 2) - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#ordered" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [1, 2] - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#ordered" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#yields" do - macro "#yields" do - it "returns DoubleDefinition" do - definition.yields(:baz).should === definition - end - - context "when there is a no returns value set" do - it "yields the passed in argument to the call block" do - @passed_in_block_arg.should == :baz - end - end - end - - context "when not passed a block" do - before do - definition.with(1, 2).once.yields(:baz) - passed_in_block_arg = nil - subject.foobar(1, 2) do |arg| - passed_in_block_arg = arg - end - @passed_in_block_arg = passed_in_block_arg - end - - send "#yields" - end - - context "when passed a block" do - def call_double_injection - actual_args = nil - definition.with(1, 2).once.yields(:baz) do |*args| - actual_args = args - :new_return_value - end - passed_in_block_arg = nil - @block = lambda do |arg| - passed_in_block_arg = arg - end - @return_value = subject.foobar(1, 2, &@block) - @passed_in_block_arg = passed_in_block_arg - - @args = actual_args - end - - context "with returns block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Reimplementation" - send "#yields" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - end - - it "passes an array of the args with the block appended as a RR::ProcFromBlock around the original block" do - @args.length.should == 3 - @args[0..1].should == [1, 2] - @args[2].should be_instance_of(RR::ProcFromBlock) - @block.should == Proc.new(&@block) - @args[2].should == @block - end - end - end - - context "with after_call block_callback_strategy" do - send "DoubleDefinition where #double_definition_create is a Proxy" - send "#yields" - - describe "#subject.method_name being called" do - it "returns the return value of the block" do - @return_value.should == :new_return_value - @args.should == [:original_return_value] - end - end - end - end - end - - describe "#after_call" do - context "when passed a block" do - it "returns DoubleDefinition" do - definition.after_call {}.should === definition - end - - describe "#subject.method_name being called" do - it "calls the block with the return value of the implementation" do - return_value = {:original => :value} - definition.with_any_args.returns(return_value).after_call do |value| - value[:foo] = :bar - value - end - - actual_value = subject.foobar - actual_value.should === return_value - actual_value.should == {:original => :value, :foo => :bar} - end - - context "when the return value of the #after_call_proc is a DoubleDefinition" do - it "returns the #subject of the DoubleDefinition" do - return_value = Object.new - inner_double_definition = nil - definition.with_any_args.returns(return_value).after_call do |value| - inner_double_definition = mock(value).inner_method(1) {:baz} - end - - foobar_return_value = subject.foobar - foobar_return_value.should == inner_double_definition.subject - foobar_return_value.inner_method(1).should == :baz - end - end - - context "when the return value of the #after_call_proc is a DoubleDefinitionCreateBlankSlate" do - it "returns the #__subject__ of the DoubleDefinitionCreateBlankSlate" do - return_value = Object.new - inner_double_proxy = nil - definition.with_any_args.returns(return_value).after_call do |value| - inner_double_proxy = mock(value) - end - - foobar_return_value = subject.foobar - foobar_return_value.should == inner_double_proxy.__double_definition_create__.subject - end - end - - context "when the return value of the #after_call_proc is an Object" do - it "returns the return value of the #after_call_proc" do - return_value = :returns_value - definition.with_any_args.returns(return_value).after_call do |value| - :after_call_proc - end - - actual_value = subject.foobar - actual_value.should == :after_call_proc - end - end - end - end - - context "when not passed a block" do - it "raises an ArgumentError" do - lambda do - definition.after_call - end.should raise_error(ArgumentError, "after_call expects a block") - end - end - end - - describe "#returns" do - it "returns DoubleDefinition" do - definition.returns {:baz}.should === definition - definition.returns(:baz).should === definition - end - - context "when passed neither an argument nor a block" do - describe "#subject.method_name being called" do - it "returns nil" do - definition.with_any_args.returns - subject.foobar.should be_nil - end - end - end - - context "when passed a block" do - describe "#subject.method_name being called" do - it "returns the return value of the block" do - definition.with_any_args.returns {:baz} - subject.foobar.should == :baz - end - end - end - - context "when passed an argument" do - describe "#subject.method_name being called" do - it "returns the passed-in argument" do - definition.returns(:baz).with_no_args - subject.foobar.should == :baz - end - end - - context "when the argument is false" do - describe "#subject.method_name being called" do - it "returns false" do - definition.returns(false).with_any_args - subject.foobar.should == false - end - end - end - end - - context "when passed both an argument and a block" do - it "raises an error" do - lambda do - definition.returns(:baz) {:another} - end.should raise_error(ArgumentError, "returns cannot accept both an argument and a block") - end - end - end - - describe "#implemented_by" do - it "returns the DoubleDefinition" do - definition.implemented_by(lambda{:baz}).should === definition - end - - context "when passed a Proc" do - describe "#subject.method_name being called" do - it "returns the return value of the passed-in Proc" do - definition.implemented_by(lambda{:baz}).with_no_args - subject.foobar.should == :baz - end - end - end - - context "when passed a Method" do - it "sets the implementation to the passed in method" do - class << subject - remove_method :foobar - def foobar(a, b) - [b, a] - end - end - definition.implemented_by(subject.method(:foobar)) - subject.foobar(1, 2).should == [2, 1] - end - end - end - - describe "#verbose" do - it "sets the verbose? to true" do - definition.should_not be_verbose - definition.verbose - definition.should be_verbose - end - end - - describe "#verify_method_signature" do - it "sets #verify_method_signature? to true" do - definition.verify_method_signature?.should be_false - definition.verify_method_signature - definition.verify_method_signature?.should be_true - end - - it "returns self" do - definition.verify_method_signature.should == definition - end - end - end - - describe "NestedDoubleCreationMethods" do - attr_reader :child_double_definition_create - after do - RR.verify(ChildDoubleDefinitionCreate) - RR.verify(child_double_definition_create) - end - - describe "#mock" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #mock method with the passed-in arguments and block" do - child_subject = Object.new - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).mock(child_subject, :baz) - child_double_definition_create = child_double_definition_create - end - - definition.mock(child_subject, :baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#mock!" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #mock! method with the passed-in arguments and block" do - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).mock!(:baz) - child_double_definition_create = child_double_definition_create - end - - definition.mock!(:baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#stub" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #stub method with the passed-in arguments and block" do - child_subject = Object.new - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).stub(child_subject, :baz) - child_double_definition_create = child_double_definition_create - end - - definition.stub(child_subject, :baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#stub!" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #stub! method with the passed-in arguments and block" do - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).stub!(:baz) - child_double_definition_create = child_double_definition_create - end - - definition.stub!(:baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#dont_allow" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #dont_allow method with the passed-in arguments and block" do - child_subject = Object.new - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).dont_allow(child_subject, :baz) - child_double_definition_create = child_double_definition_create - end - - definition.dont_allow(child_subject, :baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#dont_allow!" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #dont_allow! method with the passed-in arguments and block" do - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).dont_allow!(:baz) - child_double_definition_create = child_double_definition_create - end - - definition.dont_allow!(:baz) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#proxy" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #proxy method with the passed-in arguments and block" do - child_subject = Object.new - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).proxy(DoubleDefinitionCreate::NO_SUBJECT, nil) - child_double_definition_create = child_double_definition_create - end - - definition.proxy.mock(child_subject) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#proxy!" do - it "raises a DoubleDefinitionError" do - lambda do - definition.proxy!(:baz) - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - - describe "#strong" do - it "instantiates a ChildDoubleDefinitionCreate with self and delegates to its #strong method with the passed-in arguments and block" do - child_subject = Object.new - child_double_definition_create = nil - mock.proxy(ChildDoubleDefinitionCreate).new(definition) do |child_double_definition_create| - mock.proxy(child_double_definition_create).strong(DoubleDefinitionCreate::NO_SUBJECT, nil) - child_double_definition_create = child_double_definition_create - end - - definition.strong.mock(child_subject) - @child_double_definition_create = child_double_definition_create - end - end - - describe "#strong!" do - it "raises a DoubleDefinitionError" do - lambda do - definition.strong!(:baz) - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - end - - describe "StateQueryMethods" do - describe "#ordered?" do - it "defaults to false" do - definition.should_not be_ordered - end - end - - describe "#exact_match?" do - context "when no argument_expectation set" do - it "raises a DoubleDefinitionError" do - definition.argument_expectation = nil - lambda do - definition.exact_match? - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - - context "when arguments are not an exact match" do - it "returns false" do - definition.with(1, 2, 3) - definition.should_not be_exact_match(1, 2) - definition.should_not be_exact_match(1) - definition.should_not be_exact_match() - definition.should_not be_exact_match("does not match") - end - end - - context "when arguments are an exact match" do - it "returns true" do - definition.with(1, 2, 3) - definition.should be_exact_match(1, 2, 3) - end - end - end - - describe "#wildcard_match?" do - context "when no #argument_expectation is set" do - it "raises a DoubleDefinitionError" do - definition.argument_expectation = nil - lambda do - definition.wildcard_match? - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - - context "when arguments are an exact match" do - it "returns true" do - definition.with(1, 2, 3) - definition.should be_wildcard_match(1, 2, 3) - definition.should_not be_wildcard_match(1, 2) - definition.should_not be_wildcard_match(1) - definition.should_not be_wildcard_match() - definition.should_not be_wildcard_match("does not match") - end - end - - context "when with_any_args" do - it "returns true" do - definition.with_any_args - - definition.should be_wildcard_match(1, 2, 3) - definition.should be_wildcard_match(1, 2) - definition.should be_wildcard_match(1) - definition.should be_wildcard_match() - definition.should be_wildcard_match("does not match") - end - end - end - - describe "#terminal?" do - context "when times_matcher's terminal? is true" do - it "returns true" do - definition.once - definition.times_matcher.should be_terminal - definition.should be_terminal - end - end - - context "when times_matcher's terminal? is false" do - it "returns false" do - definition.any_number_of_times - definition.times_matcher.should_not be_terminal - definition.should_not be_terminal - end - end - - context "when there is not times_matcher" do - it "raises a DoubleDefinitionError" do - definition.times_matcher = nil - lambda do - definition.terminal? - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - end - - describe "#expected_arguments" do - context "when there is a argument expectation" do - it "returns argument expectation's expected_arguments" do - definition.with(1, 2) - definition.expected_arguments.should == [1, 2] - end - end - - context "when there is no argument expectation" do - it "returns an empty array" do - definition.argument_expectation = nil - definition.expected_arguments.should == [] - end - end - end - end - end - end -end \ No newline at end of file diff --git a/spec/rr/double_injection/double_injection_verify_spec.rb b/spec/rr/double_injection/double_injection_verify_spec.rb index c8b0e163..52c27232 100644 --- a/spec/rr/double_injection/double_injection_verify_spec.rb +++ b/spec/rr/double_injection/double_injection_verify_spec.rb @@ -9,7 +9,7 @@ module Injections @subject = Object.new @method_name = :foobar subject.methods.should_not include(method_name.to_s) - @double_injection = space.double_injection(subject, method_name) + @double_injection = Injections::DoubleInjection.create(subject, method_name) end it "verifies each double was met" do diff --git a/spec/rr/double_spec.rb b/spec/rr/double_spec.rb deleted file mode 100644 index 832da6e9..00000000 --- a/spec/rr/double_spec.rb +++ /dev/null @@ -1,361 +0,0 @@ -require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper") - -module RR - describe Double do - it_should_behave_like "Swapped Space" - attr_reader :subject, :double_injection, :definition, :definition_creator, :double - before do - @subject = Object.new - def subject.foobar(a, b) - [b, a] - end - @double_injection = create_double_injection - @definition_creator = DoubleDefinitions::DoubleDefinitionCreate.new - @definition = DoubleDefinitions::DoubleDefinition.new(definition_creator). - any_number_of_times. - with_any_args - @double = Double.new(double_injection, definition) - end - - def create_double_injection - space.double_injection(subject, :foobar) - end - - describe "#initialize" do - it "registers self with associated DoubleInjection" do - double_injection.doubles.should include(double) - end - end - - describe "#ordered?" do - it "defaults to false" do - double.should_not be_ordered - end - end - - describe "#call" do - describe "when verbose" do - attr_reader :original_stdout - before do - @original_stdout = $stdout - end - - after do - $stdout = original_stdout - end - - it "prints the message call" do - double.definition.verbose - $stdout = StringIO.new(output = "") - subject.foobar(1, 2) - output.strip.should == Double.formatted_name(:foobar, [1, 2]) - end - end - - describe "when not verbose" do - it "does not print the message call" do - output = nil - (class << double; self; end).__send__(:define_method, :puts) do |output| - output = output - end - subject.foobar(1, 2) - output.should be_nil - end - end - - describe "when implemented by a lambda" do - it "calls the return lambda when implemented by a lambda" do - double.definition.returns {|arg| "returning #{arg}"} - subject.foobar(:foobar).should == "returning foobar" - end - - it "calls and returns the after_call when after_call is set" do - double.definition.returns {|arg| "returning #{arg}"}.after_call do |value| - "#{value} after call" - end - subject.foobar(:foobar).should == "returning foobar after call" - end - - it "returns nil when to returns is not set" do - subject.foobar.should be_nil - end - - it "works when times_called is not set" do - double.definition.returns {:value} - subject.foobar - end - - it "verifes the times_called does not exceed the TimesCalledExpectation" do - double.definition.times(2).returns {:value} - - subject.foobar(:foobar) - subject.foobar(:foobar) - lambda {subject.foobar(:foobar)}.should raise_error(Errors::TimesCalledError) - end - - it "raises DoubleOrderError when ordered and called out of order" do - double1 = double - double2 = Double.new(double_injection, DoubleDefinitions::DoubleDefinition.new(definition_creator)) - - double1.definition.with(1).returns {:return_1}.once.ordered - double2.definition.with(2).returns {:return_2}.once.ordered - - lambda do - subject.foobar(2) - end.should raise_error( - Errors::DoubleOrderError, - "foobar(2) called out of order in list\n" << - "- foobar(1)\n" << - "- foobar(2)" - ) - end - - it "dispatches to Space#verify_ordered_double when ordered" do - verify_ordered_double_called = false - passed_in_double = nil - space.method(:verify_ordered_double).arity.should == 1 - (class << space; self; end).class_eval do - define_method :verify_ordered_double do |double| - passed_in_double = double - verify_ordered_double_called = true - end - end - - double.definition.returns {:value}.ordered - subject.foobar(:foobar) - verify_ordered_double_called.should be_true - passed_in_double.should === double - end - - it "does not dispatche to Space#verify_ordered_double when not ordered" do - verify_ordered_double_called = false - space.method(:verify_ordered_double).arity.should == 1 - (class << space; self; end).class_eval do - define_method :verify_ordered_double do |double| - verify_ordered_double_called = true - end - end - - double.definition.returns {:value} - subject.foobar(:foobar) - verify_ordered_double_called.should be_false - end - - it "does not add block argument if no block passed in" do - double.definition.with(1, 2).returns {|*args| args} - - args = subject.foobar(1, 2) - args.should == [1, 2] - end - - it "makes the block the last argument" do - double.definition.with(1, 2).returns {|a, b, blk| blk} - - block = subject.foobar(1, 2) {|a, b| [b, a]} - block.call(3, 4).should == [4, 3] - end - - it "raises ArgumentError when yields was called and no block passed in" do - double.definition.with(1, 2).yields(55) - - lambda do - subject.foobar(1, 2) - end.should raise_error(ArgumentError, "A Block must be passed into the method call when using yields") - end - end - - describe "when implemented by a method" do - it "sends block to the method" do - class << subject - remove_method :foobar - def foobar(a, b) - yield(a, b) - end - end - - double.definition.with(1, 2).implemented_by(subject.method(:foobar)) - - subject.foobar(1, 2) {|a, b| [b, a]}.should == [2, 1] - end - end - end - - describe "#exact_match?" do - context "when no expectation is set" do - it "raises a DoubleDefinitionError" do - double.definition.argument_expectation = nil - lambda do - double.exact_match? - end.should raise_error(Errors::DoubleDefinitionError) - end - end - - context "when arguments are not an exact match" do - it "returns false" do - double.definition.with(1, 2, 3) - double.should_not be_exact_match(1, 2) - double.should_not be_exact_match(1) - double.should_not be_exact_match() - double.should_not be_exact_match("does not match") - end - end - - context "when arguments are an exact match" do - it "returns true" do - double.definition.with(1, 2, 3) - double.should be_exact_match(1, 2, 3) - end - end - end - - describe "#wildcard_match?" do - context "when no expectation set" do - it "raises a DoubleDefinitionError" do - double.definition.argument_expectation = nil - lambda do - double.wildcard_match? - end.should raise_error(Errors::DoubleDefinitionError) - end - end - - context "when arguments are an exact match" do - it "returns true" do - double.definition.with(1, 2, 3) - double.should be_wildcard_match(1, 2, 3) - double.should_not be_wildcard_match(1, 2) - double.should_not be_wildcard_match(1) - double.should_not be_wildcard_match() - double.should_not be_wildcard_match("does not match") - end - end - - context "when with_any_args" do - it "returns true" do - double.definition.with_any_args - - double.should be_wildcard_match(1, 2, 3) - double.should be_wildcard_match(1, 2) - double.should be_wildcard_match(1) - double.should be_wildcard_match() - double.should be_wildcard_match("does not match") - end - end - end - - describe "#attempt?" do - context "when TimesCalledExpectation#attempt? is true" do - it "returns true" do - double.definition.with(1, 2, 3).twice - subject.foobar(1, 2, 3) - double.times_called_expectation.should be_attempt - double.should be_attempt - end - end - - context "when TimesCalledExpectation#attempt? is true" do - it "returns false" do - double.definition.with(1, 2, 3).twice - subject.foobar(1, 2, 3) - subject.foobar(1, 2, 3) - double.times_called_expectation.should_not be_attempt - double.should_not be_attempt - end - end - - context "when there is no Times Called expectation" do - it "raises a DoubleDefinitionError" do - double.definition.with(1, 2, 3) - double.definition.times_matcher = nil - lambda do - double.should be_attempt - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - end - - describe "#verify" do - it "verifies that times called expectation was met" do - double.definition.twice.returns {:return_value} - - lambda {double.verify}.should raise_error(Errors::TimesCalledError) - subject.foobar - lambda {double.verify}.should raise_error(Errors::TimesCalledError) - subject.foobar - - lambda {double.verify}.should_not raise_error - end - - it "does not raise an error when there is no times called expectation" do - lambda {double.verify}.should_not raise_error - subject.foobar - lambda {double.verify}.should_not raise_error - subject.foobar - lambda {double.verify}.should_not raise_error - end - end - - describe "#terminal?" do - context "when times_called_expectation's terminal? is true" do - it "returns true" do - double.definition.once - double.times_called_expectation.should be_terminal - double.should be_terminal - end - end - - context "when times_called_expectation's terminal? is false" do - it "returns false" do - double.definition.any_number_of_times - double.times_called_expectation.should_not be_terminal - double.should_not be_terminal - end - end - - context "when there is no times_matcher" do - it "raises a DoubleDefinitionError" do - double.definition.times_matcher = nil - lambda do - double.should_not be_terminal - end.should raise_error(RR::Errors::DoubleDefinitionError) - end - end - end - - describe "#method_name" do - it "returns the DoubleInjection's method_name" do - double_injection.method_name.should == :foobar - double.method_name.should == :foobar - end - end - - describe "#expected_arguments" do - context "when there is an argument expectation" do - it "returns argument expectation's expected_arguments" do - double.definition.with(1, 2) - double.definition.argument_expectation.should_not be_nil - double.expected_arguments.should == [1, 2] - end - end - - context "when there is no argument expectation" do - it "raises an DoubleDefinitionError" do - double.definition.argument_expectation = nil - lambda do - double.expected_arguments - end.should raise_error(Errors::DoubleDefinitionError) - end - end - end - - describe "#formatted_name" do - it "renders the formatted name of the Double with no arguments" do - double.formatted_name.should == "foobar()" - end - - it "renders the formatted name of the Double with arguments" do - double.definition.with(1, 2) - double.formatted_name.should == "foobar(1, 2)" - end - end - end -end \ No newline at end of file diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb index 08d76781..0638c926 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb @@ -5,39 +5,15 @@ module Expectations describe TimesCalledExpectation do context "when using an AnyTimesMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :matcher, :expectation - - before do - double.definition.any_number_of_times - @matcher = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) - end describe "#verify!" do it "always passes" do - expectation.verify! - 10.times {expectation.attempt} - expectation.verify! - end - end - - describe "#attempt?" do - it "always returns true" do - expectation.should be_attempt - 10.times {expectation.attempt} - expectation.should be_attempt - end - end - - describe "#attempt!" do - it "always passes" do - 10.times {expectation.attempt} - end - end + stub(subject).foobar.any_number_of_times + RR.verify - describe "#terminal?" do - it "returns false" do - expectation.should_not be_terminal + stub(subject).foobar.any_number_of_times + 10.times {subject.foobar} + RR.verify end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb index 1f828dd7..da44044b 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb @@ -5,64 +5,32 @@ module Expectations describe TimesCalledExpectation do context "when using an AtLeastMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :times, :at_least, :expectation before do - @times = 3 - double.definition.at_least(times) - @at_least = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) + mock(subject).foobar.at_least(3) end describe "#verify!" do it "passes when times called > times" do - 4.times {expectation.attempt} - expectation.verify! + 4.times {subject.foobar} + RR.verify end it "passes when times called == times" do - 3.times {expectation.attempt} - expectation.verify! + 3.times {subject.foobar} + RR.verify end it "raises error when times called < times" do - expectation.attempt + subject.foobar lambda do - expectation.verify! + RR.verify end.should raise_error( RR::Errors::TimesCalledError, "foobar()\nCalled 1 time.\nExpected at least 3 times." ) end end - - describe "#attempt?" do - it "always returns true" do - expectation.should be_attempt - 10.times {expectation.attempt} - expectation.should be_attempt - end - end - - describe "#attempt!" do - it "passes when times called more than times" do - 4.times {expectation.attempt} - end - - it "passes when times called == times" do - 3.times {expectation.attempt} - end - - it "passes when times called < times" do - expectation.attempt - end - end - - describe "#terminal?" do - it "returns false" do - expectation.should_not be_terminal - end - end end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb index 174ab24f..9340a771 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb @@ -5,64 +5,36 @@ module Expectations describe TimesCalledExpectation do context "when using an AtMostMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :times, :at_most, :expectation before do - @times = 3 - double.definition.at_most(times) - @at_most = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) + stub(subject).foobar.at_most(3) end describe "#verify!" do - it "returns true when times called == times" do - 3.times {expectation.attempt} - expectation.verify! - end - - it "raises error when times called < times" do - 2.times {expectation.attempt} - expectation.verify! - end - end - - describe "#attempt?" do - it "returns true when attempted less than expected times" do - 2.times {expectation.attempt} - expectation.should be_attempt - end - - it "returns false when attempted expected times" do - 3.times {expectation.attempt} - expectation.should_not be_attempt - end - - it "raises error before attempted more than expected times" do - 3.times {expectation.attempt} - lambda {expectation.attempt}.should raise_error( RR::Errors::TimesCalledError ) - end - end - - describe "#attempt!" do - it "fails when times called more than times" do - 3.times {expectation.attempt} - lambda do - expectation.attempt - end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 4 times.\nExpected at most 3 times.") - end - it "passes when times called == times" do - 3.times {expectation.attempt} + 3.times {subject.foobar} + RR.verify end it "passes when times called < times" do - expectation.attempt + 2.times {subject.foobar} + RR.verify end - end - describe "#terminal?" do - it "returns true" do - expectation.should be_terminal + it "raises error when times called > times" do + lambda do + 4.times {subject.foobar} + end.should raise_error( + RR::Errors::TimesCalledError, + "foobar()\nCalled 4 times.\nExpected at most 3 times." + ) + + lambda do + RR.verify + end.should raise_error( + RR::Errors::TimesCalledError, + "foobar()\nCalled 4 times.\nExpected at most 3 times." + ) end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb index 3cec2962..ece8068d 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb @@ -1,17 +1,10 @@ module RR module Expectations describe TimesCalledExpectation, :shared => true do - attr_reader :subject, :method_name, :double_injection, :double, :double_definition + attr_reader :subject it_should_behave_like "Swapped Space" before do @subject = Object.new - @method_name = :foobar - @double_injection = space.double_injection(subject, method_name) - @double_definition = RR::DoubleDefinitions::DoubleDefinition.new( - RR::DoubleDefinitions::DoubleDefinitionCreate.new - ) - @double = new_double(double_injection) - double.definition.with_any_args.any_number_of_times end def raises_expectation_error(&block) diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb index 2c48359d..c6947ca2 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb @@ -5,99 +5,53 @@ module Expectations describe TimesCalledExpectation do context "when using an IntegerMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :matcher, :expected_line, :expectation before do - double.definition.times(2) - @matcher = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) + stub(subject).foobar.times(2) end - describe "#verify" do - it "returns true when times called exactly matches an integer" do - expectation.verify.should == false - expectation.attempt - expectation.verify.should == false - expectation.attempt - expectation.verify.should == true - end - end - - describe "#verify! when passed an Integer (2)" do + describe "verify" do it "passes after attempt! called 2 times" do - expectation.attempt - expectation.attempt - expectation.verify! + subject.foobar + subject.foobar + RR.verify end it "fails after attempt! called 1 time" do - expectation.attempt - lambda {expectation.verify!}.should raise_error( - RR::Errors::TimesCalledError, - "foobar()\nCalled 1 time.\nExpected 2 times." + subject.foobar + lambda {RR.verify}.should raise_error( + RR::Errors::TimesCalledError, + "foobar()\nCalled 1 time.\nExpected 2 times." ) end it "can't be called when attempt! is called 3 times" do - expectation.attempt - expectation.attempt + subject.foobar + subject.foobar + lambda do + subject.foobar + end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 2 times.") lambda do - expectation.attempt + RR.verify end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 2 times.") end it "has a backtrace to where the TimesCalledExpectation was instantiated on failure" do error = nil begin - expectation.verify! + RR.verify rescue RR::Errors::TimesCalledError => e error = e end - e.backtrace.first.should include(__FILE__) - e.backtrace.first.should include(":#{expected_line}") + e.backtrace.join("\n").should include(__FILE__) end it "has an error message that includes the number of times called and expected number of times" do lambda do - expectation.verify! + RR.verify end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 0 times.\nExpected 2 times.") end end - - describe "#attempt?" do - it "returns true when attempted less than expected times" do - 1.times {expectation.attempt} - expectation.should be_attempt - end - - it "returns false when attempted expected times" do - 2.times {expectation.attempt} - expectation.should_not be_attempt - end - - it "raises error before attempted more than expected times" do - 2.times {expectation.attempt} - lambda {expectation.attempt}.should raise_error( - RR::Errors::TimesCalledError - ) - end - end - - describe "#attempt! for an IntegerMatcher" do - it "raises error when attempt! called more than the expected number of times" do - expectation.attempt - expectation.attempt - lambda do - expectation.attempt - end.should raise_error(RR::Errors::TimesCalledError) - end - end - - describe "#terminal?" do - it "returns true" do - expectation.should be_terminal - end - end end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb index e9c417ed..16de91a4 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb @@ -5,74 +5,28 @@ module Expectations describe TimesCalledExpectation do context "when using a ProcMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :matcher, :expectation before do - double.definition.times(lambda {|value| value == 2}) - @matcher = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) + stub(subject).foobar.times(lambda {|value| value == 2}) end describe "#verify" do - it "matches a block" do - expectation.verify.should == false - expectation.attempt - expectation.verify.should == false - expectation.attempt - expectation.verify.should == true - expectation.attempt - expectation.verify.should == false - end - end - - describe "#verify! when passed a block (== 2 times)" do it "passes after attempt! called 2 times" do - expectation.attempt - expectation.attempt - expectation.verify! + subject.foobar + subject.foobar + RR.verify end it "fails after attempt! called 1 time" do - expectation.attempt - lambda {expectation.verify!}.should raise_error(RR::Errors::TimesCalledError) + subject.foobar + lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError) end it "fails after attempt! called 3 times" do - expectation.attempt - expectation.attempt - expectation.attempt - lambda {expectation.verify!}.should raise_error(RR::Errors::TimesCalledError) - end - end - - describe "#attempt? with IntegerMatcher" do - it "returns true when attempted less than expected times" do - 1.times {expectation.attempt} - expectation.should be_attempt - end - - it "returns true when attempted expected times" do - 2.times {expectation.attempt} - expectation.should be_attempt - end - - it "returns true when attempted more than expected times" do - 3.times {expectation.attempt} - expectation.should be_attempt - end - end - - describe "#attempt! for a lambda expectation" do - it "lets everything pass" do subject.foobar subject.foobar subject.foobar - end - end - - describe "#terminal? with ProcMatcher" do - it "returns false" do - expectation.should_not be_terminal + lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError) end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb index dc206965..351ba66e 100644 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +++ b/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb @@ -5,76 +5,32 @@ module Expectations describe TimesCalledExpectation do context "when using a RangeMatcher" do it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :matcher, :expectation before do - double.definition.times(1..2) - @matcher = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) + stub(subject).foobar.times(1..2) end describe "#verify" do - it "returns true when times called falls within a range" do - expectation.verify.should == false - expectation.attempt - expectation.verify.should == true - expectation.attempt - expectation.verify.should == true - end - end - - describe "#verify! when passed a Range (1..2)" do it "passes after attempt! called 1 time" do - expectation.attempt - expectation.verify! + subject.foobar + RR.verify end it "passes after attempt! called 2 times" do - expectation.attempt - expectation.attempt - expectation.verify! + subject.foobar + subject.foobar + RR.verify end it "can't be called when attempt! is called 3 times" do - expectation.attempt - expectation.attempt + subject.foobar + subject.foobar lambda do - expectation.attempt + subject.foobar + end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 1..2 times.") + lambda do + RR.verify end.should raise_error(RR::Errors::TimesCalledError, "foobar()\nCalled 3 times.\nExpected 1..2 times.") - end - end - - describe "#attempt? with RangeMatcher" do - it "returns true when attempted less than low end of range" do - expectation.should be_attempt - end - - it "returns false when attempted in range" do - expectation.attempt - expectation.should be_attempt - expectation.attempt - expectation.should be_attempt - end - - it "raises error before attempted more than expected times" do - 2.times {expectation.attempt} - lambda {expectation.attempt}.should raise_error( - RR::Errors::TimesCalledError - ) - end - end - - describe "#attempt! for a range expectation" do - it "raises error when attempt! called more than range permits" do - expectation.attempt - expectation.attempt - raises_expectation_error {expectation.attempt} - end - end - - describe "#terminal? with RangeMatcher" do - it "returns true" do - expectation.should be_terminal end end end diff --git a/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb b/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb deleted file mode 100644 index 3ef92794..00000000 --- a/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require File.expand_path("#{File.dirname(__FILE__)}/../../../spec_helper") - -module RR - module Expectations - describe TimesCalledExpectation do - context "with a failure" do - it_should_behave_like "RR::Expectations::TimesCalledExpectation" - attr_reader :times, :matcher, :expectation - - before do - @times = 0 - double.definition.times(0) - @matcher = double.definition.times_matcher - @expectation = TimesCalledExpectation.new(double) - end - - describe "#attempt!" do - it "raises error that includes the double" do - lambda {expectation.attempt}.should raise_error( - RR::Errors::TimesCalledError, - "#{double.formatted_name}\n#{matcher.error_message(1)}" - ) - end - end - - describe "#verify!" do - it "raises error with passed in message prepended" do - expectation.instance_variable_set(:@times_called, 1) - lambda {expectation.verify!}.should raise_error( - RR::Errors::TimesCalledError, - "#{double.formatted_name}\n#{matcher.error_message(1)}" - ) - end - end - end - end - end -end diff --git a/spec/rr/rspec/rspec_adapter_spec.rb b/spec/rr/rspec/rspec_adapter_spec.rb index bd40b8d3..6b82335f 100644 --- a/spec/rr/rspec/rspec_adapter_spec.rb +++ b/spec/rr/rspec/rspec_adapter_spec.rb @@ -14,11 +14,11 @@ module Adapters end it "resets the double_injections" do - RR.double_injection(subject, method_name) - RR.double_injections.should_not be_empty + stub(subject).foobar + Injections::DoubleInjection.instances.should_not be_empty fixture.setup_mocks_for_rspec - RR.double_injections.should be_empty + Injections::DoubleInjection.instances.should be_empty end end @@ -32,15 +32,12 @@ module Adapters end it "verifies the double_injections" do - double_injection = RR.double_injection(subject, method_name) - double = new_double(double_injection) - - double.definition.once + mock(subject).foobar lambda do fixture.verify_mocks_for_rspec end.should raise_error(::RR::Errors::TimesCalledError) - RR.double_injections.should be_empty + Injections::DoubleInjection.instances.should be_empty end end @@ -54,11 +51,11 @@ module Adapters end it "resets the double_injections" do - RR.double_injection(subject, method_name) - RR.double_injections.should_not be_empty + stub(subject).foobar + Injections::DoubleInjection.instances.should_not be_empty fixture.teardown_mocks_for_rspec - RR.double_injections.should be_empty + Injections::DoubleInjection.instances.should be_empty end end end diff --git a/spec/rr/space/space_spec.rb b/spec/rr/space/space_spec.rb index 2bd5bd9d..546a3c3f 100644 --- a/spec/rr/space/space_spec.rb +++ b/spec/rr/space/space_spec.rb @@ -9,23 +9,6 @@ module RR @subject = Object.new end - describe ".method_missing" do - it "proxies to a singleton instance of Space" do - create_double_args = nil - ( - class << space; - self; - end).class_eval do - define_method :double_injection do |*args| - create_double_args = args - end - end - - space.double_injection(:foo, :bar) - create_double_args.should == [:foo, :bar] - end - end - describe "#record_call" do it "should add a call to the list" do object = Object.new @@ -43,8 +26,8 @@ class << space; (subject_1 === subject_2).should be_true subject_1.__id__.should_not == subject_2.__id__ - injection_1 = space.double_injection(subject_1, :foobar) - injection_2 = space.double_injection(subject_2, :foobar) + injection_1 = Injections::DoubleInjection.create(subject_1, :foobar) + injection_2 = Injections::DoubleInjection.create(subject_2, :foobar) injection_1.should_not == injection_2 end @@ -61,8 +44,8 @@ def subject.foobar(*args) context "when method_name is a symbol" do it "returns double_injection and adds double_injection to double_injection list" do - double_injection = space.double_injection(subject, method_name) - space.double_injection(subject, method_name).should === double_injection + double_injection = Injections::DoubleInjection.create(subject, method_name) + Injections::DoubleInjection.create(subject, method_name).should === double_injection double_injection.subject.should === subject double_injection.method_name.should === method_name end @@ -70,8 +53,8 @@ def subject.foobar(*args) context "when method_name is a string" do it "returns double_injection and adds double_injection to double_injection list" do - double_injection = space.double_injection(subject, 'foobar') - space.double_injection(subject, method_name).should === double_injection + double_injection = Injections::DoubleInjection.create(subject, 'foobar') + Injections::DoubleInjection.create(subject, method_name).should === double_injection double_injection.subject.should === subject double_injection.method_name.should === method_name end @@ -79,7 +62,7 @@ def subject.foobar(*args) it "overrides the method when passing a block" do original_method = subject.method(:foobar) - space.double_injection(subject, method_name) + Injections::DoubleInjection.create(subject, method_name) subject.method(:foobar).should_not == original_method end end @@ -95,11 +78,11 @@ def subject.foobar(*args) context "when a DoubleInjection is registered for the subject and method_name" do it "returns the existing DoubleInjection" do - @double_injection = space.double_injection(subject, 'foobar') + @double_injection = Injections::DoubleInjection.create(subject, 'foobar') double_injection.subject_has_original_method?.should be_true - space.double_injection(subject, 'foobar').should === double_injection + Injections::DoubleInjection.create(subject, 'foobar').should === double_injection double_injection.reset subject.foobar.should == :original_foobar @@ -116,8 +99,8 @@ def subject.foobar(*args) (subject_1 === subject_2).should be_true subject_1.__id__.should_not == subject_2.__id__ - injection_1 = space.method_missing_injection(subject_1) - injection_2 = space.method_missing_injection(subject_2) + injection_1 = Injections::MethodMissingInjection.create(subject_1) + injection_2 = Injections::MethodMissingInjection.create(subject_2) injection_1.should_not == injection_2 end @@ -132,7 +115,7 @@ def subject.method_missing(method_name, *args, &block) it "overrides the method when passing a block" do original_method = subject.method(:method_missing) - space.method_missing_injection(subject) + Injections::MethodMissingInjection.create(subject) subject.method(:method_missing).should_not == original_method end end @@ -146,10 +129,10 @@ def subject.method_missing(method_name, *args, &block) context "when a DoubleInjection is registered for the subject and method_name" do it "returns the existing DoubleInjection" do - injection = space.method_missing_injection(subject) + injection = Injections::MethodMissingInjection.create(subject) injection.subject_has_original_method?.should be_true - space.method_missing_injection(subject).should === injection + Injections::MethodMissingInjection.create(subject).should === injection injection.reset subject.method_missing(:foobar).should == :original_method_missing @@ -166,8 +149,8 @@ def subject.method_missing(method_name, *args, &block) (subject_1 === subject_2).should be_true subject_1.__id__.should_not == subject_2.__id__ - injection_1 = space.singleton_method_added_injection(subject_1) - injection_2 = space.singleton_method_added_injection(subject_2) + injection_1 = Injections::SingletonMethodAddedInjection.create(subject_1) + injection_2 = Injections::SingletonMethodAddedInjection.create(subject_2) injection_1.should_not == injection_2 end @@ -182,7 +165,7 @@ def subject.singleton_method_added(method_name) it "overrides the method when passing a block" do original_method = subject.method(:singleton_method_added) - space.singleton_method_added_injection(subject) + Injections::SingletonMethodAddedInjection.create(subject) subject.method(:singleton_method_added).should_not == original_method end end @@ -196,10 +179,10 @@ def subject.singleton_method_added(method_name) context "when a DoubleInjection is registered for the subject and method_name" do it "returns the existing DoubleInjection" do - injection = space.singleton_method_added_injection(subject) + injection = Injections::SingletonMethodAddedInjection.create(subject) injection.subject_has_original_method?.should be_true - space.singleton_method_added_injection(subject).should === injection + Injections::SingletonMethodAddedInjection.create(subject).should === injection injection.reset subject.singleton_method_added(:foobar).should == :original_singleton_method_added @@ -225,16 +208,8 @@ def subject.singleton_method_added(method_name) end it "removes the ordered doubles" do - double_1 = new_double( - space.double_injection(subject_1, :foobar1), - RR::DoubleDefinitions::DoubleDefinition.new(creator = Object.new) - ) - double_2 = new_double( - space.double_injection(subject_2, :foobar2), - RR::DoubleDefinitions::DoubleDefinition.new(creator = Object.new) - ) - double_1.definition.ordered - double_2.definition.ordered + mock(subject_1).foobar1.ordered + mock(subject_2).foobar2.ordered space.ordered_doubles.should_not be_empty @@ -246,63 +221,63 @@ def subject.singleton_method_added(method_name) subject_1.respond_to?(method_name).should be_false subject_2.respond_to?(method_name).should be_false - space.double_injection(subject_1, method_name) - space.double_injection_exists?(subject_1, method_name).should be_true + Injections::DoubleInjection.create(subject_1, method_name) + Injections::DoubleInjection.exists?(subject_1, method_name).should be_true subject_1.respond_to?(method_name).should be_true - space.double_injection(subject_2, method_name) - space.double_injection_exists?(subject_2, method_name).should be_true + Injections::DoubleInjection.create(subject_2, method_name) + Injections::DoubleInjection.exists?(subject_2, method_name).should be_true subject_2.respond_to?(method_name).should be_true space.reset subject_1.respond_to?(method_name).should be_false - space.double_injection_exists?(subject_1, method_name).should be_false + Injections::DoubleInjection.exists?(subject_1, method_name).should be_false subject_2.respond_to?(method_name).should be_false - space.double_injection_exists?(subject_2, method_name).should be_false + Injections::DoubleInjection.exists?(subject_2, method_name).should be_false end it "resets all method_missing_injections" do subject_1.respond_to?(:method_missing).should be_false subject_2.respond_to?(:method_missing).should be_false - space.method_missing_injection(subject_1) - space.method_missing_injection_exists?(subject_1).should be_true + Injections::MethodMissingInjection.create(subject_1) + Injections::MethodMissingInjection.exists?(subject_1).should be_true subject_1.respond_to?(:method_missing).should be_true - space.method_missing_injection(subject_2) - space.method_missing_injection_exists?(subject_2).should be_true + Injections::MethodMissingInjection.create(subject_2) + Injections::MethodMissingInjection.exists?(subject_2).should be_true subject_2.respond_to?(:method_missing).should be_true space.reset subject_1.respond_to?(:method_missing).should be_false - space.method_missing_injection_exists?(subject_1).should be_false + Injections::MethodMissingInjection.exists?(subject_1).should be_false subject_2.respond_to?(:method_missing).should be_false - space.method_missing_injection_exists?(subject_2).should be_false + Injections::MethodMissingInjection.exists?(subject_2).should be_false end it "resets all singleton_method_added_injections" do subject_1.respond_to?(:singleton_method_added).should be_false subject_2.respond_to?(:singleton_method_added).should be_false - space.singleton_method_added_injection(subject_1) - space.singleton_method_added_injection_exists?(subject_1).should be_true + Injections::SingletonMethodAddedInjection.create(subject_1) + Injections::SingletonMethodAddedInjection.exists?(subject_1).should be_true subject_1.respond_to?(:singleton_method_added).should be_true - space.singleton_method_added_injection(subject_2) - space.singleton_method_added_injection_exists?(subject_2).should be_true + Injections::SingletonMethodAddedInjection.create(subject_2) + Injections::SingletonMethodAddedInjection.exists?(subject_2).should be_true subject_2.respond_to?(:singleton_method_added).should be_true space.reset subject_1.respond_to?(:singleton_method_added).should be_false - space.singleton_method_added_injection_exists?(subject_1).should be_false + Injections::SingletonMethodAddedInjection.exists?(subject_1).should be_false subject_2.respond_to?(:singleton_method_added).should be_false - space.singleton_method_added_injection_exists?(subject_2).should be_false + Injections::SingletonMethodAddedInjection.exists?(subject_2).should be_false end end @@ -317,36 +292,37 @@ def subject.foobar it "resets the double_injections and restores the original method" do original_method = subject.method(method_name) - @double_injection = space.double_injection(subject, method_name) - space.double_injections[subject][method_name].should === double_injection + @double_injection = Injections::DoubleInjection.create(subject, method_name) + Injections::DoubleInjection.instances.keys.should include(subject) + Injections::DoubleInjection.instances[subject].keys.should include(method_name) subject.method(method_name).should_not == original_method space.reset_double(subject, method_name) - space.double_injections[subject][method_name].should be_nil + Injections::DoubleInjection.instances.keys.should_not include(subject) subject.method(method_name).should == original_method end context "when it has no double_injections" do it "removes the subject from the double_injections map" do - double_1 = space.double_injection(subject, :foobar1) - double_2 = space.double_injection(subject, :foobar2) + double_1 = Injections::DoubleInjection.create(subject, :foobar1) + double_2 = Injections::DoubleInjection.create(subject, :foobar2) - space.double_injections.include?(subject).should == true - space.double_injections[subject][:foobar1].should_not be_nil - space.double_injections[subject][:foobar2].should_not be_nil + Injections::DoubleInjection.instances.include?(subject).should == true + Injections::DoubleInjection.instances[subject][:foobar1].should_not be_nil + Injections::DoubleInjection.instances[subject][:foobar2].should_not be_nil space.reset_double(subject, :foobar1) - space.double_injections.include?(subject).should == true - space.double_injections[subject][:foobar1].should be_nil - space.double_injections[subject][:foobar2].should_not be_nil + Injections::DoubleInjection.instances.include?(subject).should == true + Injections::DoubleInjection.instances[subject][:foobar1].should be_nil + Injections::DoubleInjection.instances[subject][:foobar2].should_not be_nil space.reset_double(subject, :foobar2) - space.double_injections.include?(subject).should == false + Injections::DoubleInjection.instances.include?(subject).should == false end end end - describe "#reset_double_injections" do + describe "#DoubleInjection.reset" do attr_reader :subject_1, :subject_2 before do @subject_1 = Object.new @@ -355,52 +331,27 @@ def subject.foobar end it "resets the double_injection and removes it from the double_injections list" do - double_injection_1 = space.double_injection(subject_1, method_name) + double_injection_1 = Injections::DoubleInjection.create(subject_1, method_name) double_1_reset_call_count = 0 - ( - class << double_injection_1; - self; - end).class_eval do + ( class << double_injection_1; self; end).class_eval do define_method(:reset) do double_1_reset_call_count += 1 end end - double_injection_2 = space.double_injection(subject_2, method_name) + double_injection_2 = Injections::DoubleInjection.create(subject_2, method_name) double_2_reset_call_count = 0 - ( - class << double_injection_2; - self; - end).class_eval do + ( class << double_injection_2; self; end).class_eval do define_method(:reset) do double_2_reset_call_count += 1 end end - space.__send__(:reset_double_injections) + Injections::DoubleInjection.reset double_1_reset_call_count.should == 1 double_2_reset_call_count.should == 1 end end - describe "#register_ordered_double" do - before(:each) do - @method_name = :foobar - @double_injection = space.double_injection(subject, method_name) - end - - it "adds the ordered double to the ordered_doubles collection" do - double_1 = new_double - - space.ordered_doubles.should == [] - space.register_ordered_double double_1 - space.ordered_doubles.should == [double_1] - - double_2 = new_double - space.register_ordered_double double_2 - space.ordered_doubles.should == [double_1, double_2] - end - end - describe "#verify_doubles" do attr_reader :subject_1, :subject_2, :subject3, :double_1, :double_2, :double3 before do @@ -408,9 +359,9 @@ class << double_injection_2; @subject_2 = Object.new @subject3 = Object.new @method_name = :foobar - @double_1 = space.double_injection(subject_1, method_name) - @double_2 = space.double_injection(subject_2, method_name) - @double3 = space.double_injection(subject3, method_name) + @double_1 = Injections::DoubleInjection.create(subject_1, method_name) + @double_2 = Injections::DoubleInjection.create(subject_2, method_name) + @double3 = Injections::DoubleInjection.create(subject3, method_name) end context "when passed no arguments" do @@ -549,10 +500,7 @@ class << double3; it "does not raise an error" do double_1_verify_call_count = 0 double_1_reset_call_count = 0 - ( - class << double_1; - self; - end).class_eval do + ( class << double_1; self; end).class_eval do define_method(:verify) do double_1_verify_call_count += 1 end @@ -563,10 +511,7 @@ class << double_1; double_2_verify_call_count = 0 double_2_reset_call_count = 0 - ( - class << double_2; - self; - end).class_eval do + ( class << double_2; self; end).class_eval do define_method(:verify) do double_2_verify_call_count += 1 end @@ -577,10 +522,7 @@ class << double_2; double3_verify_call_count = 0 double3_reset_call_count = 0 - ( - class << double3; - self; - end).class_eval do + ( class << double3; self; end).class_eval do define_method(:verify) do double3_verify_call_count += 1 end @@ -611,14 +553,11 @@ def subject.foobar end it "verifies and deletes the double_injection" do - @double_injection = space.double_injection(subject, method_name) - space.double_injections[subject][method_name].should === double_injection + @double_injection = Injections::DoubleInjection.create(subject, method_name) + Injections::DoubleInjection.instances[subject][method_name].should === double_injection verify_call_count = 0 - ( - class << double_injection; - self; - end).class_eval do + ( class << double_injection; self; end).class_eval do define_method(:verify) do verify_call_count += 1 end @@ -626,23 +565,20 @@ class << double_injection; space.verify_double(subject, method_name) verify_call_count.should == 1 - space.double_injections[subject][method_name].should be_nil + Injections::DoubleInjection.instances[subject][method_name].should be_nil end context "when verifying the double_injection raises an error" do it "deletes the double_injection and restores the original method" do original_method = subject.method(method_name) - @double_injection = space.double_injection(subject, method_name) + @double_injection = Injections::DoubleInjection.create(subject, method_name) subject.method(method_name).should_not == original_method - space.double_injections[subject][method_name].should === double_injection + Injections::DoubleInjection.instances[subject][method_name].should === double_injection verify_called = true - ( - class << double_injection; - self; - end).class_eval do + ( class << double_injection; self; end).class_eval do define_method(:verify) do verify_called = true raise "An Error" @@ -651,86 +587,10 @@ class << double_injection; lambda {space.verify_double(subject, method_name)}.should raise_error verify_called.should be_true - space.double_injections[subject][method_name].should be_nil + Injections::DoubleInjection.instances[subject][method_name].should be_nil subject.method(method_name).should == original_method end end end - - describe "#verify_ordered_double" do - before do - @method_name = :foobar - @double_injection = space.double_injection(subject, method_name) - end - - macro "#verify_ordered_double" do - it "raises an error when Double is NonTerminal" do - double = new_double - space.register_ordered_double(double) - - double.definition.any_number_of_times - double.should_not be_terminal - - lambda do - space.verify_ordered_double(double) - end.should raise_error( - Errors::DoubleOrderError, - "Ordered Doubles cannot have a NonTerminal TimesCalledExpectation" - ) - end - end - - context "when the passed in double is at the front of the queue" do - send "#verify_ordered_double" - it "keeps the double when times called is not verified" do - double = new_double - space.register_ordered_double(double) - - double.definition.twice - double.should be_attempt - - space.verify_ordered_double(double) - space.ordered_doubles.should include(double) - end - - context "when Double#attempt? is false" do - it "removes the double" do - double = new_double - space.register_ordered_double(double) - - double.definition.with(1).once - subject.foobar(1) - double.should_not be_attempt - - space.verify_ordered_double(double) - space.ordered_doubles.should_not include(double) - end - end - end - - context "when the passed in double is not at the front of the queue" do - send "#verify_ordered_double" - it "raises error" do - first_double = new_double - second_double = new_double - - lambda do - space.verify_ordered_double(second_double) - end.should raise_error( - Errors::DoubleOrderError, - "foobar() called out of order in list\n" << - "- foobar()\n" << - "- foobar()" - ) - end - - def new_double - double = super - double.definition.once - space.register_ordered_double(double) - double - end - end - end end end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3589cab2..4ec3df2e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -29,82 +29,6 @@ def macro(name, &implementation) define_method(name, &implementation) end end - - define_method("normal strategy definition") do - describe "strategy definition" do - attr_reader :strategy_method_name - - context "when passed a subject" do - it "returns a DoubleDefinitionCreateBlankSlate" do - double = call_strategy(subject).foobar - double.should be_instance_of(RR::DoubleDefinitions::DoubleDefinition) - end - end - - context "when passed a method name and a definition_eval_block" do - it "raises an ArgumentError" do - lambda do - call_strategy(subject, :foobar) {} - end.should raise_error(ArgumentError, "Cannot pass in a method name and a block") - end - end - end - end - - define_method("! strategy definition") do - describe "strategy definition" do - attr_reader :strategy_method_name - - context "when not passed a method_name argument" do - it "returns a DoubleDefinitionCreateBlankSlate" do - call_strategy.should respond_to(:__subject__) - end - - context "when passed a definition_eval_block argument" do - it "calls the definition_eval_block and passes in the DoubleDefinitionCreateBlankSlate" do - passed_in_proxy = nil - proxy = call_strategy do |proxy| - passed_in_proxy = proxy - end - - passed_in_proxy.should == proxy - end - end - end - - context "when passed a method_name argument" do - it "returns a DoubleDefinition" do - double_definition = call_strategy(:foobar) - double_definition.class.should == RR::DoubleDefinitions::DoubleDefinition - end - - describe "the returned DoubleDefinition" do - it "has #subject set to an anonymous Object" do - double_definition = call_strategy(:foobar) - double_definition.subject.class.should == Object - end - end - end - - context "when passed a method name and a definition_eval_block" do - it "raises an ArgumentError" do - lambda do - call_strategy(:foobar) {} - end.should raise_error(ArgumentError, "Cannot pass in a method name and a block") - end - end - end - end - end - - def new_double( - double_injection=double_injection, - double_definition=RR::DoubleDefinitions::DoubleDefinition.new(creator = RR::DoubleDefinitions::DoubleDefinitionCreate.new).with_any_args.any_number_of_times - ) - RR::Double.new( - double_injection, - double_definition - ) end def eigen(object) diff --git a/spec/spy_verification_spec.rb b/spec/spy_verification_spec.rb index 898f9dd7..a25e2723 100644 --- a/spec/spy_verification_spec.rb +++ b/spec/spy_verification_spec.rb @@ -119,7 +119,7 @@ def bob context "when the subject is expected where there is not DoubleInjection" do it "raises a DoubleInjectionNotFoundError" do - space.double_injection_exists?(subject, :method_that_does_not_exist).should be_false + ::RR::Injections::DoubleInjection.exists?(subject, :method_that_does_not_exist).should be_false lambda do received(subject).method_that_does_not_exist.call end.should raise_error(RR::Errors::SpyVerificationErrors::DoubleInjectionNotFoundError) From a8cbb5af249e85fb7549ad095edc61d4b8a98c6a Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:34:23 -0700 Subject: [PATCH 2/7] Extracted BlankSlate object with BlankSlate.call method. --- lib/rr.rb | 2 ++ lib/rr/blank_slate.rb | 17 +++++++++++++++++ .../double_definition_create_blank_slate.rb | 13 +------------ lib/rr/space.rb | 4 ++++ lib/rr/spy_verification_proxy.rb | 7 +------ 5 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 lib/rr/blank_slate.rb diff --git a/lib/rr.rb b/lib/rr.rb index 85be0cf1..929cc81f 100644 --- a/lib/rr.rb +++ b/lib/rr.rb @@ -2,6 +2,8 @@ require 'rubygems' require 'forwardable' +require "#{dir}/rr/blank_slate" + require "#{dir}/rr/errors/rr_error" require "#{dir}/rr/errors/subject_does_not_implement_method_error" require "#{dir}/rr/errors/subject_has_different_arity_error" diff --git a/lib/rr/blank_slate.rb b/lib/rr/blank_slate.rb new file mode 100644 index 00000000..b05b9ec8 --- /dev/null +++ b/lib/rr/blank_slate.rb @@ -0,0 +1,17 @@ +module RR + module BlankSlate + class << self + def call(klass) + klass.instance_eval do + instance_methods.each do |unformatted_method_name| + method_name = unformatted_method_name.to_s + unless method_name =~ /^_/ || Space.blank_slate_whitelist.any? {|whitelisted_method_name| method_name == whitelisted_method_name} + alias_method "__blank_slated_#{method_name}", method_name + undef_method method_name + end + end + end + end + end + end +end \ No newline at end of file diff --git a/lib/rr/double_definitions/double_definition_create_blank_slate.rb b/lib/rr/double_definitions/double_definition_create_blank_slate.rb index 627aa92d..31a6e756 100644 --- a/lib/rr/double_definitions/double_definition_create_blank_slate.rb +++ b/lib/rr/double_definitions/double_definition_create_blank_slate.rb @@ -1,20 +1,9 @@ module RR module DoubleDefinitions class DoubleDefinitionCreateBlankSlate - class << self - def blank_slate_methods - instance_methods.each do |m| - unless m =~ /^_/ || m.to_s == 'object_id' || m.to_s == 'respond_to?' || m.to_s == 'method_missing' || m.to_s == 'instance_eval' || m.to_s == 'instance_exec' - alias_method "__blank_slated_#{m}", m - undef_method m - end - end - end - end - def initialize(double_definition_create, &block) #:nodoc: @double_definition_create = double_definition_create - respond_to?(:class) ? self.class.blank_slate_methods : __blank_slated_class.blank_slate_methods + BlankSlate.call(respond_to?(:class) ? self.class : __blank_slated_class) if block_given? if block.arity == 1 diff --git a/lib/rr/space.rb b/lib/rr/space.rb index 13fb3a62..ed6c698d 100644 --- a/lib/rr/space.rb +++ b/lib/rr/space.rb @@ -79,6 +79,10 @@ def record_call(subject, method_name, arguments, block) @recorded_calls << [subject, method_name, arguments, block] end + def blank_slate_whitelist + @blank_slate_whitelist ||= ["object_id", "respond_to?", "method_missing", "instance_eval", "instance_exec"] + end + protected # Removes the ordered Doubles from the list def reset_ordered_doubles diff --git a/lib/rr/spy_verification_proxy.rb b/lib/rr/spy_verification_proxy.rb index dd5774dd..12ad4abe 100644 --- a/lib/rr/spy_verification_proxy.rb +++ b/lib/rr/spy_verification_proxy.rb @@ -1,11 +1,6 @@ module RR class SpyVerificationProxy - instance_methods.each do |m| - unless m =~ /^_/ || m.to_s == 'object_id' || m.to_s == "instance_eval" || m.to_s == "instance_exec" || m.to_s == 'respond_to?' - alias_method "__blank_slated_#{m}", m - undef_method m - end - end + BlankSlate.call(self) def initialize(subject) @subject = subject From 8a855d47477a469a0f83fb1308828b1c12c02c01 Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:34:23 -0700 Subject: [PATCH 3/7] Added RR.blank_slate_whitelist which allows users to add method names. Extracted BlankSlate object with BlankSlate.call method. --- lib/rr.rb | 2 ++ lib/rr/blank_slate.rb | 17 +++++++++++++++++ .../double_definition_create_blank_slate.rb | 13 +------------ lib/rr/space.rb | 4 ++++ lib/rr/spy_verification_proxy.rb | 7 +------ 5 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 lib/rr/blank_slate.rb diff --git a/lib/rr.rb b/lib/rr.rb index 85be0cf1..929cc81f 100644 --- a/lib/rr.rb +++ b/lib/rr.rb @@ -2,6 +2,8 @@ require 'rubygems' require 'forwardable' +require "#{dir}/rr/blank_slate" + require "#{dir}/rr/errors/rr_error" require "#{dir}/rr/errors/subject_does_not_implement_method_error" require "#{dir}/rr/errors/subject_has_different_arity_error" diff --git a/lib/rr/blank_slate.rb b/lib/rr/blank_slate.rb new file mode 100644 index 00000000..b05b9ec8 --- /dev/null +++ b/lib/rr/blank_slate.rb @@ -0,0 +1,17 @@ +module RR + module BlankSlate + class << self + def call(klass) + klass.instance_eval do + instance_methods.each do |unformatted_method_name| + method_name = unformatted_method_name.to_s + unless method_name =~ /^_/ || Space.blank_slate_whitelist.any? {|whitelisted_method_name| method_name == whitelisted_method_name} + alias_method "__blank_slated_#{method_name}", method_name + undef_method method_name + end + end + end + end + end + end +end \ No newline at end of file diff --git a/lib/rr/double_definitions/double_definition_create_blank_slate.rb b/lib/rr/double_definitions/double_definition_create_blank_slate.rb index 627aa92d..31a6e756 100644 --- a/lib/rr/double_definitions/double_definition_create_blank_slate.rb +++ b/lib/rr/double_definitions/double_definition_create_blank_slate.rb @@ -1,20 +1,9 @@ module RR module DoubleDefinitions class DoubleDefinitionCreateBlankSlate - class << self - def blank_slate_methods - instance_methods.each do |m| - unless m =~ /^_/ || m.to_s == 'object_id' || m.to_s == 'respond_to?' || m.to_s == 'method_missing' || m.to_s == 'instance_eval' || m.to_s == 'instance_exec' - alias_method "__blank_slated_#{m}", m - undef_method m - end - end - end - end - def initialize(double_definition_create, &block) #:nodoc: @double_definition_create = double_definition_create - respond_to?(:class) ? self.class.blank_slate_methods : __blank_slated_class.blank_slate_methods + BlankSlate.call(respond_to?(:class) ? self.class : __blank_slated_class) if block_given? if block.arity == 1 diff --git a/lib/rr/space.rb b/lib/rr/space.rb index 13fb3a62..ed6c698d 100644 --- a/lib/rr/space.rb +++ b/lib/rr/space.rb @@ -79,6 +79,10 @@ def record_call(subject, method_name, arguments, block) @recorded_calls << [subject, method_name, arguments, block] end + def blank_slate_whitelist + @blank_slate_whitelist ||= ["object_id", "respond_to?", "method_missing", "instance_eval", "instance_exec"] + end + protected # Removes the ordered Doubles from the list def reset_ordered_doubles diff --git a/lib/rr/spy_verification_proxy.rb b/lib/rr/spy_verification_proxy.rb index dd5774dd..12ad4abe 100644 --- a/lib/rr/spy_verification_proxy.rb +++ b/lib/rr/spy_verification_proxy.rb @@ -1,11 +1,6 @@ module RR class SpyVerificationProxy - instance_methods.each do |m| - unless m =~ /^_/ || m.to_s == 'object_id' || m.to_s == "instance_eval" || m.to_s == "instance_exec" || m.to_s == 'respond_to?' - alias_method "__blank_slated_#{m}", m - undef_method m - end - end + BlankSlate.call(self) def initialize(subject) @subject = subject From b534b65da07477daaa12c832f7048db28161c36e Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:50:07 -0700 Subject: [PATCH 4/7] - Fixed class_eval method redefinition warning in jruby --- CHANGES | 3 +++ lib/rr/space.rb | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 3fa3d9a8..32e18a72 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +- Added RR.blank_slate_whitelist +- Fixed class_eval method redefinition warning in jruby + 0.10.10 - Suite passes for Ruby 1.9.1 diff --git a/lib/rr/space.rb b/lib/rr/space.rb index ed6c698d..cbbef44f 100644 --- a/lib/rr/space.rb +++ b/lib/rr/space.rb @@ -80,7 +80,9 @@ def record_call(subject, method_name, arguments, block) end def blank_slate_whitelist - @blank_slate_whitelist ||= ["object_id", "respond_to?", "method_missing", "instance_eval", "instance_exec"] + @blank_slate_whitelist ||= [ + "object_id", "respond_to?", "method_missing", "instance_eval", "instance_exec", "class_eval" + ] end protected From bc62b955fe924b15a6a11cf280c38b59a7fcc393 Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:51:39 -0700 Subject: [PATCH 5/7] Version 0.10.11 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 32e18a72..545e3817 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,4 @@ +0.10.11 - Added RR.blank_slate_whitelist - Fixed class_eval method redefinition warning in jruby From b0e44d829c7c2ad7df21a56627ada59b4b9a4e10 Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:51:48 -0700 Subject: [PATCH 6/7] Version bump to 0.10.11 --- VERSION.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.yml b/VERSION.yml index 3ba400a4..472d40ca 100644 --- a/VERSION.yml +++ b/VERSION.yml @@ -1,5 +1,5 @@ --- :build: :minor: 10 -:patch: 10 +:patch: 11 :major: 0 From 9e2f3684f5e3ca08e2f359e989542c1d64811646 Mon Sep 17 00:00:00 2001 From: Brian Takita Date: Mon, 22 Mar 2010 22:51:52 -0700 Subject: [PATCH 7/7] Regenerated gemspec for version 0.10.11 --- rr.gemspec | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/rr.gemspec b/rr.gemspec index 2facdf10..4d8bc2a2 100644 --- a/rr.gemspec +++ b/rr.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = %q{rr} - s.version = "0.10.10" + s.version = "0.10.11" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Brian Takita"] - s.date = %q{2010-02-25} + s.date = %q{2010-03-22} s.description = %q{RR (Double Ruby) is a double framework that features a rich selection of double techniques and a terse syntax. http://xunitpatterns.com/Test%20Double.html} s.email = %q{brian@pivotallabs.com} s.extra_rdoc_files = [ @@ -26,11 +26,12 @@ Gem::Specification.new do |s| "lib/rr/adapters/rr_methods.rb", "lib/rr/adapters/rspec.rb", "lib/rr/adapters/test_unit.rb", + "lib/rr/blank_slate.rb", "lib/rr/double.rb", "lib/rr/double_definitions/child_double_definition_create.rb", "lib/rr/double_definitions/double_definition.rb", "lib/rr/double_definitions/double_definition_create.rb", - "lib/rr/double_definitions/double_definition_create_proxy.rb", + "lib/rr/double_definitions/double_definition_create_blank_slate.rb", "lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb", "lib/rr/double_definitions/strategies/implementation/proxy.rb", "lib/rr/double_definitions/strategies/implementation/reimplementation.rb", @@ -91,7 +92,6 @@ Gem::Specification.new do |s| "lib/rr/wildcard_matchers/range.rb", "lib/rr/wildcard_matchers/regexp.rb", "lib/rr/wildcard_matchers/satisfy.rb", - "ruby_19_spec.rb", "spec/api/dont_allow/dont_allow_after_stub_spec.rb", "spec/api/mock/mock_spec.rb", "spec/api/proxy/proxy_spec.rb", @@ -106,13 +106,11 @@ Gem::Specification.new do |s| "spec/rr/adapters/rr_methods_space_spec.rb", "spec/rr/adapters/rr_methods_spec_helper.rb", "spec/rr/adapters/rr_methods_times_matcher_spec.rb", - "spec/rr/double_definitions/child_double_definition_create_spec.rb", - "spec/rr/double_definitions/double_definition_create_proxy_spec.rb", + "spec/rr/double_definitions/child_double_definition_creator_spec.rb", + "spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb", "spec/rr/double_definitions/double_definition_create_spec.rb", - "spec/rr/double_definitions/double_definition_spec.rb", "spec/rr/double_injection/double_injection_spec.rb", "spec/rr/double_injection/double_injection_verify_spec.rb", - "spec/rr/double_spec.rb", "spec/rr/errors/rr_error_spec.rb", "spec/rr/expectations/any_argument_expectation_spec.rb", "spec/rr/expectations/anything_argument_equality_expectation_spec.rb", @@ -129,7 +127,6 @@ Gem::Specification.new do |s| "spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb", "spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb", "spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb", - "spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb", "spec/rr/rspec/invocation_matcher_spec.rb", "spec/rr/rspec/rspec_adapter_spec.rb", "spec/rr/rspec/rspec_backtrace_tweaking_spec.rb",