transproc 0.4.2 → 1.0.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.
@@ -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
  {