stubborn 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Daniel Cadenas
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,55 @@
1
+ = stubborn
2
+
3
+ A Ruby gem that helps you find missing stubs in your tests.
4
+
5
+ Say you have this classes:
6
+
7
+ class Api
8
+ def slow_method(a, b, c)
9
+ ...
10
+ end
11
+ end
12
+
13
+ class MyClassThatUsesApi
14
+ def useful_method
15
+ ...
16
+ important_value = api.slow_method(important_parameter, something_else, another)
17
+ ...
18
+ end
19
+ end
20
+
21
+ And you have this somewhere in your test_helper/spec_helper:
22
+
23
+ require 'rubygems'
24
+ require 'stubborn'
25
+
26
+ 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
+
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:
35
+
36
+ You've missed adding a stub. Consider this suggestions:
37
+ api_instance.stub!(:slow_method).with(123, AClass, "hi").and_return(another_class_instance)
38
+ api_instance.stub!(:slow_method).and_return(another_class_instance)
39
+
40
+ == Installation
41
+
42
+ sudo gem install stubborn
43
+
44
+ == To Do
45
+
46
+ * 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
48
+
49
+ == Collaborate
50
+
51
+ http://github.com/dcadenas/stubborn
52
+
53
+ == Copyright
54
+
55
+ Copyright (c) 2009 Daniel Cadenas. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,83 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "stubborn"
8
+ gem.summary = %Q{A gem to help you find your missing stubs}
9
+ gem.email = "dcadenas@gmail.com"
10
+ gem.homepage = "http://github.com/dcadenas/stubborn"
11
+ gem.authors = ["Daniel Cadenas"]
12
+ gem.rubyforge_project = "stubborn"
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION.yml')
46
+ config = YAML.load(File.read('VERSION.yml'))
47
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "stubborn #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
57
+
58
+ begin
59
+ require 'rake/contrib/sshpublisher'
60
+ namespace :rubyforge do
61
+
62
+ desc "Release gem and RDoc documentation to RubyForge"
63
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
64
+
65
+ namespace :release do
66
+ desc "Publish RDoc to RubyForge."
67
+ task :docs => [:rdoc] do
68
+ config = YAML.load(
69
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
70
+ )
71
+
72
+ host = "#{config['username']}@rubyforge.org"
73
+ remote_dir = "/var/www/gforge-projects/stubborn/"
74
+ local_dir = 'rdoc'
75
+
76
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
77
+ end
78
+ end
79
+ end
80
+ rescue LoadError
81
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
82
+ end
83
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,27 @@
1
+ module Stubborn
2
+ class MissedStubException < RuntimeError
3
+ def initialize(object, method_name, args, result, suggester)
4
+ object_label = friendly_name(object)
5
+ args = args.map{|a| friendly_name(a)}.join(", ")
6
+ result = friendly_name(result)
7
+
8
+ @suggestions = suggester.suggestions(object_label, method_name, args, result)
9
+ end
10
+
11
+ def message
12
+ "You've missed adding a stub. Consider this suggestion#{@suggestions.size > 1 ? "s" : ""}:\n#{@suggestions.join("\n")}"
13
+ end
14
+
15
+ private
16
+ def friendly_name(object)
17
+ return "\"#{object}\"" if object.respond_to?(:to_str)
18
+ return object.inspect if object.respond_to?(:to_int)
19
+
20
+ if object.is_a?(Class)
21
+ object.name
22
+ else
23
+ "#{object.class.name.downcase}_instance"
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/stubborn.rb ADDED
@@ -0,0 +1,62 @@
1
+ begin
2
+ require 'proxen'
3
+ rescue LoadError
4
+ puts "You need to install the proxen gem: sudo gem install nakajima-proxen -s http://gems.github.com"
5
+ exit
6
+ end
7
+
8
+ require 'suggesters/rspec_suggester'
9
+ require 'missed_stub_exception'
10
+
11
+ module Stubborn
12
+ def self.should_be_stubbed(object)
13
+ if object.is_a?(Class)
14
+ ProxyForClass.new(object)
15
+ else
16
+ ProxyForInstance.new(object)
17
+ end
18
+ end
19
+
20
+ class ProxyForInstance
21
+ attr_accessor :proxy_target
22
+ proxy_to :proxy_target, :blank_slate => true
23
+
24
+ def initialize(proxy_target, klass = proxy_target.class)
25
+ @proxy_target = proxy_target
26
+ @klass = klass
27
+ @methods_to_skip = ["respond_to?", "is_a?"]
28
+ end
29
+
30
+ def class
31
+ @klass
32
+ end
33
+
34
+ def method_missing(method_name, *args, &block)
35
+ result = @proxy_target.send(method_name, *args, &block)
36
+ return result if @methods_to_skip.include?(method_name.to_s)
37
+ raise MissedStubException.new(@proxy_target, method_name, args, result, Suggesters::RSpecSuggester)
38
+ end
39
+ end
40
+
41
+ class ProxyForClass < ProxyForInstance
42
+ def initialize(proxy_target)
43
+ super
44
+ redefine_const(proxy_target.name, self) unless proxy_target.name.strip.empty?
45
+ end
46
+
47
+ def name
48
+ @proxy_target.name
49
+ end
50
+
51
+ def new(*args, &block)
52
+ new_instance = @proxy_target.new(*args, &block)
53
+ ProxyForInstance.new(new_instance, self)
54
+ end
55
+
56
+ private
57
+ def redefine_const(name, value)
58
+ Object.__send__(:remove_const, name) if Object.const_defined?(name)
59
+ Object.const_set(name, value)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,14 @@
1
+ module Stubborn
2
+ module Suggesters
3
+ module RSpecSuggester
4
+ def self.suggestions(object_label, method_name, args, result)
5
+ with = args.strip.empty? ? nil : ".with(#{args})"
6
+ and_return = result.nil? ? nil : ".and_return(#{result})"
7
+ suggestions = []
8
+ suggestions << "#{object_label}.stub!(:#{method_name})#{with}#{and_return}"
9
+ suggestions << "#{object_label}.stub!(:#{method_name})#{and_return}"
10
+ suggestions.uniq
11
+ end
12
+ end
13
+ end
14
+ end
data/stubborn.gemspec ADDED
@@ -0,0 +1,53 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{stubborn}
5
+ s.version = "0.1.2"
6
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.authors = ["Daniel Cadenas"]
8
+ s.date = %q{2009-10-02}
9
+ s.email = %q{dcadenas@gmail.com}
10
+ s.extra_rdoc_files = [
11
+ "LICENSE",
12
+ "README.rdoc"
13
+ ]
14
+
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "lib/missed_stub_exception.rb",
23
+ "lib/stubborn.rb",
24
+ "lib/suggesters/rspec_suggester.rb",
25
+ "stubborn.gemspec",
26
+ "test/stubborn_method_filtering_test.rb",
27
+ "test/stubborn_test.rb",
28
+ "test/suggesters/rspec_suggester_test.rb",
29
+ "test/test_helper.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/dcadenas/stubborn}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubyforge_project = %q{stubborn}
35
+ s.rubygems_version = %q{1.3.3}
36
+ s.summary = %q{A gem to help you find your missing stubs}
37
+ s.test_files = [
38
+ "test/stubborn_method_filtering_test.rb",
39
+ "test/stubborn_test.rb",
40
+ "test/suggesters/rspec_suggester_test.rb",
41
+ "test/test_helper.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ else
50
+ end
51
+ else
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+
3
+ def reset_test_api_class
4
+ name = "TestApi"
5
+ Object.__send__(:remove_const, name) if Object.const_defined?(name)
6
+ klass = Class.new do
7
+ def instance_method_1
8
+ "instance_method_1 called"
9
+ end
10
+
11
+ def instance_method_2
12
+ "instance_method_2 called"
13
+ end
14
+
15
+ def self.class_method_1
16
+ "class_method_1 called"
17
+ end
18
+
19
+ def self.class_method_2
20
+ "class_method_2 called"
21
+ end
22
+ end
23
+ Object.const_set(name, klass)
24
+ end
25
+
26
+ __END__
27
+ PENDING
28
+
29
+ Expectations do
30
+ expect "instance_method_1 called" do
31
+ api = TestApi.new
32
+ Stubborn.should_be_stubbed(api, :except => :instance_method_1)
33
+ api.instance_method_1
34
+ end
35
+
36
+ expect Stubborn::MissedStubException do
37
+ api = TestApi.new
38
+ Stubborn.should_be_stubbed(api, :except => :instance_method_1)
39
+ api.instance_method_2
40
+ end
41
+
42
+ expect "instance_method_2 called" do
43
+ api = TestApi.new
44
+ Stubborn.should_be_stubbed(api, :only => :instance_method_1)
45
+ api.instance_method_2
46
+ end
47
+
48
+ expect Stubborn::MissedStubException do
49
+ api = TestApi.new
50
+ Stubborn.should_be_stubbed(api, :only => :instance_method_1)
51
+ api.instance_method_1
52
+ end
53
+ end
@@ -0,0 +1,105 @@
1
+ require 'test_helper'
2
+
3
+ def reset_test_api_class
4
+ name = "TestApi"
5
+ Object.__send__(:remove_const, name) if Object.const_defined?(name)
6
+ klass = Class.new do
7
+ def plus_one(number)
8
+ number + 1
9
+ end
10
+
11
+ def self.plus_two(number)
12
+ number + 2
13
+ end
14
+ end
15
+ Object.const_set(name, klass)
16
+ end
17
+
18
+ Expectations do
19
+ expect 2 do
20
+ reset_test_api_class
21
+ TestApi.new.plus_one(1)
22
+ end
23
+
24
+ expect "TestApi" do
25
+ reset_test_api_class
26
+ api = TestApi.new
27
+ api = Stubborn.should_be_stubbed(api)
28
+ api.class.name
29
+ end
30
+
31
+ expect true do
32
+ reset_test_api_class
33
+ api = TestApi.new
34
+ api = Stubborn.should_be_stubbed(api)
35
+ api.respond_to?(:plus_one)
36
+ end
37
+
38
+ expect Stubborn::MissedStubException do
39
+ reset_test_api_class
40
+ api = TestApi.new
41
+ api = Stubborn.should_be_stubbed(api)
42
+ api.plus_one(1)
43
+ end
44
+
45
+ expect 3 do
46
+ reset_test_api_class
47
+ api = TestApi.new
48
+ api = Stubborn.should_be_stubbed(api)
49
+ api.class.plus_two(1)
50
+ end
51
+
52
+ expect "You've missed adding a stub. Consider this suggestions:\ntestapi_instance.stub!(:plus_one).with(0).and_return(1)\ntestapi_instance.stub!(:plus_one).and_return(1)" do
53
+ reset_test_api_class
54
+ api = TestApi.new
55
+ api = Stubborn.should_be_stubbed(api)
56
+ message = ""
57
+ begin
58
+ api.plus_one(0)
59
+ rescue => e
60
+ message = e.message
61
+ end
62
+ end
63
+
64
+ expect "TestApi" do
65
+ reset_test_api_class
66
+ Stubborn.should_be_stubbed(TestApi)
67
+ api = TestApi.new
68
+ api.class.name
69
+ end
70
+
71
+ expect true do
72
+ reset_test_api_class
73
+ Stubborn.should_be_stubbed(TestApi)
74
+ api = TestApi.new
75
+ api.respond_to?(:plus_one)
76
+ end
77
+
78
+ expect Stubborn::MissedStubException do
79
+ reset_test_api_class
80
+ Stubborn.should_be_stubbed(TestApi)
81
+ api = TestApi.new
82
+ api.plus_one(1)
83
+ end
84
+
85
+ expect Stubborn::MissedStubException do
86
+ reset_test_api_class
87
+ Stubborn.should_be_stubbed(TestApi)
88
+ api = TestApi.new
89
+ api.class.plus_two(1)
90
+ end
91
+
92
+ expect "You've missed adding a stub. Consider this suggestions:\ntestapi_instance.stub!(:plus_one).with(0).and_return(1)\ntestapi_instance.stub!(:plus_one).and_return(1)" do
93
+ reset_test_api_class
94
+ Stubborn.should_be_stubbed(TestApi)
95
+ message = ""
96
+ api = TestApi.new
97
+ begin
98
+ api.plus_one(0)
99
+ rescue => e
100
+ message = e.message
101
+ end
102
+ end
103
+ end
104
+
105
+
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class AClass; end
4
+ class Api; end
5
+
6
+ include Stubborn
7
+
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
11
+ end
12
+
13
+ expect "You've missed adding a stub. Consider this suggestion:\napi_instance.stub!(:method).and_return(aclass_instance)" do
14
+ MissedStubException.new(Api.new, :method, [], AClass.new, Suggesters::RSpecSuggester).message
15
+ end
16
+ end
17
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'expectations'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'stubborn'
7
+
8
+ class Test::Unit::TestCase
9
+ end
10
+
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stubborn
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Cadenas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-02 00:00:00 -03:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: dcadenas@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.rdoc
30
+ - Rakefile
31
+ - VERSION
32
+ - lib/missed_stub_exception.rb
33
+ - lib/stubborn.rb
34
+ - lib/suggesters/rspec_suggester.rb
35
+ - stubborn.gemspec
36
+ - test/stubborn_method_filtering_test.rb
37
+ - test/stubborn_test.rb
38
+ - test/suggesters/rspec_suggester_test.rb
39
+ - test/test_helper.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/dcadenas/stubborn
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --charset=UTF-8
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project: stubborn
64
+ rubygems_version: 1.3.3
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A gem to help you find your missing stubs
68
+ test_files:
69
+ - test/stubborn_method_filtering_test.rb
70
+ - test/stubborn_test.rb
71
+ - test/suggesters/rspec_suggester_test.rb
72
+ - test/test_helper.rb