kind 5.6.0 → 5.7.0

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
  SHA256:
3
- metadata.gz: b72fec7c07a6b3178717f30c81ecdbb6375cc1fc625c1a3fa1d39611e4dc3960
4
- data.tar.gz: efec52f15083b538c99546f8d5e1c6b095c6c5c243379fc21365bae99a176e60
3
+ metadata.gz: a01866d3dbb6b0ae5977a7e711b35eaa2152471b4d52781a285de03ec9ef86a1
4
+ data.tar.gz: 8fd0cc81e96aa364a90f3c161e824d1a501296b4c4b40e2aca1e4286a75baaec
5
5
  SHA512:
6
- metadata.gz: fad78e10047e8fdd21e4c56ddcc5c8620b1ad6018f3fdfb7af097b84be23bb73c3c549cd519bec3af7980c4df89fbc5b9db2796510c518a4ad9d9b9165ef6e02
7
- data.tar.gz: 3d0fa5b46405e4a766285c6e3fd95e3568c5bb1875e310941a3dd592cd99372893c7aab6cfe91a321fc6a843c966ab5fb7414e726e903021b16b92dfc03bac1e
6
+ metadata.gz: 10282e2b8777f2d1a738a6ce38285fc9f17f0d9a6b3aec26d46409d995cb0004fde5c20a3998ef68a98530c5fa25ee463fba8f3501e5cbeb0cb2b01e0f2627ba
7
+ data.tar.gz: 7d16bf63dbb4928bef6182a7886e9268da869bddab12ac0e1192e39bac3fce2a4489ed308366188df4d6550047b2003e1b427f87430ec5e68c49c34a3974c13f
data/CHANGELOG.md CHANGED
@@ -3,83 +3,85 @@
3
3
  This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the recommendations of [keepachangelog.com](http://keepachangelog.com/).
4
4
 
5
5
  - [Unreleased](#unreleased)
6
- - [5.6.0 (2021-05-14)](#560-2021-05-14)
6
+ - [5.7.0 (2021-06-22)](#570-2021-06-22)
7
7
  - [Added](#added)
8
- - [5.5.0 (2021-04-05)](#550-2021-04-05)
8
+ - [5.6.0 (2021-05-14)](#560-2021-05-14)
9
9
  - [Added](#added-1)
10
+ - [5.5.0 (2021-04-05)](#550-2021-04-05)
11
+ - [Added](#added-2)
10
12
  - [5.4.1 (2021-03-26)](#541-2021-03-26)
11
13
  - [Fixed](#fixed)
12
14
  - [5.4.0 (2021-03-25)](#540-2021-03-25)
13
- - [Added](#added-2)
14
- - [5.3.0 (2021-03-23)](#530-2021-03-23)
15
15
  - [Added](#added-3)
16
- - [5.2.0 (2021-03-17)](#520-2021-03-17)
16
+ - [5.3.0 (2021-03-23)](#530-2021-03-23)
17
17
  - [Added](#added-4)
18
+ - [5.2.0 (2021-03-17)](#520-2021-03-17)
19
+ - [Added](#added-5)
18
20
  - [Deprecated](#deprecated)
19
21
  - [Changes](#changes)
20
22
  - [5.1.0 (2021-02-23)](#510-2021-02-23)
21
- - [Added](#added-5)
23
+ - [Added](#added-6)
22
24
  - [Deprecated](#deprecated-1)
23
25
  - [5.0.0 (2021-02-22)](#500-2021-02-22)
24
26
  - [Breaking Changes](#breaking-changes)
25
27
  - [Removed](#removed)
26
28
  - [4.1.0 (2021-02-22)](#410-2021-02-22)
27
- - [Added](#added-6)
28
- - [4.0.0 (2021-02-22)](#400-2021-02-22)
29
29
  - [Added](#added-7)
30
+ - [4.0.0 (2021-02-22)](#400-2021-02-22)
31
+ - [Added](#added-8)
30
32
  - [Deprecated](#deprecated-2)
31
33
  - [Fixed](#fixed-1)
32
34
  - [3.1.0 (2020-07-08)](#310-2020-07-08)
33
- - [Added](#added-8)
35
+ - [Added](#added-9)
34
36
  - [3.0.0 (2020-06-25)](#300-2020-06-25)
35
37
  - [Breaking Changes](#breaking-changes-1)
36
- - [Added](#added-9)
37
- - [2.3.0 (2020-06-24)](#230-2020-06-24)
38
38
  - [Added](#added-10)
39
- - [2.2.0 (2020-06-23)](#220-2020-06-23)
39
+ - [2.3.0 (2020-06-24)](#230-2020-06-24)
40
40
  - [Added](#added-11)
41
- - [2.1.0 (2020-05-12)](#210-2020-05-12)
41
+ - [2.2.0 (2020-06-23)](#220-2020-06-23)
42
42
  - [Added](#added-12)
43
+ - [2.1.0 (2020-05-12)](#210-2020-05-12)
44
+ - [Added](#added-13)
43
45
  - [Breaking Changes](#breaking-changes-2)
44
46
  - [2.0.0 (2020-05-07)](#200-2020-05-07)
45
- - [Added](#added-13)
47
+ - [Added](#added-14)
46
48
  - [Breaking Changes](#breaking-changes-3)
47
49
  - [Removed](#removed-1)
48
50
  - [1.9.0 (2020-05-06)](#190-2020-05-06)
49
- - [Added](#added-14)
50
- - [1.8.0 (2020-05-03)](#180-2020-05-03)
51
51
  - [Added](#added-15)
52
+ - [1.8.0 (2020-05-03)](#180-2020-05-03)
53
+ - [Added](#added-16)
52
54
  - [1.7.0 (2020-05-03)](#170-2020-05-03)
53
55
  - [Fixed](#fixed-2)
54
56
  - [1.6.0 (2020-04-17)](#160-2020-04-17)
55
- - [Added](#added-16)
57
+ - [Added](#added-17)
56
58
  - [Changes](#changes-1)
57
59
  - [1.5.0 (2020-04-12)](#150-2020-04-12)
58
- - [Added](#added-17)
59
- - [1.4.0 (2020-04-12)](#140-2020-04-12)
60
60
  - [Added](#added-18)
61
- - [1.3.0 (2020-04-12)](#130-2020-04-12)
61
+ - [1.4.0 (2020-04-12)](#140-2020-04-12)
62
62
  - [Added](#added-19)
63
- - [1.2.0 (2020-04-12)](#120-2020-04-12)
63
+ - [1.3.0 (2020-04-12)](#130-2020-04-12)
64
64
  - [Added](#added-20)
65
- - [1.1.0 (2020-04-09)](#110-2020-04-09)
65
+ - [1.2.0 (2020-04-12)](#120-2020-04-12)
66
66
  - [Added](#added-21)
67
+ - [1.1.0 (2020-04-09)](#110-2020-04-09)
68
+ - [Added](#added-22)
67
69
  - [Fixed](#fixed-3)
68
70
  - [1.0.0 (2020-03-16)](#100-2020-03-16)
69
- - [Added](#added-22)
70
- - [0.6.0 (2020-01-06)](#060-2020-01-06)
71
71
  - [Added](#added-23)
72
- - [0.5.0 (2020-01-04)](#050-2020-01-04)
72
+ - [0.6.0 (2020-01-06)](#060-2020-01-06)
73
73
  - [Added](#added-24)
74
- - [0.4.0 (2020-01-03)](#040-2020-01-03)
74
+ - [0.5.0 (2020-01-04)](#050-2020-01-04)
75
75
  - [Added](#added-25)
76
- - [0.3.0 (2020-01-03)](#030-2020-01-03)
76
+ - [0.4.0 (2020-01-03)](#040-2020-01-03)
77
77
  - [Added](#added-26)
78
+ - [0.3.0 (2020-01-03)](#030-2020-01-03)
79
+ - [Added](#added-27)
78
80
  - [Breaking Changes](#breaking-changes-4)
79
81
  - [0.2.0 (2020-01-02)](#020-2020-01-02)
80
- - [Added](#added-27)
81
- - [0.1.0 (2019-12-26)](#010-2019-12-26)
82
82
  - [Added](#added-28)
83
+ - [0.1.0 (2019-12-26)](#010-2019-12-26)
84
+ - [Added](#added-29)
83
85
 
84
86
  ## Unreleased
85
87
 
@@ -91,6 +93,59 @@ This project follows [semver 2.0.0](http://semver.org/spec/v2.0.0.html) and the
91
93
  ### Fixed
92
94
  -->
93
95
 
96
+ 5.7.0 (2021-06-22)
97
+ ------------------
98
+
99
+ ### Added
100
+
101
+ * [#58](https://github.com/serradura/kind/pull/58) - Add `Add Kind.assert_hash!(hash, keys:)`, you can use the `require_all:` option to check if the hashes have the same keys.
102
+ ```ruby
103
+ h1 = {a: 1, b: 1}
104
+
105
+ Kind.assert_hash!(h1, keys: [:a, :b])
106
+ Kind.assert_hash!(h1, keys: [:a]) # ArgumentError (Unknown key: :b. Valid keys are: :a)
107
+
108
+ # --
109
+
110
+ h2 = {'a' => 1, 'b' => 2}
111
+
112
+ Kind.assert_hash!(h2, keys: ['a', 'b'])
113
+ ```
114
+
115
+ * [#58](https://github.com/serradura/kind/pull/58) - Add `Add Kind.assert_hash!(hash, schema:)`, you can use the `require_all:` option to check if the hashes have the same keys.
116
+ ```ruby
117
+ hash = {hash: {}, array: [], number: 1, string: 'foo', email: 'bar@bar.com', null: nil}
118
+
119
+ Kind.assert_hash!(hash, schema: {
120
+ hash: {},
121
+ array: [],
122
+ email: 'bar@bar.com',
123
+ string: 'foo',
124
+ number: 1,
125
+ null: nil
126
+ })
127
+
128
+ Kind.assert_hash!(hash, schema: {
129
+ hash: Enumerable,
130
+ array: Enumerable,
131
+ email: /\A.+@.+\..+\z/,
132
+ string: String
133
+ })
134
+
135
+ Kind.assert_hash!(hash, schema: {
136
+ hash: Hash,
137
+ array: Array,
138
+ email: String,
139
+ string: String
140
+ })
141
+
142
+ Kind.assert_hash!(h1, schema: {
143
+ email: ->(value) { value.is_a?(String) && value.include?('@') }
144
+ })
145
+ ```
146
+
147
+ [⬆️  Back to Top](#changelog-)
148
+
94
149
  5.6.0 (2021-05-14)
95
150
  ------------------
96
151
 
data/README.md CHANGED
@@ -42,7 +42,7 @@ So, I invite you to check out these features to see how they could be useful for
42
42
  Version | Documentation
43
43
  ---------- | -------------
44
44
  unreleased | https://github.com/serradura/kind/blob/main/README.md
45
- 5.6.0 | https://github.com/serradura/kind/blob/v5.x/README.md
45
+ 5.7.0 | https://github.com/serradura/kind/blob/v5.x/README.md
46
46
  4.1.0 | https://github.com/serradura/kind/blob/v4.x/README.md
47
47
  3.1.0 | https://github.com/serradura/kind/blob/v3.x/README.md
48
48
  2.3.0 | https://github.com/serradura/kind/blob/v2.x/README.md
@@ -125,7 +125,7 @@ unreleased | https://github.com/serradura/kind/blob/main/README.md
125
125
  | kind | branch | ruby | activemodel |
126
126
  | -------------- | ------- | ------------------ | -------------- |
127
127
  | unreleased | main | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
128
- | 5.6.0 | v5.x | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
128
+ | 5.7.0 | v5.x | >= 2.1.0, <= 3.0.0 | >= 3.2, < 7.0 |
129
129
  | 4.1.0 | v4.x | >= 2.2.0, <= 3.0.0 | >= 3.2, < 7.0 |
130
130
  | 3.1.0 | v3.x | >= 2.2.0, <= 2.7 | >= 3.2, < 7.0 |
131
131
  | 2.3.0 | v2.x | >= 2.2.0, <= 2.7 | >= 3.2, <= 6.0 |
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kind
4
+ module ASSERT_HASH_KEYS
5
+ def self.require_all(keys, hash)
6
+ expected_keys = keys - hash.keys
7
+
8
+ unless expected_keys.empty?
9
+ raise KeyError.new("#{hash.inspect} expected to have these keys: #{expected_keys}")
10
+ end
11
+
12
+ unexpected_keys = hash.keys - keys
13
+
14
+ unless unexpected_keys.empty?
15
+ raise KeyError.new("#{hash.inspect} expected to NOT have these keys: #{unexpected_keys}")
16
+ end
17
+
18
+ hash
19
+ end
20
+ end
21
+
22
+ module ASSERT_HASH_SCHEMA
23
+ extend self
24
+
25
+ UnionType = ->(value) do
26
+ defined?(Kind::UnionType) ? Kind::UnionType === value : false
27
+ end
28
+
29
+ def any(hash, spec)
30
+ spec.each do |key, expected|
31
+ value = hash[key]
32
+ error_message = "The key #{key.inspect} has an invalid value"
33
+
34
+ case expected
35
+ when ::Module then assert_kind_of(expected, value, error_message)
36
+ when ::Proc then assert(expected.call(value), error_message)
37
+ when ::Regexp then assert_match(expected, value, error_message)
38
+ when ::NilClass then assert_nil(value, error_message)
39
+ when UnionType then assert(expected === value, error_message)
40
+ else assert_equal(expected, value, error_message)
41
+ end
42
+ end
43
+
44
+ hash
45
+ end
46
+
47
+ def all(hash, spec)
48
+ ASSERT_HASH_KEYS.require_all(spec.keys, hash)
49
+
50
+ any(hash, spec)
51
+ end
52
+
53
+ private
54
+
55
+ def assert_equal(expected, value, message)
56
+ raise_kind_error(message) if expected != value
57
+ end
58
+
59
+ def assert(value, message)
60
+ raise_kind_error(message) unless value
61
+ end
62
+
63
+ def assert_nil(value, message)
64
+ raise_kind_error(message) unless value.nil?
65
+ end
66
+
67
+ def assert_match(expected, value, message)
68
+ STRICT.kind_of(String, value)
69
+
70
+ raise_kind_error(message) if value !~ expected
71
+ end
72
+
73
+ def assert_kind_of(expected, value, message)
74
+ raise_kind_error(message) unless expected === value
75
+ end
76
+
77
+ def raise_kind_error(message)
78
+ raise Error.new(message)
79
+ end
80
+ end
81
+ end
@@ -6,6 +6,8 @@ module Kind
6
6
  module STRICT
7
7
  extend self
8
8
 
9
+ require 'kind/__lib__/assert_hash_schema'
10
+
9
11
  def error(kind_name, value, label = nil) # :nodoc:
10
12
  raise Error.new(kind_name, value, label: label)
11
13
  end
@@ -43,6 +45,41 @@ module Kind
43
45
 
44
46
  raise Error.new("#{label_text}expected to not be nil")
45
47
  end
48
+
49
+ def in!(list, value)
50
+ return value if list.include?(value)
51
+
52
+ raise Error.new("#{value} expected to be included in #{list.inspect}")
53
+ end
54
+
55
+ def assert_hash!(hash, options)
56
+ require_all = options[:require_all]
57
+
58
+ return assert_hash_keys!(hash, options[:keys], require_all) if options.key?(:keys)
59
+ return assert_hash_schema!(hash, options[:schema], require_all) if options.key?(:schema)
60
+
61
+ raise ArgumentError, ':keys or :schema is missing'
62
+ end
63
+
64
+ private
65
+
66
+ def assert_hash_keys!(hash, arg, require_all)
67
+ keys = Array(arg)
68
+
69
+ ASSERT_HASH_KEYS.require_all(keys, hash) if require_all
70
+
71
+ hash.each_key do |k|
72
+ unless keys.include?(k)
73
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{keys.map(&:inspect).join(', ')}")
74
+ end
75
+ end
76
+ end
77
+
78
+ def assert_hash_schema!(hash, schema, require_all)
79
+ return ASSERT_HASH_SCHEMA.all(hash, schema) if require_all
80
+
81
+ ASSERT_HASH_SCHEMA.any(hash, schema)
82
+ end
46
83
  end
47
84
 
48
85
  private_constant :STRICT
data/lib/kind/basic.rb CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'kind/version'
4
4
 
5
- require 'kind/__lib__/kind'
6
5
  require 'kind/__lib__/undefined'
6
+ require 'kind/__lib__/kind'
7
7
 
8
8
  require 'kind/basic/undefined'
9
9
  require 'kind/basic/error'
@@ -80,4 +80,16 @@ module Kind
80
80
  def or_nil(kind, value)
81
81
  return value if kind === value
82
82
  end
83
+
84
+ def in!(list, value)
85
+ STRICT.in!(list, value)
86
+ end
87
+
88
+ def include!(value, list)
89
+ STRICT.in!(list, value)
90
+ end
91
+
92
+ def assert_hash!(hash, **kargs)
93
+ STRICT.assert_hash!(hash, kargs)
94
+ end
83
95
  end
@@ -3,8 +3,14 @@
3
3
  module Kind
4
4
  module STRICT
5
5
  [
6
- :object_is_a, :class!, :kind_of,
7
- :module_or_class, :module!, :not_nil
6
+ :object_is_a,
7
+ :class!,
8
+ :kind_of,
9
+ :module_or_class,
10
+ :module!,
11
+ :not_nil,
12
+ :in!,
13
+ :assert_hash!
8
14
  ].each { |method_name| remove_method(method_name) }
9
15
 
10
16
  def object_is_a(_kind, value, _label = nil) # :nodoc:
@@ -30,5 +36,17 @@ module Kind
30
36
  def not_nil(value, label) # :nodoc:
31
37
  value
32
38
  end
39
+
40
+ def in!(list, value) # :nodoc:
41
+ value
42
+ end
43
+
44
+ def assert_hash!(hash, _options) # :nodoc:
45
+ hash
46
+ end
47
+
48
+ def assert_hash!(hash, _options) # :nodoc:
49
+ hash
50
+ end
33
51
  end
34
52
  end
data/lib/kind/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kind
4
- VERSION = '5.6.0'
4
+ VERSION = '5.7.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kind
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.0
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-14 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A development toolkit for Ruby with several small/cohesive abstractions
14
14
  (monads, enums, business logic, data validation...) to empower your development
@@ -34,6 +34,7 @@ files:
34
34
  - kind.gemspec
35
35
  - lib/kind.rb
36
36
  - lib/kind/__lib__/action_steps.rb
37
+ - lib/kind/__lib__/assert_hash_schema.rb
37
38
  - lib/kind/__lib__/attributes.rb
38
39
  - lib/kind/__lib__/kind.rb
39
40
  - lib/kind/__lib__/of.rb