kind 5.6.0 → 5.7.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.
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