transproc 1.0.3 → 1.1.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +15 -0
  3. data/.gitignore +3 -0
  4. data/.travis.yml +10 -10
  5. data/CHANGELOG.md +14 -2
  6. data/Gemfile +5 -17
  7. data/lib/transproc.rb +3 -4
  8. data/lib/transproc/all.rb +2 -0
  9. data/lib/transproc/array.rb +2 -0
  10. data/lib/transproc/array/combine.rb +2 -0
  11. data/lib/transproc/class.rb +2 -0
  12. data/lib/transproc/coercions.rb +2 -0
  13. data/lib/transproc/compiler.rb +45 -0
  14. data/lib/transproc/composer.rb +2 -0
  15. data/lib/transproc/composite.rb +2 -0
  16. data/lib/transproc/conditional.rb +2 -0
  17. data/lib/transproc/constants.rb +5 -0
  18. data/lib/transproc/error.rb +2 -0
  19. data/lib/transproc/function.rb +2 -0
  20. data/lib/transproc/functions.rb +2 -0
  21. data/lib/transproc/hash.rb +31 -0
  22. data/lib/transproc/proc.rb +2 -0
  23. data/lib/transproc/recursion.rb +2 -0
  24. data/lib/transproc/registry.rb +1 -0
  25. data/lib/transproc/store.rb +1 -0
  26. data/lib/transproc/support/deprecations.rb +2 -0
  27. data/lib/transproc/transformer.rb +7 -1
  28. data/lib/transproc/transformer/class_interface.rb +31 -65
  29. data/lib/transproc/transformer/deprecated/class_interface.rb +80 -0
  30. data/lib/transproc/transformer/dsl.rb +51 -0
  31. data/lib/transproc/version.rb +3 -1
  32. data/spec/spec_helper.rb +5 -7
  33. data/spec/unit/array/combine_spec.rb +3 -1
  34. data/spec/unit/array_transformations_spec.rb +1 -1
  35. data/spec/unit/class_transformations_spec.rb +9 -6
  36. data/spec/unit/coercions_spec.rb +1 -1
  37. data/spec/unit/composer_spec.rb +1 -1
  38. data/spec/unit/conditional_spec.rb +1 -1
  39. data/spec/unit/function_not_found_error_spec.rb +1 -1
  40. data/spec/unit/function_spec.rb +1 -1
  41. data/spec/unit/hash_transformations_spec.rb +12 -1
  42. data/spec/unit/proc_transformations_spec.rb +3 -1
  43. data/spec/unit/recursion_spec.rb +1 -1
  44. data/spec/unit/registry_spec.rb +1 -1
  45. data/spec/unit/store_spec.rb +2 -1
  46. data/spec/unit/transformer/class_interface_spec.rb +364 -0
  47. data/spec/unit/transformer/dsl_spec.rb +15 -0
  48. data/spec/unit/transformer/instance_methods_spec.rb +25 -0
  49. data/spec/unit/transformer_spec.rb +128 -40
  50. data/spec/unit/transproc_spec.rb +1 -1
  51. data/transproc.gemspec +0 -4
  52. metadata +15 -53
  53. data/.rubocop.yml +0 -66
  54. data/.rubocop_todo.yml +0 -11
  55. data/rakelib/mutant.rake +0 -16
  56. data/rakelib/rubocop.rake +0 -18
  57. data/spec/support/mutant.rb +0 -10
@@ -0,0 +1,15 @@
1
+ RSpec.describe Transproc::Transformer do
2
+ let(:container) { Module.new { extend Transproc::Registry } }
3
+ let(:klass) { Transproc::Transformer[container] }
4
+ let(:transformer) { klass.new }
5
+
6
+ context 'when invalid method is used' do
7
+ it 'raises an error on initialization' do
8
+ klass.define! do
9
+ not_valid
10
+ end
11
+
12
+ expect { klass.new }.to raise_error(Transproc::Compiler::InvalidFunctionNameError, /not_valid/)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ RSpec.describe Transproc::Transformer, 'instance methods' do
2
+ subject(:transformer) do
3
+ Class.new(Transproc::Transformer[registry]) do
4
+ define! do
5
+ map_array(&:capitalize)
6
+ end
7
+
8
+ def capitalize(input)
9
+ input.upcase
10
+ end
11
+ end.new
12
+ end
13
+
14
+ let(:registry) do
15
+ Module.new do
16
+ extend Transproc::Registry
17
+
18
+ import Transproc::ArrayTransformations
19
+ end
20
+ end
21
+
22
+ it 'registers a new transformation function' do
23
+ expect(transformer.call(%w[foo bar])).to eql(%w[FOO BAR])
24
+ end
25
+ end
@@ -1,4 +1,7 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+ require 'dry/equalizer'
2
5
 
3
6
  describe Transproc::Transformer do
4
7
  let(:container) { Module.new { extend Transproc::Registry } }
@@ -6,23 +9,76 @@ describe Transproc::Transformer do
6
9
  let(:transformer) { klass.new }
7
10
 
8
11
  describe '.container' do
9
- it { expect(klass.container).to eq container }
12
+ it 'returns the configured container' do
13
+ expect(klass.container).to be(container)
14
+ end
10
15
 
11
- context 'with default transformer' do
12
- let(:klass) { described_class }
16
+ context 'with setter argument' do
17
+ let(:container) { double(:custom_container) }
18
+
19
+ it 'sets and returns the container' do
20
+ klass.container(container)
13
21
 
14
- it 'raises exception because there is no container by default' do
15
- message = 'Transformer function registry is empty. '\
16
- 'Provide your registry via Transproc::Transformer[YourRegistry]'
17
- expect { klass.container }.to raise_error(ArgumentError, message)
22
+ expect(klass.container).to be(container)
18
23
  end
19
24
  end
25
+ end
20
26
 
21
- context 'with setter argument' do
22
- subject! { klass.container({}) }
27
+ describe '.method_missing' do
28
+ context 'when the method name matches a registered function' do
29
+ it 'registers a transformation without args' do
30
+ container.import(Transproc::Coercions)
23
31
 
24
- it 'sets and returns the container' do
25
- expect(klass.container).to eq({})
32
+ func = klass.t(:to_string)
33
+
34
+ result = klass.to_string
35
+
36
+ expect(result).to eql(func)
37
+ end
38
+
39
+ it 'registers a transformation with args' do
40
+ container.import(Transproc::HashTransformations)
41
+
42
+ func = klass.t(:rename_keys, id: :user_id)
43
+
44
+ result = klass.rename_keys(id: :user_id)
45
+
46
+ expect(result).to eql(func)
47
+ end
48
+
49
+ it 'registers a transformation with a block' do
50
+ container.import(Transproc::ArrayTransformations)
51
+ container.import(Transproc::HashTransformations)
52
+
53
+ func = klass.t(:map_array, klass.t(:rename_keys, id: :user_id))
54
+
55
+ result = klass.map_array { rename_keys(id: :user_id) }
56
+
57
+ expect(result).to eql(func)
58
+ end
59
+
60
+ it 'registers a transformation with args and a block' do
61
+ container.import(Transproc::HashTransformations)
62
+
63
+ func = klass.t(:map_value, :user, klass.t(:rename_keys, id: :user_id))
64
+
65
+ result = klass.map_value(:user) { rename_keys(id: :user_id) }
66
+
67
+ expect(result).to eql(func)
68
+ end
69
+
70
+ it 'works with #method' do
71
+ container.import(Transproc::Coercions)
72
+
73
+ func = klass.t(:to_string)
74
+
75
+ expect(klass.method(:to_string).()).to eql(func)
76
+ end
77
+ end
78
+
79
+ context 'when the method name does not match any registered function' do
80
+ it 'raises NoMethodError' do
81
+ expect { klass.not_here }.to raise_error(NoMethodError, /not_here/)
26
82
  end
27
83
  end
28
84
  end
@@ -37,11 +93,13 @@ describe Transproc::Transformer do
37
93
  end
38
94
  end
39
95
  end
96
+
40
97
  let(:superclass) do
41
98
  Class.new(Transproc::Transformer[container]) do
42
99
  arbitrary ->(v) { v + 1 }
43
100
  end
44
101
  end
102
+
45
103
  let(:subclass) do
46
104
  Class.new(superclass) do
47
105
  arbitrary ->(v) { v * 2 }
@@ -49,38 +107,53 @@ describe Transproc::Transformer do
49
107
  end
50
108
 
51
109
  it 'inherits container from superclass' do
52
- expect(subclass.container).to eq superclass.container
110
+ expect(subclass.container).to be(superclass.container)
53
111
  end
54
112
 
55
- it 'does not inherit transproc from superclass' do
56
- expect(superclass.new.call(2)).to eq 3
57
- expect(subclass.new.call(2)).to eq 4
113
+ it 'inherits transproc from superclass' do
114
+ expect(superclass.new.call(2)).to be(3)
115
+ expect(subclass.new.call(2)).to be(6)
58
116
  end
59
117
  end
60
118
 
61
119
  describe '.[]' do
120
+ subject(:subclass) { klass[another_container] }
121
+
62
122
  let(:another_container) { double('Transproc') }
63
123
 
64
- subject(:subclass) { klass[another_container] }
124
+ it 'sets a container' do
125
+ expect(subclass.container).to be(another_container)
126
+ end
65
127
 
66
- it { expect(subclass.container).to eq(another_container) }
67
- it { is_expected.to be_a(::Class) }
68
- it { expect(subclass.ancestors).to include(Transproc::Transformer) }
128
+ it 'returns a class' do
129
+ expect(subclass).to be_a(Class)
130
+ end
131
+
132
+ it 'creates a subclass of Transformer' do
133
+ expect(subclass).to be < Transproc::Transformer
134
+ end
69
135
 
70
136
  it 'does not change super class' do
71
- expect(klass.container).to eq(container)
137
+ expect(klass.container).to be(container)
138
+ end
139
+
140
+ it 'does not inherit transproc' do
141
+ expect(klass[container].transproc).to be_nil
72
142
  end
73
143
 
74
144
  context 'with predefined transformer' do
75
145
  let(:klass) do
76
- Class.new(Transproc::Transformer) do
146
+ Class.new(Transproc::Transformer[container]) do
147
+ container.import Transproc::Coercions
148
+ container.import Transproc::HashTransformations
149
+
77
150
  map_value :attr, t(:to_symbol)
78
151
  end
79
152
  end
80
- end
81
153
 
82
- it 'does not inherit transproc' do
83
- expect(klass[container].transproc).to be_nil
154
+ it "inherits parent's transproc" do
155
+ expect(klass[container].transproc).to eql(klass.transproc)
156
+ end
84
157
  end
85
158
  end
86
159
 
@@ -96,12 +169,14 @@ describe Transproc::Transformer do
96
169
  end
97
170
  end
98
171
  end
172
+
99
173
  let(:klass) { Transproc::Transformer[container] }
100
174
 
101
175
  it 'defines anonymous transproc' do
102
176
  transproc = klass.define do
103
177
  map_value(:attr, t(:to_symbol))
104
178
  end
179
+
105
180
  expect(transproc[attr: 'abc']).to eq(attr: :abc)
106
181
  end
107
182
 
@@ -109,6 +184,7 @@ describe Transproc::Transformer do
109
184
  transproc = klass.build do
110
185
  map_value(:attr, t(:to_symbol))
111
186
  end
187
+
112
188
  expect(transproc[attr: 'abc']).to eq(attr: :abc)
113
189
  end
114
190
 
@@ -116,6 +192,7 @@ describe Transproc::Transformer do
116
192
  klass.define do
117
193
  map_value(:attr, :to_sym.to_proc)
118
194
  end
195
+
119
196
  expect(klass.transproc).to be_nil
120
197
  end
121
198
 
@@ -129,12 +206,14 @@ describe Transproc::Transformer do
129
206
  end
130
207
  end
131
208
  end
209
+
132
210
  let(:klass) { described_class[container] }
133
211
 
134
212
  it 'uses a container from the transformer' do
135
213
  transproc = klass.define do
136
214
  arbitrary ->(v) { v + 1 }
137
215
  end
216
+
138
217
  expect(transproc.call(2)).to eq 3
139
218
  end
140
219
  end
@@ -155,12 +234,15 @@ describe Transproc::Transformer do
155
234
  transproc = klass.define do
156
235
  map_value :attr, ->(v) { v * 2 }
157
236
  end
237
+
158
238
  expect(transproc.call(attr: 2)).to eq(attr: 4)
159
239
  end
160
240
  end
161
241
  end
162
242
 
163
243
  describe '.t' do
244
+ subject(:klass) { Transproc::Transformer[container] }
245
+
164
246
  let(:container) do
165
247
  Module.new do
166
248
  extend Transproc::Registry
@@ -174,9 +256,9 @@ describe Transproc::Transformer do
174
256
  end
175
257
  end
176
258
 
177
- subject!(:klass) { Transproc::Transformer[container] }
178
-
179
- it { expect(klass.t(:custom, '_bar')).to eq container[:custom, '_bar'] }
259
+ it 'returns a registed function' do
260
+ expect(klass.t(:custom, '_bar')).to eql(container[:custom, '_bar'])
261
+ end
180
262
 
181
263
  it 'is useful in DSL' do
182
264
  transproc = Class.new(klass) do
@@ -214,13 +296,16 @@ describe Transproc::Transformer do
214
296
  symbolize_keys
215
297
  rename_keys user_name: :name
216
298
  nest :address, [:city, :street, :zipcode]
299
+
217
300
  map_value :address do
218
301
  constructor_inject Test::Address
219
302
  end
303
+
220
304
  constructor_inject Test::User
221
305
  end
222
306
  end
223
307
  end
308
+
224
309
  let(:input) do
225
310
  [
226
311
  { 'user_name' => 'Jane',
@@ -230,7 +315,8 @@ describe Transproc::Transformer do
230
315
  }
231
316
  ]
232
317
  end
233
- let(:output) do
318
+
319
+ let(:expected_output) do
234
320
  [
235
321
  Test::User.new(
236
322
  name: 'Jane',
@@ -245,38 +331,40 @@ describe Transproc::Transformer do
245
331
 
246
332
  before do
247
333
  module Test
248
- class User
249
- include Anima.new(:name, :address)
334
+ class User < OpenStruct
335
+ include Dry::Equalizer(:name, :address)
250
336
  end
251
337
 
252
- class Address
253
- include Anima.new(:city, :street, :zipcode)
338
+ class Address < OpenStruct
339
+ include Dry::Equalizer(:city, :street, :zipcode)
254
340
  end
255
341
  end
256
342
  end
257
343
 
258
- subject! { transformer.call(input) }
259
-
260
- it { is_expected.to eq(output) }
344
+ it "transforms input" do
345
+ expect(transformer.(input)).to eql(expected_output)
346
+ end
261
347
 
262
348
  context 'with custom registry' do
263
349
  let(:klass) do
264
350
  Class.new(Transproc::Transformer[registry]) do
265
- custom ' is awesome'
351
+ append ' is awesome'
266
352
  end
267
353
  end
354
+
268
355
  let(:registry) do
269
356
  Module.new do
270
357
  extend Transproc::Registry
271
358
 
272
- def self.custom(value, suffix)
359
+ def self.append(value, suffix)
273
360
  value + suffix
274
361
  end
275
362
  end
276
363
  end
277
- let(:input) { 'transproc' }
278
364
 
279
- it { is_expected.to eq('transproc is awesome') }
365
+ it 'uses custom functions' do
366
+ expect(transformer.('transproc')).to eql('transproc is awesome')
367
+ end
280
368
  end
281
369
  end
282
370
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  describe Transproc do
4
4
  describe 'composition' do
@@ -17,8 +17,4 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
  spec.required_ruby_version = '>= 2.3.0'
20
-
21
- spec.add_development_dependency 'bundler', '~> 1.7'
22
- spec.add_development_dependency 'rake', '~> 10.0'
23
- spec.add_development_dependency 'rspec', '~> 3.3'
24
20
  end
metadata CHANGED
@@ -1,57 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transproc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.7'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.7'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '10.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '10.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.3'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.3'
11
+ date: 2019-07-18 00:00:00.000000000 Z
12
+ dependencies: []
55
13
  description: Transform Ruby objects in functional style
56
14
  email:
57
15
  - piotr.solnica@gmail.com
@@ -59,10 +17,9 @@ executables: []
59
17
  extensions: []
60
18
  extra_rdoc_files: []
61
19
  files:
20
+ - ".codeclimate.yml"
62
21
  - ".gitignore"
63
22
  - ".rspec"
64
- - ".rubocop.yml"
65
- - ".rubocop_todo.yml"
66
23
  - ".travis.yml"
67
24
  - CHANGELOG.md
68
25
  - Gemfile
@@ -76,9 +33,11 @@ files:
76
33
  - lib/transproc/array/combine.rb
77
34
  - lib/transproc/class.rb
78
35
  - lib/transproc/coercions.rb
36
+ - lib/transproc/compiler.rb
79
37
  - lib/transproc/composer.rb
80
38
  - lib/transproc/composite.rb
81
39
  - lib/transproc/conditional.rb
40
+ - lib/transproc/constants.rb
82
41
  - lib/transproc/error.rb
83
42
  - lib/transproc/function.rb
84
43
  - lib/transproc/functions.rb
@@ -90,11 +49,10 @@ files:
90
49
  - lib/transproc/support/deprecations.rb
91
50
  - lib/transproc/transformer.rb
92
51
  - lib/transproc/transformer/class_interface.rb
52
+ - lib/transproc/transformer/deprecated/class_interface.rb
53
+ - lib/transproc/transformer/dsl.rb
93
54
  - lib/transproc/version.rb
94
- - rakelib/mutant.rake
95
- - rakelib/rubocop.rake
96
55
  - spec/spec_helper.rb
97
- - spec/support/mutant.rb
98
56
  - spec/unit/array/combine_spec.rb
99
57
  - spec/unit/array_transformations_spec.rb
100
58
  - spec/unit/class_transformations_spec.rb
@@ -108,6 +66,9 @@ files:
108
66
  - spec/unit/recursion_spec.rb
109
67
  - spec/unit/registry_spec.rb
110
68
  - spec/unit/store_spec.rb
69
+ - spec/unit/transformer/class_interface_spec.rb
70
+ - spec/unit/transformer/dsl_spec.rb
71
+ - spec/unit/transformer/instance_methods_spec.rb
111
72
  - spec/unit/transformer_spec.rb
112
73
  - spec/unit/transproc_spec.rb
113
74
  - transproc.gemspec
@@ -130,14 +91,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
91
  - !ruby/object:Gem::Version
131
92
  version: '0'
132
93
  requirements: []
133
- rubyforge_project:
134
- rubygems_version: 2.7.6
94
+ rubygems_version: 3.0.3
135
95
  signing_key:
136
96
  specification_version: 4
137
97
  summary: Transform Ruby objects in functional style
138
98
  test_files:
139
99
  - spec/spec_helper.rb
140
- - spec/support/mutant.rb
141
100
  - spec/unit/array/combine_spec.rb
142
101
  - spec/unit/array_transformations_spec.rb
143
102
  - spec/unit/class_transformations_spec.rb
@@ -151,5 +110,8 @@ test_files:
151
110
  - spec/unit/recursion_spec.rb
152
111
  - spec/unit/registry_spec.rb
153
112
  - spec/unit/store_spec.rb
113
+ - spec/unit/transformer/class_interface_spec.rb
114
+ - spec/unit/transformer/dsl_spec.rb
115
+ - spec/unit/transformer/instance_methods_spec.rb
154
116
  - spec/unit/transformer_spec.rb
155
117
  - spec/unit/transproc_spec.rb