crispy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce5cdae0bd61dc34b874f0d39aff7633c43e7418
4
+ data.tar.gz: 4865b17724178158276ea6e1134fd614e1cdffb8
5
+ SHA512:
6
+ metadata.gz: e42a8e7746d256b99f4f9fa07ae84f55a154cce1c41a55a41812736249e2b5a49483eeff86d7315de0abd502ad4996ce455605c9283469a400510b81429fa7c3
7
+ data.tar.gz: a0b29456ff5b7a4b993716c3fbebce7b6c0d71fa1cbc0e8f4ec58cfa5d70448306bb464d8eaf782b3c4d801a6ac2a4fc3595990d62ecfe07fb4a1d0558fc0ad5
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in crispy.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Yamamoto Yuji
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # Crispy
2
+
3
+ Test Spy for Any Object in Ruby.
4
+
5
+ ## Features
6
+
7
+ - Test spy for any object by using `prepend` (Sorry, it runs by Ruby 2.0 or higher!)
8
+ - Extremely flexible query for received messages with `received_messages` method.
9
+ - By using Array and Enumerable's methods, you never have to remember the complex API and tons of the argument matchers in RSpec anymore!
10
+ - Makes mocks obsolete so you don't have to be worried about where to put the expectations (i.e. *before or after the subject method*).
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'crispy'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install crispy
25
+
26
+ ## Usage
27
+
28
+ <!--
29
+ # Sample class for doctest.
30
+ doctest_require: './test/doctest-fixtures/your_cool_class.rb'
31
+ -->
32
+
33
+ ### Spy on a Object
34
+
35
+ ```ruby
36
+ >> require 'crispy'
37
+ >> include Crispy # import spy, spy_into and any other functions from Crispy namespace.
38
+
39
+ >> object = YourCoolClass.new
40
+ >> spy = spy_into object
41
+
42
+ >> object.your_cool_method 1, 2, 3
43
+ >> object.your_method_without_argument
44
+ >> object.your_lovely_method 'great', 'arguments'
45
+ >> object.your_lovely_method 'great', 'arguments', 'again'
46
+ >> object.your_finalizer 'resource to release'
47
+ ```
48
+
49
+ #### Spy methods with no arguments
50
+
51
+ Call query methods through the spy object, instead of YourCoolClass's instance.
52
+
53
+ ```ruby
54
+ >> spy(object).received? :your_cool_method
55
+ => true
56
+ >> spy(object).received? :your_method_without_argument
57
+ => true
58
+ >> spy(object).received? :your_lovely_method
59
+ => true
60
+ >> spy(object).received? :your_ugly_method
61
+ => false
62
+ ```
63
+
64
+ #### Spy methods with arguments
65
+
66
+ Each argument is compared by `==` method.
67
+
68
+ ```ruby
69
+ >> spy(object).received? :your_cool_method, 1, 2, 3
70
+ => true
71
+ >> spy(object).received? :your_cool_method, 0, 0, 0
72
+ => false
73
+ >> spy(object).received? :your_method_without_argument, :not, :given, :arguments
74
+ => false
75
+ >> spy(object).received? :your_lovely_method, 'great', 'arguments'
76
+ => true
77
+ >> spy(object).received? :your_ugly_method, 'of course', 'I gave no arguments'
78
+ => false
79
+ ```
80
+
81
+ #### Spy methods with arguments and a block
82
+
83
+ *Sorry, I'm still thinking of the specification for that case.*
84
+
85
+ #### Count method calls
86
+
87
+ ```ruby
88
+ >> spy(object).count_received :your_cool_method
89
+ => 1
90
+ >> spy(object).count_received :your_cool_method, 1, 2, 3
91
+ => 1
92
+ >> spy(object).count_received :your_cool_method, 0, 0, 0
93
+ => 0
94
+ ```
95
+
96
+ #### Get more detailed log
97
+
98
+ You can check arbitrary received methods with the familliar Array's (and of course including Enumerable's!) methods such as `any?`, `all`, `first`, `[]`, `index`.
99
+ Because `spy(object).received_messages` returns an array of `Crispy::ReceivedMessage` instances.
100
+ **You don't have to remember the tons of matchers for received arguments any more!!**
101
+
102
+ ```ruby
103
+ >>
104
+ spy(object).received_messages.any? do|m|
105
+ m.method_name == :your_cool_method && m.arguments.all? {|arg| arg.is_a? Integer }
106
+ end
107
+ => true
108
+
109
+ >> last_method_call = spy(object).received_messages.last
110
+ >>
111
+ last_method_call.method_name == :your_finalizer &&
112
+ last_method_call.arguments == ['resource to release']
113
+ => true
114
+ ```
115
+
116
+ ### Stub Methods of a Spy
117
+
118
+ ```ruby
119
+ >> spy(object).stub(:your_cool_method, 'Awesome!')
120
+ >> object.your_cool_method
121
+ => "Awesome!"
122
+
123
+ >> spy(object).stub(your_lovely_method: 'I love this method!', your_finalizer: 'Finalized!')
124
+ >> object.your_lovely_method
125
+ => "I love this method!"
126
+ >> object.your_finalizer
127
+ => "Finalized!"
128
+ ```
129
+
130
+ ### Stub Methods of a Double
131
+
132
+ ```ruby
133
+ >> your_awesome_double = double('your awesome double', nice!: '+1!', sexy?: true)
134
+ >> your_awesome_double.nice!
135
+ => "+1!"
136
+ >> your_awesome_double.sexy?
137
+ => true
138
+
139
+ >> your_awesome_double.stub(:another_method, 'can be stubbed.')
140
+ >> your_awesome_double.another_method
141
+ => "can be stubbed."
142
+ ```
143
+
144
+ ## Contributing
145
+
146
+ 1. Fork it ( https://github.com/igrep/crispy/fork )
147
+ 2. Create your feature branch (`git checkout -b your-new-feature`)
148
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
149
+ 4. Push to the branch (`git push origin your-new-feature`)
150
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/crispy.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'crispy/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "crispy"
7
+ spec.version = Crispy::VERSION
8
+ spec.authors = ["Yamamoto Yuji"]
9
+ spec.email = ["whosekiteneverfly@gmail.com"]
10
+ spec.summary = %q{Test spy for any object in Ruby.}
11
+ spec.description =
12
+ "Test spy for any object in Ruby.\n" \
13
+ "It makes mocks obsolete so you don't have to be worried about " \
14
+ "where to put the expectations (i.e. before or after the subject method)."
15
+ spec.homepage = "https://github.com/igrep/crispy"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = []
20
+ spec.test_files = spec.files.grep(%r{^test/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "minitest", "~> 5.4"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "rubydoctest"
28
+
29
+ spec.required_ruby_version = '>= 2.0'
30
+ end
data/lib/crispy.rb ADDED
@@ -0,0 +1,41 @@
1
+ require "crispy/version"
2
+ require "crispy/crispy_internal/spy"
3
+ require "crispy/crispy_internal/double"
4
+
5
+ module Crispy
6
+ # All methods of this module should be module_function.
7
+ module_function
8
+
9
+ # Returns a Spy object to wrap all methods of the object.
10
+ def spy_into object, stubs_map = {}
11
+ ::Crispy::CrispyInternal::Spy.new object, stubs_map
12
+ end
13
+
14
+ def double name_or_stubs_map = nil, stubs_map = {}
15
+ ::Crispy::CrispyInternal::Double.new name_or_stubs_map, stubs_map
16
+ end
17
+
18
+ # Make and returns a Crispy::ClassSpy's instance to spy all instances of a class.
19
+ def spy_on_any_instance_of klass
20
+ raise NotImplementedError, "Sorry, this feature is under construction :("
21
+ ::Crispy::CrispyInternal::ClassSpy.new klass
22
+ end
23
+
24
+ def spy object
25
+ object.__CRISPY_SPY__
26
+ end
27
+
28
+ # Begins to log all instances and its received messages of a class.
29
+ # _NOTE_: replace the constant containing the class
30
+ def spy_into_class! klass
31
+ raise NotImplementedError, "Sorry, this feature is under construction :("
32
+ spy_class = spy_on_any_instance_of klass
33
+ stub_const! klass.name, spy_class
34
+ spy_class
35
+ end
36
+
37
+ def stub_const! const_name, value
38
+ raise NotImplementedError, "Sorry, this feature is under construction :("
39
+ end
40
+
41
+ end
@@ -0,0 +1,25 @@
1
+ module Crispy
2
+ module Crispy
3
+ class ReceivedMessage
4
+
5
+ attr_reader :method_name, :arguments, :attached_block
6
+
7
+ class << self
8
+ alias [] new
9
+ end
10
+
11
+ def initialize method_name, *arguments, &attached_block
12
+ @method_name = method_name
13
+ @arguments = arguments
14
+ @attached_block = attached_block
15
+ end
16
+
17
+ def == other
18
+ @method_name == other.method_name &&
19
+ @arguments == other.arguments &&
20
+ @attached_block == other.attached_block
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'crispy/crispy_internal/with_stubber'
2
+
3
+ module Crispy
4
+ module CrispyInternal
5
+ class Double
6
+ include WithStubber
7
+
8
+ def initialize name_or_stubs_map = nil, stubs_map = {}
9
+ if name_or_stubs_map.is_a? ::Hash
10
+ @name = ''.freeze
11
+ initialize_stubber(name_or_stubs_map)
12
+ else
13
+ @name = name_or_stubs_map
14
+ initialize_stubber(stubs_map)
15
+ end
16
+ singleton_class =
17
+ class << self
18
+ self
19
+ end
20
+ prepend_stubber singleton_class
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ require 'crispy/crispy/received_message'
2
+ require 'crispy/crispy_internal/spy_mixin'
3
+ require 'crispy/crispy_internal/with_stubber'
4
+
5
+ module Crispy
6
+ module CrispyInternal
7
+ class Spy < ::Module
8
+ include SpyMixin
9
+ include WithStubber
10
+
11
+ def initialize target, stubs_map = {}
12
+ super()
13
+ @received_messages = []
14
+ singleton_class =
15
+ class << target
16
+ self
17
+ end
18
+ initialize_stubber stubs_map
19
+ prepend_stubber singleton_class
20
+
21
+ prepend_features singleton_class
22
+ target.__CRISPY_SPY__ = self
23
+ end
24
+
25
+ def prepend_features klass
26
+ super
27
+ klass.public_instance_methods.each do|method_name|
28
+ self.module_eval { public define_wrapper(method_name) }
29
+ end
30
+ klass.protected_instance_methods.each do|method_name|
31
+ self.module_eval { protected define_wrapper(method_name) }
32
+ end
33
+ klass.private_instance_methods.each do|method_name|
34
+ self.module_eval { private define_wrapper(method_name) }
35
+ end
36
+
37
+ # define accessor after prepending to avoid to spy unexpectedly.
38
+ module_eval { attr_accessor :__CRISPY_SPY__ }
39
+ end
40
+
41
+ private def define_wrapper method_name
42
+ define_method method_name do|*arguments, &attached_block|
43
+ @__CRISPY_SPY__.received_messages <<
44
+ ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
45
+ super(*arguments, &attached_block)
46
+ end
47
+ method_name
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,37 @@
1
+ require 'crispy/crispy/received_message'
2
+
3
+ module Crispy
4
+ module CrispyInternal
5
+ module SpyMixin
6
+
7
+ attr_reader :received_messages
8
+
9
+ def received? method_name, *arguments, &attached_block
10
+ if arguments.empty? and attached_block.nil?
11
+ @received_messages.map(&:method_name).include? method_name
12
+ else
13
+ @received_messages.include? ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
14
+ end
15
+ end
16
+
17
+ def received_once? method_name, *arguments, &attached_block
18
+ if arguments.empty? and attached_block.nil?
19
+ @received_messages.map(&:method_name).one? {|self_method_name| self_method_name == method_name }
20
+ else
21
+ @received_messages.one? do |self_received_message|
22
+ self_received_message == ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
23
+ end
24
+ end
25
+ end
26
+
27
+ def count_received method_name, *arguments, &attached_block
28
+ if arguments.empty? and attached_block.nil?
29
+ @received_messages.map(&:method_name).count method_name
30
+ else
31
+ @received_messages.count ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ module Crispy
2
+ module CrispyInternal
3
+ class Stubber < Module
4
+ public :prepend_features
5
+
6
+ def initialize stubs_map = {}
7
+ super()
8
+ stub stubs_map
9
+ end
10
+
11
+ NOT_SPECIFIED = ::Object.new
12
+
13
+ def stub method_name_or_hash, returned_value = NOT_SPECIFIED, &definition
14
+ case method_name_or_hash
15
+ when Hash
16
+ hash = method_name_or_hash
17
+ hash.each do|method_name, value|
18
+ stub method_name, value
19
+ end
20
+ when ::Symbol, ::String
21
+ self.module_exec method_name_or_hash do|method_name|
22
+ # TODO: should not ignore arguments?
23
+ define_method(method_name) {|*_arguments| returned_value }
24
+ end
25
+ end
26
+ self
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ require 'crispy/crispy_internal/stubber'
2
+
3
+ module Crispy
4
+ module CrispyInternal
5
+ module WithStubber
6
+
7
+ private def initialize_stubber stubs_map = {}
8
+ @__CRISPY_STUBBER__ = Stubber.new(stubs_map)
9
+ end
10
+
11
+ private def prepend_stubber klass
12
+ @__CRISPY_STUBBER__.prepend_features klass
13
+ end
14
+
15
+ def stub *arguments, &definition
16
+ @__CRISPY_STUBBER__.stub(*arguments, &definition)
17
+ self
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Crispy
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ class YourCoolClass
2
+ def your_cool_method *args
3
+ end
4
+ def your_method_without_argument
5
+ end
6
+ def your_lovely_method *args
7
+ end
8
+ def your_finalizer *args
9
+ end
10
+ end
@@ -0,0 +1,145 @@
1
+ $VERBOSE = true # enable warnings
2
+
3
+ require 'crispy'
4
+ require 'minitest/autorun'
5
+
6
+ class TestCrispy < MiniTest::Test
7
+ include ::Crispy
8
+
9
+ # Inherit BasicObject because it has fewer meta-programming methods than Object
10
+ class ObjectClass < BasicObject
11
+ def hoge a, b, c
12
+ private_foo a
13
+ [a, b, c]
14
+ end
15
+ def foo
16
+ 123
17
+ end
18
+ def bar
19
+ []
20
+ end
21
+ def method_to_stub1
22
+ fail "Not stubbed actually! The test fails."
23
+ end
24
+ def method_to_stub2
25
+ fail "Not stubbed actually! The test fails."
26
+ end
27
+
28
+ private def private_foo a
29
+ :private_foo
30
+ end
31
+ end
32
+
33
+ class TestCrispySpyInto < TestCrispy
34
+
35
+ def setup
36
+ @object = ObjectClass.new
37
+
38
+ @returned_spy = spy_into(
39
+ @object, method_to_stub1: :stubbed1, method_to_stub2: :stubbed2
40
+ )
41
+
42
+ @object.hoge 1, 2, 3
43
+ @object.foo
44
+ @object.hoge 3, 4, 5
45
+
46
+ @subject = spy(@object)
47
+ end
48
+
49
+ def test_spy_logs_messages_sent_to_an_object
50
+ assert_equal(
51
+ [
52
+ Crispy::ReceivedMessage[:hoge, 1, 2, 3],
53
+ Crispy::ReceivedMessage[:private_foo, 1],
54
+ Crispy::ReceivedMessage[:foo],
55
+ Crispy::ReceivedMessage[:hoge, 3, 4, 5],
56
+ Crispy::ReceivedMessage[:private_foo, 3],
57
+ ],
58
+ @subject.received_messages
59
+ )
60
+ end
61
+
62
+ def test_spy_has_received_messages_sent_to_an_object
63
+ assert @subject.received?(:hoge)
64
+ assert @subject.received?(:foo)
65
+ assert not(@subject.received?(:bar))
66
+ assert @subject.received?(:private_foo)
67
+ end
68
+
69
+ def test_spy_has_received_messages_with_arguments_sent_to_an_object
70
+ assert @subject.received?(:hoge, 1, 2, 3)
71
+ assert @subject.received?(:hoge, 3, 4, 5)
72
+ assert @subject.received?(:private_foo, 1)
73
+ assert @subject.received?(:private_foo, 3)
74
+ assert not(@subject.received?(:hoge, 0, 0, 0))
75
+ assert not(@subject.received?(:private_foo, 0, 0, 0))
76
+ assert not(@subject.received?(:foo, 1))
77
+ assert not(@subject.received?(:bar, nil))
78
+ end
79
+
80
+ def test_spy_has_received_messages_once_sent_to_an_object
81
+ assert not(@subject.received_once?(:hoge))
82
+ assert not(@subject.received_once?(:private_foo))
83
+ assert @subject.received_once?(:hoge, 3, 4, 5)
84
+ assert @subject.received_once?(:private_foo, 3)
85
+ assert not(@subject.received_once?(:private_foo, 3, 4))
86
+ assert @subject.received_once?(:foo)
87
+ assert not(@subject.received_once?(:bar))
88
+ end
89
+
90
+ def test_spy_counts_received_messages_sent_to_an_object
91
+ assert_equal(1, @subject.count_received(:hoge, 1, 2, 3))
92
+ assert_equal(1, @subject.count_received(:hoge, 3, 4, 5))
93
+ assert_equal(0, @subject.count_received(:hoge, 0, 0, 0))
94
+ assert_equal(2, @subject.count_received(:hoge))
95
+
96
+ assert_equal(1, @subject.count_received(:private_foo, 1))
97
+ assert_equal(1, @subject.count_received(:private_foo, 3))
98
+ assert_equal(0, @subject.count_received(:private_foo, 0))
99
+ assert_equal(2, @subject.count_received(:private_foo))
100
+
101
+ assert_equal(1, @subject.count_received(:foo))
102
+ assert_equal(0, @subject.count_received(:bar))
103
+ end
104
+
105
+ def test_spy_changes_stubbed_method
106
+ assert_equal(:stubbed1, @object.method_to_stub1)
107
+ assert_equal(:stubbed2, @object.method_to_stub2)
108
+ end
109
+
110
+ def test_spy_is_also_returned_by_spy_into_method
111
+ assert_same @subject, @returned_spy
112
+ end
113
+
114
+ end
115
+
116
+ class TestCrispyDouble < TestCrispy
117
+ def setup
118
+ @expected_hoge = Object.new
119
+ @expected_foo = Object.new
120
+ @expected_bar = Object.new
121
+ @expected_baz = Object.new
122
+
123
+ @double = double('some double', hoge: @expected_hoge, foo: @expected_foo)
124
+ @double.stub(bar: @expected_bar, baz: @expected_baz)
125
+
126
+ @actual_hoge1 = @double.hoge :with, :any, :arguments do
127
+ 'and a block'
128
+ end
129
+ @actual_hoge2 = @double.hoge
130
+ @actual_foo = @double.foo
131
+ @actual_bar = @double.bar
132
+ @actual_baz = @double.baz
133
+ end
134
+
135
+ def test_double_can_stub_specified_methods
136
+ assert_same @expected_hoge, @actual_hoge1
137
+ assert_same @expected_hoge, @actual_hoge2
138
+ assert_same @expected_foo, @actual_foo
139
+ assert_same @expected_bar, @actual_bar
140
+ assert_same @expected_baz, @actual_baz
141
+ end
142
+
143
+ end
144
+
145
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crispy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Yamamoto Yuji
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubydoctest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: |-
84
+ Test spy for any object in Ruby.
85
+ It makes mocks obsolete so you don't have to be worried about where to put the expectations (i.e. before or after the subject method).
86
+ email:
87
+ - whosekiteneverfly@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - crispy.gemspec
98
+ - lib/crispy.rb
99
+ - lib/crispy/crispy/received_message.rb
100
+ - lib/crispy/crispy_internal/double.rb
101
+ - lib/crispy/crispy_internal/spy.rb
102
+ - lib/crispy/crispy_internal/spy_mixin.rb
103
+ - lib/crispy/crispy_internal/stubber.rb
104
+ - lib/crispy/crispy_internal/with_stubber.rb
105
+ - lib/crispy/version.rb
106
+ - test/doctest-fixtures/your_cool_class.rb
107
+ - test/test_crispy.rb
108
+ homepage: https://github.com/igrep/crispy
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '2.0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.2.2
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Test spy for any object in Ruby.
132
+ test_files:
133
+ - test/doctest-fixtures/your_cool_class.rb
134
+ - test/test_crispy.rb