transproc 0.2.4 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +33 -15
- data/lib/transproc.rb +23 -14
- data/lib/transproc/array.rb +21 -15
- data/lib/transproc/class.rb +7 -3
- data/lib/transproc/coercions.rb +15 -11
- data/lib/transproc/composer.rb +26 -2
- data/lib/transproc/conditional.rb +7 -3
- data/lib/transproc/error.rb +7 -1
- data/lib/transproc/function.rb +28 -5
- data/lib/transproc/functions.rb +5 -0
- data/lib/transproc/hash.rb +102 -26
- data/lib/transproc/recursion.rb +11 -7
- data/lib/transproc/registry.rb +53 -55
- data/lib/transproc/rspec.rb +59 -0
- data/lib/transproc/store.rb +94 -0
- data/lib/transproc/support/deprecations.rb +11 -0
- data/lib/transproc/version.rb +1 -1
- data/spec/unit/array_transformations_spec.rb +29 -25
- data/spec/unit/class_transformations_spec.rb +2 -2
- data/spec/unit/coercions_spec.rb +13 -13
- data/spec/unit/composer_spec.rb +13 -2
- data/spec/unit/conditional_spec.rb +3 -1
- data/spec/unit/function_not_found_error_spec.rb +20 -0
- data/spec/unit/function_spec.rb +49 -8
- data/spec/unit/hash_transformations_spec.rb +101 -63
- data/spec/unit/recursion_spec.rb +12 -6
- data/spec/unit/registry_spec.rb +65 -55
- data/spec/unit/store_spec.rb +148 -0
- data/spec/unit/transproc_spec.rb +8 -0
- metadata +9 -2
@@ -7,7 +7,7 @@ describe Transproc::ClassTransformations do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'returns a new object initialized with the given arguments' do
|
10
|
-
constructor_inject = t(:constructor_inject, klass)
|
10
|
+
constructor_inject = described_class.t(:constructor_inject, klass)
|
11
11
|
|
12
12
|
input = ['Jane', 25]
|
13
13
|
output = klass.new(*input)
|
@@ -33,7 +33,7 @@ describe Transproc::ClassTransformations do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'allocates a new object and sets instance variables from hash key/value pairs' do
|
36
|
-
set_ivars = t(:set_ivars, klass)
|
36
|
+
set_ivars = described_class.t(:set_ivars, klass)
|
37
37
|
|
38
38
|
input = { name: 'Jane', age: 25 }
|
39
39
|
output = klass.new(input)
|
data/spec/unit/coercions_spec.rb
CHANGED
@@ -3,69 +3,69 @@ require 'spec_helper'
|
|
3
3
|
describe Transproc::Coercions do
|
4
4
|
describe '.to_string' do
|
5
5
|
it 'turns integer into a string' do
|
6
|
-
expect(t(:to_string)[1]).to eql('1')
|
6
|
+
expect(described_class.t(:to_string)[1]).to eql('1')
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '.to_symbol' do
|
11
11
|
it 'turns string into a symbol' do
|
12
|
-
expect(t(:to_symbol)['test']).to eql(:test)
|
12
|
+
expect(described_class.t(:to_symbol)['test']).to eql(:test)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
describe '.to_integer' do
|
17
17
|
it 'turns string into an integer' do
|
18
|
-
expect(t(:to_integer)['1']).to eql(1)
|
18
|
+
expect(described_class.t(:to_integer)['1']).to eql(1)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
describe '.to_float' do
|
23
23
|
it 'turns string into a float' do
|
24
|
-
expect(t(:to_float)['1']).to eql(1.0)
|
24
|
+
expect(described_class.t(:to_float)['1']).to eql(1.0)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'turns integer into a float' do
|
28
|
-
expect(t(:to_float)[1]).to eql(1.0)
|
28
|
+
expect(described_class.t(:to_float)[1]).to eql(1.0)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
describe '.to_decimal' do
|
33
33
|
it 'turns string into a decimal' do
|
34
|
-
expect(t(:to_decimal)['1.251']).to eql(BigDecimal('1.251'))
|
34
|
+
expect(described_class.t(:to_decimal)['1.251']).to eql(BigDecimal('1.251'))
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'turns float into a decimal' do
|
38
|
-
expect(t(:to_decimal)[1.251]).to eql(BigDecimal('1.251'))
|
38
|
+
expect(described_class.t(:to_decimal)[1.251]).to eql(BigDecimal('1.251'))
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'turns integer into a decimal' do
|
42
|
-
expect(t(:to_decimal)[1]).to eql(BigDecimal('1.0'))
|
42
|
+
expect(described_class.t(:to_decimal)[1]).to eql(BigDecimal('1.0'))
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
describe '.to_date' do
|
47
47
|
it 'turns string into a date' do
|
48
48
|
date = Date.new(1983, 11, 18)
|
49
|
-
expect(t(:to_date)['18th, November 1983']).to eql(date)
|
49
|
+
expect(described_class.t(:to_date)['18th, November 1983']).to eql(date)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
describe '.to_time' do
|
54
54
|
it 'turns string into a time object' do
|
55
55
|
time = Time.new(2012, 1, 23, 11, 7, 7)
|
56
|
-
expect(t(:to_time)['2012-01-23 11:07:07']).to eql(time)
|
56
|
+
expect(described_class.t(:to_time)['2012-01-23 11:07:07']).to eql(time)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
describe '.to_datetime' do
|
61
61
|
it 'turns string into a date' do
|
62
62
|
datetime = DateTime.new(2012, 1, 23, 11, 7, 7)
|
63
|
-
expect(t(:to_datetime)['2012-01-23 11:07:07']).to eql(datetime)
|
63
|
+
expect(described_class.t(:to_datetime)['2012-01-23 11:07:07']).to eql(datetime)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
describe '.to_boolean' do
|
68
|
-
subject(:coercer) { t(:to_boolean) }
|
68
|
+
subject(:coercer) { described_class.t(:to_boolean) }
|
69
69
|
|
70
70
|
Transproc::Coercions::TRUE_VALUES.each do |value|
|
71
71
|
it "turns #{value.inspect} to true" do
|
@@ -81,7 +81,7 @@ describe Transproc::Coercions do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
describe '.to_tuples' do
|
84
|
-
subject(:to_tuples) { t(:to_tuples) }
|
84
|
+
subject(:to_tuples) { described_class.t(:to_tuples) }
|
85
85
|
|
86
86
|
context 'non-array' do
|
87
87
|
let(:input) { :foo }
|
data/spec/unit/composer_spec.rb
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Transproc::Composer do
|
4
|
+
before do
|
5
|
+
module Foo
|
6
|
+
extend Transproc::Registry
|
7
|
+
import Transproc::ArrayTransformations
|
8
|
+
import Transproc::HashTransformations
|
9
|
+
import Transproc::Coercions
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
subject(:object) do
|
5
14
|
Class.new do
|
6
15
|
include Transproc::Composer
|
7
16
|
|
8
17
|
def fn
|
9
18
|
compose do |fns|
|
10
|
-
fns <<
|
11
|
-
|
19
|
+
fns << Foo[:map_array, Foo[:symbolize_keys]] <<
|
20
|
+
Foo[:map_array, Foo[:map_value, :age, Foo[:to_integer]]]
|
12
21
|
end
|
13
22
|
end
|
14
23
|
end.new
|
@@ -17,4 +26,6 @@ describe Transproc::Composer do
|
|
17
26
|
it 'allows composing functions' do
|
18
27
|
expect(object.fn[[{ 'age' => '12' }]]).to eql([{ age: 12 }])
|
19
28
|
end
|
29
|
+
|
30
|
+
after { Object.send :remove_const, :Foo }
|
20
31
|
end
|
@@ -2,7 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Transproc::Conditional do
|
4
4
|
describe '.guard' do
|
5
|
-
let(:fn) { t(:guard,
|
5
|
+
let(:fn) { described_class.t(:guard, condition, operation) }
|
6
|
+
let(:condition) { ->(value) { value.is_a?(::String) } }
|
7
|
+
let(:operation) { Transproc::Coercions.t(:to_integer) }
|
6
8
|
|
7
9
|
context 'when predicate returns truthy value' do
|
8
10
|
it 'applies the transformation and returns the result' do
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
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
|
13
|
+
Foo = Module.new { extend Transproc::Registry }
|
14
|
+
|
15
|
+
expect { Foo[:foo] }.to raise_error do |error|
|
16
|
+
expect(error).to be_kind_of described_class
|
17
|
+
expect(error.message["function Foo[:foo]"]).not_to be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/unit/function_spec.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Transproc::Function do
|
4
|
+
let(:hashes) { Transproc::HashTransformations }
|
5
|
+
|
6
|
+
describe '#name' do
|
7
|
+
let(:block) { proc { |v| v } }
|
8
|
+
|
9
|
+
it 'returns the name of the module function' do
|
10
|
+
expect(hashes[:symbolize_keys].name).to eql :symbolize_keys
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns the explicitly assigned name' do
|
14
|
+
expect(described_class.new(block, name: :identity).name).to eql :identity
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns the unnamed closure' do
|
18
|
+
expect(described_class.new(block).name).to eql block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
describe '#>>' do
|
5
23
|
it 'composes named functions' do
|
6
|
-
f1 =
|
7
|
-
f2 =
|
24
|
+
f1 = hashes[:symbolize_keys]
|
25
|
+
f2 = hashes[:rename_keys, user_name: :name]
|
8
26
|
|
9
27
|
f3 = f1 >> f2
|
10
28
|
|
@@ -19,7 +37,7 @@ describe 'Transproc::Function' do
|
|
19
37
|
|
20
38
|
expect(f3['user_name' => 'Jane']).to eql(name: 'Jane')
|
21
39
|
|
22
|
-
f4 = f3 >>
|
40
|
+
f4 = f3 >> hashes[:nest, :details, [:name]]
|
23
41
|
|
24
42
|
expect(f4.to_ast).to eql(
|
25
43
|
[
|
@@ -54,7 +72,7 @@ describe 'Transproc::Function' do
|
|
54
72
|
end
|
55
73
|
|
56
74
|
it 'plays well with registered compositions' do
|
57
|
-
Transproc.register(:user_names,
|
75
|
+
Transproc.register(:user_names, hashes[:symbolize_keys] + hashes[:rename_keys, user_name: :name])
|
58
76
|
f = t(:user_names)
|
59
77
|
|
60
78
|
expect(f['user_name' => 'Jane']).to eql(name: 'Jane')
|
@@ -70,10 +88,33 @@ describe 'Transproc::Function' do
|
|
70
88
|
|
71
89
|
it 'plays well with registered functions' do
|
72
90
|
Transproc.register(:to_s, t(:to_string))
|
73
|
-
|
91
|
+
fn = t(:to_s)
|
92
|
+
|
93
|
+
expect(fn[:ok]).to eql('ok')
|
94
|
+
expect(fn.to_ast).to eql([:to_string, []])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#==' do
|
99
|
+
let(:fns) do
|
100
|
+
Module.new do
|
101
|
+
extend Transproc::Registry
|
102
|
+
import :wrap, from: Transproc::ArrayTransformations
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns true when the other is equal' do
|
107
|
+
left = fns[:wrap, :user, [:name, :email]]
|
108
|
+
right = fns[:wrap, :user, [:name, :email]]
|
109
|
+
|
110
|
+
expect(left == right).to be(true)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'returns false when the other is not a fn' do
|
114
|
+
left = fns[:wrap, :user, [:name, :email]]
|
115
|
+
right = 'boo!'
|
74
116
|
|
75
|
-
expect(
|
76
|
-
expect(f.to_ast).to eql([:to_string, []])
|
117
|
+
expect(left == right).to be(false)
|
77
118
|
end
|
78
119
|
end
|
79
120
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'transproc/rspec'
|
2
3
|
|
3
4
|
describe Transproc::HashTransformations do
|
4
5
|
describe '.map_keys' do
|
5
6
|
it 'returns a new hash with given proc applied to keys' do
|
6
|
-
map_keys = t(:map_keys, ->(key) { key.strip })
|
7
|
+
map_keys = described_class.t(:map_keys, ->(key) { key.strip })
|
7
8
|
|
8
9
|
input = { ' foo ' => 'bar' }
|
9
10
|
output = { 'foo' => 'bar' }
|
@@ -15,7 +16,7 @@ describe Transproc::HashTransformations do
|
|
15
16
|
|
16
17
|
describe '.map_keys!' do
|
17
18
|
it 'returns updated hash with given proc applied to keys' do
|
18
|
-
map_keys = t(:map_keys!, ->(key) { key.strip })
|
19
|
+
map_keys = described_class.t(:map_keys!, ->(key) { key.strip })
|
19
20
|
|
20
21
|
input = { ' foo ' => 'bar' }
|
21
22
|
output = { 'foo' => 'bar' }
|
@@ -27,7 +28,7 @@ describe Transproc::HashTransformations do
|
|
27
28
|
|
28
29
|
describe '.symbolize_keys' do
|
29
30
|
it 'returns a new hash with symbolized keys' do
|
30
|
-
symbolize_keys = t(:symbolize_keys)
|
31
|
+
symbolize_keys = described_class.t(:symbolize_keys)
|
31
32
|
|
32
33
|
input = { 'foo' => 'bar' }
|
33
34
|
output = { foo: 'bar' }
|
@@ -37,9 +38,21 @@ describe Transproc::HashTransformations do
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
41
|
+
describe '.deep_symbolize_keys' do
|
42
|
+
it 'returns a new hash with symbolized keys' do
|
43
|
+
symbolize_keys = described_class.t(:deep_symbolize_keys)
|
44
|
+
|
45
|
+
input = { 'foo' => 'bar', 'baz' => [{ 'one' => 1 }, 'two'] }
|
46
|
+
output = { foo: 'bar', baz: [{ one: 1 }, 'two'] }
|
47
|
+
|
48
|
+
expect(symbolize_keys[input]).to eql(output)
|
49
|
+
expect(input).to eql({ 'foo' => 'bar', 'baz' => [{ 'one' => 1 }, 'two'] })
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
40
53
|
describe '.symbolize_keys!' do
|
41
54
|
it 'returns updated hash with symbolized keys' do
|
42
|
-
symbolize_keys = t(:symbolize_keys!)
|
55
|
+
symbolize_keys = described_class.t(:symbolize_keys!)
|
43
56
|
|
44
57
|
input = { 'foo' => 'bar' }
|
45
58
|
output = { foo: 'bar' }
|
@@ -52,7 +65,7 @@ describe Transproc::HashTransformations do
|
|
52
65
|
|
53
66
|
describe '.stringify_keys' do
|
54
67
|
it 'returns a new hash with stringified keys' do
|
55
|
-
stringify_keys = t(:stringify_keys)
|
68
|
+
stringify_keys = described_class.t(:stringify_keys)
|
56
69
|
|
57
70
|
input = { foo: 'bar' }
|
58
71
|
output = { 'foo' => 'bar' }
|
@@ -64,7 +77,7 @@ describe Transproc::HashTransformations do
|
|
64
77
|
|
65
78
|
describe '.stringify_keys!' do
|
66
79
|
it 'returns a new hash with stringified keys' do
|
67
|
-
stringify_keys = t(:stringify_keys!)
|
80
|
+
stringify_keys = described_class.t(:stringify_keys!)
|
68
81
|
|
69
82
|
input = { foo: 'bar' }
|
70
83
|
output = { 'foo' => 'bar' }
|
@@ -76,7 +89,7 @@ describe Transproc::HashTransformations do
|
|
76
89
|
|
77
90
|
describe '.map_values' do
|
78
91
|
it 'returns a new hash with given proc applied to values' do
|
79
|
-
map_values = t(:map_values, ->(value) { value.strip })
|
92
|
+
map_values = described_class.t(:map_values, ->(value) { value.strip })
|
80
93
|
|
81
94
|
input = { 'foo' => ' bar ' }
|
82
95
|
output = { 'foo' => 'bar' }
|
@@ -88,7 +101,7 @@ describe Transproc::HashTransformations do
|
|
88
101
|
|
89
102
|
describe '.map_values!' do
|
90
103
|
it 'returns updated hash with given proc applied to values' do
|
91
|
-
map_values = t(:map_values!, ->(value) { value.strip })
|
104
|
+
map_values = described_class.t(:map_values!, ->(value) { value.strip })
|
92
105
|
|
93
106
|
input = { 'foo' => ' bar ' }
|
94
107
|
output = { 'foo' => 'bar' }
|
@@ -100,7 +113,7 @@ describe Transproc::HashTransformations do
|
|
100
113
|
|
101
114
|
describe '.rename_keys' do
|
102
115
|
it 'returns a new hash with applied functions' do
|
103
|
-
map = t(:rename_keys, 'foo' => :foo)
|
116
|
+
map = described_class.t(:rename_keys, 'foo' => :foo)
|
104
117
|
|
105
118
|
input = { 'foo' => 'bar', :bar => 'baz' }
|
106
119
|
output = { foo: 'bar', bar: 'baz' }
|
@@ -112,7 +125,7 @@ describe Transproc::HashTransformations do
|
|
112
125
|
|
113
126
|
describe '.rename_keys!' do
|
114
127
|
it 'returns updated hash with applied functions' do
|
115
|
-
map = t(:rename_keys!, 'foo' => :foo)
|
128
|
+
map = described_class.t(:rename_keys!, 'foo' => :foo)
|
116
129
|
|
117
130
|
input = { 'foo' => 'bar', :bar => 'baz' }
|
118
131
|
output = { foo: 'bar', bar: 'baz' }
|
@@ -125,7 +138,8 @@ describe Transproc::HashTransformations do
|
|
125
138
|
|
126
139
|
describe '.map_value' do
|
127
140
|
it 'applies function to value under specified key' do
|
128
|
-
transformation =
|
141
|
+
transformation =
|
142
|
+
described_class.t(:map_value, :user, described_class.t(:symbolize_keys))
|
129
143
|
|
130
144
|
input = { user: { 'name' => 'Jane' } }
|
131
145
|
output = { user: { name: 'Jane' } }
|
@@ -137,7 +151,9 @@ describe Transproc::HashTransformations do
|
|
137
151
|
|
138
152
|
describe '.map_value!' do
|
139
153
|
it 'applies function to value under specified key' do
|
140
|
-
transformation =
|
154
|
+
transformation =
|
155
|
+
described_class
|
156
|
+
.t(:map_value!, :user, described_class.t(:symbolize_keys))
|
141
157
|
|
142
158
|
input = { user: { 'name' => 'Jane' } }
|
143
159
|
output = { user: { name: 'Jane' } }
|
@@ -150,7 +166,7 @@ describe Transproc::HashTransformations do
|
|
150
166
|
|
151
167
|
describe '.nest' do
|
152
168
|
it 'returns new hash with keys nested under a new key' do
|
153
|
-
nest = t(:nest, :baz, ['foo'])
|
169
|
+
nest = described_class.t(:nest, :baz, ['foo'])
|
154
170
|
|
155
171
|
input = { 'foo' => 'bar' }
|
156
172
|
output = { baz: { 'foo' => 'bar' } }
|
@@ -162,7 +178,7 @@ describe Transproc::HashTransformations do
|
|
162
178
|
|
163
179
|
describe '.nest!' do
|
164
180
|
it 'returns new hash with keys nested under a new key' do
|
165
|
-
nest = t(:nest!, :baz, ['one', 'two', 'not-here'])
|
181
|
+
nest = described_class.t(:nest!, :baz, ['one', 'two', 'not-here'])
|
166
182
|
|
167
183
|
input = { 'foo' => 'bar', 'one' => nil, 'two' => false }
|
168
184
|
output = { 'foo' => 'bar', baz: { 'one' => nil, 'two' => false } }
|
@@ -173,7 +189,7 @@ describe Transproc::HashTransformations do
|
|
173
189
|
end
|
174
190
|
|
175
191
|
it 'returns new hash with keys nested under the existing key' do
|
176
|
-
nest = t(:nest!, :baz, ['two'])
|
192
|
+
nest = described_class.t(:nest!, :baz, ['two'])
|
177
193
|
|
178
194
|
input = { 'foo' => 'bar', baz: { 'one' => nil }, 'two' => false }
|
179
195
|
output = { 'foo' => 'bar', baz: { 'one' => nil, 'two' => false } }
|
@@ -184,7 +200,7 @@ describe Transproc::HashTransformations do
|
|
184
200
|
end
|
185
201
|
|
186
202
|
it 'rewrites the existing key if its value is not a hash' do
|
187
|
-
nest = t(:nest!, :baz, ['two'])
|
203
|
+
nest = described_class.t(:nest!, :baz, ['two'])
|
188
204
|
|
189
205
|
input = { 'foo' => 'bar', baz: 'one', 'two' => false }
|
190
206
|
output = { 'foo' => 'bar', baz: { 'two' => false } }
|
@@ -195,7 +211,7 @@ describe Transproc::HashTransformations do
|
|
195
211
|
end
|
196
212
|
|
197
213
|
it 'returns new hash with an empty hash under a new key when nest-keys are missing' do
|
198
|
-
nest = t(:nest!, :baz, ['foo'])
|
214
|
+
nest = described_class.t(:nest!, :baz, ['foo'])
|
199
215
|
|
200
216
|
input = { 'bar' => 'foo' }
|
201
217
|
output = { 'bar' => 'foo', baz: {} }
|
@@ -208,7 +224,7 @@ describe Transproc::HashTransformations do
|
|
208
224
|
|
209
225
|
describe '.unwrap!' do
|
210
226
|
it 'returns updated hash with nested keys lifted to the root' do
|
211
|
-
unwrap = t(:unwrap!, 'wrapped', %w(one))
|
227
|
+
unwrap = described_class.t(:unwrap!, 'wrapped', %w(one))
|
212
228
|
|
213
229
|
input = { 'foo' => 'bar', 'wrapped' => { 'one' => nil, 'two' => false } }
|
214
230
|
output = { 'foo' => 'bar', 'one' => nil, 'wrapped' => { 'two' => false } }
|
@@ -219,7 +235,7 @@ describe Transproc::HashTransformations do
|
|
219
235
|
end
|
220
236
|
|
221
237
|
it 'lifts all keys if none are passed' do
|
222
|
-
unwrap = t(:unwrap!, 'wrapped')
|
238
|
+
unwrap = described_class.t(:unwrap!, 'wrapped')
|
223
239
|
|
224
240
|
input = { 'wrapped' => { 'one' => nil, 'two' => false } }
|
225
241
|
output = { 'one' => nil, 'two' => false }
|
@@ -230,7 +246,7 @@ describe Transproc::HashTransformations do
|
|
230
246
|
end
|
231
247
|
|
232
248
|
it 'ignores unknown keys' do
|
233
|
-
unwrap = t(:unwrap!, 'wrapped', %w(one two three))
|
249
|
+
unwrap = described_class.t(:unwrap!, 'wrapped', %w(one two three))
|
234
250
|
|
235
251
|
input = { 'wrapped' => { 'one' => nil, 'two' => false } }
|
236
252
|
output = { 'one' => nil, 'two' => false }
|
@@ -243,7 +259,7 @@ describe Transproc::HashTransformations do
|
|
243
259
|
|
244
260
|
describe '.unwrap' do
|
245
261
|
it 'returns new hash with nested keys lifted to the root' do
|
246
|
-
unwrap = t(:unwrap, 'wrapped')
|
262
|
+
unwrap = described_class.t(:unwrap, 'wrapped')
|
247
263
|
|
248
264
|
input = {
|
249
265
|
'foo' => 'bar',
|
@@ -260,8 +276,8 @@ describe Transproc::HashTransformations do
|
|
260
276
|
|
261
277
|
describe 'nested transform' do
|
262
278
|
it 'applies functions to nested hashes' do
|
263
|
-
symbolize_keys = t(:symbolize_keys)
|
264
|
-
map_user_key = t(:map_value, :user, symbolize_keys)
|
279
|
+
symbolize_keys = described_class.t(:symbolize_keys)
|
280
|
+
map_user_key = described_class.t(:map_value, :user, symbolize_keys)
|
265
281
|
|
266
282
|
transformation = symbolize_keys >> map_user_key
|
267
283
|
|
@@ -274,8 +290,8 @@ describe Transproc::HashTransformations do
|
|
274
290
|
|
275
291
|
describe 'combining transformations' do
|
276
292
|
it 'applies functions to the hash' do
|
277
|
-
symbolize_keys = t(:symbolize_keys)
|
278
|
-
map = t(:rename_keys, user_name: :name, user_email: :email)
|
293
|
+
symbolize_keys = described_class.t(:symbolize_keys)
|
294
|
+
map = described_class.t(:rename_keys, user_name: :name, user_email: :email)
|
279
295
|
|
280
296
|
transformation = symbolize_keys >> map
|
281
297
|
|
@@ -290,7 +306,7 @@ describe Transproc::HashTransformations do
|
|
290
306
|
|
291
307
|
describe '.reject_keys!' do
|
292
308
|
it 'returns an updated hash with rejected keys' do
|
293
|
-
reject_keys = t(:reject_keys, [:name, :age])
|
309
|
+
reject_keys = described_class.t(:reject_keys, [:name, :age])
|
294
310
|
|
295
311
|
input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
|
296
312
|
output = { email: 'jane@doe.org' }
|
@@ -301,7 +317,7 @@ describe Transproc::HashTransformations do
|
|
301
317
|
|
302
318
|
describe '.reject_keys' do
|
303
319
|
it 'returns a new hash with rejected keys' do
|
304
|
-
reject_keys = t(:reject_keys, [:name, :age])
|
320
|
+
reject_keys = described_class.t(:reject_keys, [:name, :age])
|
305
321
|
|
306
322
|
input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
|
307
323
|
output = { email: 'jane@doe.org' }
|
@@ -313,7 +329,7 @@ describe Transproc::HashTransformations do
|
|
313
329
|
|
314
330
|
describe '.accept_keys!' do
|
315
331
|
it 'returns an updated hash with accepted keys' do
|
316
|
-
accept_keys = t(:accept_keys, [:age])
|
332
|
+
accept_keys = described_class.t(:accept_keys, [:age])
|
317
333
|
|
318
334
|
input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
|
319
335
|
output = { age: 21 }
|
@@ -324,7 +340,7 @@ describe Transproc::HashTransformations do
|
|
324
340
|
|
325
341
|
describe '.reject_keys' do
|
326
342
|
it 'returns a new hash with rejected keys' do
|
327
|
-
accept_keys = t(:accept_keys, [:age])
|
343
|
+
accept_keys = described_class.t(:accept_keys, [:age])
|
328
344
|
|
329
345
|
input = { name: 'Jane', email: 'jane@doe.org', age: 21 }
|
330
346
|
output = { age: 21 }
|
@@ -342,22 +358,14 @@ describe Transproc::HashTransformations do
|
|
342
358
|
}
|
343
359
|
end
|
344
360
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
output = { name: 'Jane', tasks: ['be nice', 'sleep well'] }
|
349
|
-
|
350
|
-
expect { fold[input] }.not_to change { input }
|
351
|
-
expect(fold[input]).to eq output
|
361
|
+
it_behaves_like :transforming_immutable_data do
|
362
|
+
let(:arguments) { [:fold, :tasks, :title] }
|
363
|
+
let(:output) { { name: 'Jane', tasks: ['be nice', 'sleep well'] } }
|
352
364
|
end
|
353
365
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
output = { name: 'Jane', tasks: [1, nil] }
|
358
|
-
|
359
|
-
expect { fold[input] }.not_to change { input }
|
360
|
-
expect(fold[input]).to eql output
|
366
|
+
it_behaves_like :transforming_immutable_data do
|
367
|
+
let(:arguments) { [:fold, :tasks, :priority] }
|
368
|
+
let(:output) { { name: 'Jane', tasks: [1, nil] } }
|
361
369
|
end
|
362
370
|
end
|
363
371
|
|
@@ -369,22 +377,14 @@ describe Transproc::HashTransformations do
|
|
369
377
|
}
|
370
378
|
end
|
371
379
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
output = { name: 'Jane', tasks: ['be nice', 'sleep well'] }
|
376
|
-
|
377
|
-
expect(fold[input]).to eql output
|
378
|
-
expect(input).to eql output
|
380
|
+
it_behaves_like :mutating_input_data do
|
381
|
+
let(:arguments) { [:fold!, :tasks, :title] }
|
382
|
+
let(:output) { { name: 'Jane', tasks: ['be nice', 'sleep well'] } }
|
379
383
|
end
|
380
384
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
output = { name: 'Jane', tasks: [1, nil] }
|
385
|
-
|
386
|
-
expect(fold[input]).to eql output
|
387
|
-
expect(input).to eql output
|
385
|
+
it_behaves_like :mutating_input_data do
|
386
|
+
let(:arguments) { [:fold!, :tasks, :priority] }
|
387
|
+
let(:output) { { name: 'Jane', tasks: [1, nil] } }
|
388
388
|
end
|
389
389
|
end
|
390
390
|
|
@@ -403,7 +403,7 @@ describe Transproc::HashTransformations do
|
|
403
403
|
end
|
404
404
|
|
405
405
|
it 'splits a tuple into array partially by given keys' do
|
406
|
-
split = t(:split, :tasks, [:priority])
|
406
|
+
split = described_class.t(:split, :tasks, [:priority])
|
407
407
|
|
408
408
|
output = [
|
409
409
|
{
|
@@ -424,7 +424,7 @@ describe Transproc::HashTransformations do
|
|
424
424
|
end
|
425
425
|
|
426
426
|
it 'splits a tuple into array fully by all subkeys' do
|
427
|
-
split = t(:split, :tasks, [:priority, :title])
|
427
|
+
split = described_class.t(:split, :tasks, [:priority, :title])
|
428
428
|
|
429
429
|
output = [
|
430
430
|
{ name: 'Joe', title: 'sleep well', priority: 1 },
|
@@ -451,24 +451,62 @@ describe Transproc::HashTransformations do
|
|
451
451
|
}
|
452
452
|
]
|
453
453
|
|
454
|
-
split = t(:split, :tasks, [])
|
454
|
+
split = described_class.t(:split, :tasks, [])
|
455
455
|
expect(split[input]).to eql output
|
456
456
|
|
457
|
-
split = t(:split, :tasks, [:absent])
|
457
|
+
split = described_class.t(:split, :tasks, [:absent])
|
458
458
|
expect(split[input]).to eql output
|
459
459
|
end
|
460
460
|
|
461
461
|
it 'returns an array of initial tuple when attribute is absent' do
|
462
|
-
split = t(:split, :absent, [:priority, :title])
|
462
|
+
split = described_class.t(:split, :absent, [:priority, :title])
|
463
463
|
expect(split[input]).to eql [input]
|
464
464
|
end
|
465
465
|
|
466
466
|
it 'ignores empty array' do
|
467
467
|
input = { name: 'Joe', tasks: [] }
|
468
468
|
|
469
|
-
split = t(:split, :tasks, [:title])
|
469
|
+
split = described_class.t(:split, :tasks, [:title])
|
470
470
|
|
471
471
|
expect(split[input]).to eql [{ name: 'Joe' }]
|
472
472
|
end
|
473
473
|
end
|
474
|
+
|
475
|
+
describe ':eval_values' do
|
476
|
+
it 'recursively evaluates values' do
|
477
|
+
evaluate = described_class.t(:eval_values, 1)
|
478
|
+
|
479
|
+
input = {
|
480
|
+
one: 1, two: -> i { i+1 },
|
481
|
+
three: -> i { i+2 }, four: 4,
|
482
|
+
more: [{ one: -> i { i }, two: 2 }]
|
483
|
+
}
|
484
|
+
|
485
|
+
output = {
|
486
|
+
one: 1, two: 2,
|
487
|
+
three: 3, four: 4,
|
488
|
+
more: [{ one: 1, two: 2 }]
|
489
|
+
}
|
490
|
+
|
491
|
+
expect(evaluate[input]).to eql(output)
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'recursively evaluates values matching key names' do
|
495
|
+
evaluate = described_class.t(:eval_values, 1, [:one, :two])
|
496
|
+
|
497
|
+
input = {
|
498
|
+
one: 1, two: -> i { i+1 },
|
499
|
+
three: -> i { i+2 }, four: 4,
|
500
|
+
array: [{ one: -> i { i }, two: 2 }],
|
501
|
+
hash: { one: -> i { i } }
|
502
|
+
}
|
503
|
+
|
504
|
+
result = evaluate[input]
|
505
|
+
|
506
|
+
expect(result[:three]).to be_a(Proc)
|
507
|
+
expect(result).to include(two: 2)
|
508
|
+
expect(result[:array]).to eql([{ one: 1, two: 2 }])
|
509
|
+
expect(result[:hash]).to eql(one: 1)
|
510
|
+
end
|
511
|
+
end
|
474
512
|
end
|