invoca-utils 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|