active_mocker 2.5.1 → 2.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 785f7ca8b4d2444dfd83cb8352f76590228b6f75
4
- data.tar.gz: 90ca606083940692eaa6775f0628320028bde325
3
+ metadata.gz: 5e2c739418bd430963f4bd13337a9ede2fad3530
4
+ data.tar.gz: 8a5a7d90e9a7c1169a8738c8df531d85b841f411
5
5
  SHA512:
6
- metadata.gz: a8aaaa9f3670f62b90e3f8ea0b9e7a0448b713c7d12187ed7bf69eb52ef2d5d9e266092a38bccd6e810fb30d25837154f083c80453ffed6d01a4e008b649696d
7
- data.tar.gz: 94726fc0af740ead662ab8965ab8f47300c000980c0ef16cc0643b52a9e49f2bcb20e4cd4da2e0915b64d71e950a6c9e3187017d462d4f5940cad889414af05c
6
+ metadata.gz: ab36a730b55d55dee3c9eeb2420573fb4fd25542c81206e66960f38fc6a3655674e747a74901625f598a6afec3f457047fa48c9531d7e74ecc30d2eae36a0a50
7
+ data.tar.gz: 62d6910efdf106bb1243f99fa871238b03a7eb7b9834a70f34e64066965f436d77012586d962e1e774a208c06bc432843d7084780a70c44864ae24963e4e5cb2
@@ -1,6 +1,30 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## 2.5.2 - 2017-09-29
5
+ ### Feature
6
+ - Add mockable class methods to relations.
7
+ - In ActiveRecord model comment Macro `ActiveMocker.safe_methods` now allow class_methods
8
+ ```ruby
9
+ ActiveMocker.safe_methods(*instance_methods, scopes: [], instance_methods: [], class_methods: [])
10
+ ```
11
+
12
+ ### Enhancement
13
+ - Better error message when calling mockable method. Shows RSpec syntax to stub method.
14
+ ```ruby
15
+ Unknown implementation for mock method: UserMock.new_remember_token
16
+ Stub method to continue.
17
+
18
+ RSpec:
19
+ allow(
20
+ UserMock
21
+ ).to receive(:new_remember_token).and_return(:some_expected_result)
22
+ ```
23
+
24
+ ### Removed
25
+ - `ActiveMocker::MockAbilities` required by "active_mocker/deprecated_components/mock_abilities"
26
+ - `mock_method('ClassName')` required by "active_mocker/deprecated_components/rspec" Use `active_mocker.mocks.find('ClassName')` instead
27
+
4
28
  ## 2.5.1 - 2017-07-21
5
29
  ### Feature
6
30
  - Support ActiveRecord v5.1 when generating under that version delete_all does not accept any arguments.
data/README.md CHANGED
@@ -6,7 +6,15 @@
6
6
  [![Gittip](http://img.shields.io/gittip/zeisler.svg)](https://www.gittip.com/zeisler/)
7
7
 
8
8
  ## Description
9
- ActiveMocker creates mock classes from ActiveRecord models, allowing your test suite to run at breakneck speed. This can be done by not loading Rails or hitting a database. The models are read dynamically and statically so that ActiveMocker can generate a Ruby file to require within a test. The mock file can be run by itself and comes with a partial implementation of ActiveRecord. Attributes and associations can be used the same as in ActiveRecord. Methods have the same argument signature but raise a NotImplementedError when called, allowing you to stub it with a mocking framework, like RSpec. Mocks are regenerated when the schema is modified so your mocks won't go stale, preventing the case where your units tests pass but production code fails.
9
+ ActiveMocker creates mock classes from ActiveRecord models,
10
+ allowing your test suite to run at breakneck speed.
11
+ This is done by not loading Rails or hitting the database.
12
+ The models are read dynamically/statically so that ActiveMocker can generate a Ruby file to require within a test.
13
+ The mock file can be run standalone and comes with many use parts of ActiveRecord included.
14
+ Attributes and associations can be used the same as in ActiveRecord.
15
+ Method signatures can be brought over for stubbing or ActiveMocker friendly code can be brought over in it's entirety.
16
+ Mocks are regenerated when the schema is modified so your mocks won't go stale,
17
+ preventing the case where your units tests pass but production code fails.
10
18
 
11
19
  Examples from a real apps
12
20
 
@@ -221,7 +229,7 @@ ActiveMocker::LoadedMocks.features.enable(:stub_active_record_exceptions)
221
229
  Be careful that it does not contain anything that ActiveMocker cannot run.
222
230
 
223
231
  ```ruby
224
- # ActiveMocker.safe_methods(scopes: [], instance_methods: [:full_name])
232
+ # ActiveMocker.safe_methods(scopes: [], instance_methods: [:full_name], class_methods: [])
225
233
  class User
226
234
  def full_name
227
235
  "#{first_name} + #{last_name}"
@@ -12,6 +12,7 @@ require "active_mocker/loaded_mocks"
12
12
  require "active_mocker/mock/hash_process"
13
13
  require "active_mocker/mock/collection"
14
14
  require "active_mocker/mock/queries"
15
+ require "active_mocker/mock/mockable_method"
15
16
  require "active_mocker/mock/relation"
16
17
  require "active_mocker/mock/mock_relation"
17
18
  require "active_mocker/mock/association"
@@ -5,6 +5,8 @@ module ActiveMocker
5
5
  include TemplateMethods
6
6
  extend Queries
7
7
  extend AliasAttribute
8
+ extend MockableMethod
9
+ include MockableMethod
8
10
 
9
11
  def self.inherited(subclass)
10
12
  ActiveMocker::LoadedMocks.send(:add, subclass)
@@ -155,16 +157,6 @@ module ActiveMocker
155
157
  end
156
158
  raise UpdateMocksError.new(name, version, ActiveMocker::Mock::VERSION) if version != ActiveMocker::Mock::VERSION
157
159
  end
158
-
159
- # @deprecated
160
- def call_mock_method(method:, caller:, arguments: [])
161
- is_implemented(method, "::", caller)
162
- end
163
-
164
- # @deprecated
165
- def is_implemented(method, type, call_stack)
166
- raise NotImplementedError, "#{type}#{method} for Class: #{name}. To continue stub the method.", call_stack
167
- end
168
160
  end
169
161
 
170
162
  # @deprecated
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveMocker
4
+ module MockableMethod
5
+ private
6
+
7
+ def __am_raise_not_mocked_error(method:, caller:, type:)
8
+ variable_name = if is_a?(Relation)
9
+ "#{self.class.name.underscore.split("/").first}_relation"
10
+ elsif type == "#"
11
+ "#{self.class.name.underscore}_record"
12
+ else
13
+ name
14
+ end
15
+
16
+ message = <<-ERROR.strip_heredoc
17
+ Unknown implementation for mock method: #{variable_name}.#{method}
18
+ Stub method to continue.
19
+
20
+ RSpec:
21
+ allow(
22
+ #{variable_name}
23
+ ).to receive(:#{method}).and_return(:some_expected_result)
24
+ ERROR
25
+
26
+ raise NotImplementedError, message, caller
27
+ end
28
+ end
29
+ end
@@ -2,6 +2,7 @@
2
2
  module ActiveMocker
3
3
  class Relation < Collection
4
4
  include Queries
5
+ include MockableMethod
5
6
 
6
7
  def initialize(collection = [])
7
8
  super
@@ -18,14 +19,14 @@ module ActiveMocker
18
19
  @from_limit
19
20
  end
20
21
 
22
+ def name
23
+ self.class.name
24
+ end
25
+
21
26
  private
22
27
 
23
28
  def set_from_limit
24
29
  @from_limit = true
25
30
  end
26
-
27
- def name
28
- self.class.name
29
- end
30
31
  end
31
32
  end
@@ -9,9 +9,9 @@ module ActiveMocker
9
9
  :modules_constants,
10
10
  :class_methods,
11
11
  :attributes,
12
- :scopes,
13
12
  :recreate_class_method_calls,
14
13
  :defined_methods,
14
+ :scopes,
15
15
  :associations,
16
16
  ].freeze
17
17
 
@@ -25,20 +25,21 @@ module ActiveMocker
25
25
  def create_method(m, type)
26
26
  plural_type = (type.to_s + "s").to_sym
27
27
  if safe_methods[plural_type].include?(m)
28
- raise "ActiveMocker.safe_methods(class_methods: []) is currently unsupported." if type == :method
29
- def_method = class_introspector.parsed_source.defs.detect { |meth| meth.name == m }
28
+ def_type = type == :method ? :class_defs : :defs
29
+ def_method = class_introspector.parsed_source.public_send(def_type).detect { |meth| meth.name == m }
30
30
  Method.new(
31
31
  m,
32
32
  def_method.arguments,
33
33
  def_method.body
34
34
  )
35
35
  else
36
+ type_symbol = type == :method ? "::" : "#"
36
37
  Method.new(
37
38
  m,
38
39
  ReverseParameters.new(
39
40
  class_introspector.get_class.send(type, m).parameters
40
41
  ).parameters,
41
- "call_mock_method(method: __method__, caller: Kernel.caller, arguments: [])"
42
+ "__am_raise_not_mocked_error(method: __method__, caller: Kernel.caller, type: '#{type_symbol}')"
42
43
  )
43
44
  end
44
45
  end
@@ -19,10 +19,13 @@ module ActiveMocker
19
19
  if safe_methods[:scopes].include?(name)
20
20
  find_scope_body_from_ast(name)
21
21
  else
22
- "#{class_name}.send(:call_mock_method, " \
23
- "method: '#{name}', " \
24
- "caller: Kernel.caller, " \
25
- "arguments: [#{arguments.arguments}])"
22
+ <<-METHOD
23
+ __am_raise_not_mocked_error(
24
+ method: "#{name}",
25
+ caller: Kernel.caller,
26
+ type: "::"
27
+ )
28
+ METHOD
26
29
  end
27
30
  end
28
31
 
@@ -7,7 +7,7 @@ class <%= class_name + mock_append_name %> < <%= parent_class_inspector.parent_m
7
7
  <%= partials.class_methods %>
8
8
  <%= partials.attributes %>
9
9
  <%= partials.associations %>
10
- <%= partials.scopes %>
11
10
  <%= partials.recreate_class_method_calls %>
12
11
  <%= partials.defined_methods %>
12
+ <%= partials.scopes %>
13
13
  end
@@ -3,8 +3,12 @@
3
3
  <%= method.body %>
4
4
  end
5
5
  <% end -%>
6
+ module ClassMethods
6
7
  <% class_methods.each do |method| -%>
7
- def self.<%= method.name %><%= "(#{method.arguments})" unless method.arguments.blank? %>
8
+ def <%= method.name %><%= "(#{method.arguments})" unless method.arguments.blank? %>
8
9
  <%= method.body %>
9
10
  end
10
11
  <% end -%>
12
+ end
13
+
14
+ extend ClassMethods
@@ -14,6 +14,7 @@ end
14
14
 
15
15
  class ScopeRelation < ActiveMocker::Association
16
16
  include <%= class_name + mock_append_name %>::Scopes
17
+ include ClassMethods
17
18
  end
18
19
 
19
20
  def self.__new_relation__(collection)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module ActiveMocker
3
- VERSION = "2.5.1"
3
+ VERSION = "2.5.2"
4
4
  module Mock
5
5
  VERSION = "2" # This increments when breaking changes happen in the generated mocks
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_mocker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dustin Zeisler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-21 00:00:00.000000000 Z
11
+ date: 2017-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -212,8 +212,6 @@ files:
212
212
  - lib/active_mocker/attribute_types/enum.rb
213
213
  - lib/active_mocker/attribute_types/register.rb
214
214
  - lib/active_mocker/config.rb
215
- - lib/active_mocker/deprecated_components/mock_abilities.rb
216
- - lib/active_mocker/deprecated_components/rspec.rb
217
215
  - lib/active_mocker/display_errors.rb
218
216
  - lib/active_mocker/error_object.rb
219
217
  - lib/active_mocker/file_path_to_ruby_class.rb
@@ -244,6 +242,7 @@ files:
244
242
  - lib/active_mocker/mock/has_one.rb
245
243
  - lib/active_mocker/mock/hash_process.rb
246
244
  - lib/active_mocker/mock/mock_relation.rb
245
+ - lib/active_mocker/mock/mockable_method.rb
247
246
  - lib/active_mocker/mock/object_inspect.rb
248
247
  - lib/active_mocker/mock/queries.rb
249
248
  - lib/active_mocker/mock/records.rb
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
- module ActiveMocker
3
- # @deprecated to keep using until removal, require this file.
4
- module MockAbilities
5
- module InstanceAndClassMethods
6
- def mock_instance_method(method, exe_bind = false, &block)
7
- mockable_instance_methods[method.to_sym] = MockMethod.new(block, exe_bind)
8
- end
9
-
10
- alias stub_instance_method mock_instance_method
11
-
12
- def clear_mocked_methods
13
- mockable_instance_methods.clear
14
- mockable_class_methods.clear
15
- end
16
-
17
- # @deprecated
18
- def clear_mock
19
- clear_mocked_methods
20
- delete_all
21
- end
22
-
23
- private
24
-
25
- def mockable_instance_methods
26
- @mockable_instance_methods ||= {}
27
- end
28
-
29
- def class_name
30
- return name if self.class == Class
31
- self.class
32
- end
33
-
34
- def is_implemented(val, method, type, call_stack)
35
- raise NotImplementedError, "#{type}#{method} for Class: #{class_name}. To continue stub the method.", call_stack if val.nil?
36
- end
37
-
38
- def execute_block(method)
39
- return instance_exec(method.arguments, &method.block) if method.exe_bind
40
- method.block.call(*method.arguments)
41
- end
42
- end
43
-
44
- def self.included(base)
45
- base.extend(ClassMethods)
46
- end
47
-
48
- def self.prepended(base)
49
- class << base
50
- prepend(ClassMethods)
51
- end
52
- end
53
-
54
- module ClassMethods
55
- include InstanceAndClassMethods
56
-
57
- def mockable_class_methods
58
- @mockable_class_methods ||= {}
59
- end
60
-
61
- def mock_class_method(method, exe_bind = false, &block)
62
- mockable_class_methods[method.to_sym] = MockMethod.new(block, exe_bind)
63
- end
64
-
65
- alias stub_class_method mock_class_method
66
-
67
- def call_mock_method(method:, caller:, arguments: [])
68
- mock_method = mockable_class_methods[method.to_sym]
69
- is_implemented(mock_method, method, "::", caller)
70
- mock_method.arguments = arguments
71
- execute_block(mock_method)
72
- end
73
-
74
- private :call_mock_method
75
- end
76
-
77
- include InstanceAndClassMethods
78
-
79
- def call_mock_method(method:, caller:, arguments: [])
80
- mock_method = mockable_instance_methods[method.to_sym]
81
- mock_method = self.class.send(:mockable_instance_methods)[method.to_sym] if mock_method.nil?
82
- is_implemented(mock_method, method, '#', caller)
83
- mock_method.arguments = arguments
84
- execute_block mock_method
85
- end
86
-
87
- private :call_mock_method
88
-
89
- def clear_mocked_methods
90
- mockable_instance_methods.clear
91
- end
92
-
93
- class MockMethod
94
- attr_accessor :block, :arguments, :exe_bind
95
-
96
- def initialize(block, exe_bind)
97
- @block = block
98
- @exe_bind = exe_bind
99
- end
100
- end
101
- end
102
-
103
- class Base
104
- prepend MockAbilities
105
- end
106
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- require "active_mocker/rspec"
3
-
4
- module ActiveMocker
5
- module Rspec
6
- # @deprecated method, will be removed in version 2.1
7
- # Use +active_mocker.mocks.find('ClassName')+ instead
8
- # To keep using until removal, require this file.
9
- def mock_class(*args)
10
- active_mocker.mocks.find(*args)
11
- end
12
- end
13
- end