rspec-mocks 3.0.4 → 3.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +26 -0
  5. data/README.md +29 -15
  6. data/lib/rspec/mocks/any_instance/chain.rb +2 -2
  7. data/lib/rspec/mocks/any_instance/expectation_chain.rb +2 -3
  8. data/lib/rspec/mocks/any_instance/message_chains.rb +8 -7
  9. data/lib/rspec/mocks/any_instance/proxy.rb +2 -2
  10. data/lib/rspec/mocks/any_instance/recorder.rb +27 -25
  11. data/lib/rspec/mocks/any_instance/stub_chain.rb +3 -5
  12. data/lib/rspec/mocks/argument_list_matcher.rb +4 -4
  13. data/lib/rspec/mocks/argument_matchers.rb +23 -5
  14. data/lib/rspec/mocks/configuration.rb +3 -10
  15. data/lib/rspec/mocks/error_generator.rb +33 -27
  16. data/lib/rspec/mocks/example_methods.rb +74 -6
  17. data/lib/rspec/mocks/instance_method_stasher.rb +5 -5
  18. data/lib/rspec/mocks/matchers/have_received.rb +7 -8
  19. data/lib/rspec/mocks/matchers/receive.rb +8 -8
  20. data/lib/rspec/mocks/matchers/receive_message_chain.rb +4 -5
  21. data/lib/rspec/mocks/matchers/receive_messages.rb +6 -7
  22. data/lib/rspec/mocks/message_chain.rb +5 -5
  23. data/lib/rspec/mocks/message_expectation.rb +56 -28
  24. data/lib/rspec/mocks/method_double.rb +15 -12
  25. data/lib/rspec/mocks/method_reference.rb +8 -7
  26. data/lib/rspec/mocks/mutate_const.rb +26 -100
  27. data/lib/rspec/mocks/object_reference.rb +12 -13
  28. data/lib/rspec/mocks/order_group.rb +4 -5
  29. data/lib/rspec/mocks/proxy.rb +31 -25
  30. data/lib/rspec/mocks/space.rb +24 -24
  31. data/lib/rspec/mocks/syntax.rb +8 -8
  32. data/lib/rspec/mocks/targets.rb +6 -6
  33. data/lib/rspec/mocks/test_double.rb +3 -3
  34. data/lib/rspec/mocks/verifying_double.rb +10 -12
  35. data/lib/rspec/mocks/verifying_message_expecation.rb +15 -13
  36. data/lib/rspec/mocks/verifying_proxy.rb +11 -15
  37. data/lib/rspec/mocks/version.rb +1 -1
  38. metadata +5 -5
  39. metadata.gz.sig +0 -0
@@ -59,7 +59,7 @@ module RSpec
59
59
  define_method(method_name) do |*args, &block|
60
60
  method_double.proxy_method_invoked(self, *args, &block)
61
61
  end
62
- self.__send__ visibility, method_name
62
+ __send__(visibility, method_name)
63
63
  end
64
64
 
65
65
  @method_is_proxied = true
@@ -69,7 +69,7 @@ module RSpec
69
69
  # method to perform additional operations.
70
70
  #
71
71
  # @private
72
- def proxy_method_invoked(obj, *args, &block)
72
+ def proxy_method_invoked(_obj, *args, &block)
73
73
  @proxy.message_received method_name, *args, &block
74
74
  end
75
75
 
@@ -80,9 +80,7 @@ module RSpec
80
80
 
81
81
  definition_target.__send__(:remove_method, @method_name)
82
82
 
83
- if @method_stasher.method_is_stashed?
84
- @method_stasher.restore
85
- end
83
+ @method_stasher.restore if @method_stasher.method_is_stashed?
86
84
  restore_original_visibility
87
85
 
88
86
  @method_is_proxied = false
@@ -91,7 +89,9 @@ module RSpec
91
89
  # @private
92
90
  def show_frozen_warning
93
91
  RSpec.warn_with(
94
- "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` method on #{@object.inspect} because it has been frozen. If you reuse this object, `#{@method_name}` will continue to respond with its stub implementation.",
92
+ "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` " \
93
+ "method on #{@object.inspect} because it has been frozen. If you reuse this " \
94
+ "object, `#{@method_name}` will continue to respond with its stub implementation.",
95
95
  :call_site => nil,
96
96
  :use_spec_location_as_call_site => true
97
97
  )
@@ -107,7 +107,7 @@ module RSpec
107
107
 
108
108
  # @private
109
109
  def verify
110
- expectations.each {|e| e.verify_messages_received}
110
+ expectations.each { |e| e.verify_messages_received }
111
111
  end
112
112
 
113
113
  # @private
@@ -134,7 +134,7 @@ module RSpec
134
134
  def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation)
135
135
  configure_method
136
136
  expectation = message_expectation_class.new(error_generator, expectation_ordering,
137
- expected_from, self, :expectation, opts, &implementation)
137
+ expected_from, self, :expectation, opts, &implementation)
138
138
  expectations << expectation
139
139
  expectation
140
140
  end
@@ -149,7 +149,7 @@ module RSpec
149
149
  def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
150
150
  configure_method
151
151
  stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from,
152
- self, :stub, opts, &implementation)
152
+ self, :stub, opts, &implementation)
153
153
  stubs.unshift stub
154
154
  stub
155
155
  end
@@ -172,7 +172,7 @@ module RSpec
172
172
  end
173
173
 
174
174
  # @private
175
- def setup_simple_method_double(method_name, response, collection, error_generator = nil, backtrace_line = nil)
175
+ def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil)
176
176
  define_proxy_method
177
177
 
178
178
  me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line)
@@ -202,8 +202,6 @@ module RSpec
202
202
  raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed"
203
203
  end
204
204
 
205
- private
206
-
207
205
  # In Ruby 2.0.0 and above prepend will alter the method lookup chain.
208
206
  # We use an object's singleton class to define method doubles upon,
209
207
  # however if the object has had it's singleton class (as opposed to
@@ -216,6 +214,9 @@ module RSpec
216
214
  # of our own.
217
215
  #
218
216
  if Support::RubyFeatures.module_prepends_supported?
217
+
218
+ private
219
+
219
220
  # We subclass `Module` in order to be able to easily detect our prepended module.
220
221
  RSpecPrependedModule = Class.new(Module)
221
222
 
@@ -247,6 +248,8 @@ module RSpec
247
248
 
248
249
  else
249
250
 
251
+ private
252
+
250
253
  def definition_target
251
254
  object_singleton_class
252
255
  end
@@ -27,7 +27,7 @@ module RSpec
27
27
  # cases when we don't know if a method is implemented and
28
28
  # both `implemented?` and `unimplemented?` will return false.
29
29
  def unimplemented?
30
- @object_reference.when_loaded do |m|
30
+ @object_reference.when_loaded do |_m|
31
31
  return !implemented?
32
32
  end
33
33
 
@@ -44,9 +44,8 @@ module RSpec
44
44
  end
45
45
 
46
46
  def with_signature
47
- if original = original_method
48
- yield Support::MethodSignature.new(original)
49
- end
47
+ return unless (original = original_method)
48
+ yield Support::MethodSignature.new(original)
50
49
  end
51
50
 
52
51
  def visibility
@@ -59,7 +58,7 @@ module RSpec
59
58
  :public
60
59
  end
61
60
 
62
- private
61
+ private
63
62
 
64
63
  def original_method
65
64
  @object_reference.when_loaded do |m|
@@ -98,7 +97,8 @@ module RSpec
98
97
 
99
98
  # @private
100
99
  class InstanceMethodReference < MethodReference
101
- private
100
+ private
101
+
102
102
  def method_implemented?(mod)
103
103
  MethodReference.method_defined_at_any_visibility?(mod, @method_name)
104
104
  end
@@ -133,7 +133,8 @@ module RSpec
133
133
 
134
134
  # @private
135
135
  class ObjectMethodReference < MethodReference
136
- private
136
+ private
137
+
137
138
  def method_implemented?(object)
138
139
  object.respond_to?(@method_name, true)
139
140
  end
@@ -1,85 +1,11 @@
1
+ RSpec::Support.require_rspec_support 'recursive_const_methods'
2
+
1
3
  module RSpec
2
4
  module Mocks
3
- # Provides recursive constant lookup methods useful for
4
- # constant stubbing.
5
- #
6
- # @private
7
- module RecursiveConstMethods
8
- # We only want to consider constants that are defined directly on a
9
- # particular module, and not include top-level/inherited constants.
10
- # Unfortunately, the constant API changed between 1.8 and 1.9, so
11
- # we need to conditionally define methods to ignore the top-level/inherited
12
- # constants.
13
- #
14
- # Given:
15
- # class A; B = 1; end
16
- # class C < A; end
17
- #
18
- # On 1.8:
19
- # - C.const_get("Hash") # => ::Hash
20
- # - C.const_defined?("Hash") # => false
21
- # - C.constants # => ["B"]
22
- # - None of these methods accept the extra `inherit` argument
23
- # On 1.9:
24
- # - C.const_get("Hash") # => ::Hash
25
- # - C.const_defined?("Hash") # => true
26
- # - C.const_get("Hash", false) # => raises NameError
27
- # - C.const_defined?("Hash", false) # => false
28
- # - C.constants # => [:B]
29
- # - C.constants(false) #=> []
30
- if Module.method(:const_defined?).arity == 1
31
- def const_defined_on?(mod, const_name)
32
- mod.const_defined?(const_name)
33
- end
34
-
35
- def get_const_defined_on(mod, const_name)
36
- if const_defined_on?(mod, const_name)
37
- return mod.const_get(const_name)
38
- end
39
-
40
- raise NameError, "uninitialized constant #{mod.name}::#{const_name}"
41
- end
42
-
43
- def constants_defined_on(mod)
44
- mod.constants.select { |c| const_defined_on?(mod, c) }
45
- end
46
- else
47
- def const_defined_on?(mod, const_name)
48
- mod.const_defined?(const_name, false)
49
- end
50
-
51
- def get_const_defined_on(mod, const_name)
52
- mod.const_get(const_name, false)
53
- end
54
-
55
- def constants_defined_on(mod)
56
- mod.constants(false)
57
- end
58
- end
59
-
60
- def recursive_const_get(const_name)
61
- normalize_const_name(const_name).split('::').inject(Object) do |mod, name|
62
- get_const_defined_on(mod, name)
63
- end
64
- end
65
-
66
- def recursive_const_defined?(const_name)
67
- normalize_const_name(const_name).split('::').inject([Object, '']) do |(mod, full_name), name|
68
- yield(full_name, name) if block_given? && !(Module === mod)
69
- return false unless const_defined_on?(mod, name)
70
- [get_const_defined_on(mod, name), [mod, name].join('::')]
71
- end
72
- end
73
-
74
- def normalize_const_name(const_name)
75
- const_name.sub(/\A::/, '')
76
- end
77
- end
78
-
79
5
  # Provides information about constants that may (or may not)
80
6
  # have been mutated by rspec-mocks.
81
7
  class Constant
82
- extend RecursiveConstMethods
8
+ extend Support::RecursiveConstMethods
83
9
 
84
10
  # @api private
85
11
  def initialize(name)
@@ -154,7 +80,7 @@ module RSpec
154
80
 
155
81
  # Provides a means to stub constants.
156
82
  class ConstantMutator
157
- extend RecursiveConstMethods
83
+ extend Support::RecursiveConstMethods
158
84
 
159
85
  # Stubs a constant.
160
86
  #
@@ -167,12 +93,12 @@ module RSpec
167
93
  # examples. This is an alternate public API that is provided
168
94
  # so you can stub constants in other contexts (e.g. helper
169
95
  # classes).
170
- def self.stub(constant_name, value, options = {})
96
+ def self.stub(constant_name, value, options={})
171
97
  mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const)
172
- DefinedConstantReplacer
173
- else
174
- UndefinedConstantSetter
175
- end
98
+ DefinedConstantReplacer
99
+ else
100
+ UndefinedConstantSetter
101
+ end
176
102
 
177
103
  mutate(mutator.new(constant_name, value, options[:transfer_nested_constants]))
178
104
  value
@@ -188,7 +114,7 @@ module RSpec
188
114
  # so you can hide constants in other contexts (e.g. helper
189
115
  # classes).
190
116
  def self.hide(constant_name)
191
- mutate(ConstantHider.new(constant_name, nil, { }))
117
+ mutate(ConstantHider.new(constant_name, nil, {}))
192
118
  nil
193
119
  end
194
120
 
@@ -196,7 +122,7 @@ module RSpec
196
122
  #
197
123
  # @private
198
124
  class BaseMutator
199
- include RecursiveConstMethods
125
+ include Support::RecursiveConstMethods
200
126
 
201
127
  attr_reader :original_value, :full_constant_name
202
128
 
@@ -227,7 +153,7 @@ module RSpec
227
153
  # @private
228
154
  class ConstantHider < BaseMutator
229
155
  def mutate
230
- return unless @defined = recursive_const_defined?(full_constant_name)
156
+ return unless (@defined = recursive_const_defined?(full_constant_name))
231
157
  @context = recursive_const_get(@context_parts.join('::'))
232
158
  @original_value = get_const_defined_on(@context, @const_name)
233
159
 
@@ -298,12 +224,12 @@ module RSpec
298
224
  return [] unless should_transfer_nested_constants?
299
225
 
300
226
  { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description|
301
- unless value.respond_to?(:constants)
302
- raise ArgumentError,
303
- "Cannot transfer nested constants for #{@full_constant_name} " +
304
- "since #{description} is not a class or module and only classes " +
305
- "and modules support nested constants."
306
- end
227
+ next if value.respond_to?(:constants)
228
+
229
+ raise ArgumentError,
230
+ "Cannot transfer nested constants for #{@full_constant_name} " \
231
+ "since #{description} is not a class or module and only classes " \
232
+ "and modules support nested constants."
307
233
  end
308
234
 
309
235
  if Array === @transfer_nested_constants
@@ -313,9 +239,9 @@ module RSpec
313
239
  if undefined_constants.any?
314
240
  available_constants = constants_defined_on(@original_value) - @transfer_nested_constants
315
241
  raise ArgumentError,
316
- "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " +
317
- "for #{@full_constant_name} since they are not defined. Did you mean " +
318
- "#{available_constants.join(' or ')}?"
242
+ "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " \
243
+ "for #{@full_constant_name} since they are not defined. Did you mean " \
244
+ "#{available_constants.join(' or ')}?"
319
245
  end
320
246
 
321
247
  @transfer_nested_constants
@@ -363,10 +289,10 @@ module RSpec
363
289
 
364
290
  def name_for(parent, name)
365
291
  root = if parent == Object
366
- ''
367
- else
368
- parent.name
369
- end
292
+ ''
293
+ else
294
+ parent.name
295
+ end
370
296
  root + '::' + name
371
297
  end
372
298
  end
@@ -389,7 +315,7 @@ module RSpec
389
315
  # @api private
390
316
  def self.raise_on_invalid_const
391
317
  lambda do |const_name, failed_name|
392
- raise "Cannot stub constant #{failed_name} on #{const_name} " +
318
+ raise "Cannot stub constant #{failed_name} on #{const_name} " \
393
319
  "since #{const_name} is not a module."
394
320
  end
395
321
  end
@@ -1,21 +1,20 @@
1
1
  module RSpec
2
2
  module Mocks
3
-
4
3
  # @private
5
4
  class ObjectReference
6
5
  # Returns an appropriate Object or Module reference based
7
6
  # on the given argument.
8
- def self.for(object_module_or_name, allow_direct_object_refs = false)
7
+ def self.for(object_module_or_name, allow_direct_object_refs=false)
9
8
  case object_module_or_name
10
- when Module then DirectModuleReference.new(object_module_or_name)
11
- when String then NamedObjectReference.new(object_module_or_name)
9
+ when Module then DirectModuleReference.new(object_module_or_name)
10
+ when String then NamedObjectReference.new(object_module_or_name)
11
+ else
12
+ if allow_direct_object_refs
13
+ DirectObjectReference.new(object_module_or_name)
12
14
  else
13
- if allow_direct_object_refs
14
- DirectObjectReference.new(object_module_or_name)
15
- else
16
- raise ArgumentError,
17
- "Module or String expected, got #{object_module_or_name.inspect}"
18
- end
15
+ raise ArgumentError,
16
+ "Module or String expected, got #{object_module_or_name.inspect}"
17
+ end
19
18
  end
20
19
  end
21
20
  end
@@ -35,7 +34,7 @@ module RSpec
35
34
 
36
35
  def const_to_replace
37
36
  raise ArgumentError,
38
- "Can not perform constant replacement with an object."
37
+ "Can not perform constant replacement with an object."
39
38
  end
40
39
 
41
40
  def defined?
@@ -78,11 +77,11 @@ module RSpec
78
77
  end
79
78
  alias description const_to_replace
80
79
 
81
- def when_loaded(&block)
80
+ def when_loaded(&_block)
82
81
  yield object if object
83
82
  end
84
83
 
85
- private
84
+ private
86
85
 
87
86
  def object
88
87
  @object ||= Constant.original(@const_name).original_value
@@ -25,10 +25,10 @@ module RSpec
25
25
  # @private
26
26
  def consume
27
27
  remaining_expectations.each_with_index do |expectation, index|
28
- if expectation.ordered?
29
- @index += index + 1
30
- return expectation
31
- end
28
+ next unless expectation.ordered?
29
+
30
+ @index += index + 1
31
+ return expectation
32
32
  end
33
33
  nil
34
34
  end
@@ -76,7 +76,6 @@ module RSpec
76
76
  def expectation_for(message)
77
77
  @expectations.find { |e| message == e }
78
78
  end
79
-
80
79
  end
81
80
  end
82
81
  end
@@ -9,7 +9,7 @@ module RSpec
9
9
  end
10
10
 
11
11
  # @private
12
- def ensure_implemented(*args)
12
+ def ensure_implemented(*_args)
13
13
  # noop for basic proxies, see VerifyingProxy for behaviour.
14
14
  end
15
15
 
@@ -42,7 +42,7 @@ module RSpec
42
42
  end
43
43
 
44
44
  # @private
45
- def original_method_handle_for(message)
45
+ def original_method_handle_for(_message)
46
46
  nil
47
47
  end
48
48
 
@@ -89,20 +89,19 @@ module RSpec
89
89
  end
90
90
 
91
91
  @messages_received.each do |(actual_method_name, args, _)|
92
- if expectation.matches?(actual_method_name, *args)
93
- expectation.invoke(nil)
94
- block.call(*args) if block
95
- end
96
- end
92
+ next unless expectation.matches?(actual_method_name, *args)
97
93
 
94
+ expectation.invoke(nil)
95
+ block.call(*args) if block
96
+ end
98
97
  end
99
98
 
100
99
  # @private
101
100
  def check_for_unexpected_arguments(expectation)
102
101
  @messages_received.each do |(method_name, args, _)|
103
- if expectation.matches_name_but_not_args(method_name, *args)
104
- raise_unexpected_message_args_error(expectation, *args)
105
- end
102
+ next unless expectation.matches_name_but_not_args(method_name, *args)
103
+
104
+ raise_unexpected_message_args_error(expectation, *args)
106
105
  end
107
106
  end
108
107
 
@@ -129,7 +128,7 @@ module RSpec
129
128
 
130
129
  # @private
131
130
  def verify
132
- @method_doubles.each_value {|d| d.verify}
131
+ @method_doubles.each_value { |d| d.verify }
133
132
  end
134
133
 
135
134
  # @private
@@ -139,12 +138,12 @@ module RSpec
139
138
 
140
139
  # @private
141
140
  def received_message?(method_name, *args, &block)
142
- @messages_received.any? {|array| array == [method_name, args, block]}
141
+ @messages_received.any? { |array| array == [method_name, args, block] }
143
142
  end
144
143
 
145
144
  # @private
146
145
  def has_negative_expectation?(message)
147
- method_double_for(message).expectations.detect {|expectation| expectation.negative_expectation_for?(message)}
146
+ method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) }
148
147
  end
149
148
 
150
149
  # @private
@@ -162,16 +161,19 @@ module RSpec
162
161
 
163
162
  if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
164
163
  expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters?
165
- if expectation = find_almost_matching_expectation(message, *args)
164
+ if (expectation = find_almost_matching_expectation(message, *args))
166
165
  expectation.advise(*args) unless expectation.expected_messages_received?
167
166
  end
168
167
  stub.invoke(nil, *args, &block)
169
168
  elsif expectation
170
169
  expectation.invoke(stub, *args, &block)
171
- elsif expectation = find_almost_matching_expectation(message, *args)
170
+ elsif (expectation = find_almost_matching_expectation(message, *args))
172
171
  expectation.advise(*args) if null_object? unless expectation.expected_messages_received?
173
- raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(message) or null_object?)
174
- elsif stub = find_almost_matching_stub(message, *args)
172
+
173
+ if null_object? || !has_negative_expectation?(message)
174
+ raise_unexpected_message_args_error(expectation, *args)
175
+ end
176
+ elsif (stub = find_almost_matching_stub(message, *args))
175
177
  stub.advise(*args)
176
178
  raise_missing_default_stub_error(stub, *args)
177
179
  elsif Class === @object
@@ -197,7 +199,7 @@ module RSpec
197
199
  end
198
200
 
199
201
  # @private
200
- def visibility_for(method_name)
202
+ def visibility_for(_method_name)
201
203
  # This is the default (for test doubles). Subclasses override this.
202
204
  :public
203
205
  end
@@ -206,9 +208,13 @@ module RSpec
206
208
  def prepended_modules_of_singleton_class
207
209
  @prepended_modules_of_singleton_class ||= begin
208
210
  singleton_class = @object.singleton_class
209
- singleton_class.ancestors.take_while do |mod|
210
- !(Class === mod || @object.equal?(mod))
211
- end
211
+ ancestors = singleton_class.ancestors
212
+
213
+ # `|| 0` is necessary for Ruby 2.0, where the singleton class
214
+ # is only in the ancestor list when there are prepended modules.
215
+ singleton_index = ancestors.index(singleton_class) || 0
216
+
217
+ ancestors[0, singleton_index]
212
218
  end
213
219
  end
214
220
  end
@@ -244,11 +250,11 @@ module RSpec
244
250
  end
245
251
 
246
252
  def find_matching_method_stub(method_name, *args)
247
- method_double_for(method_name).stubs.find {|stub| stub.matches?(method_name, *args)}
253
+ method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) }
248
254
  end
249
255
 
250
256
  def find_almost_matching_stub(method_name, *args)
251
- method_double_for(method_name).stubs.find {|stub| stub.matches_name_but_not_args(method_name, *args)}
257
+ method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) }
252
258
  end
253
259
  end
254
260
 
@@ -295,7 +301,7 @@ module RSpec
295
301
  end
296
302
 
297
303
  def reset
298
- @method_doubles.each_value {|d| d.reset}
304
+ @method_doubles.each_value { |d| d.reset }
299
305
  super
300
306
  end
301
307
 
@@ -415,7 +421,7 @@ module RSpec
415
421
 
416
422
  private
417
423
 
418
- def warn method_name
424
+ def warn(method_name)
419
425
  source = CallerFilter.first_non_rspec_line
420
426
  Kernel.warn("An expectation of :#{method_name} was set on nil. Called from #{source}. Use allow_message_expectations_on_nil to disable warnings.")
421
427
  end