invoca-utils 0.2.0 → 0.3.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 +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -7
- data/lib/invoca/utils.rb +3 -0
- data/lib/invoca/utils/array.rb +10 -12
- data/lib/invoca/utils/enumerable.rb +23 -0
- data/lib/invoca/utils/hash.rb +44 -0
- data/lib/invoca/utils/hash_with_indifferent_access.rb +42 -0
- data/lib/invoca/utils/module.rb +29 -0
- data/lib/invoca/utils/version.rb +1 -1
- data/test/unit/enumerable_test.rb +38 -0
- data/test/unit/hash_test.rb +81 -0
- data/test/unit/hash_with_indifferent_access_test.rb +100 -0
- data/test/unit/module_test.rb +39 -0
- metadata +11 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 926143286cf40283408cd86732347339453d12a671c2e1539f01e391cef84ed4
|
|
4
|
+
data.tar.gz: b4114b43131585610f6e875680895e1be15fe68e164a0a8904ddec46b59e58cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 50a6cf86a1547385b1b7dabfce31f4a89d0156f872f7dde7b6e179afd6373f8b56cc6e4bfea3b383af02aaabb6567a096d4dfe9250a8e639a0f02c3d0535455f
|
|
7
|
+
data.tar.gz: 2bcfc2fa9de854a2f78ba03a5bd9814fc921c9ab668ca0660491b14679e81536a9e4c61cb6e4b8f00f88ddb609a891956f02094de64e48efbe0411fdc4afbeff
|
data/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,18 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
4
4
|
|
|
5
5
|
Note: This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.3.0] - 2020-04-28
|
|
8
|
+
### Added
|
|
9
|
+
- Array::* operator changed to use alias_method instead of prepend to prevent infinite recursion when HoboSupport gem is present
|
|
10
|
+
- Enumerable::map_and_find, map_with_index, and map_hash methods ported from HoboSupport
|
|
11
|
+
- Hash::select_hash, map_hash, partition_hash, & and - methods ported from HoboSupport
|
|
12
|
+
- HashWithIndifferentAccess::partition_hash, & and - methods ported from HoboSupport
|
|
13
|
+
- Module::alias_method_chain ported from HoboSupport
|
|
14
|
+
|
|
7
15
|
## [0.2.0] - 2020-04-27
|
|
8
16
|
### Added
|
|
9
17
|
- Enumerable::build_hash method ported from HoboSupport
|
|
10
18
|
- Enumerable::* operator ported from HoboSupport
|
|
11
19
|
|
|
20
|
+
[0.3.0]: https://github.com/Invoca/invoca-utils/compare/v0.2.0...v0.3.0
|
|
12
21
|
[0.2.0]: https://github.com/Invoca/invoca-utils/compare/v0.1.1...v0.2.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
invoca-utils (0.
|
|
4
|
+
invoca-utils (0.3.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
activesupport (
|
|
10
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
9
|
+
activesupport (4.2.11.1)
|
|
11
10
|
i18n (~> 0.7)
|
|
12
11
|
minitest (~> 5.1)
|
|
12
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
|
13
13
|
tzinfo (~> 1.1)
|
|
14
14
|
ansi (1.5.0)
|
|
15
15
|
builder (3.2.4)
|
|
16
16
|
coderay (1.1.2)
|
|
17
|
-
concurrent-ruby (1.
|
|
17
|
+
concurrent-ruby (1.1.6)
|
|
18
18
|
hoe (3.22.1)
|
|
19
19
|
rake (>= 0.8, < 15.0)
|
|
20
|
-
i18n (0.9.
|
|
20
|
+
i18n (0.9.5)
|
|
21
21
|
concurrent-ruby (~> 1.0)
|
|
22
22
|
method_source (0.9.0)
|
|
23
|
-
minitest (5.
|
|
23
|
+
minitest (5.14.0)
|
|
24
24
|
minitest-reporters (1.1.14)
|
|
25
25
|
ansi
|
|
26
26
|
builder
|
|
@@ -42,13 +42,14 @@ GEM
|
|
|
42
42
|
test-unit (1.2.3)
|
|
43
43
|
hoe (>= 1.5.1)
|
|
44
44
|
thread_safe (0.3.6)
|
|
45
|
-
tzinfo (1.2.
|
|
45
|
+
tzinfo (1.2.7)
|
|
46
46
|
thread_safe (~> 0.1)
|
|
47
47
|
|
|
48
48
|
PLATFORMS
|
|
49
49
|
ruby
|
|
50
50
|
|
|
51
51
|
DEPENDENCIES
|
|
52
|
+
activesupport (~> 4.2)
|
|
52
53
|
invoca-utils!
|
|
53
54
|
minitest
|
|
54
55
|
minitest-reporters
|
data/lib/invoca/utils.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "invoca/utils/module"
|
|
3
4
|
require "invoca/utils/array"
|
|
4
5
|
require "invoca/utils/enumerable"
|
|
5
6
|
require "invoca/utils/diff"
|
|
7
|
+
require "invoca/utils/hash"
|
|
8
|
+
require "invoca/utils/hash_with_indifferent_access"
|
|
6
9
|
require "invoca/utils/http"
|
|
7
10
|
require "invoca/utils/map_compact"
|
|
8
11
|
require "invoca/utils/min_max"
|
data/lib/invoca/utils/array.rb
CHANGED
|
@@ -3,18 +3,16 @@
|
|
|
3
3
|
require_relative './multi_sender'
|
|
4
4
|
|
|
5
5
|
# Invoca ::Array extensions
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
# TODO: Once the hobo_support gem is no longer used by any of our code, use prepend instead of alias
|
|
7
|
+
class Array
|
|
8
|
+
|
|
9
|
+
alias_method :original_multiply_operator, :* # rubocop:disable Style/Alias
|
|
10
|
+
|
|
11
|
+
def *(rhs = nil)
|
|
12
|
+
if rhs
|
|
13
|
+
original_multiply_operator(rhs)
|
|
14
|
+
else
|
|
15
|
+
Invoca::Utils::MultiSender.new(self, :map)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
-
|
|
20
|
-
Array.prepend(Invoca::Utils::ArrayMultiply)
|
|
@@ -4,6 +4,21 @@ require_relative './multi_sender'
|
|
|
4
4
|
|
|
5
5
|
# Invoca ::Enumerable extensions
|
|
6
6
|
module Enumerable
|
|
7
|
+
def map_and_find(not_found = nil)
|
|
8
|
+
each do |x|
|
|
9
|
+
val = yield(x)
|
|
10
|
+
return val if val
|
|
11
|
+
end
|
|
12
|
+
not_found
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def map_with_index(res = [])
|
|
16
|
+
each_with_index do |x, i|
|
|
17
|
+
res << yield(x, i)
|
|
18
|
+
end
|
|
19
|
+
res
|
|
20
|
+
end
|
|
21
|
+
|
|
7
22
|
def build_hash(res = {})
|
|
8
23
|
each do |x|
|
|
9
24
|
pair = block_given? ? yield(x) : x
|
|
@@ -12,6 +27,14 @@ module Enumerable
|
|
|
12
27
|
res
|
|
13
28
|
end
|
|
14
29
|
|
|
30
|
+
def map_hash(res = {})
|
|
31
|
+
each do |x|
|
|
32
|
+
v = yield x
|
|
33
|
+
res[x] = v
|
|
34
|
+
end
|
|
35
|
+
res
|
|
36
|
+
end
|
|
37
|
+
|
|
15
38
|
def *
|
|
16
39
|
Invoca::Utils::MultiSender.new(self, :map)
|
|
17
40
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Invoca ::Hash extensions
|
|
4
|
+
class Hash
|
|
5
|
+
|
|
6
|
+
def select_hash(&block)
|
|
7
|
+
res = {}
|
|
8
|
+
each { |k, v| res[k] = v if (block.arity == 1 ? yield(v) : yield(k, v)) } # rubocop:disable Style/ParenthesesAroundCondition
|
|
9
|
+
res
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def map_hash(&block)
|
|
13
|
+
res = {}
|
|
14
|
+
each { |k, v| res[k] = block.arity == 1 ? yield(v) : yield(k, v) }
|
|
15
|
+
res
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def partition_hash(keys = nil)
|
|
19
|
+
yes = {}
|
|
20
|
+
no = {}
|
|
21
|
+
each do |k, v|
|
|
22
|
+
if block_given? ? yield(k, v) : keys.include?(k)
|
|
23
|
+
yes[k] = v
|
|
24
|
+
else
|
|
25
|
+
no[k] = v
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
[yes, no]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# rubocop:disable Naming/BinaryOperatorParameterName
|
|
32
|
+
def -(keys)
|
|
33
|
+
res = {}
|
|
34
|
+
each_pair { |k, v| res[k] = v unless k.in?(keys) }
|
|
35
|
+
res
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def &(keys)
|
|
39
|
+
res = {}
|
|
40
|
+
keys.each { |k| res[k] = self[k] if has_key?(k) }
|
|
41
|
+
res
|
|
42
|
+
end
|
|
43
|
+
# rubocop:enable Naming/BinaryOperatorParameterName
|
|
44
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Invoca ::HashWithIndifferentAccess extensions
|
|
4
|
+
if defined? HashWithIndifferentAccess
|
|
5
|
+
|
|
6
|
+
class HashWithIndifferentAccess
|
|
7
|
+
|
|
8
|
+
# rubocop:disable Naming/BinaryOperatorParameterName
|
|
9
|
+
def -(keys)
|
|
10
|
+
res = HashWithIndifferentAccess.new
|
|
11
|
+
keys = keys.map { |k| k.is_a?(Symbol) ? k.to_s : k }
|
|
12
|
+
each_pair { |k, v| res[k] = v unless k.in?(keys) }
|
|
13
|
+
res
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def &(keys)
|
|
17
|
+
res = HashWithIndifferentAccess.new
|
|
18
|
+
keys.each do |k|
|
|
19
|
+
k = k.to_s if k.is_a?(Symbol)
|
|
20
|
+
res[k] = self[k] if has_key?(k)
|
|
21
|
+
end
|
|
22
|
+
res
|
|
23
|
+
end
|
|
24
|
+
# rubocop:enable Naming/BinaryOperatorParameterName
|
|
25
|
+
|
|
26
|
+
def partition_hash(keys = nil)
|
|
27
|
+
keys = keys&.map { |k| k.is_a?(Symbol) ? k.to_s : k }
|
|
28
|
+
yes = HashWithIndifferentAccess.new
|
|
29
|
+
no = HashWithIndifferentAccess.new
|
|
30
|
+
each do |k, v|
|
|
31
|
+
if block_given? ? yield(k, v) : keys.include?(k)
|
|
32
|
+
yes[k] = v
|
|
33
|
+
else
|
|
34
|
+
no[k] = v
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
[yes, no]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Module
|
|
4
|
+
|
|
5
|
+
# Custom alias_method_chain that won't cause infinite recursion if called twice.
|
|
6
|
+
# NOTE: Calling alias_method_chain on alias_method_chain was just way too confusing, so I copied it :-/
|
|
7
|
+
def alias_method_chain(target, feature)
|
|
8
|
+
# Strip out punctuation on predicates, bang or writer methods since
|
|
9
|
+
# e.g. target?_without_feature is not a valid method name.
|
|
10
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 # rubocop:disable Style/PerlBackrefs
|
|
11
|
+
yield(aliased_target, punctuation) if block_given?
|
|
12
|
+
|
|
13
|
+
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
|
14
|
+
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
|
15
|
+
|
|
16
|
+
unless method_defined?(without_method)
|
|
17
|
+
alias_method without_method, target
|
|
18
|
+
alias_method target, with_method
|
|
19
|
+
|
|
20
|
+
if public_method_defined?(without_method)
|
|
21
|
+
public target
|
|
22
|
+
elsif protected_method_defined?(without_method)
|
|
23
|
+
protected target
|
|
24
|
+
elsif private_method_defined?(without_method)
|
|
25
|
+
private target
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/invoca/utils/version.rb
CHANGED
|
@@ -6,6 +6,44 @@ require_relative '../test_helper'
|
|
|
6
6
|
|
|
7
7
|
class EnumerableTest < Minitest::Test
|
|
8
8
|
|
|
9
|
+
context 'map_and_find' do
|
|
10
|
+
should 'return the mapped value of the first match' do
|
|
11
|
+
assert_equal('FOUND 3', [1, 2, 3, 4].map_and_find { |v| 'FOUND 3' if v == 3 })
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
should 'return the mapped value of the first match, even if there are multiple matches' do
|
|
15
|
+
assert_equal('FOUND 3', [1, 2, 3, 4].map_and_find { |v| "FOUND #{v}" if v > 2 })
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
should 'return the provided argument if the value is not found' do
|
|
19
|
+
assert_equal('NOT FOUND', [1, 2, 3, 4].map_and_find('NOT FOUND') { |v| "FOUND 6" if v == 6 })
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should 'return nil if the value is not found and no argument is provided' do
|
|
23
|
+
assert_nil([1, 2, 3, 4].map_and_find { |v| "FOUND 6" if v == 6 })
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'map_with_index' do
|
|
28
|
+
should 'call the block with the value and index' do
|
|
29
|
+
assert_equal([10, 21, 32, 43], [10, 20, 30, 40].map_with_index { |v, index| v + index })
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
should 'assumulate into the provided enumerable' do
|
|
33
|
+
assert_equal([1, 10, 21, 32, 43], [10, 20, 30, 40].map_with_index([1]) { |v, index| v + index })
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'map_hash' do
|
|
38
|
+
should 'convert enumerables into a hash using the value for key and the map result as the hash value' do
|
|
39
|
+
assert_equal({ 1 => 11, 2 => 12, 3 => 13 }, [1, 2, 3].map_hash { |v| v + 10 })
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
should 'includes nils returned from map' do
|
|
43
|
+
assert_equal({ 1 => 11, 2 => nil, 3 => 13 }, [1, 2, 3].map_hash { |v| v + 10 unless v == 2 })
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
9
47
|
context 'build_hash' do
|
|
10
48
|
should 'convert arrays of [key, value] to a hash of { key => value }' do
|
|
11
49
|
assert_equal({ 'some' => 4, 'short' => 5, 'words' => 5 }, ['some', 'short', 'words'].build_hash { |s| [s, s.length] })
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../lib/invoca/utils/hash.rb'
|
|
4
|
+
require_relative '../test_helper'
|
|
5
|
+
|
|
6
|
+
class HashTest < Minitest::Test
|
|
7
|
+
|
|
8
|
+
context 'select_hash' do
|
|
9
|
+
should 'return a hash containing key/values identified by the block' do
|
|
10
|
+
assert_equal({ 1 => 2, 3 => 4 }, { 1 => 2, 3 => 4, 6 => 5 }.select_hash { |key, value| key < value })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should 'handle blocks that only check values' do
|
|
14
|
+
assert_equal({ 3 => 4, 6 => 5 }, { 1 => 2, 3 => 4, 6 => 5 }.select_hash { |value| value != 2 })
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'map_hash' do
|
|
19
|
+
should 'return a hash containing values updated by the block' do
|
|
20
|
+
assert_equal({ 1 => true, 3 => true, 6 => false }, { 1 => 2, 3 => 4, 6 => 5 }.map_hash { |key, value| key < value })
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should 'handle blocks that only receive values' do
|
|
24
|
+
assert_equal({ 1 => 4, 3 => 8, 6 => 10 }, { 1 => 2, 3 => 4, 6 => 5 }.map_hash { |value| value * 2 })
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'partition_hash' do
|
|
29
|
+
should 'return two hashes, the first contains the pairs with matching keys, the second contains the rest' do
|
|
30
|
+
assert_equal([{ 1 => 2, 3 => 4 }, { 6 => 5 }], { 1 => 2, 3 => 4, 6 => 5 }.partition_hash([1, 3]))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should 'return two hashes, the first contains the pairs with identified by the block, the second contains the rest' do
|
|
34
|
+
assert_equal([{ 1 => 2, 3 => 4 }, { 6 => 5 }], { 1 => 2, 3 => 4, 6 => 5 }.partition_hash { |key, value| key < value })
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
should 'handle no matches' do
|
|
38
|
+
assert_equal([{}, { 1 => 2, 3 => 4, 6 => 5 }], { 1 => 2, 3 => 4, 6 => 5 }.partition_hash([100]))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
should 'handle all matches' do
|
|
42
|
+
assert_equal([{ 1 => 2, 3 => 4, 6 => 5 }, {}], { 1 => 2, 3 => 4, 6 => 5 }.partition_hash { |_key, _value| true })
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context '- operator' do
|
|
47
|
+
should 'return a hash with pairs removed that match the keys in rhs array' do
|
|
48
|
+
assert_equal({ 3 => 4 }, { 1 => 2, 3 => 4, 6 => 5 } - [1, 6])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
should 'handle empty rhs array' do
|
|
52
|
+
assert_equal({ 1 => 2, 3 => 4, 6 => 5 }, { 1 => 2, 3 => 4, 6 => 5 } - [])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should 'handle no matches in rhs array' do
|
|
56
|
+
assert_equal({ 1 => 2, 3 => 4, 6 => 5 }, { 1 => 2, 3 => 4, 6 => 5 } - [100, 600])
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
should 'handle all matches in rhs array' do
|
|
60
|
+
assert_equal({}, { 1 => 2, 3 => 4, 6 => 5 } - [1, 3, 6])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context '& operator' do
|
|
65
|
+
should 'return a hash with pairs removed that do NOT match the keys in rhs array' do
|
|
66
|
+
assert_equal({ 1 => 2, 6 => 5 }, { 1 => 2, 3 => 4, 6 => 5 } & [1, 6])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
should 'handle empty rhs array' do
|
|
70
|
+
assert_equal({}, { 1 => 2, 3 => 4, 6 => 5 } & [])
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
should 'handle no matches in rhs array' do
|
|
74
|
+
assert_equal({}, { 1 => 2, 3 => 4, 6 => 5 } & [100, 600])
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
should 'handle all matches in rhs array' do
|
|
78
|
+
assert_equal({ 1 => 2, 3 => 4, 6 => 5 }, { 1 => 2, 3 => 4, 6 => 5 } & [1, 3, 6])
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/hash_with_indifferent_access'
|
|
4
|
+
require_relative '../../lib/invoca/utils/hash_with_indifferent_access.rb'
|
|
5
|
+
require_relative '../test_helper'
|
|
6
|
+
|
|
7
|
+
class HashWithIndifferentAccessTest < Minitest::Test
|
|
8
|
+
|
|
9
|
+
context 'partition_hash' do
|
|
10
|
+
setup do
|
|
11
|
+
@hash_to_test = HashWithIndifferentAccess.new('one' => 2, :three => 4, 'six' => 5)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
should 'return two hashes, the first contains the pairs with matching keys, the second contains the rest' do
|
|
15
|
+
assert_equal([{ 'one' => 2, 'three' => 4 }, { 'six' => 5 }], @hash_to_test.partition_hash(['one', 'three']))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
should 'return two hashes, the first contains the pairs with identified by the block, the second contains the rest' do
|
|
19
|
+
assert_equal([{ 'one' => 2, 'three' => 4 }, { 'six' => 5 }], @hash_to_test.partition_hash { |key, _value| ['one', 'three'].include?(key) })
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should 'handle no matches' do
|
|
23
|
+
assert_equal([{}, @hash_to_test], @hash_to_test.partition_hash([:not_found]))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
should 'handle all matches' do
|
|
27
|
+
assert_equal([@hash_to_test, {}], @hash_to_test.partition_hash { |_key, _value| true })
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
should 'handle symbols for key matching' do
|
|
31
|
+
assert_equal([{ 'one' => 2, 'three' => 4 }, { 'six' => 5 }], @hash_to_test.partition_hash([:one, :three]))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should 'return HashWithIndifferentAccess objects' do
|
|
35
|
+
matched, unmatched = @hash_to_test.partition_hash([:one, :three])
|
|
36
|
+
assert(matched.is_a?(HashWithIndifferentAccess))
|
|
37
|
+
assert(unmatched.is_a?(HashWithIndifferentAccess))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context '- operator' do
|
|
42
|
+
setup do
|
|
43
|
+
@hash_to_test = HashWithIndifferentAccess.new('one' => 2, :three => 4, 'six' => 5)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
should 'return a hash with pairs removed that match the keys in rhs array' do
|
|
47
|
+
assert_equal({ 'three' => 4 }, @hash_to_test - ['one', 'six'])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
should 'handle empty rhs array' do
|
|
51
|
+
assert_equal(@hash_to_test, @hash_to_test - [])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
should 'handle no matches in rhs array' do
|
|
55
|
+
assert_equal(@hash_to_test, @hash_to_test - ['100', '600'])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
should 'handle all matches in rhs array' do
|
|
59
|
+
assert_equal({}, @hash_to_test - ['one', 'three', 'six'])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
should 'handle symbols for key matching' do
|
|
63
|
+
assert_equal({ 'six' => 5 }, @hash_to_test - [:one, :three])
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
should 'return HashWithIndifferentAccess object' do
|
|
67
|
+
assert((@hash_to_test - [:one, :three]).is_a?(HashWithIndifferentAccess))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context '& operator' do
|
|
72
|
+
setup do
|
|
73
|
+
@hash_to_test = HashWithIndifferentAccess.new('one' => 2, :three => 4, 'six' => 5)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
should 'return a hash with pairs removed that do NOT match the keys in rhs array' do
|
|
77
|
+
assert_equal({ 'one' => 2, 'six' => 5 }, @hash_to_test & ['one', 'six'])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
should 'handle empty rhs array' do
|
|
81
|
+
assert_equal({}, @hash_to_test & [])
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
should 'handle no matches in rhs array' do
|
|
85
|
+
assert_equal({}, @hash_to_test & ['100', '600'])
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
should 'handle all matches in rhs array' do
|
|
89
|
+
assert_equal(@hash_to_test, @hash_to_test & ['one', 'three', 'six'])
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
should 'handle symbols for key matching' do
|
|
93
|
+
assert_equal({ 'one' => 2, 'three' => 4 }, @hash_to_test & [:one, :three])
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
should 'return HashWithIndifferentAccess object' do
|
|
97
|
+
assert((@hash_to_test & [:one, :three]).is_a?(HashWithIndifferentAccess))
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# must require active_support's alias_method_chain first, to ensure that our module monkey patches it
|
|
4
|
+
require 'active_support/core_ext/module/aliasing'
|
|
5
|
+
require_relative '../../lib/invoca/utils/module.rb'
|
|
6
|
+
require_relative '../test_helper'
|
|
7
|
+
|
|
8
|
+
class ModuleTest < Minitest::Test
|
|
9
|
+
class NumberFun
|
|
10
|
+
def self.around_filter(around_method, method_names)
|
|
11
|
+
method_names.each do |meth|
|
|
12
|
+
define_method("#{meth}_with_around_filter") do |*args|
|
|
13
|
+
send(around_method, *args) do |*ar_args|
|
|
14
|
+
send("#{meth}_without_around_filter", *ar_args)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias_method_chain meth, :around_filter
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def increment_filter(num)
|
|
23
|
+
yield(num + 1)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def number_printer(num)
|
|
27
|
+
num
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
around_filter :increment_filter, [:number_printer]
|
|
31
|
+
around_filter :increment_filter, [:number_printer]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'alias_method_chain' do
|
|
35
|
+
should 'not cause infinite recursion when double aliasing the same method' do
|
|
36
|
+
assert_equal(4, NumberFun.new.number_printer(3))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: invoca-utils
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Invoca development
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-04-
|
|
11
|
+
date: 2020-04-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A public collection of helpers used in multiple projects
|
|
14
14
|
email:
|
|
@@ -34,9 +34,12 @@ files:
|
|
|
34
34
|
- lib/invoca/utils/diff.rb
|
|
35
35
|
- lib/invoca/utils/enumerable.rb
|
|
36
36
|
- lib/invoca/utils/guaranteed_utf8_string.rb
|
|
37
|
+
- lib/invoca/utils/hash.rb
|
|
38
|
+
- lib/invoca/utils/hash_with_indifferent_access.rb
|
|
37
39
|
- lib/invoca/utils/http.rb
|
|
38
40
|
- lib/invoca/utils/map_compact.rb
|
|
39
41
|
- lib/invoca/utils/min_max.rb
|
|
42
|
+
- lib/invoca/utils/module.rb
|
|
40
43
|
- lib/invoca/utils/multi_sender.rb
|
|
41
44
|
- lib/invoca/utils/stable_sort.rb
|
|
42
45
|
- lib/invoca/utils/time.rb
|
|
@@ -46,7 +49,10 @@ files:
|
|
|
46
49
|
- test/unit/array_test.rb
|
|
47
50
|
- test/unit/enumerable_test.rb
|
|
48
51
|
- test/unit/guaranteed_utf8_string_test.rb
|
|
52
|
+
- test/unit/hash_test.rb
|
|
53
|
+
- test/unit/hash_with_indifferent_access_test.rb
|
|
49
54
|
- test/unit/map_compact_test.rb
|
|
55
|
+
- test/unit/module_test.rb
|
|
50
56
|
- test/unit/multi_sender_test.rb
|
|
51
57
|
- test/unit/stable_sort_test.rb
|
|
52
58
|
- test/unit/time_calculations_test.rb
|
|
@@ -81,7 +87,10 @@ test_files:
|
|
|
81
87
|
- test/unit/array_test.rb
|
|
82
88
|
- test/unit/enumerable_test.rb
|
|
83
89
|
- test/unit/guaranteed_utf8_string_test.rb
|
|
90
|
+
- test/unit/hash_test.rb
|
|
91
|
+
- test/unit/hash_with_indifferent_access_test.rb
|
|
84
92
|
- test/unit/map_compact_test.rb
|
|
93
|
+
- test/unit/module_test.rb
|
|
85
94
|
- test/unit/multi_sender_test.rb
|
|
86
95
|
- test/unit/stable_sort_test.rb
|
|
87
96
|
- test/unit/time_calculations_test.rb
|