crispy 0.1.1

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.
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