transproc 0.4.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module Transproc
2
- VERSION = '0.4.2'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -17,7 +17,3 @@ end
17
17
 
18
18
  root = Pathname(__FILE__).dirname
19
19
  Dir[root.join('support/*.rb').to_s].each { |f| require f }
20
-
21
- RSpec.configure do |config|
22
- config.include(Transproc::Helper)
23
- end
@@ -7,45 +7,25 @@ describe Transproc::ArrayTransformations do
7
7
  it 'extracts values by key from all hashes' do
8
8
  extract_key = described_class.t(:extract_key, 'name')
9
9
 
10
- original = [
11
- { 'name' => 'Alice', 'role' => 'sender' },
12
- { 'name' => 'Bob', 'role' => 'receiver' },
13
- { 'role' => 'listener' }
14
- ]
15
-
16
- input = original
17
-
18
- output = ['Alice', 'Bob', nil]
19
-
20
- expect(extract_key[input]).to eql(output)
21
- expect(input).to eql(original)
22
- end
23
- end
24
-
25
- describe '.extract_key!' do
26
- it 'extracts values by key from all hashes' do
27
- extract_key = described_class.t(:extract_key!, 'name')
28
-
29
10
  input = [
30
11
  { 'name' => 'Alice', 'role' => 'sender' },
31
12
  { 'name' => 'Bob', 'role' => 'receiver' },
32
13
  { 'role' => 'listener' }
33
- ]
14
+ ].freeze
34
15
 
35
16
  output = ['Alice', 'Bob', nil]
36
17
 
37
18
  expect(extract_key[input]).to eql(output)
38
- expect(input).to eql(output)
39
19
  end
40
20
  end
41
21
 
22
+ it { expect(described_class).not_to be_contain(:extract_key!) }
23
+
42
24
  describe '.insert_key' do
43
25
  it 'wraps values to tuples with given key' do
44
26
  insert_key = described_class.t(:insert_key, 'name')
45
27
 
46
- original = ['Alice', 'Bob', nil]
47
-
48
- input = original
28
+ input = ['Alice', 'Bob', nil].freeze
49
29
 
50
30
  output = [
51
31
  { 'name' => 'Alice' },
@@ -54,36 +34,16 @@ describe Transproc::ArrayTransformations do
54
34
  ]
55
35
 
56
36
  expect(insert_key[input]).to eql(output)
57
- expect(input).to eql(original)
58
37
  end
59
38
  end
60
39
 
61
- describe '.insert_key!' do
62
- it 'wraps values to tuples with given key' do
63
- insert_key = described_class.t(:insert_key!, 'name')
64
-
65
- original = ['Alice', 'Bob', nil]
66
-
67
- input = original
68
-
69
- output = [
70
- { 'name' => 'Alice' },
71
- { 'name' => 'Bob' },
72
- { 'name' => nil }
73
- ]
74
-
75
- expect(insert_key[input]).to eql(output)
76
- expect(input).to eql(output)
77
- end
78
- end
40
+ it { expect(described_class).not_to be_contain(:insert_key!) }
79
41
 
80
42
  describe '.add_keys' do
81
43
  it 'returns a new array with missed keys added to tuples' do
82
44
  add_keys = described_class.t(:add_keys, [:foo, :bar, :baz])
83
45
 
84
- original = [{ foo: 'bar' }, { bar: 'baz' }]
85
-
86
- input = original
46
+ input = [{ foo: 'bar' }, { bar: 'baz' }].freeze
87
47
 
88
48
  output = [
89
49
  { foo: 'bar', bar: nil, baz: nil },
@@ -91,38 +51,19 @@ describe Transproc::ArrayTransformations do
91
51
  ]
92
52
 
93
53
  expect(add_keys[input]).to eql(output)
94
- expect(input).to eql(original)
95
54
  end
96
55
  end
97
56
 
98
- describe '.add_keys!' do
99
- it 'adds missed keys to tuples' do
100
- add_keys = described_class.t(:add_keys!, [:foo, :bar, :baz])
101
-
102
- original = [{ foo: 'bar' }, { bar: 'baz' }]
103
-
104
- input = original
105
-
106
- output = [
107
- { foo: 'bar', bar: nil, baz: nil },
108
- { foo: nil, bar: 'baz', baz: nil }
109
- ]
110
-
111
- expect(add_keys[input]).to eql(output)
112
- expect(input).to eql(output)
113
- end
114
- end
57
+ it { expect(described_class).not_to be_contain(:add_keys!) }
115
58
 
116
59
  describe '.map_array' do
117
60
  it 'applies funtions to all values' do
118
61
  map = described_class.t(:map_array, hashes[:symbolize_keys])
119
62
 
120
- original = [
121
- { 'name' => 'Jane', 'title' => 'One' },
122
- { 'name' => 'Jane', 'title' => 'Two' }
123
- ]
124
-
125
- input = original
63
+ input = [
64
+ { 'name' => 'Jane', 'title' => 'One' }.freeze,
65
+ { 'name' => 'Jane', 'title' => 'Two' }.freeze
66
+ ].freeze
126
67
 
127
68
  output = [
128
69
  { name: 'Jane', title: 'One' },
@@ -130,38 +71,25 @@ describe Transproc::ArrayTransformations do
130
71
  ]
131
72
 
132
73
  expect(map[input]).to eql(output)
133
- expect(input).to eql(original)
134
74
  end
135
75
 
136
76
  it 'handles huge arrays' do
137
77
  map = described_class.t(:map_array, hashes[:symbolize_keys])
138
78
 
139
- input = 138706.times.map { |i| { 'key' => i } }
79
+ input = Array.new(138_706) { |i| { 'key' => i } }
140
80
 
141
- expect { map[input] }.to_not raise_error(SystemStackError, /stack level too deep/)
81
+ expect { map[input] }.to_not raise_error
142
82
  end
143
- end
144
-
145
- describe '.map_array!' do
146
- it 'updates array with the result of the function applied to each value' do
147
- map = described_class.t(:map_array!, hashes[:symbolize_keys])
148
-
149
- input = [
150
- { 'name' => 'Jane', 'title' => 'One' },
151
- { 'name' => 'Jane', 'title' => 'Two' }
152
- ]
153
83
 
154
- output = [
155
- { name: 'Jane', title: 'One' },
156
- { name: 'Jane', title: 'Two' }
157
- ]
158
-
159
- map[input]
84
+ it 'handles flat value arrays' do
85
+ map = described_class.t(:map_array, :upcase.to_proc)
160
86
 
161
- expect(input).to eql(output)
87
+ expect(map['foo']).to eql(%w(FOO))
162
88
  end
163
89
  end
164
90
 
91
+ it { expect(described_class).not_to be_contain(:map_array!) }
92
+
165
93
  describe '.wrap' do
166
94
  it 'returns a new array with wrapped hashes' do
167
95
  wrap = described_class.t(:wrap, :task, [:title])
@@ -1,15 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  describe Transproc::FunctionNotFoundError do
4
- it 'complains that the function not registered globally' do
5
- expect { Transproc(:foo) }.to raise_error do |error|
6
- expect(error).to be_kind_of described_class
7
- expect(error.message['foo']).not_to be_nil
8
- expect(error.message['global']).not_to be_nil
9
- end
10
- end
11
-
12
- it 'complains that the function not registered locally' do
4
+ it 'complains that the function not registered' do
13
5
  Foo = Module.new { extend Transproc::Registry }
14
6
 
15
7
  expect { Foo[:foo] }.to raise_error do |error|
@@ -1,13 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Transproc::Function do
4
- let(:hashes) { Transproc::HashTransformations }
4
+ let(:container) do
5
+ Module.new do
6
+ extend Transproc::Registry
7
+
8
+ import Transproc::HashTransformations
9
+ end
10
+ end
5
11
 
6
12
  describe '#name' do
7
13
  let(:block) { proc { |v| v } }
8
14
 
9
15
  it 'returns the name of the module function' do
10
- expect(hashes[:symbolize_keys].name).to eql :symbolize_keys
16
+ expect(container[:symbolize_keys].name).to eql :symbolize_keys
11
17
  end
12
18
 
13
19
  it 'returns the explicitly assigned name' do
@@ -21,8 +27,8 @@ describe Transproc::Function do
21
27
 
22
28
  describe '#>>' do
23
29
  it 'composes named functions' do
24
- f1 = hashes[:symbolize_keys]
25
- f2 = hashes[:rename_keys, user_name: :name]
30
+ f1 = container[:symbolize_keys]
31
+ f2 = container[:rename_keys, user_name: :name]
26
32
 
27
33
  f3 = f1 >> f2
28
34
 
@@ -37,7 +43,7 @@ describe Transproc::Function do
37
43
 
38
44
  expect(f3['user_name' => 'Jane']).to eql(name: 'Jane')
39
45
 
40
- f4 = f3 >> hashes[:nest, :details, [:name]]
46
+ f4 = f3 >> container[:nest, :details, [:name]]
41
47
 
42
48
  expect(f4.to_ast).to eql(
43
49
  [
@@ -55,9 +61,8 @@ describe Transproc::Function do
55
61
  end
56
62
 
57
63
  it 'composes anonymous functions' do
58
- # TODO: Use Transproc -> (v) { v.to_s } after release of jruby-9k
59
- f1 = Transproc proc { |v, m| v * m }, 2
60
- f2 = Transproc proc(&:to_s)
64
+ f1 = container[->(v, m) { v * m }, 2]
65
+ f2 = container[:to_s.to_proc]
61
66
 
62
67
  f3 = f1 >> f2
63
68
 
@@ -72,8 +77,8 @@ describe Transproc::Function do
72
77
  end
73
78
 
74
79
  it 'plays well with registered compositions' do
75
- Transproc.register(:user_names, hashes[:symbolize_keys] + hashes[:rename_keys, user_name: :name])
76
- f = t(:user_names)
80
+ container.register(:user_names, container[:symbolize_keys] + container[:rename_keys, user_name: :name])
81
+ f = container[:user_names]
77
82
 
78
83
  expect(f['user_name' => 'Jane']).to eql(name: 'Jane')
79
84
  expect(f.to_ast).to eql(
@@ -87,8 +92,8 @@ describe Transproc::Function do
87
92
  end
88
93
 
89
94
  it 'plays well with registered functions' do
90
- Transproc.register(:to_s, t(:to_string))
91
- fn = t(:to_s)
95
+ container.register(:to_string, Transproc::Coercions.t(:to_string))
96
+ fn = container.t(:to_string)
92
97
 
93
98
  expect(fn[:ok]).to eql('ok')
94
99
  expect(fn.to_ast).to eql([:to_string, []])
@@ -1,40 +1,27 @@
1
1
  require 'spec_helper'
2
- require 'transproc/rspec'
3
2
 
4
3
  describe Transproc::HashTransformations do
5
4
  describe '.map_keys' do
6
5
  it 'returns a new hash with given proc applied to keys' do
7
6
  map_keys = described_class.t(:map_keys, ->(key) { key.strip })
8
7
 
9
- input = { ' foo ' => 'bar' }
8
+ input = { ' foo ' => 'bar' }.freeze
10
9
  output = { 'foo' => 'bar' }
11
10
 
12
11
  expect(map_keys[input]).to eql(output)
13
- expect(input).to eql(' foo ' => 'bar')
14
12
  end
15
13
  end
16
14
 
17
- describe '.map_keys!' do
18
- it 'returns updated hash with given proc applied to keys' do
19
- map_keys = described_class.t(:map_keys!, ->(key) { key.strip })
20
-
21
- input = { ' foo ' => 'bar' }
22
- output = { 'foo' => 'bar' }
23
-
24
- expect(map_keys[input]).to eql(output)
25
- expect(input).to eql('foo' => 'bar')
26
- end
27
- end
15
+ it { expect(described_class).not_to be_contain(:map_keys!) }
28
16
 
29
17
  describe '.symbolize_keys' do
30
18
  it 'returns a new hash with symbolized keys' do
31
19
  symbolize_keys = described_class.t(:symbolize_keys)
32
20
 
33
- input = { 1 => 'bar' }
21
+ input = { 1 => 'bar' }.freeze
34
22
  output = { '1'.to_sym => 'bar' }
35
23
 
36
24
  expect(symbolize_keys[input]).to eql(output)
37
- expect { symbolize_keys[input] }.not_to change { input }
38
25
  end
39
26
  end
40
27
 
@@ -50,111 +37,65 @@ describe Transproc::HashTransformations do
50
37
  end
51
38
  end
52
39
 
53
- describe '.symbolize_keys!' do
54
- it 'returns updated hash with symbolized keys' do
55
- symbolize_keys = described_class.t(:symbolize_keys!)
56
-
57
- input = { 'foo' => 'bar' }
58
- output = { foo: 'bar' }
59
-
60
- symbolize_keys[input]
61
-
62
- expect(input).to eql(output)
63
- end
64
- end
40
+ it { expect(described_class).not_to be_contain(:symbolize_keys!) }
65
41
 
66
42
  describe '.stringify_keys' do
67
43
  it 'returns a new hash with stringified keys' do
68
44
  stringify_keys = described_class.t(:stringify_keys)
69
45
 
70
- input = { foo: 'bar' }
46
+ input = { foo: 'bar' }.freeze
71
47
  output = { 'foo' => 'bar' }
72
48
 
73
49
  expect(stringify_keys[input]).to eql(output)
74
- expect(input).to eql(foo: 'bar')
75
50
  end
76
51
  end
77
52
 
78
- describe '.stringify_keys!' do
79
- it 'returns a new hash with stringified keys' do
80
- stringify_keys = described_class.t(:stringify_keys!)
81
-
82
- input = { foo: 'bar' }
83
- output = { 'foo' => 'bar' }
84
-
85
- expect(stringify_keys[input]).to eql(output)
86
- expect(input).to eql('foo' => 'bar')
87
- end
88
- end
53
+ it { expect(described_class).not_to be_contain(:stringify_keys!) }
89
54
 
90
55
  describe '.map_values' do
91
56
  it 'returns a new hash with given proc applied to values' do
92
57
  map_values = described_class.t(:map_values, ->(value) { value.strip })
93
58
 
94
- input = { 'foo' => ' bar ' }
59
+ input = { 'foo' => ' bar ' }.freeze
95
60
  output = { 'foo' => 'bar' }
96
61
 
97
62
  expect(map_values[input]).to eql(output)
98
- expect(input).to eql('foo' => ' bar ')
99
63
  end
100
64
  end
101
65
 
102
- describe '.map_values!' do
103
- it 'returns updated hash with given proc applied to values' do
104
- map_values = described_class.t(:map_values!, ->(value) { value.strip })
105
-
106
- input = { 'foo' => ' bar ' }
107
- output = { 'foo' => 'bar' }
108
-
109
- expect(map_values[input]).to eql(output)
110
- expect(input).to eql('foo' => 'bar')
111
- end
112
- end
66
+ it { expect(described_class).not_to be_contain(:map_values!) }
113
67
 
114
68
  describe '.rename_keys' do
115
69
  it 'returns a new hash with applied functions' do
116
70
  map = described_class.t(:rename_keys, 'foo' => :foo)
117
71
 
118
- input = { 'foo' => 'bar', :bar => 'baz' }
72
+ input = { 'foo' => 'bar', :bar => 'baz' }.freeze
119
73
  output = { foo: 'bar', bar: 'baz' }
120
74
 
121
75
  expect(map[input]).to eql(output)
122
- expect(input).to eql('foo' => 'bar', :bar => 'baz')
123
76
  end
124
77
 
125
- it "only renames keys and never creates new ones" do
78
+ it 'only renames keys and never creates new ones' do
126
79
  map = described_class.t(:rename_keys, 'foo' => :foo, 'bar' => :bar)
127
80
 
128
- input = { 'bar' => 'baz' }
81
+ input = { 'bar' => 'baz' }.freeze
129
82
  output = { bar: 'baz' }
130
83
 
131
84
  expect(map[input]).to eql(output)
132
- expect(input).to eql('bar' => 'baz')
133
85
  end
134
86
  end
135
87
 
136
- describe '.rename_keys!' do
137
- it 'returns updated hash with applied functions' do
138
- map = described_class.t(:rename_keys!, 'foo' => :foo)
88
+ it { expect(described_class).not_to be_contain(:rename_keys!) }
139
89
 
140
- input = { 'foo' => 'bar', :bar => 'baz' }
141
- output = { foo: 'bar', bar: 'baz' }
142
-
143
- map[input]
144
-
145
- expect(input).to eql(output)
146
- end
147
- end
148
90
  describe '.copy_keys' do
149
91
  context 'with single destination key' do
150
92
  it 'returns a new hash with applied functions' do
151
93
  map = described_class.t(:copy_keys, 'foo' => :foo)
152
94
 
153
- input = { 'foo' => 'bar', :bar => 'baz' }
95
+ input = { 'foo' => 'bar', :bar => 'baz' }.freeze
154
96
  output = { 'foo' => 'bar', foo: 'bar', bar: 'baz' }
155
97
 
156
98
  expect(map[input]).to eql(output)
157
- expect(input).to eql('foo' => 'bar', :bar => 'baz')
158
99
  end
159
100
  end
160
101
 
@@ -162,202 +103,127 @@ describe Transproc::HashTransformations do
162
103
  it 'returns a new hash with applied functions' do
163
104
  map = described_class.t(:copy_keys, 'foo' => [:foo, :baz])
164
105
 
165
- input = { 'foo' => 'bar', :bar => 'baz' }
106
+ input = { 'foo' => 'bar', :bar => 'baz' }.freeze
166
107
  output = { 'foo' => 'bar', foo: 'bar', baz: 'bar', bar: 'baz' }
167
108
 
168
109
  expect(map[input]).to eql(output)
169
- expect(input).to eql('foo' => 'bar', :bar => 'baz')
170
110
  end
171
111
  end
172
112
  end
173
113
 
174
- describe '.copy_keys!' do
175
- context 'with single destination key' do
176
- it 'returns updated hash with applied functions' do
177
- map = described_class.t(:copy_keys!, 'foo' => :foo)
178
-
179
- input = { 'foo' => 'bar', :bar => 'baz' }
180
- output = { 'foo' => 'bar', foo: 'bar', bar: 'baz' }
181
-
182
- map[input]
183
-
184
- expect(input).to eql(output)
185
- end
186
- end
187
-
188
- context 'with multiple destination keys' do
189
- it 'returns updated hash with applied functions' do
190
- map = described_class.t(:copy_keys!, 'foo' => [:foo, :baz])
191
-
192
- input = { 'foo' => 'bar', :bar => 'baz' }
193
- output = { 'foo' => 'bar', foo: 'bar', baz: 'bar', bar: 'baz' }
194
-
195
- map[input]
196
-
197
- expect(input).to eql(output)
198
- end
199
- end
200
- end
114
+ it { expect(described_class).not_to be_contain(:copy_keys!) }
201
115
 
202
116
  describe '.map_value' do
203
117
  it 'applies function to value under specified key' do
204
118
  transformation =
205
119
  described_class.t(:map_value, :user, described_class.t(:symbolize_keys))
206
120
 
207
- input = { user: { 'name' => 'Jane' } }
121
+ input = { user: { 'name' => 'Jane' }.freeze }.freeze
208
122
  output = { user: { name: 'Jane' } }
209
123
 
210
124
  expect(transformation[input]).to eql(output)
211
- expect(input).to eql(user: { 'name' => 'Jane' })
212
125
  end
213
126
  end
214
127
 
215
- describe '.map_value!' do
216
- it 'applies function to value under specified key' do
217
- transformation =
218
- described_class
219
- .t(:map_value!, :user, described_class.t(:symbolize_keys))
220
-
221
- input = { user: { 'name' => 'Jane' } }
222
- output = { user: { name: 'Jane' } }
223
-
224
- transformation[input]
225
-
226
- expect(input).to eql(output)
227
- end
228
- end
128
+ it { expect(described_class).not_to be_contain(:map_value!) }
229
129
 
230
130
  describe '.nest' do
231
131
  it 'returns new hash with keys nested under a new key' do
232
132
  nest = described_class.t(:nest, :baz, ['foo'])
233
133
 
234
- input = { 'foo' => 'bar' }
134
+ input = { 'foo' => 'bar' }.freeze
235
135
  output = { baz: { 'foo' => 'bar' } }
236
136
 
237
137
  expect(nest[input]).to eql(output)
238
- expect(input).to eql('foo' => 'bar')
239
- end
240
- end
241
-
242
- describe '.nest!' do
243
- it 'returns new hash with keys nested under a new key' do
244
- nest = described_class.t(:nest!, :baz, %w(one two not-here))
245
-
246
- input = { 'foo' => 'bar', 'one' => nil, 'two' => false }
247
- output = { 'foo' => 'bar', baz: { 'one' => nil, 'two' => false } }
248
-
249
- nest[input]
250
-
251
- expect(input).to eql(output)
252
138
  end
253
139
 
254
140
  it 'returns new hash with keys nested under the existing key' do
255
- nest = described_class.t(:nest!, :baz, ['two'])
141
+ nest = described_class.t(:nest, :baz, ['two'])
256
142
 
257
- input = { 'foo' => 'bar', baz: { 'one' => nil }, 'two' => false }
258
- output = { 'foo' => 'bar', baz: { 'one' => nil, 'two' => false } }
143
+ input = {
144
+ 'foo' => 'bar',
145
+ baz: { 'one' => nil }.freeze,
146
+ 'two' => false
147
+ }.freeze
259
148
 
260
- nest[input]
149
+ output = { 'foo' => 'bar', baz: { 'one' => nil, 'two' => false } }
261
150
 
262
- expect(input).to eql(output)
151
+ expect(nest[input]).to eql(output)
263
152
  end
264
153
 
265
154
  it 'rewrites the existing key if its value is not a hash' do
266
- nest = described_class.t(:nest!, :baz, ['two'])
155
+ nest = described_class.t(:nest, :baz, ['two'])
267
156
 
268
- input = { 'foo' => 'bar', baz: 'one', 'two' => false }
157
+ input = { 'foo' => 'bar', baz: 'one', 'two' => false }.freeze
269
158
  output = { 'foo' => 'bar', baz: { 'two' => false } }
270
159
 
271
- nest[input]
272
-
273
- expect(input).to eql(output)
160
+ expect(nest[input]).to eql(output)
274
161
  end
275
162
 
276
163
  it 'returns new hash with an empty hash under a new key when nest-keys are missing' do
277
- nest = described_class.t(:nest!, :baz, ['foo'])
164
+ nest = described_class.t(:nest, :baz, ['foo'])
278
165
 
279
- input = { 'bar' => 'foo' }
166
+ input = { 'bar' => 'foo' }.freeze
280
167
  output = { 'bar' => 'foo', baz: {} }
281
168
 
282
- nest[input]
283
-
284
- expect(input).to eql(output)
169
+ expect(nest[input]).to eql(output)
285
170
  end
286
171
  end
287
172
 
288
- describe '.unwrap!' do
289
- it 'returns updated hash with nested keys lifted to the root' do
290
- unwrap = described_class.t(:unwrap!, 'wrapped', %w(one))
173
+ it { expect(described_class).not_to be_contain(:nest!) }
291
174
 
292
- input = { 'foo' => 'bar', 'wrapped' => { 'one' => nil, 'two' => false } }
293
- output = { 'foo' => 'bar', 'one' => nil, 'wrapped' => { 'two' => false } }
175
+ describe '.unwrap' do
176
+ it 'returns new hash with nested keys lifted to the root' do
177
+ unwrap = described_class.t(:unwrap, 'wrapped', %w(one))
178
+
179
+ input = {
180
+ 'foo' => 'bar',
181
+ 'wrapped' => { 'one' => nil, 'two' => false }.freeze
182
+ }.freeze
294
183
 
295
- unwrap[input]
184
+ output = { 'foo' => 'bar', 'one' => nil, 'wrapped' => { 'two' => false } }
296
185
 
297
- expect(input).to eql(output)
186
+ expect(unwrap[input]).to eql(output)
298
187
  end
299
188
 
300
189
  it 'lifts all keys if none are passed' do
301
- unwrap = described_class.t(:unwrap!, 'wrapped')
190
+ unwrap = described_class.t(:unwrap, 'wrapped')
302
191
 
303
- input = { 'wrapped' => { 'one' => nil, 'two' => false } }
192
+ input = { 'wrapped' => { 'one' => nil, 'two' => false }.freeze }.freeze
304
193
  output = { 'one' => nil, 'two' => false }
305
194
 
306
- unwrap[input]
307
-
308
- expect(input).to eql(output)
195
+ expect(unwrap[input]).to eql(output)
309
196
  end
310
197
 
311
198
  it 'ignores unknown keys' do
312
- unwrap = described_class.t(:unwrap!, 'wrapped', %w(one two three))
199
+ unwrap = described_class.t(:unwrap, 'wrapped', %w(one two three))
313
200
 
314
- input = { 'wrapped' => { 'one' => nil, 'two' => false } }
201
+ input = { 'wrapped' => { 'one' => nil, 'two' => false }.freeze }.freeze
315
202
  output = { 'one' => nil, 'two' => false }
316
203
 
317
- unwrap[input]
318
-
319
- expect(input).to eql(output)
204
+ expect(unwrap[input]).to eql(output)
320
205
  end
321
206
 
322
207
  it 'prefixes unwrapped keys and retains root string type if prefix option is truthy' do
323
- unwrap = described_class.t(:unwrap!, 'wrapped', prefix: true)
208
+ unwrap = described_class.t(:unwrap, 'wrapped', prefix: true)
324
209
 
325
- input = { 'wrapped' => { one: nil, two: false } }
210
+ input = { 'wrapped' => { one: nil, two: false }.freeze }.freeze
326
211
  output = { 'wrapped_one' => nil, 'wrapped_two' => false }
327
212
 
328
- unwrap[input]
329
-
330
- expect(input).to eql(output)
213
+ expect(unwrap[input]).to eql(output)
331
214
  end
332
215
 
333
216
  it 'prefixes unwrapped keys and retains root type if prefix option is truthy' do
334
- unwrap = described_class.t(:unwrap!, :wrapped, prefix: true)
217
+ unwrap = described_class.t(:unwrap, :wrapped, prefix: true)
335
218
 
336
- input = { wrapped: { 'one' => nil, 'two' => false } }
219
+ input = { wrapped: { 'one' => nil, 'two' => false }.freeze }.freeze
337
220
  output = { wrapped_one: nil, wrapped_two: false }
338
221
 
339
- unwrap[input]
340
-
341
- expect(input).to eql(output)
222
+ expect(unwrap[input]).to eql(output)
342
223
  end
343
224
  end
344
225
 
345
- describe '.unwrap' do
346
- it 'returns new hash with nested keys lifted to the root' do
347
- unwrap = described_class.t(:unwrap, 'wrapped')
348
-
349
- input = {
350
- 'foo' => 'bar',
351
- 'wrapped' => { 'one' => nil, 'two' => false }
352
- }.freeze
353
-
354
- expect(unwrap[input]).to eql(
355
- 'foo' => 'bar',
356
- 'one' => nil,
357
- 'two' => false
358
- )
359
- end
360
- end
226
+ it { expect(described_class).not_to be_contain(:unwrap!) }
361
227
 
362
228
  describe 'nested transform' do
363
229
  it 'applies functions to nested hashes' do
@@ -389,90 +255,62 @@ describe Transproc::HashTransformations do
389
255
  end
390
256
  end
391
257
 
392
- describe '.reject_keys!' do
393
- it 'returns an updated hash with rejected keys' do
394
- reject_keys = described_class.t(:reject_keys, [:name, :age])
395
-
396
- input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
397
- output = { email: 'jane@doe.org' }
398
-
399
- expect(reject_keys[input]).to eql(output)
400
- end
401
- end
402
-
403
258
  describe '.reject_keys' do
404
259
  it 'returns a new hash with rejected keys' do
405
260
  reject_keys = described_class.t(:reject_keys, [:name, :age])
406
261
 
407
- input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
262
+ input = { name: 'Jane', email: 'jane@doe.org', age: 21 }.freeze
408
263
  output = { email: 'jane@doe.org' }
409
264
 
410
265
  expect(reject_keys[input]).to eql(output)
411
- expect(input).to eql(name: 'Jane', email: 'jane@doe.org', age: 21)
412
266
  end
413
267
  end
414
268
 
415
- describe '.accept_keys!' do
416
- it 'returns an updated hash with accepted keys' do
417
- accept_keys = described_class.t(:accept_keys, [:age])
418
-
419
- input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
420
- output = { age: 21 }
421
-
422
- expect(accept_keys[input]).to eql(output)
423
- end
424
- end
269
+ it { expect(described_class).not_to be_contain(:reject_keys!) }
425
270
 
426
- describe '.reject_keys' do
271
+ describe '.accept_keys' do
427
272
  it 'returns a new hash with rejected keys' do
428
273
  accept_keys = described_class.t(:accept_keys, [:age])
429
274
 
430
- input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
275
+ input = { name: 'Jane', email: 'jane@doe.org', age: 21 }.freeze
431
276
  output = { age: 21 }
432
277
 
433
278
  expect(accept_keys[input]).to eql(output)
434
- expect(input).to eql(name: 'Jane', email: 'jane@doe.org', age: 21)
435
279
  end
436
280
  end
437
281
 
282
+ it { expect(described_class).not_to be_contain(:accept_keys!) }
283
+
438
284
  describe '.fold' do
439
285
  let(:input) do
440
286
  {
441
287
  name: 'Jane',
442
- tasks: [{ title: 'be nice', priority: 1 }, { title: 'sleep well' }]
443
- }
288
+ tasks: [
289
+ { title: 'be nice', priority: 1 }.freeze,
290
+ { title: 'sleep well' }.freeze
291
+ ].freeze
292
+ }.freeze
444
293
  end
445
294
 
446
- it_behaves_like :transforming_immutable_data do
447
- let(:arguments) { [:fold, :tasks, :title] }
448
- let(:output) { { name: 'Jane', tasks: ['be nice', 'sleep well'] } }
449
- end
295
+ it 'returns a new hash with folded values' do
296
+ fold = described_class.t(:fold, :tasks, :title)
450
297
 
451
- it_behaves_like :transforming_immutable_data do
452
- let(:arguments) { [:fold, :tasks, :priority] }
453
- let(:output) { { name: 'Jane', tasks: [1, nil] } }
454
- end
455
- end
298
+ output = { name: 'Jane', tasks: ['be nice', 'sleep well'] }
456
299
 
457
- describe '.fold!' do
458
- let(:input) do
459
- {
460
- name: 'Jane',
461
- tasks: [{ title: 'be nice', priority: 1 }, { title: 'sleep well' }]
462
- }
300
+ expect(fold[input]).to eql(output)
463
301
  end
464
302
 
465
- it_behaves_like :mutating_input_data do
466
- let(:arguments) { [:fold!, :tasks, :title] }
467
- let(:output) { { name: 'Jane', tasks: ['be nice', 'sleep well'] } }
468
- end
303
+ it 'uses nil if there was not such attribute' do
304
+ fold = described_class.t(:fold, :tasks, :priority)
469
305
 
470
- it_behaves_like :mutating_input_data do
471
- let(:arguments) { [:fold!, :tasks, :priority] }
472
- let(:output) { { name: 'Jane', tasks: [1, nil] } }
306
+ output = { name: 'Jane', tasks: [1, nil] }
307
+
308
+ expect(fold[input]).to eql(output)
473
309
  end
474
310
  end
475
311
 
312
+ it { expect(described_class).not_to be_contain(:fold!) }
313
+
476
314
  describe '.split' do
477
315
  let(:input) do
478
316
  {