acfs 0.45.0 → 0.50.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 (34) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +34 -0
  3. data/README.md +0 -1
  4. data/acfs.gemspec +3 -3
  5. data/lib/acfs/middleware/json.rb +1 -1
  6. data/lib/acfs/middleware/msgpack.rb +1 -1
  7. data/lib/acfs/resource/attributes/base.rb +10 -18
  8. data/lib/acfs/resource/attributes/boolean.rb +10 -6
  9. data/lib/acfs/resource/attributes/date_time.rb +7 -8
  10. data/lib/acfs/resource/attributes/dict.rb +15 -5
  11. data/lib/acfs/resource/attributes/float.rb +11 -3
  12. data/lib/acfs/resource/attributes/integer.rb +7 -7
  13. data/lib/acfs/resource/attributes/list.rb +13 -4
  14. data/lib/acfs/resource/attributes/string.rb +3 -3
  15. data/lib/acfs/resource/attributes/uuid.rb +8 -15
  16. data/lib/acfs/resource/attributes.rb +11 -37
  17. data/lib/acfs/resource/dirty.rb +3 -15
  18. data/lib/acfs/resource/query_methods.rb +5 -2
  19. data/lib/acfs/resource/validation.rb +4 -2
  20. data/lib/acfs/response/formats.rb +1 -1
  21. data/lib/acfs/service/middleware/stack.rb +38 -9
  22. data/lib/acfs/version.rb +1 -1
  23. data/spec/acfs/resource/attributes/boolean_spec.rb +40 -9
  24. data/spec/acfs/resource/attributes/date_time_spec.rb +29 -35
  25. data/spec/acfs/resource/attributes/dict_spec.rb +54 -29
  26. data/spec/acfs/resource/attributes/float_spec.rb +48 -9
  27. data/spec/acfs/resource/attributes/integer_spec.rb +23 -8
  28. data/spec/acfs/resource/attributes/list_spec.rb +43 -19
  29. data/spec/acfs/resource/attributes/uuid_spec.rb +31 -54
  30. data/spec/acfs/resource/attributes_spec.rb +10 -24
  31. data/spec/acfs/resource/query_methods_spec.rb +10 -3
  32. data/spec/acfs/response/formats_spec.rb +3 -3
  33. data/spec/spec_helper.rb +1 -1
  34. metadata +9 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 94d04da7b680edf457505737b4bcc1d18d6e3fb3
4
- data.tar.gz: 629b89356e8be9625b20722ca89bfe88ff3d5bc9
2
+ SHA256:
3
+ metadata.gz: 5f6205aca10d63d37898eecce39e239605fc0a4165d17a9ad994ead94e0037dd
4
+ data.tar.gz: e1dac804253b61cabd8d5e9410784268c689771fedb9bdcad8c99a67e0b946ef
5
5
  SHA512:
6
- metadata.gz: 7afc2b923b468780cd3dabd0d6ff592e829b2b158d3b96469513ca324e2644a6e4d30f48408efb0ef48bc53e35595b963b8700131d8a8a81933eb4bef8f324b1
7
- data.tar.gz: 45349a36fa4c76f564f95897102e74e4a934b9ddee69cb785868a9b75a2fd652b4ada7687d4c974a856a65b1dfb18caf372eaa963211851edf75edbc8a1a40d1
6
+ metadata.gz: 150fd36e55507f600437fe65dc3d853379799b6f5afc30c0aaa9644e36d4e025fa3ced557569f6af9e8cbbb8e484ede41281cefac7ceaecda3d6957647e5b76b
7
+ data.tar.gz: 206228583c974b3ef735d1cfb524938595856bd8741e481c80b331da1779839c4ab31073f34d615561d68f53955ea5f58c501c2d5208039522e5296233d002aa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0
4
+
5
+ * Add Rails 5.2 compatibility
6
+
7
+ ## 1.1.1
8
+
9
+ * `each_item`: Pass collection to provided block (#40)
10
+
11
+ ## 1.1.0
12
+
13
+ * Add support for Rails 5.1
14
+
15
+ ## 1.0.1
16
+
17
+ * Fix deprecation warnings when using ::Mime
18
+
19
+ ## 1.0.0
20
+
21
+ * Switch to first non-development major as it's long time used in production.
22
+ * Fix NewRelic RPM inference with middleware stack inherited from `ActionDispatch::MiddlewareStack`.
23
+
24
+ ## 0.48.0
25
+
26
+ * Remove #attribute_types broke since f7e4109 (Sep 2013, v0.23)
27
+ * Fix attribute inheritance on subclassing broken since commit 7cf1d11 (Apr 2014, v0.43)
28
+
29
+ ## 0.47.0
30
+
31
+ * Change blank value handling of dict and list type (0a12ef1)
32
+
33
+ ## 0.46.0
34
+
35
+ * Rework types system (#39)
36
+
3
37
  ## 0.45.0
4
38
 
5
39
  * Fetching multiple records (`find(ary)`) is stable now, but untested (#38)
data/README.md CHANGED
@@ -313,7 +313,6 @@ Read [official guide][2] to see to to subscribe.
313
313
  * Reusing model definitions for generating responses?
314
314
  * Rails responders providing REST operations with integrated ETag,
315
315
  Modified Headers, conflict detection, ...
316
- * Pagination? Filtering? (If service API provides such features.)
317
316
  * Documentation
318
317
 
319
318
  ## Contributing
data/acfs.gemspec CHANGED
@@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = %w(lib)
20
20
 
21
- spec.add_runtime_dependency 'activesupport', '>= 3.1'
22
- spec.add_runtime_dependency 'activemodel', '>= 3.1'
23
- spec.add_runtime_dependency 'actionpack', '>= 3.1'
21
+ spec.add_runtime_dependency 'activesupport', '>= 4.2'
22
+ spec.add_runtime_dependency 'activemodel', '>= 4.2'
23
+ spec.add_runtime_dependency 'actionpack', '>= 4.2'
24
24
  spec.add_runtime_dependency 'multi_json'
25
25
 
26
26
  # Bundle update w/o version resolves to 0.3.3 ...
@@ -6,7 +6,7 @@ module Acfs
6
6
  #
7
7
  class JSON < Serializer
8
8
  def mime
9
- ::Mime::JSON
9
+ ::Mime[:json]
10
10
  end
11
11
 
12
12
  def encode(data)
@@ -9,7 +9,7 @@ module Acfs
9
9
  end
10
10
 
11
11
  def mime
12
- ::Mime::MSGPACK
12
+ ::Mime[:msgpack]
13
13
  end
14
14
 
15
15
  def encode(data)
@@ -1,35 +1,27 @@
1
1
  module Acfs::Resource::Attributes
2
2
  #
3
3
  class Base
4
- attr_reader :options
4
+ attr_reader :default
5
5
 
6
- def initialize(opts = {})
7
- @options = opts
8
- @options.reverse_merge! allow_nil: true
6
+ def initialize(default: nil)
7
+ @default = default
9
8
  end
10
9
 
11
- def nil_allowed?
12
- options[:allow_nil]
13
- end
14
-
15
- def blank_allowed?
16
- options[:allow_blank]
10
+ def cast(value)
11
+ cast_value(value) unless value.nil?
17
12
  end
18
13
 
19
14
  def default_value
20
- if options[:default].is_a? Proc
21
- options[:default]
15
+ if default.respond_to? :call
16
+ default
22
17
  else
23
- cast options[:default]
18
+ cast default
24
19
  end
25
20
  end
26
21
 
27
- def cast(obj)
28
- return nil if obj.nil? && nil_allowed? || (obj == '' && blank_allowed?)
29
- cast_type obj
30
- end
22
+ private
31
23
 
32
- def cast_type(_obj)
24
+ def cast_value(_value)
33
25
  raise NotImplementedError
34
26
  end
35
27
  end
@@ -14,20 +14,24 @@ module Acfs::Resource::Attributes
14
14
  # true, on, yes
15
15
  #
16
16
  class Boolean < Base
17
- TRUE_VALUES = %w(true on yes 1)
17
+ FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF', 'no', 'NO'].to_set
18
18
 
19
19
  # @api public
20
20
  #
21
21
  # Cast given object to boolean.
22
22
  #
23
- # @param [Object] obj Object to cast.
23
+ # @param [Object] value Object to cast.
24
24
  # @return [TrueClass, FalseClass] Casted boolean.
25
25
  #
26
- def cast_type(obj)
27
- return true if obj.is_a? TrueClass
28
- return false if obj.is_a? FalseClass
26
+ def cast_value(value)
27
+ return true if value == true
28
+ return false if value == false
29
29
 
30
- TRUE_VALUES.include? obj.to_s
30
+ if value.blank?
31
+ nil
32
+ else
33
+ !FALSE_VALUES.include?(value)
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -10,22 +10,21 @@ module Acfs::Resource::Attributes
10
10
  # end
11
11
  #
12
12
  class DateTime < Base
13
+
13
14
  # @api public
14
15
  #
15
16
  # Cast given object to DateTime.
16
17
  #
17
- # @param [Object] obj Object to cast.
18
+ # @param [Object] value Object to cast.
18
19
  # @return [DateTime] Casted object as DateTime.
19
20
  #
20
- def cast_type(obj)
21
- if nil_allowed? && obj.blank?
21
+ def cast_value(value)
22
+ if value.blank?
22
23
  nil
23
- elsif obj.is_a? ::DateTime
24
- obj
25
- elsif obj.is_a?(Time) || obj.is_a?(Date)
26
- ::DateTime.iso8601 obj.iso8601
24
+ elsif value.acts_like?(:time) || value.acts_like?(:date)
25
+ value.to_datetime
27
26
  else
28
- ::DateTime.iso8601 obj
27
+ ::DateTime.iso8601 value
29
28
  end
30
29
  end
31
30
  end
@@ -14,14 +14,24 @@ module Acfs::Resource::Attributes
14
14
  #
15
15
  # Cast given object to a dict/hash.
16
16
  #
17
- # @param [Object] obj Object to cast.
17
+ # @param [Object] value Object to cast.
18
18
  # @return [Hash] Casted object as hash.
19
19
  # @raise [TypeError] If object cannot be casted to a hash.
20
20
  #
21
- def cast_type(obj)
22
- return obj if obj.is_a? Hash
23
- return obj.to_h if obj.respond_to? :to_h
24
- raise TypeError.new "Cannot cast #{obj.inspect} to hash."
21
+ def cast_value(value)
22
+ return {} if value.blank?
23
+
24
+ if value.is_a?(Hash)
25
+ value
26
+ elsif value.respond_to?(:serializable_hash)
27
+ value.serializable_hash
28
+ elsif value.respond_to?(:to_hash)
29
+ value.to_hash
30
+ elsif value.respond_to?(:to_h)
31
+ value.to_h
32
+ else
33
+ Hash(value)
34
+ end
25
35
  end
26
36
  end
27
37
  end
@@ -13,11 +13,19 @@ module Acfs::Resource::Attributes
13
13
  #
14
14
  # Cast given object to float.
15
15
  #
16
- # @param [Object] obj Object to cast.
16
+ # @param [Object] value Object to cast.
17
17
  # @return [Float] Casted object as float.
18
18
  #
19
- def cast_type(obj)
20
- Float obj
19
+ def cast_value(value)
20
+ return 0.0 if value.blank?
21
+
22
+ case value
23
+ when ::Float then value
24
+ when "Infinity" then ::Float::INFINITY
25
+ when "-Infinity" then -::Float::INFINITY
26
+ when "NaN" then ::Float::NAN
27
+ else Float(value)
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -13,15 +13,15 @@ module Acfs::Resource::Attributes
13
13
  #
14
14
  # Cast given object to integer.
15
15
  #
16
- # @param [Object] obj Object to cast.
16
+ # @param [Object] value Object to cast.
17
17
  # @return [Fixnum] Casted object as fixnum.
18
18
  #
19
- def cast_type(obj)
20
- return 0 if obj == ''
21
-
22
- Integer obj
23
- rescue ArgumentError => e
24
- raise TypeError.new e.message
19
+ def cast_value(value)
20
+ if value.blank?
21
+ 0
22
+ else
23
+ Integer(value)
24
+ end
25
25
  end
26
26
  end
27
27
  end
@@ -13,13 +13,22 @@ module Acfs::Resource::Attributes
13
13
  #
14
14
  # Cast given object to a list.
15
15
  #
16
- # @param [Object] obj Object to cast.
16
+ # @param [Object] value Object to cast.
17
17
  # @return [Fixnum] Casted object as list.
18
18
  # @raise [TypeError] If object cannot be casted to a list.
19
19
  #
20
- def cast_type(obj)
21
- return obj.to_a if obj.respond_to? :to_a
22
- raise TypeError.new "Cannot cast #{obj.inspect} to array."
20
+ def cast_value(value)
21
+ return [] if value.blank?
22
+
23
+ if value.is_a?(::Array)
24
+ value
25
+ elsif value.respond_to?(:to_ary)
26
+ value.to_ary
27
+ elsif value.respond_to?(:to_a)
28
+ value.to_a
29
+ else
30
+ Array(value)
31
+ end
23
32
  end
24
33
  end
25
34
  end
@@ -14,11 +14,11 @@ module Acfs::Resource::Attributes
14
14
  #
15
15
  # Cast given object to string.
16
16
  #
17
- # @param [Object] obj Object to cast.
17
+ # @param [Object] value Object to cast.
18
18
  # @return [String] Casted string.
19
19
  #
20
- def cast_type(obj)
21
- obj.to_s
20
+ def cast_value(value)
21
+ value.to_s
22
22
  end
23
23
  end
24
24
  end
@@ -10,7 +10,7 @@ module Acfs::Resource::Attributes
10
10
  #
11
11
  class UUID < Base
12
12
  #
13
- REGEXP = /[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/i
13
+ UUID_REGEXP = /[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/i
14
14
 
15
15
  # @api public
16
16
  #
@@ -28,23 +28,16 @@ module Acfs::Resource::Attributes
28
28
  # | 4 | 4 |
29
29
  # | 5 | 12 |
30
30
  #
31
- # @param [Object] obj Object to cast.
31
+ # @param [Object] value Object to cast.
32
32
  # @return [String] Casted object as UUID.
33
33
  #
34
- def cast_type(obj)
35
- cast_string obj.to_s
36
- end
37
-
38
- private
39
-
40
- def cast_string(str)
41
- if nil_allowed? && str.blank?
42
- return nil
43
- elsif str =~ REGEXP
44
- str
34
+ def cast_value(value)
35
+ if value.blank?
36
+ nil
37
+ elsif value.to_s =~ UUID_REGEXP
38
+ value
45
39
  else
46
- raise ArgumentError.new "given String `#{str}` " \
47
- 'does not look like a UUID'
40
+ raise TypeError.new "Invalid UUID: `#{value.to_s}'"
48
41
  end
49
42
  end
50
43
  end
@@ -47,7 +47,7 @@ class Acfs::Resource
47
47
  # Attributes and their values.
48
48
  #
49
49
  def attributes
50
- @attributes ||= HashWithIndifferentAccess.new
50
+ @_attrs ||= HashWithIndifferentAccess.new
51
51
  end
52
52
 
53
53
  # @api public
@@ -222,56 +222,30 @@ class Acfs::Resource
222
222
  # Attributes with default values.
223
223
  #
224
224
  def attributes
225
- {}.tap do |attrs|
226
- defined_attributes.each do |key, attr|
227
- attrs[key] = attr.default_value
228
- end
225
+ defined_attributes.each_with_object({}) do |(key, attr), hash|
226
+ hash[key] = attr.default_value
229
227
  end
230
228
  end
231
229
 
232
230
  def defined_attributes
233
- @attributes ||= begin
234
- attributes = {}
235
- if superclass.respond_to?(:defined_attributes)
236
- attributes.merge superclass.defined_attributes
237
- end
238
-
239
- attributes
231
+ if superclass.respond_to?(:defined_attributes)
232
+ superclass.defined_attributes.merge(local_attributes)
233
+ else
234
+ local_attributes
240
235
  end
241
236
  end
242
237
 
243
- # @api public
244
- #
245
- # Return hash of attributes and there types.
246
- #
247
- # @example
248
- # class User < Acfs::Resource
249
- # attribute :name, :string
250
- # attribute :age, :integer, default: 25
251
- # end
252
- # User.attributes # => {"name": Acfs::Model::Attributes::String,
253
- # # "age": Acfs::Model::Attributes::Integer}
254
- #
255
- # @return [Hash{Symbol => Class}] Attributes and their types.
256
- #
257
- def attribute_types
258
- @attribute_types ||= begin
259
- attribute_types = {}
260
- if superclass.respond_to?(:attribute_types)
261
- attribute_types.merge superclass.attribute_types
262
- end
238
+ private
263
239
 
264
- attribute_types
265
- end
240
+ def local_attributes
241
+ @local_attributes ||= {}
266
242
  end
267
243
 
268
- private
269
-
270
244
  def define_attribute(name, type, opts = {})
271
245
  name = name.to_s
272
246
  attribute = type.new opts
273
247
 
274
- defined_attributes[name] = attribute
248
+ local_attributes[name] = attribute
275
249
  define_attribute_method name
276
250
 
277
251
  send :define_method, name do
@@ -8,26 +8,14 @@ class Acfs::Resource
8
8
 
9
9
  # @api private
10
10
  #
11
- # Resets all changes. Does not touch previous changes.
12
- #
13
11
  def reset_changes
14
- changed_attributes.clear
15
- end
16
-
17
- # @api private
18
- #
19
- # Save current changes as previous changes and reset
20
- # current one.
21
- #
22
- def swap_changes
23
- @previously_changed = changes
24
- reset_changes
12
+ clear_changes_information
25
13
  end
26
14
 
27
15
  # @api private
28
16
  #
29
17
  def save!(*)
30
- super.tap {|_| swap_changes }
18
+ super.tap {|_| changes_applied }
31
19
  end
32
20
 
33
21
  # @api private
@@ -40,7 +28,7 @@ class Acfs::Resource
40
28
  # @api private
41
29
  #
42
30
  def write_raw_attribute(name, value, opts = {})
43
- attribute_will_change! name if opts[:change].nil? || opts[:change]
31
+ attribute_will_change!(name) if opts[:change].nil? || opts[:change]
44
32
  super
45
33
  end
46
34
  end
@@ -193,10 +193,13 @@ class Acfs::Resource
193
193
  #
194
194
  # @yield [item] Callback that will be invoked for each item.
195
195
  # @yieldparam item [self] Resource.
196
+ # @yieldparam collection [Acfs::Collection] Collection.
196
197
  #
197
- def each_item(opts = {}, &block)
198
+ def each_item(opts = {})
198
199
  each_page(opts) do |collection|
199
- collection.each(&block)
200
+ collection.each do |item|
201
+ yield item, collection
202
+ end
200
203
  end
201
204
  end
202
205
 
@@ -13,8 +13,10 @@ class Acfs::Resource
13
13
 
14
14
  def remote_errors=(errors)
15
15
  (errors || []).each do |field, errs|
16
- self.errors.set field.to_sym, errs
17
- remote_errors.set field.to_sym, errs
16
+ errs.each do |err|
17
+ self.errors.add field.to_sym, err
18
+ remote_errors.add field.to_sym, err
19
+ end
18
20
  end
19
21
  end
20
22
 
@@ -9,7 +9,7 @@ module Acfs
9
9
  end
10
10
 
11
11
  def json?
12
- content_type == Mime::JSON
12
+ content_type == Mime[:json]
13
13
  end
14
14
 
15
15
  private
@@ -1,28 +1,57 @@
1
- require 'action_dispatch/middleware/stack'
2
-
3
1
  module Acfs
4
2
  class Service
5
3
  module Middleware
6
- class Stack < ActionDispatch::MiddlewareStack
4
+ class Stack
5
+ include Enumerable
6
+
7
7
  MUTEX = Mutex.new
8
8
  IDENTITY = -> (i) { i }
9
9
 
10
+ attr_reader :middlewares
11
+
12
+ def initialize
13
+ @middlewares = []
14
+ end
15
+
16
+ def call(request)
17
+ build! unless @app
18
+
19
+ @app.call request
20
+ end
21
+
10
22
  def build!
23
+ return if @app
24
+
11
25
  MUTEX.synchronize do
12
- return if @stack
26
+ return if @app
13
27
 
14
- @stack = build
28
+ @app = build
15
29
  end
16
30
  end
17
31
 
18
32
  def build(app = IDENTITY)
19
- super
33
+ middlewares.reverse.inject(app) do |next_middleware, current_middleware|
34
+ klass, args, block = current_middleware
35
+ args ||= []
36
+
37
+ if klass.is_a?(Class)
38
+ klass.new(next_middleware, *args, &block)
39
+ elsif klass.respond_to?(:call)
40
+ lambda do |env|
41
+ next_middleware.call(klass.call(env, *args))
42
+ end
43
+ else
44
+ fail "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
45
+ end
46
+ end
20
47
  end
21
48
 
22
- def call(request)
23
- build! unless @stack
49
+ def insert(index, klass, *args, &block)
50
+ middlewares.insert(index, [klass, args, block])
51
+ end
24
52
 
25
- @stack.call request
53
+ def each
54
+ middlewares.each { |x| yield x.first }
26
55
  end
27
56
 
28
57
  def clear
data/lib/acfs/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Acfs
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 45
4
+ MINOR = 50
5
5
  PATCH = 0
6
6
  STAGE = nil
7
7
 
@@ -3,23 +3,54 @@ require 'spec_helper'
3
3
  describe Acfs::Resource::Attributes::Boolean do
4
4
  subject { Acfs::Resource::Attributes::Boolean.new }
5
5
 
6
- describe 'cast' do
7
- it 'should preserve boolean values' do
6
+ describe '#cast' do
7
+ it 'casts nil' do
8
+ expect(subject.cast(nil)).to eq nil
9
+ end
10
+
11
+ it 'casts empty string to false' do
12
+ expect(subject.cast('')).to eq nil
13
+ end
14
+
15
+ it 'casts blank string to false' do
16
+ expect(subject.cast(" \t")).to eq nil
17
+ end
18
+
19
+ it 'preserves boolean values' do
8
20
  expect(subject.cast(false)).to eq false
9
21
  expect(subject.cast(true)).to eq true
10
22
  end
11
23
 
12
- it 'should cast TRUE_VALUES to true' do
24
+ it 'casts falsy values to false' do
25
+ expect(subject.cast(false)).to eq false
26
+ expect(subject.cast(0)).to eq false
27
+ expect(subject.cast('0')).to eq false
28
+ expect(subject.cast('no')).to eq false
29
+ expect(subject.cast('NO')).to eq false
30
+ expect(subject.cast('off')).to eq false
31
+ expect(subject.cast('OFF')).to eq false
32
+ expect(subject.cast('false')).to eq false
33
+ expect(subject.cast('FALSE')).to eq false
34
+ expect(subject.cast('f')).to eq false
35
+ expect(subject.cast('F')).to eq false
36
+ end
37
+
38
+ it 'casts any other value to true' do
39
+ expect(subject.cast(true)).to eq true
40
+ expect(subject.cast(1)).to eq true
41
+ expect(subject.cast('1')).to eq true
13
42
  expect(subject.cast('yes')).to eq true
43
+ expect(subject.cast('YES')).to eq true
14
44
  expect(subject.cast('on')).to eq true
45
+ expect(subject.cast('ON')).to eq true
15
46
  expect(subject.cast('true')).to eq true
16
- expect(subject.cast('1')).to eq true
17
- end
47
+ expect(subject.cast('TRUE')).to eq true
48
+ expect(subject.cast('t')).to eq true
49
+ expect(subject.cast('T')).to eq true
18
50
 
19
- it 'should cast any other value to false' do
20
- expect(subject.cast('')).to eq false
21
- expect(subject.cast('wrong')).to eq false
22
- expect(subject.cast('random')).to eq false
51
+ expect(subject.cast(2)).to eq true
52
+ expect(subject.cast('wrong')).to eq true
53
+ expect(subject.cast('random')).to eq true
23
54
  end
24
55
  end
25
56
  end