dry-transformer 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/LICENSE +1 -1
  4. data/README.md +1 -1
  5. data/dry-transformer.gemspec +17 -10
  6. data/lib/dry/transformer/hash.rb +2 -1
  7. data/lib/dry/transformer/version.rb +1 -1
  8. metadata +10 -56
  9. data/.codeclimate.yml +0 -12
  10. data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
  11. data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
  12. data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
  13. data/.github/workflows/custom_ci.yml +0 -66
  14. data/.github/workflows/docsite.yml +0 -34
  15. data/.github/workflows/sync_configs.yml +0 -34
  16. data/.gitignore +0 -16
  17. data/.rspec +0 -4
  18. data/.rubocop.yml +0 -95
  19. data/CODE_OF_CONDUCT.md +0 -13
  20. data/CONTRIBUTING.md +0 -29
  21. data/Gemfile +0 -19
  22. data/Rakefile +0 -6
  23. data/docsite/source/built-in-transformations.html.md +0 -47
  24. data/docsite/source/index.html.md +0 -15
  25. data/docsite/source/transformation-objects.html.md +0 -32
  26. data/docsite/source/using-standalone-functions.html.md +0 -82
  27. data/spec/spec_helper.rb +0 -31
  28. data/spec/unit/array/combine_spec.rb +0 -224
  29. data/spec/unit/array_transformations_spec.rb +0 -233
  30. data/spec/unit/class_transformations_spec.rb +0 -50
  31. data/spec/unit/coercions_spec.rb +0 -132
  32. data/spec/unit/conditional_spec.rb +0 -48
  33. data/spec/unit/function_not_found_error_spec.rb +0 -12
  34. data/spec/unit/function_spec.rb +0 -193
  35. data/spec/unit/hash_transformations_spec.rb +0 -490
  36. data/spec/unit/proc_transformations_spec.rb +0 -20
  37. data/spec/unit/recursion_spec.rb +0 -145
  38. data/spec/unit/registry_spec.rb +0 -202
  39. data/spec/unit/store_spec.rb +0 -198
  40. data/spec/unit/transformer/class_interface_spec.rb +0 -350
  41. data/spec/unit/transformer/dsl_spec.rb +0 -15
  42. data/spec/unit/transformer/instance_methods_spec.rb +0 -25
@@ -1,233 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Dry::Transformer::ArrayTransformations do
4
- let(:hashes) { Dry::Transformer::HashTransformations }
5
-
6
- describe '.extract_key' do
7
- it 'extracts values by key from all hashes' do
8
- extract_key = described_class.t(:extract_key, 'name')
9
-
10
- input = [
11
- { 'name' => 'Alice', 'role' => 'sender' },
12
- { 'name' => 'Bob', 'role' => 'receiver' },
13
- { 'role' => 'listener' }
14
- ].freeze
15
-
16
- output = ['Alice', 'Bob', nil]
17
-
18
- expect(extract_key[input]).to eql(output)
19
- end
20
- end
21
-
22
- it { expect(described_class).not_to be_contain(:extract_key!) }
23
-
24
- describe '.insert_key' do
25
- it 'wraps values to tuples with given key' do
26
- insert_key = described_class.t(:insert_key, 'name')
27
-
28
- input = ['Alice', 'Bob', nil].freeze
29
-
30
- output = [
31
- { 'name' => 'Alice' },
32
- { 'name' => 'Bob' },
33
- { 'name' => nil }
34
- ]
35
-
36
- expect(insert_key[input]).to eql(output)
37
- end
38
- end
39
-
40
- it { expect(described_class).not_to be_contain(:insert_key!) }
41
-
42
- describe '.add_keys' do
43
- it 'returns a new array with missed keys added to tuples' do
44
- add_keys = described_class.t(:add_keys, [:foo, :bar, :baz])
45
-
46
- input = [{ foo: 'bar' }, { bar: 'baz' }].freeze
47
-
48
- output = [
49
- { foo: 'bar', bar: nil, baz: nil },
50
- { foo: nil, bar: 'baz', baz: nil }
51
- ]
52
-
53
- expect(add_keys[input]).to eql(output)
54
- end
55
- end
56
-
57
- it { expect(described_class).not_to be_contain(:add_keys!) }
58
-
59
- describe '.map_array' do
60
- it 'applies funtions to all values' do
61
- map = described_class.t(:map_array, hashes[:symbolize_keys])
62
-
63
- input = [
64
- { 'name' => 'Jane', 'title' => 'One' }.freeze,
65
- { 'name' => 'Jane', 'title' => 'Two' }.freeze
66
- ].freeze
67
-
68
- output = [
69
- { name: 'Jane', title: 'One' },
70
- { name: 'Jane', title: 'Two' }
71
- ]
72
-
73
- expect(map[input]).to eql(output)
74
- end
75
-
76
- it 'handles huge arrays' do
77
- map = described_class.t(:map_array, hashes[:symbolize_keys])
78
-
79
- input = Array.new(138_706) { |i| { 'key' => i } }
80
-
81
- expect { map[input] }.to_not raise_error
82
- end
83
-
84
- it 'handles flat value arrays' do
85
- map = described_class.t(:map_array, :upcase.to_proc)
86
-
87
- expect(map['foo']).to eql(%w(FOO))
88
- end
89
- end
90
-
91
- it { expect(described_class).not_to be_contain(:map_array!) }
92
-
93
- describe '.wrap' do
94
- it 'returns a new array with wrapped hashes' do
95
- wrap = described_class.t(:wrap, :task, [:title])
96
-
97
- input = [{ name: 'Jane', title: 'One' }]
98
- output = [{ name: 'Jane', task: { title: 'One' } }]
99
-
100
- expect(wrap[input]).to eql(output)
101
- end
102
-
103
- it 'returns a array new with deeply wrapped hashes' do
104
- wrap =
105
- described_class.t(
106
- :map_array,
107
- hashes[:nest, :user, [:name, :title]] +
108
- hashes[:map_value, :user, hashes[:nest, :task, [:title]]]
109
- )
110
-
111
- input = [{ name: 'Jane', title: 'One' }]
112
- output = [{ user: { name: 'Jane', task: { title: 'One' } } }]
113
-
114
- expect(wrap[input]).to eql(output)
115
- end
116
-
117
- it 'adds data to the existing tuples' do
118
- wrap = described_class.t(:wrap, :task, [:title])
119
-
120
- input = [{ name: 'Jane', task: { priority: 1 }, title: 'One' }]
121
- output = [{ name: 'Jane', task: { priority: 1, title: 'One' } }]
122
-
123
- expect(wrap[input]).to eql(output)
124
- end
125
- end
126
-
127
- describe '.group' do
128
- subject(:group) { described_class.t(:group, :tasks, [:title]) }
129
-
130
- it 'returns a new array with grouped hashes' do
131
- input = [{ name: 'Jane', title: 'One' }, { name: 'Jane', title: 'Two' }]
132
- output = [{ name: 'Jane', tasks: [{ title: 'One' }, { title: 'Two' }] }]
133
-
134
- expect(group[input]).to eql(output)
135
- end
136
-
137
- it 'updates the existing group' do
138
- input = [
139
- {
140
- name: 'Jane',
141
- title: 'One',
142
- tasks: [{ type: 'one' }, { type: 'two' }]
143
- },
144
- {
145
- name: 'Jane',
146
- title: 'Two',
147
- tasks: [{ type: 'one' }, { type: 'two' }]
148
- }
149
- ]
150
- output = [
151
- {
152
- name: 'Jane',
153
- tasks: [
154
- { title: 'One', type: 'one' },
155
- { title: 'One', type: 'two' },
156
- { title: 'Two', type: 'one' },
157
- { title: 'Two', type: 'two' }
158
- ]
159
- }
160
- ]
161
-
162
- expect(group[input]).to eql(output)
163
- end
164
-
165
- it 'ingnores old values except for array of tuples' do
166
- input = [
167
- { name: 'Jane', title: 'One', tasks: [{ priority: 1 }, :wrong] },
168
- { name: 'Jane', title: 'Two', tasks: :wrong }
169
- ]
170
- output = [
171
- {
172
- name: 'Jane',
173
- tasks: [{ title: 'One', priority: 1 }, { title: 'Two' }]
174
- }
175
- ]
176
-
177
- expect(group[input]).to eql(output)
178
- end
179
- end
180
-
181
- describe '.ungroup' do
182
- subject(:ungroup) { described_class.t(:ungroup, :tasks, [:title]) }
183
-
184
- it 'returns a new array with ungrouped hashes' do
185
- input = [{ name: 'Jane', tasks: [{ title: 'One' }, { title: 'Two' }] }]
186
- output = [{ name: 'Jane', title: 'One' }, { name: 'Jane', title: 'Two' }]
187
-
188
- expect(ungroup[input]).to eql(output)
189
- end
190
-
191
- it 'returns an input with empty array removed' do
192
- input = [{ name: 'Jane', tasks: [] }]
193
- output = [{ name: 'Jane' }]
194
-
195
- expect(ungroup[input]).to eql(output)
196
- end
197
-
198
- it 'returns an input when a key is absent' do
199
- input = [{ name: 'Jane' }]
200
- output = [{ name: 'Jane' }]
201
-
202
- expect(ungroup[input]).to eql(output)
203
- end
204
-
205
- it 'ungroups array partially' do
206
- input = [
207
- {
208
- name: 'Jane',
209
- tasks: [
210
- { title: 'One', type: 'one' },
211
- { title: 'One', type: 'two' },
212
- { title: 'Two', type: 'one' },
213
- { title: 'Two', type: 'two' }
214
- ]
215
- }
216
- ]
217
- output = [
218
- {
219
- name: 'Jane',
220
- title: 'One',
221
- tasks: [{ type: 'one' }, { type: 'two' }]
222
- },
223
- {
224
- name: 'Jane',
225
- title: 'Two',
226
- tasks: [{ type: 'one' }, { type: 'two' }]
227
- }
228
- ]
229
-
230
- expect(ungroup[input]).to eql(output)
231
- end
232
- end
233
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dry/equalizer'
4
-
5
- RSpec.describe Dry::Transformer::ClassTransformations do
6
- describe '.constructor_inject' do
7
- let(:klass) do
8
- Struct.new(:name, :age) { include Dry::Equalizer.new(:name, :age) }
9
- end
10
-
11
- it 'returns a new object initialized with the given arguments' do
12
- constructor_inject = described_class.t(:constructor_inject, klass)
13
-
14
- input = ['Jane', 25]
15
- output = klass.new(*input)
16
- result = constructor_inject[*input]
17
-
18
- expect(result).to eql(output)
19
- expect(result).to be_instance_of(klass)
20
- end
21
- end
22
-
23
- describe '.set_ivars' do
24
- let(:klass) do
25
- Class.new do
26
- include Dry::Equalizer.new(:name, :age)
27
-
28
- attr_reader :name, :age, :test
29
-
30
- def initialize(name:, age:)
31
- @name = name
32
- @age = age
33
- @test = true
34
- end
35
- end
36
- end
37
-
38
- it 'allocates a new object and sets instance variables from hash key/value pairs' do
39
- set_ivars = described_class.t(:set_ivars, klass)
40
-
41
- input = { name: 'Jane', age: 25 }
42
- output = klass.new(input)
43
- result = set_ivars[input]
44
-
45
- expect(result).to eql(output)
46
- expect(result.test).to be(nil)
47
- expect(result).to be_instance_of(klass)
48
- end
49
- end
50
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Dry::Transformer::Coercions do
4
- describe '.identity' do
5
- let(:fn) { described_class.t(:identity) }
6
-
7
- it 'returns the original value' do
8
- expect(fn[:foo]).to eql :foo
9
- end
10
-
11
- it 'returns nil by default' do
12
- expect(fn[]).to eql nil
13
- end
14
- end
15
-
16
- describe '.to_string' do
17
- it 'turns integer into a string' do
18
- expect(described_class.t(:to_string)[1]).to eql('1')
19
- end
20
- end
21
-
22
- describe '.to_symbol' do
23
- it 'turns string into a symbol' do
24
- expect(described_class.t(:to_symbol)['test']).to eql(:test)
25
- end
26
-
27
- it 'turns non-string into a symbol' do
28
- expect(described_class.t(:to_symbol)[1]).to eql(:'1')
29
- end
30
- end
31
-
32
- describe '.to_integer' do
33
- it 'turns string into an integer' do
34
- expect(described_class.t(:to_integer)['1']).to eql(1)
35
- end
36
- end
37
-
38
- describe '.to_float' do
39
- it 'turns string into a float' do
40
- expect(described_class.t(:to_float)['1']).to eql(1.0)
41
- end
42
-
43
- it 'turns integer into a float' do
44
- expect(described_class.t(:to_float)[1]).to eql(1.0)
45
- end
46
- end
47
-
48
- describe '.to_decimal' do
49
- it 'turns string into a decimal' do
50
- expect(described_class.t(:to_decimal)['1.251']).to eql(BigDecimal('1.251'))
51
- end
52
-
53
- it 'turns float into a decimal' do
54
- expect(described_class.t(:to_decimal)[1.251]).to eql(BigDecimal('1.251'))
55
- end
56
-
57
- it 'turns integer into a decimal' do
58
- expect(described_class.t(:to_decimal)[1]).to eql(BigDecimal('1.0'))
59
- end
60
- end
61
-
62
- describe '.to_date' do
63
- it 'turns string into a date' do
64
- date = Date.new(1983, 11, 18)
65
- expect(described_class.t(:to_date)['18th, November 1983']).to eql(date)
66
- end
67
- end
68
-
69
- describe '.to_time' do
70
- it 'turns string into a time object' do
71
- time = Time.new(2012, 1, 23, 11, 7, 7)
72
- expect(described_class.t(:to_time)['2012-01-23 11:07:07']).to eql(time)
73
- end
74
- end
75
-
76
- describe '.to_datetime' do
77
- it 'turns string into a date' do
78
- datetime = DateTime.new(2012, 1, 23, 11, 7, 7)
79
- expect(described_class.t(:to_datetime)['2012-01-23 11:07:07']).to eql(datetime)
80
- end
81
- end
82
-
83
- describe '.to_boolean' do
84
- subject(:coercer) { described_class.t(:to_boolean) }
85
-
86
- Dry::Transformer::Coercions::TRUE_VALUES.each do |value|
87
- it "turns #{value.inspect} to true" do
88
- expect(coercer[value]).to be(true)
89
- end
90
- end
91
-
92
- Dry::Transformer::Coercions::FALSE_VALUES.each do |value|
93
- it "turns #{value.inspect} to false" do
94
- expect(coercer[value]).to be(false)
95
- end
96
- end
97
- end
98
-
99
- describe '.to_tuples' do
100
- subject(:to_tuples) { described_class.t(:to_tuples) }
101
-
102
- context 'non-array' do
103
- let(:input) { :foo }
104
-
105
- it 'returns an array with one blank tuple' do
106
- output = [{}]
107
-
108
- expect(to_tuples[input]).to eql(output)
109
- end
110
- end
111
-
112
- context 'empty array' do
113
- let(:input) { [] }
114
-
115
- it 'returns an array with one blank tuple' do
116
- output = [{}]
117
-
118
- expect(to_tuples[input]).to eql(output)
119
- end
120
- end
121
-
122
- context 'array of tuples' do
123
- let(:input) { [:foo, { bar: :BAZ }, :qux] }
124
-
125
- it 'returns an array with tuples only' do
126
- output = [{ bar: :BAZ }]
127
-
128
- expect(to_tuples[input]).to eql(output)
129
- end
130
- end
131
- end
132
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Dry::Transformer::Conditional do
4
- describe '.not' do
5
- let(:fn) { described_class.t(:not, -> value { value.is_a? String }) }
6
- subject { fn[input] }
7
-
8
- context 'when predicate returns truthy value' do
9
- let(:input) { 'foo' }
10
- let(:output) { false }
11
-
12
- it 'applies the first transformation' do
13
- expect(subject).to eql output
14
- end
15
- end
16
-
17
- context 'when predicate returns falsey value' do
18
- let(:input) { :foo }
19
- let(:output) { true }
20
-
21
- it 'applies the first transformation' do
22
- expect(subject).to eql output
23
- end
24
- end
25
- end
26
-
27
- describe '.guard' do
28
- let(:fn) { described_class.t(:guard, condition, operation) }
29
- let(:condition) { ->(value) { value.is_a?(::String) } }
30
- let(:operation) { Dry::Transformer::Coercions.t(:to_integer) }
31
-
32
- context 'when predicate returns truthy value' do
33
- it 'applies the transformation and returns the result' do
34
- input = '2'
35
-
36
- expect(fn[input]).to eql(2)
37
- end
38
- end
39
-
40
- context 'when predicate returns falsey value' do
41
- it 'returns the original value' do
42
- input = { 'foo' => 'bar' }
43
-
44
- expect(fn[input]).to eql('foo' => 'bar')
45
- end
46
- end
47
- end
48
- end