eapi 0.2.0 → 0.2.1

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: 24226b6df180842850c926be63af60c33803e6e0
4
- data.tar.gz: 1764202eb7a457a16bde2590b25909af05d4d17b
3
+ metadata.gz: 63f4151b5dc72b051cea9b0c448472007841deaa
4
+ data.tar.gz: a0f4c037e605fd4ca96e6c1d8518accaee6d9509
5
5
  SHA512:
6
- metadata.gz: abef4e5a06756f1f32db42e60e0358451d524620ea0d7dc21af6f4929da5eea21f86a74a9930142164b219ba68ecb362cefe6f7115baffda67ba93a2477d7ec2
7
- data.tar.gz: d67597321bb8c496167825f17b558c2e0e6e02b2bd75064eee1a7126146d2ffa0ecdb42742f5f912c19cce4ee45c5ef43e6d81158a5081dfbda353bab9960a09
6
+ metadata.gz: b06d56359371a02be843a0bc48b11f8fb9c873656e08d7d877427c95840d58b1595ea07d0faa1c9a176a7cfbb2432a2b67e74ace65f113c0836c51bde87d0147
7
+ data.tar.gz: 24e712cec447d69b9a65202b946d6a73e23aaa35334c0e92b46a9aba15fa119245e6cde824da3c0a34c9daff0dbf3e233e8747f7061dbc44c73aebedba855858
data/README.md CHANGED
@@ -316,6 +316,87 @@ eapi.something # => {}
316
316
 
317
317
  To trigger the error, the value must not be an instance of the given Type, and also must not respond `true` to `value.is?(type)`
318
318
 
319
+ #### Skip type validation with 'raw' values with `allow_raw` option
320
+
321
+ If we want to check for the type of the elements, but still want the flexibility of using raw `Hash` or `Array` in case we want something specific there, we can specify it with the `allow_raw` option.
322
+
323
+ With this, eapi will let you skip the type validation when the value is either a `Hash` or an `Array`, assuming that "you know what you are doing".
324
+
325
+ ```ruby
326
+ class ValueKlass
327
+ include Eapi::Item
328
+
329
+ property :value
330
+ end
331
+
332
+ class TestKlass
333
+ include Eapi::Item
334
+
335
+ property :something, type: ValueKlass, allow_raw: true
336
+ property :somelist, multiple: true, element_type: ValueKlass, allow_raw: true
337
+ end
338
+
339
+ class TestList
340
+ include Eapi::List
341
+
342
+ elements type: ValueKlass, allow_raw: true
343
+ end
344
+
345
+ i = TestKlass.new
346
+ i.something 1
347
+ i.valid? # => false
348
+
349
+ i.something ValueKlass.new
350
+ i.valid? # => true
351
+
352
+ i.something({some: :hash})
353
+ i.valid? # => true
354
+
355
+ i.add_somelist 1
356
+ i.valid? # => false
357
+
358
+ i.clear_somelist.add_somelist({a: :hash}).add_somelist([:an, :array])
359
+ i.valid? # => true
360
+
361
+ l = TestList.new
362
+ l.add 1
363
+ l.valid? # => false
364
+
365
+ i.clear.add(ValueKlass.new).add({a: :hash}).add([:an, :array])
366
+ l.valid? # => true
367
+ ```
368
+
369
+ You can also enable this option after defining the property, with the `property_allow_raw` and `property_disallow_raw` methods and check if it is enabled with `property_allow_raw?`. In `List`s, the methods are `elements_allow_raw`, `elements_disallow_raw` and `elements_allow_raw?`.
370
+
371
+ ```ruby
372
+ class TestKlass
373
+ include Eapi::Item
374
+
375
+ property :something, type: ValueKlass
376
+ end
377
+
378
+ TestKlass.property_allow_raw?(:something) # => false
379
+
380
+ TestKlass.property_allow_raw(:something)
381
+ TestKlass.property_allow_raw?(:something) # => true
382
+
383
+ TestKlass.property_disallow_raw(:something)
384
+ TestKlass.property_allow_raw?(:something) # => false
385
+
386
+ class TestList
387
+ include Eapi::List
388
+ elements type: ValueKlass
389
+ end
390
+
391
+ TestList.elements_allow_raw? # => false
392
+
393
+ TestList.elements_allow_raw
394
+ TestList.elements_allow_raw? # => true
395
+
396
+ TestList.elements_disallow_raw
397
+ TestList.elements_allow_raw? # => false
398
+ ```
399
+
319
400
  #### Custom validation with `validate_with` option
320
401
 
321
402
  A more specific validation can be used using `validate_with`, that works the same way as `ActiveModel::Validations`.
@@ -13,6 +13,7 @@ module Eapi
13
13
  run_validate_element_type
14
14
  run_validate_element_with
15
15
  run_validate_uniqueness
16
+ run_allow_raw
16
17
  end
17
18
 
18
19
  def run_validate_uniqueness
@@ -39,6 +40,10 @@ module Eapi
39
40
  end
40
41
  end
41
42
 
43
+ def run_allow_raw
44
+ Runner.allow_raw(klass: klass, field: :_list, allow_raw: allow_raw?)
45
+ end
46
+
42
47
  def required?
43
48
  definition.fetch(:required, false)
44
49
  end
@@ -54,6 +59,10 @@ module Eapi
54
59
  def element_type
55
60
  definition.fetch(:element_type, nil) || definition.fetch(:type, nil)
56
61
  end
62
+
63
+ def allow_raw?
64
+ definition.fetch(:allow_raw, false)
65
+ end
57
66
  end
58
67
 
59
68
  end
@@ -6,6 +6,7 @@ module Eapi
6
6
  run_multiple_accessor
7
7
  run_init
8
8
  run_validations
9
+ run_allow_raw
9
10
  end
10
11
 
11
12
  private
@@ -37,31 +38,29 @@ module Eapi
37
38
 
38
39
  def run_validate_type
39
40
  if type
40
- klass.send :validates_each, field do |record, attr, value|
41
- unless Eapi::TypeChecker.new(type).is_valid_type?(value)
42
- record.errors.add(attr, "must be a #{type}")
43
- end
44
- end
41
+ Runner.validate_type(klass: klass, field: field, type: type)
45
42
  end
46
43
  end
47
44
 
48
45
  def run_validate_with
49
46
  if validate_with
50
- klass.send :validates_each, field do |record, attr, value|
51
- validate_with.call(record, attr, value)
52
- end
47
+ Runner.validate_with(klass: klass, field: field, validate_with: validate_with)
53
48
  end
54
49
  end
55
50
 
51
+ def run_allow_raw
52
+ Runner.allow_raw(klass: klass, field: field, allow_raw: allow_raw?)
53
+ end
54
+
56
55
  def run_init
57
56
  if type || multiple?
58
- klass.send :define_init, field, type || Array
57
+ Runner.init(klass: klass, field: field, type: type || Array)
59
58
  end
60
59
  end
61
60
 
62
61
  def run_multiple_accessor
63
62
  if multiple?
64
- klass.send :define_multiple_accessor, field
63
+ Runner.multiple_accessor(klass: klass, field: field)
65
64
  end
66
65
  end
67
66
 
@@ -95,6 +94,10 @@ module Eapi
95
94
  def type
96
95
  definition.fetch(:type, nil)
97
96
  end
97
+
98
+ def allow_raw?
99
+ definition.fetch(:allow_raw, false)
100
+ end
98
101
  end
99
102
  end
100
103
  end
@@ -11,11 +11,27 @@ module Eapi
11
11
  end
12
12
  end
13
13
 
14
+ def self.validate_type(klass:, field:, type:)
15
+ klass.send :validates_each, field do |record, attr, value|
16
+ allow_raw = klass.property_allow_raw?(field)
17
+ unless Eapi::TypeChecker.new(type, allow_raw).is_valid_type?(value)
18
+ record.errors.add(attr, "must be a #{type}")
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.validate_with(klass:, field:, validate_with:)
24
+ klass.send :validates_each, field do |record, attr, value|
25
+ validate_with.call(record, attr, value)
26
+ end
27
+ end
28
+
14
29
  def self.validate_element_type(klass:, field:, element_type:)
15
30
  klass.send :validates_each, field do |record, attr, value|
31
+ allow_raw = klass.property_allow_raw?(field)
16
32
  if value.respond_to?(:each)
17
33
  value.each do |v|
18
- unless Eapi::TypeChecker.new(element_type).is_valid_type?(v)
34
+ unless Eapi::TypeChecker.new(element_type, allow_raw).is_valid_type?(v)
19
35
  record.errors.add(attr, "element must be a #{element_type}")
20
36
  end
21
37
  end
@@ -39,6 +55,22 @@ module Eapi
39
55
  end
40
56
  end
41
57
  end
58
+
59
+ def self.allow_raw(klass:, field:, allow_raw:)
60
+ if allow_raw
61
+ klass.send :property_allow_raw, field
62
+ else
63
+ klass.send :property_disallow_raw, field
64
+ end
65
+ end
66
+
67
+ def self.init(klass:, field:, type:)
68
+ klass.send :define_init, field, type
69
+ end
70
+
71
+ def self.multiple_accessor(klass:, field:)
72
+ klass.send :define_multiple_accessor, field
73
+ end
42
74
  end
43
75
  end
44
76
  end
@@ -28,6 +28,24 @@ module Eapi
28
28
  end
29
29
 
30
30
  module ClassMethods
31
+ def property_allow_raw(field)
32
+ @_property_allow_raw ||= {}
33
+
34
+ @_property_allow_raw[field.to_sym] = true
35
+ end
36
+
37
+ def property_disallow_raw(field)
38
+ @_property_allow_raw ||= {}
39
+
40
+ @_property_allow_raw[field.to_sym] = false
41
+ end
42
+
43
+ def property_allow_raw?(field)
44
+ @_property_allow_raw ||= {}
45
+
46
+ @_property_allow_raw.fetch(field.to_sym, false)
47
+ end
48
+
31
49
  def property(field, definition = {})
32
50
  fs = field.to_sym
33
51
  define_accessors fs
@@ -58,6 +76,18 @@ module Eapi
58
76
  end
59
77
 
60
78
  module ListCLassMethods
79
+ def elements_allow_raw
80
+ property_allow_raw(:_list)
81
+ end
82
+
83
+ def elements_disallow_raw
84
+ property_disallow_raw(:_list)
85
+ end
86
+
87
+ def elements_allow_raw?
88
+ property_allow_raw?(:_list)
89
+ end
90
+
61
91
  def elements(definition)
62
92
  run_list_definition definition
63
93
  store_list_definition definition
@@ -1,10 +1,24 @@
1
1
  module Eapi
2
- class TypeChecker < Struct.new(:given_type)
2
+ class TypeChecker
3
+
4
+ attr_reader :given_type, :allow_raw
5
+
6
+ def initialize(given_type, allow_raw = false)
7
+ @given_type = given_type
8
+ @allow_raw = allow_raw
9
+ end
10
+
3
11
  def is_valid_type?(value)
4
- value.nil? || is_same_type?(value) || poses_as_type?(value)
12
+ value.nil? || is_same_type?(value) || poses_as_type?(value) || valid_raw?(value)
5
13
  end
6
14
 
7
15
  private
16
+ def valid_raw?(value)
17
+ return false unless allow_raw?
18
+
19
+ value.kind_of?(Array) || value.kind_of?(Hash)
20
+ end
21
+
8
22
  def is_same_type?(value)
9
23
  value.kind_of?(type)
10
24
  end
@@ -20,5 +34,9 @@ module Eapi
20
34
  given_type.to_s.constantize
21
35
  end
22
36
  end
37
+
38
+ def allow_raw?
39
+ allow_raw
40
+ end
23
41
  end
24
42
  end
@@ -1,3 +1,3 @@
1
1
  module Eapi
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -373,6 +373,46 @@ RSpec.describe Eapi do
373
373
  subject.add "Many Strings"
374
374
  expect(subject).to be_valid
375
375
  end
376
+
377
+ context 'with option allow_raw (default false)' do
378
+ class AllowRawValueKlass
379
+ include Eapi::Item
380
+ property :something
381
+ end
382
+
383
+ class ListAllowRawTestKlass
384
+ include Eapi::List
385
+
386
+ elements type: AllowRawValueKlass, allow_raw: true
387
+ end
388
+
389
+ subject { ListAllowRawTestKlass.new }
390
+
391
+ it 'allows a Hash or Array value with type check' do
392
+ subject.add(1)
393
+ expect(subject).not_to be_valid
394
+
395
+ subject.clear.add(AllowRawValueKlass.new)
396
+ expect(subject).to be_valid
397
+
398
+ subject.clear.add([1, 2, 3]).add({a: :hash})
399
+ expect(subject).to be_valid
400
+ end
401
+
402
+ it 'can be allowed and disallowed after definition' do
403
+ orig = ListAllowRawTestKlass.elements_allow_raw?
404
+ ListAllowRawTestKlass.elements_allow_raw
405
+ expect(ListAllowRawTestKlass).to be_elements_allow_raw
406
+ ListAllowRawTestKlass.elements_disallow_raw
407
+ expect(ListAllowRawTestKlass).not_to be_elements_allow_raw
408
+
409
+ if orig
410
+ ListAllowRawTestKlass.elements_allow_raw
411
+ else
412
+ ListAllowRawTestKlass.elements_disallow_raw
413
+ end
414
+ end
415
+ end
376
416
  end
377
417
 
378
418
  context 'unique' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Turiño