stubborn 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,11 +2,15 @@
2
2
 
3
3
  A Ruby gem that helps you find missing stubs in your tests.
4
4
 
5
- Say you have this classes:
5
+ == Usage
6
+
7
+ Let's explain through an example. Say you have this classes:
6
8
 
7
9
  class Api
8
10
  def slow_method(a, b, c)
9
11
  ...
12
+ #this is slow or dangerous, so you want to stub it in your tests
13
+ ...
10
14
  end
11
15
  end
12
16
 
@@ -18,33 +22,47 @@ Say you have this classes:
18
22
  end
19
23
  end
20
24
 
21
- And you have this somewhere in your test_helper/spec_helper:
25
+ And you've forgot to stub your api class in many tests of your huge test suite:
26
+
27
+ it "should do something useful" do
28
+ MyClassThatUsesApi.new.useful_method.should be_useful
29
+ end
30
+
31
+ Then you could use stubborn to help you find and prevent those misses just by adding this somewhere in your test_helper/spec_helper:
22
32
 
23
33
  require 'rubygems'
24
34
  require 'stubborn'
25
35
 
26
36
  Stubborn.should_be_stubbed(Api)
27
-
28
- Then if you forget about stubbing the api class in some of your tests like this:
29
-
30
- it "should do something useful" do
31
- MyClassThatUsesApi.new.useful_method.should be_useful
32
- end
33
37
 
34
- You will know that you missed it because the test will fail with an exception including all information you need to construct the correct stub:
38
+ Now each test with a missing stub will fail throwing an exception that includes all information you need to construct the correct stub:
35
39
 
36
40
  You've missed adding a stub. Consider this suggestions:
37
41
  api_instance.stub!(:slow_method).with(123, AClass, "hi").and_return(another_class_instance)
38
42
  api_instance.stub!(:slow_method).and_return(another_class_instance)
39
43
 
44
+ You have some control on the output by using the :label option so you can better match the way you usually call the methods from your test:
45
+
46
+ Stubborn.should_be_stubbed(Api, :label => "GreatClass.singleton")
47
+
48
+ Which produces this output:
49
+
50
+ You've missed adding a stub. Consider this suggestions:
51
+ GreatClass.singleton.stub!(:slow_method).with(123, AClass, "hi").and_return(another_class_instance)
52
+ GreatClass.singleton.stub!(:slow_method).and_return(another_class_instance)
53
+
54
+ So all class methods of the Api class and all its instances will raise this special exception while running the tests. If you prefer you can use it on a single instance like this:
55
+
56
+ Stubborn.should_be_stubbed(Api.new)
57
+
40
58
  == Installation
41
59
 
42
- sudo gem install stubborn
60
+ sudo gem install stubborn -s http://gemcutter.org
43
61
 
44
62
  == To Do
45
63
 
46
64
  * Filters so that you can choose which methods to include or exclude
47
- * Stub suggestions for more test frameworks. It currently show only rspec syntax
65
+ * Give stub suggestions for more test frameworks. It currently shows only rspec syntax
48
66
 
49
67
  == Collaborate
50
68
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -1,7 +1,7 @@
1
1
  module Stubborn
2
2
  class MissedStubException < RuntimeError
3
- def initialize(object, method_name, args, result, suggester)
4
- object_label = friendly_name(object)
3
+ def initialize(object_or_label, method_name, args, result, suggester)
4
+ object_label = object_or_label.respond_to?(:to_str) ? object_or_label : friendly_name(object_or_label)
5
5
  args = args.map{|a| friendly_name(a)}.join(", ")
6
6
  result = friendly_name(result)
7
7
 
@@ -15,7 +15,7 @@ module Stubborn
15
15
  private
16
16
  def friendly_name(object)
17
17
  return "\"#{object}\"" if object.respond_to?(:to_str)
18
- return object.inspect if object.respond_to?(:to_int)
18
+ return object.inspect if object.respond_to?(:to_int) || object.is_a?(Hash)
19
19
 
20
20
  if object.is_a?(Class)
21
21
  object.name
data/lib/stubborn.rb CHANGED
@@ -9,11 +9,11 @@ require 'suggesters/rspec_suggester'
9
9
  require 'missed_stub_exception'
10
10
 
11
11
  module Stubborn
12
- def self.should_be_stubbed(object)
12
+ def self.should_be_stubbed(object, options = {})
13
13
  if object.is_a?(Class)
14
- ProxyForClass.new(object)
14
+ ProxyForClass.new(object, options)
15
15
  else
16
- ProxyForInstance.new(object)
16
+ ProxyForInstance.new(object, options)
17
17
  end
18
18
  end
19
19
 
@@ -21,10 +21,12 @@ module Stubborn
21
21
  attr_accessor :proxy_target
22
22
  proxy_to :proxy_target, :blank_slate => true
23
23
 
24
- def initialize(proxy_target, klass = proxy_target.class)
24
+ def initialize(proxy_target, options = {})
25
+ options = {:class => proxy_target.class}.merge(options)
26
+ @label = options[:label]
25
27
  @proxy_target = proxy_target
26
- @klass = klass
27
- @methods_to_skip = ["respond_to?", "is_a?"]
28
+ @klass = options[:class]
29
+ @methods_to_skip = ["respond_to?", "is_a?", "kind_of?", "equal?", "eql?", "==", "==="]
28
30
  end
29
31
 
30
32
  def class
@@ -34,12 +36,12 @@ module Stubborn
34
36
  def method_missing(method_name, *args, &block)
35
37
  result = @proxy_target.send(method_name, *args, &block)
36
38
  return result if @methods_to_skip.include?(method_name.to_s)
37
- raise MissedStubException.new(@proxy_target, method_name, args, result, Suggesters::RSpecSuggester)
39
+ raise MissedStubException.new(@label || @proxy_target, method_name, args, result, Suggesters::RSpecSuggester)
38
40
  end
39
41
  end
40
42
 
41
43
  class ProxyForClass < ProxyForInstance
42
- def initialize(proxy_target)
44
+ def initialize(proxy_target, options = {})
43
45
  super
44
46
  redefine_const(proxy_target.name, self) unless proxy_target.name.strip.empty?
45
47
  end
@@ -50,7 +52,7 @@ module Stubborn
50
52
 
51
53
  def new(*args, &block)
52
54
  new_instance = @proxy_target.new(*args, &block)
53
- ProxyForInstance.new(new_instance, self)
55
+ ProxyForInstance.new(new_instance, :class => self)
54
56
  end
55
57
 
56
58
  private
data/stubborn.gemspec CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{stubborn}
5
- s.version = "0.1.2"
5
+ s.version = "0.1.3"
6
+
6
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
8
  s.authors = ["Daniel Cadenas"]
8
9
  s.date = %q{2009-10-02}
@@ -11,7 +12,6 @@ Gem::Specification.new do |s|
11
12
  "LICENSE",
12
13
  "README.rdoc"
13
14
  ]
14
-
15
15
  s.files = [
16
16
  ".document",
17
17
  ".gitignore",
@@ -28,6 +28,24 @@ Expectations do
28
28
  api.class.name
29
29
  end
30
30
 
31
+ %w[is_a? kind_of?].each do |method|
32
+ expect true do
33
+ reset_test_api_class
34
+ api = TestApi.new
35
+ api = Stubborn.should_be_stubbed(api)
36
+ api.__send__(method, TestApi)
37
+ end
38
+ end
39
+
40
+ %w[equal? eql? == ===].each do |method|
41
+ expect true do
42
+ reset_test_api_class
43
+ api = TestApi.new
44
+ proxied_api = Stubborn.should_be_stubbed(api)
45
+ proxied_api.__send__(method, api)
46
+ end
47
+ end
48
+
31
49
  expect true do
32
50
  reset_test_api_class
33
51
  api = TestApi.new
@@ -61,6 +79,18 @@ Expectations do
61
79
  end
62
80
  end
63
81
 
82
+ expect "You've missed adding a stub. Consider this suggestions:\nApi.singleton.stub!(:plus_one).with(0).and_return(1)\nApi.singleton.stub!(:plus_one).and_return(1)" do
83
+ reset_test_api_class
84
+ api = TestApi.new
85
+ api = Stubborn.should_be_stubbed(api, :label => "Api.singleton")
86
+ message = ""
87
+ begin
88
+ api.plus_one(0)
89
+ rescue => e
90
+ message = e.message
91
+ end
92
+ end
93
+
64
94
  expect "TestApi" do
65
95
  reset_test_api_class
66
96
  Stubborn.should_be_stubbed(TestApi)
@@ -6,12 +6,16 @@ class Api; end
6
6
  include Stubborn
7
7
 
8
8
  Expectations do
9
- expect "You've missed adding a stub. Consider this suggestions:\napi_instance.stub!(:method).with(123, AClass, \"hi\").and_return(aclass_instance)\napi_instance.stub!(:method).and_return(aclass_instance)" do
10
- MissedStubException.new(Api.new, :method, [123, AClass,"hi"], AClass.new, Suggesters::RSpecSuggester).message
9
+ expect "You've missed adding a stub. Consider this suggestions:\napi_instance.stub!(:method).with(123, AClass, \"hi\", {1=>2}).and_return(aclass_instance)\napi_instance.stub!(:method).and_return(aclass_instance)" do
10
+ MissedStubException.new(Api.new, :method, [123, AClass,"hi", {1 => 2}], AClass.new, Suggesters::RSpecSuggester).message
11
11
  end
12
12
 
13
13
  expect "You've missed adding a stub. Consider this suggestion:\napi_instance.stub!(:method).and_return(aclass_instance)" do
14
14
  MissedStubException.new(Api.new, :method, [], AClass.new, Suggesters::RSpecSuggester).message
15
15
  end
16
+
17
+ expect "You've missed adding a stub. Consider this suggestion:\nApi.singleton.stub!(:method).and_return(aclass_instance)" do
18
+ MissedStubException.new("Api.singleton", :method, [], AClass.new, Suggesters::RSpecSuggester).message
19
+ end
16
20
  end
17
21
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stubborn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Cadenas