midwire_common 0.1.15 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- 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
|