tzu_mock 0.1.0

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: 73cf86478ade4e9c17bd3d3d4b89df92d2a9aeea
4
+ data.tar.gz: 294c4be784376b59e80d73510baf6dc3441015f0
5
+ SHA512:
6
+ metadata.gz: c6d4bc1e6231b7aa831406a8ed3a15015286322596672e9597bfb0aa13c3fdc051f89fa881528870ab0071964d6fcacac899c33e5dbef16851584488991cdee3
7
+ data.tar.gz: d0e1e248bfb380e251585db30c96967a71f89e0e81b312ece69f98d2c5b85462844afcf537b60bbfb77c6c26e98824a595958bcaf19c96bd9998c9a3fc89051a
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Blake Turner
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.md ADDED
@@ -0,0 +1,145 @@
1
+ # Tzu Mock
2
+
3
+ A very simple library for mocking Tzu in RSpec
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ TzuMock.success(klass, result) #=> Successful Outcome
9
+ TzuMock.invalid(klass, error) #=> Invalid Outcome
10
+ TzuMock.failure(klass, error) #=> Failed Outcome
11
+ ```
12
+
13
+ Consider this Tzu command:
14
+
15
+ ```ruby
16
+ class UpdateUser
17
+ include Tzu
18
+ include Tzu::Validation
19
+
20
+ def call(params)
21
+ raise ArgumentError.new('I should be mocked!')
22
+ end
23
+ end
24
+ ```
25
+
26
+ There are two ways this might need to be mocked. The first happens when the Tzu command is invoked without a block:
27
+ ```ruby
28
+ outcome = UpdateUser.run(params)
29
+ ```
30
+
31
+ The second is when the command is invoked with a block, as in this mock controller:
32
+ ```ruby
33
+ class MockController
34
+ attr_reader :method_called
35
+
36
+ def update(params = {})
37
+ UpdateUser.run(params) do
38
+ success do |result|
39
+ @method_called = :success
40
+ end
41
+
42
+ invalid do |error|
43
+ @method_called = :invalid
44
+ end
45
+
46
+ failure do |error|
47
+ @method_called = :failure
48
+ end
49
+ end
50
+ end
51
+ end
52
+ ```
53
+
54
+ In both cases, the use of TzuMock is the same. First, we'll mock at the simple invocation:
55
+ ```ruby
56
+ describe UpdateUser do
57
+ let(:result) { 'Desired Result' }
58
+ let(:error) { { error: 'ERROR' } }
59
+ let(:params) { { last_name: 'Turner' } }
60
+
61
+ context 'success' do
62
+ before { TzuMock.success(UpdateUser, result) }
63
+
64
+ let(:outcome) { UpdateUser.run(params) }
65
+
66
+ it 'mocks a successful outcome and allows parameters to be verified' do
67
+ expect(outcome.success?).to be true
68
+ expect(outcome.result).to eq result
69
+ expect(outcome.type).to be nil
70
+ expect(UpdateUser).to have_received(:run).with(params)
71
+ end
72
+ end
73
+
74
+ context 'invalid' do
75
+ before { TzuMock.invalid(UpdateUser, error) }
76
+
77
+ let(:outcome) { UpdateUser.run(params) }
78
+
79
+ it 'mocks an invalid outcome and allows parameters to be verified' do
80
+ expect(outcome.success?).to be false
81
+ expect(outcome.result).to eq error
82
+ expect(outcome.type).to eq :validation
83
+ expect(UpdateUser).to have_received(:run).with(params)
84
+ end
85
+ end
86
+
87
+ context 'failure' do
88
+ before { TzuMock.failure(UpdateUser, error) }
89
+
90
+ let(:outcome) { UpdateUser.run!(params) }
91
+
92
+ it 'mocks a failed outcome and allows parameters to be verified' do
93
+ expect(outcome.success?).to be false
94
+ expect(outcome.result).to eq error
95
+ expect(outcome.type).to eq :execution
96
+ expect(UpdateUser).to have_received(:run!).with(params)
97
+ end
98
+ end
99
+ end
100
+ ```
101
+
102
+ TzuMock mocks both `run` and `run!`, and spies on the class so that you can verify the parameters that were passed.
103
+
104
+ Next, we'll mock the controller:
105
+ ```ruby
106
+ describe UpdateUser do
107
+ let(:result) { 'Desired Result' }
108
+ let(:error) { { error: 'ERROR' } }
109
+ let(:params) { { last_name: 'Turner' } }
110
+
111
+ let(:controller) { MockController.new }
112
+
113
+ context 'success' do
114
+ before { TzuMock.success(UpdateUser, result) }
115
+
116
+ it 'mocks a successful outcome and allows parameters to be verified' do
117
+ controller.update(params)
118
+ expect(UpdateUser).to have_received(:run).with(params)
119
+ expect(controller.method_called).to eq :success
120
+ end
121
+ end
122
+
123
+ context 'invalid' do
124
+ before { TzuMock.invalid(UpdateUser, error) }
125
+
126
+ it 'mocks a successful outcome and allows parameters to be verified' do
127
+ controller.update(params)
128
+ expect(UpdateUser).to have_received(:run).with(params)
129
+ expect(controller.method_called).to eq :invalid
130
+ end
131
+ end
132
+
133
+ context 'failure' do
134
+ before { TzuMock.failure(UpdateUser, error) }
135
+
136
+ it 'mocks a successful outcome and allows parameters to be verified' do
137
+ controller.update(params)
138
+ expect(UpdateUser).to have_received(:run).with(params)
139
+ expect(controller.method_called).to eq :failure
140
+ end
141
+ end
142
+ end
143
+ ```
144
+
145
+ TzuMock effortlessly passes your desired outcome to the appropriate block.
data/lib/tzu_mock.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'binding_of_caller'
2
+
3
+ class TzuMock
4
+ MOCK_METHODS = [:run, :run!]
5
+
6
+ class << self
7
+ def method_missing(method, *args)
8
+ return super(method) unless [:success, :invalid, :failure].include? method
9
+ prepare(method, *args)
10
+ end
11
+
12
+ def prepare(type, klass, result, method = nil)
13
+ # Get the rspec block context. Will not work if you call TzuMock#prepare directly.
14
+ # Call TzuMock#success, TzuMock#invalid, or TzuMock#failure instead
15
+ rspec_context = binding.of_caller(2).eval('self')
16
+
17
+ new(type, klass, result, rspec_context, method).mock
18
+ end
19
+ end
20
+
21
+ def initialize(type, klass, result, rspec_context, method)
22
+ @type, @klass, @result, @rspec_context, @method = type, klass, result, rspec_context, method
23
+ end
24
+
25
+ def mock
26
+ @rspec_context.instance_eval(&mock_proc(@klass, mock_methods, success?, @result, error_type))
27
+ end
28
+
29
+ private
30
+
31
+ # Need to pass variables in explicity to give the Proc access to them
32
+ def mock_proc(klass, methods, success, result, type)
33
+ Proc.new do
34
+ methods.each do |method|
35
+ allow(klass).to receive(method) do |&block|
36
+ outcome = Tzu::Outcome.new(success, result, type)
37
+ outcome.handle(&block) if block
38
+ outcome
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def mock_methods
45
+ return [@method] if @method
46
+ MOCK_METHODS
47
+ end
48
+
49
+ def success?
50
+ @type == :success
51
+ end
52
+
53
+ def error_type
54
+ case @type
55
+ when :success
56
+ nil
57
+ when :invalid
58
+ :validation
59
+ when :failure
60
+ :execution
61
+ else
62
+ raise ArgumentError.new('Invalid type, must be :success, :invalid, or :failure')
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'byebug'
3
+ require 'tzu'
4
+ require 'rspec'
5
+ require 'bundler/setup'
6
+ Bundler.setup
7
+
8
+ require 'tzu_mock'
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe TzuMock do
4
+ let(:result) { 'Desired Result' }
5
+ let(:error) { { error: 'ERROR' } }
6
+ let(:params) { { last_name: 'Turner' } }
7
+
8
+ class UpdateUser
9
+ include Tzu
10
+ include Tzu::Validation
11
+
12
+ def call(params)
13
+ raise ArgumentError.new('I should be mocked!')
14
+ end
15
+ end
16
+
17
+ class MockController
18
+ attr_reader :method_called
19
+
20
+ def update(params = {})
21
+ UpdateUser.run(params) do
22
+ success do |result|
23
+ @method_called = :success
24
+ end
25
+
26
+ invalid do |error|
27
+ @method_called = :invalid
28
+ end
29
+
30
+ failure do |error|
31
+ @method_called = :failure
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'when invocation does not have a block' do
38
+ context 'success' do
39
+ before { TzuMock.success(UpdateUser, result) }
40
+
41
+ let(:outcome) { UpdateUser.run!(params) }
42
+
43
+ it 'mocks a successful outcome and allows parameters to be verified' do
44
+ expect(outcome.success?).to be true
45
+ expect(outcome.result).to eq result
46
+ expect(outcome.type).to be nil
47
+ expect(UpdateUser).to have_received(:run!).with(params)
48
+ end
49
+ end
50
+
51
+ context 'invalid' do
52
+ before { TzuMock.invalid(UpdateUser, error) }
53
+
54
+ let(:outcome) { UpdateUser.run!(params) }
55
+
56
+ it 'mocks an invalid outcome and allows parameters to be verified' do
57
+ expect(outcome.success?).to be false
58
+ expect(outcome.result).to eq error
59
+ expect(outcome.type).to eq :validation
60
+ expect(UpdateUser).to have_received(:run!).with(params)
61
+ end
62
+ end
63
+
64
+ context 'failure' do
65
+ before { TzuMock.failure(UpdateUser, error) }
66
+
67
+ let(:outcome) { UpdateUser.run(params) }
68
+
69
+ it 'mocks a failed outcome and allows parameters to be verified' do
70
+ expect(outcome.success?).to be false
71
+ expect(outcome.result).to eq error
72
+ expect(outcome.type).to eq :execution
73
+ expect(UpdateUser).to have_received(:run).with(params)
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'when invocation has a block' do
79
+ context 'success' do
80
+ before { TzuMock.success(UpdateUser, result) }
81
+
82
+ let(:controller) { MockController.new }
83
+
84
+ it 'mocks a successful outcome and allows parameters to be verified' do
85
+ controller.update(params)
86
+ expect(UpdateUser).to have_received(:run).with(params)
87
+ expect(controller.method_called).to eq :success
88
+ end
89
+ end
90
+
91
+ context 'invalid' do
92
+ before { TzuMock.invalid(UpdateUser, error) }
93
+
94
+ let(:controller) { MockController.new }
95
+
96
+ it 'mocks a successful outcome and allows parameters to be verified' do
97
+ controller.update(params)
98
+ expect(UpdateUser).to have_received(:run).with(params)
99
+ expect(controller.method_called).to eq :invalid
100
+ end
101
+ end
102
+
103
+ context 'failure' do
104
+ before { TzuMock.failure(UpdateUser, error) }
105
+
106
+ let(:controller) { MockController.new }
107
+
108
+ it 'mocks a successful outcome and allows parameters to be verified' do
109
+ controller.update(params)
110
+ expect(UpdateUser).to have_received(:run).with(params)
111
+ expect(controller.method_called).to eq :failure
112
+ end
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tzu_mock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Blake Turner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: binding_of_caller
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.3.pre1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.3.pre1
27
+ - !ruby/object:Gem::Dependency
28
+ name: tzu
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.1.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.0.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 2.4.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
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
+ description: Simple library for mocking Tzu in RSpec
70
+ email: mail@blakewilliamturner.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - LICENSE.txt
76
+ - README.md
77
+ - lib/tzu_mock.rb
78
+ - spec/spec_helper.rb
79
+ - spec/tzu_mock_spec.rb
80
+ homepage: https://github.com/onfido/tzu_mock
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.2.2
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: TDD with Tzu!
104
+ test_files:
105
+ - spec/spec_helper.rb
106
+ - spec/tzu_mock_spec.rb
107
+ has_rdoc: