midwire_common 0.1.15 → 0.1.16
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/.ruby-version +1 -1
- data/CHANGELOG +5 -0
- data/README.md +1 -1
- data/lib/midwire_common/hash.rb +17 -9
- data/lib/midwire_common/version.rb +1 -1
- data/midwire_common.gemspec +2 -0
- data/spec/lib/midwire_common/hash_spec.rb +67 -20
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3ea3a72051d5ddbd9d134ead5755a51d33e921
|
4
|
+
data.tar.gz: 888d58a8a4f03a580ed33026a27d71d6d5b86866
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fedc21d6d7bdec9e85588f54fb0b85498110cb4cf9d1745031f1ed119599e587c078bd559d26aeccd2c02be6152fb6ca2097110958e40772116eeb01f758812
|
7
|
+
data.tar.gz: 0d87037520b53b04b8f48000568196ff5c269053de77a77ef86b2690479a3a5019a7042a1118634c3f649091ae18a60f0c1a9aa99bce2e3a753c7ec590d40377
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.2.
|
1
|
+
2.2.2
|
data/CHANGELOG
CHANGED
data/README.md
CHANGED
data/lib/midwire_common/hash.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
|
+
class BottomlessHash < Hash
|
2
|
+
def initialize
|
3
|
+
super &-> h, k { h[k] = self.class.new }
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.from_hash(hash)
|
7
|
+
new.merge(hash)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
1
11
|
class Hash
|
2
|
-
|
12
|
+
def bottomless
|
13
|
+
BottomlessHash.from_hash(self)
|
14
|
+
end
|
15
|
+
|
3
16
|
def grep(pattern)
|
4
|
-
|
17
|
+
each_with_object([]) do |kv, res|
|
5
18
|
res << kv if kv[0] =~ pattern || kv[1] =~ pattern
|
6
19
|
res
|
7
20
|
end
|
8
21
|
end
|
9
|
-
# rubocop:enable Style/EachWithObject
|
10
22
|
|
11
|
-
# rubocop:disable Metrics/AbcSize, Style/EachWithObject
|
12
23
|
def diff(other)
|
13
|
-
(keys + other.keys).uniq.
|
24
|
+
(keys + other.keys).uniq.each_with_object({}) do |key, memo|
|
14
25
|
unless self[key] == other[key]
|
15
|
-
if self[key].is_a?(Hash) &&
|
26
|
+
if self[key].is_a?(Hash) && other[key].is_a?(Hash)
|
16
27
|
memo[key] = self[key].diff(other[key])
|
17
28
|
else
|
18
29
|
memo[key] = [self[key], other[key]]
|
@@ -21,7 +32,6 @@ class Hash
|
|
21
32
|
memo
|
22
33
|
end
|
23
34
|
end
|
24
|
-
# rubocop:enable Metrics/AbcSize, Style/EachWithObject
|
25
35
|
|
26
36
|
# TODO: Spec/Test this method
|
27
37
|
def apply_diff!(changes, direction = :right)
|
@@ -110,5 +120,3 @@ class Hash
|
|
110
120
|
self
|
111
121
|
end
|
112
122
|
end
|
113
|
-
|
114
|
-
# h = { :a => 1, :b => 2, :c => 3}
|
data/midwire_common.gemspec
CHANGED
@@ -1,39 +1,86 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
describe BottomlessHash do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
it 'does not raise on missing key' do
|
7
|
+
expect do
|
8
|
+
subject[:missing][:key]
|
9
|
+
end.to_not raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns an empty value on missing key' do
|
13
|
+
expect(subject[:missing][:key]).to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'stores and returns keys' do
|
17
|
+
subject[:existing][:key] = :value
|
18
|
+
expect(subject[:existing][:key]).to eq(:value)
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#from_hash' do
|
22
|
+
let(:hash) do
|
23
|
+
{ existing: { key: { value: :hello } } }
|
24
|
+
end
|
25
|
+
|
26
|
+
subject do
|
27
|
+
described_class.from_hash(hash)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns old hash values' do
|
31
|
+
expect(subject[:existing][:key][:value]).to eq(:hello)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'provides a bottomless version' do
|
35
|
+
expect(subject[:missing][:key]).to be_empty
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'stores and returns new values' do
|
39
|
+
subject[:existing][:key] = :value
|
40
|
+
expect(subject[:existing][:key]).to eq(:value)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'converts nested hashes as well' do
|
44
|
+
expect do
|
45
|
+
subject[:existing][:key][:missing]
|
46
|
+
end.to_not raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
4
51
|
describe Hash do
|
5
52
|
it 'greps key/value pairs using a regular expression' do
|
6
53
|
h = { a: 'this is a test', 'b' => 'this is not the answer' }
|
7
|
-
h.grep(/a test/).
|
8
|
-
h.grep(/b/).
|
9
|
-
|
10
|
-
|
11
|
-
]
|
54
|
+
expect(h.grep(/a test/)).to eq([[:a, 'this is a test']])
|
55
|
+
expect(h.grep(/b/)).to eq([['b', 'this is not the answer']])
|
56
|
+
expect(
|
57
|
+
h.grep(/^this/)
|
58
|
+
).to eq([[:a, 'this is a test'], ['b', 'this is not the answer']])
|
12
59
|
end
|
13
60
|
|
14
61
|
it 'returns elements with certain keys filtered out' do
|
15
|
-
{ a: 1, b: 2, c: 3 }.except(:a).
|
62
|
+
expect({ a: 1, b: 2, c: 3 }.except(:a)).to eq(b: 2, c: 3)
|
16
63
|
end
|
17
64
|
|
18
65
|
it 'returns elements for discretely passed keys' do
|
19
|
-
{ a: 1, b: 2, c: 3 }.only(:a).
|
66
|
+
expect({ a: 1, b: 2, c: 3 }.only(:a)).to eq(a: 1)
|
20
67
|
end
|
21
68
|
|
22
69
|
it 'pops an element off of the stack' do
|
23
70
|
h = { a: 1, b: 2, c: 3 }
|
24
|
-
h.pop(:a).
|
25
|
-
h.
|
71
|
+
expect(h.pop(:a)).to eq(a: 1)
|
72
|
+
expect(h).to eq(b: 2, c: 3)
|
26
73
|
end
|
27
74
|
|
28
75
|
it 'returns a query string' do
|
29
|
-
{ a: 1, b: 2, c: 3 }.to_query_string.
|
76
|
+
expect({ a: 1, b: 2, c: 3 }.to_query_string).to eq('a=1&b=2&c=3')
|
30
77
|
end
|
31
78
|
|
32
79
|
it 'symbolizes its keys' do
|
33
80
|
h = { 'a' => 1, 'b' => 2, 'c' => 3 }
|
34
|
-
h.symbolize_keys.
|
81
|
+
expect(h.symbolize_keys).to eq(a: 1, b: 2, c: 3)
|
35
82
|
h.symbolize_keys!
|
36
|
-
h.
|
83
|
+
expect(h).to eq(a: 1, b: 2, c: 3)
|
37
84
|
end
|
38
85
|
|
39
86
|
it 'recursively symbolizes its keys' do
|
@@ -50,9 +97,9 @@ describe Hash do
|
|
50
97
|
},
|
51
98
|
'c' => 3
|
52
99
|
}
|
53
|
-
h.recursively_symbolize_keys
|
100
|
+
expect(h.recursively_symbolize_keys!).to eq(
|
54
101
|
a: 1, b: { a: 1, b: 2, c: { a: 1, b: 2, c: 3 } }, c: 3
|
55
|
-
|
102
|
+
)
|
56
103
|
end
|
57
104
|
|
58
105
|
context 'diff methods' do
|
@@ -67,18 +114,18 @@ describe Hash do
|
|
67
114
|
|
68
115
|
context '.diff' do
|
69
116
|
it 'reports different keys' do
|
70
|
-
h1_keys.diff(h2_keys).
|
117
|
+
expect(h1_keys.diff(h2_keys)).to eq('c' => [3, nil], 'd' => [nil, 3])
|
71
118
|
end
|
72
119
|
|
73
120
|
it 'reports different values' do
|
74
|
-
h1_values.diff(h2_values).
|
121
|
+
expect(h1_values.diff(h2_values)).to eq('c' => [3, nil], 'c' => [3, 4])
|
75
122
|
end
|
76
123
|
|
77
124
|
it 'reports different keys even with nested hashes' do
|
78
|
-
h1_keys_nested.diff(h2_keys_nested).
|
79
|
-
{
|
125
|
+
expect(h1_keys_nested.diff(h2_keys_nested)).to eq(
|
126
|
+
{ 'x' => 99 } => [3, 4]
|
127
|
+
)
|
80
128
|
end
|
81
129
|
end
|
82
130
|
end
|
83
131
|
end
|
84
|
-
# rubocop:enable Lint/Void
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: midwire_common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Blackburn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0.28'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: thor
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.19'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.19'
|
139
153
|
description: A useful Ruby library for the Midwire development team
|
140
154
|
email:
|
141
155
|
- chris@midwiretech.com
|