transproc 1.0.2 → 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.
- checksums.yaml +5 -5
- data/.codeclimate.yml +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +14 -10
- data/CHANGELOG.md +22 -1
- data/Gemfile +5 -18
- data/README.md +3 -5
- data/Rakefile +1 -0
- data/lib/transproc.rb +3 -4
- data/lib/transproc/all.rb +2 -0
- data/lib/transproc/array.rb +5 -3
- data/lib/transproc/array/combine.rb +2 -0
- data/lib/transproc/class.rb +2 -0
- data/lib/transproc/coercions.rb +2 -0
- data/lib/transproc/compiler.rb +45 -0
- data/lib/transproc/composer.rb +2 -0
- data/lib/transproc/composite.rb +2 -0
- data/lib/transproc/conditional.rb +2 -0
- data/lib/transproc/constants.rb +5 -0
- data/lib/transproc/error.rb +2 -0
- data/lib/transproc/function.rb +2 -0
- data/lib/transproc/functions.rb +2 -0
- data/lib/transproc/hash.rb +83 -34
- data/lib/transproc/proc.rb +2 -0
- data/lib/transproc/recursion.rb +2 -0
- data/lib/transproc/registry.rb +1 -0
- data/lib/transproc/store.rb +1 -0
- data/lib/transproc/support/deprecations.rb +2 -0
- data/lib/transproc/transformer.rb +7 -1
- data/lib/transproc/transformer/class_interface.rb +31 -65
- data/lib/transproc/transformer/deprecated/class_interface.rb +80 -0
- data/lib/transproc/transformer/dsl.rb +51 -0
- data/lib/transproc/version.rb +3 -1
- data/spec/spec_helper.rb +15 -11
- data/spec/unit/array/combine_spec.rb +3 -1
- data/spec/unit/array_transformations_spec.rb +1 -1
- data/spec/unit/class_transformations_spec.rb +9 -6
- data/spec/unit/coercions_spec.rb +1 -1
- data/spec/unit/composer_spec.rb +1 -1
- data/spec/unit/conditional_spec.rb +1 -1
- data/spec/unit/function_not_found_error_spec.rb +1 -1
- data/spec/unit/function_spec.rb +1 -1
- data/spec/unit/hash_transformations_spec.rb +12 -1
- data/spec/unit/proc_transformations_spec.rb +3 -1
- data/spec/unit/recursion_spec.rb +1 -1
- data/spec/unit/registry_spec.rb +1 -1
- data/spec/unit/store_spec.rb +2 -1
- data/spec/unit/transformer/class_interface_spec.rb +364 -0
- data/spec/unit/transformer/dsl_spec.rb +15 -0
- data/spec/unit/transformer/instance_methods_spec.rb +25 -0
- data/spec/unit/transformer_spec.rb +128 -40
- data/spec/unit/transproc_spec.rb +1 -1
- data/transproc.gemspec +1 -5
- metadata +16 -54
- data/.rubocop.yml +0 -66
- data/.rubocop_todo.yml +0 -11
- data/rakelib/mutant.rake +0 -16
- data/rakelib/rubocop.rake +0 -18
- data/spec/support/mutant.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bd2c6ee5f665083297c1fcfd89a5e37d2284e498d6bc3953b88314e9513cbf43
|
4
|
+
data.tar.gz: 6b9a5f270234b26b479095c66187f91fcca9428afb605f75aa9f51b890976eef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c79034b27d317e52be52e98eb0cce057400efc99c05203e16fd39112a911d0bb568511d58dd138bbc32568cf8951fab586dcdf90e3c9bff434b6fd93347044b
|
7
|
+
data.tar.gz: a2086dc6a92e03837412d7665869c1ad516a3a5ce097db1b31224936d767af048eadb32c86e8e0bcf815ef38445f9aed9a878b5f5ca97b5559b3194efa567aec
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
version: "2"
|
2
|
+
|
3
|
+
prepare:
|
4
|
+
fetch:
|
5
|
+
- url: "https://raw.githubusercontent.com/dry-rb/devtools/master/.rubocop.yml"
|
6
|
+
path: ".rubocop.yml"
|
7
|
+
|
8
|
+
exclude_patterns:
|
9
|
+
- "benchmarks/"
|
10
|
+
- "examples/"
|
11
|
+
- "spec/"
|
12
|
+
|
13
|
+
plugins:
|
14
|
+
rubocop:
|
15
|
+
enabled: true
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
-
dist: trusty
|
2
1
|
language: ruby
|
3
|
-
sudo: required
|
4
2
|
cache: bundler
|
5
3
|
bundler_args: --without tools
|
4
|
+
before_script:
|
5
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
6
|
+
- chmod +x ./cc-test-reporter
|
7
|
+
- ./cc-test-reporter before-build
|
8
|
+
after_script:
|
9
|
+
- "[ -d coverage ] && ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
6
10
|
script: 'bundle exec rake spec'
|
7
|
-
after_success:
|
8
|
-
- '[ "$TRAVIS_RUBY_VERSION" = "2.3.1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
|
9
11
|
rvm:
|
10
|
-
- 2.
|
11
|
-
- 2.
|
12
|
-
- 2.
|
13
|
-
- 2.
|
14
|
-
-
|
15
|
-
|
12
|
+
- 2.3.8
|
13
|
+
- 2.6.3
|
14
|
+
- 2.5.5
|
15
|
+
- 2.4.6
|
16
|
+
- jruby-9.2.7.0
|
17
|
+
env:
|
18
|
+
global:
|
19
|
+
- COVERAGE='true'
|
16
20
|
notifications:
|
17
21
|
webhooks:
|
18
22
|
urls:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
# v1.1.0 2019-07-18
|
2
|
+
|
3
|
+
This is the last transproc release before the project will be forked to `dry-transformer`.
|
4
|
+
|
5
|
+
## Added
|
6
|
+
|
7
|
+
* New DSL for defining transformers using `define!` method, which now supports instance methods as transformation functions (@solnic)
|
8
|
+
* Simplified transformer class definition - registry is auto-configured and you can use `import` at the transformer class level (@solnic)
|
9
|
+
* New `HashTransformation.deep_stringify_keys` function
|
10
|
+
|
11
|
+
[Compare v1.0.3...v1.1.0](https://github.com/solnic/transproc/compare/v1.0.3...v1.1.0)
|
12
|
+
|
13
|
+
# v1.0.3 2018-12-01
|
14
|
+
|
15
|
+
## Changed
|
16
|
+
|
17
|
+
* [BREAKING] Added minimal Ruby version to the gemspec file. Transproc now works with Ruby 2.3 and above (flash-gordon)
|
18
|
+
* Performance improvements introduced by using new built-in methods in `Hash` (v-kolesnikov + flash-gordon)
|
19
|
+
|
20
|
+
[Compare v1.0.2...v1.0.3](https://github.com/solnic/transproc/compare/v1.0.2...v1.0.3)
|
21
|
+
|
1
22
|
# v1.0.2 2017-02-25
|
2
23
|
|
3
24
|
## Fixed
|
@@ -8,7 +29,7 @@
|
|
8
29
|
|
9
30
|
# v1.0.1 2017-02-25
|
10
31
|
|
11
|
-
* `combine` is now multiple times faster, depending on the level of nesting (Kukunin + splattael)
|
32
|
+
* `combine` is now multiple times faster, depending on the level of nesting (Kukunin + splattael)
|
12
33
|
* `nest` (thus `wrap` too) is ~2x faster now (solnic)
|
13
34
|
|
14
35
|
[Compare v1.0.0...v1.0.1](https://github.com/solnic/transproc/compare/v1.0.0...v1.0.1)
|
data/Gemfile
CHANGED
@@ -2,28 +2,15 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
gem 'rake'
|
6
|
+
gem 'rspec', '~> 3.8'
|
7
|
+
gem 'dry-equalizer', '~> 0.2'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
platform :mri do
|
11
|
-
gem 'mutant', github: 'mbj/mutant', branch: 'master'
|
12
|
-
gem 'mutant-rspec'
|
13
|
-
|
14
|
-
gem 'codeclimate-test-reporter', require: false
|
15
|
-
gem 'simplecov', require: false
|
16
|
-
end
|
17
|
-
else
|
18
|
-
gem 'anima', '~> 0.2.0'
|
19
|
-
end
|
9
|
+
platform :mri do
|
10
|
+
gem 'simplecov', require: false
|
20
11
|
end
|
21
12
|
|
22
13
|
group :tools do
|
23
|
-
gem 'rubocop', '~> 0.30.0'
|
24
14
|
gem 'byebug', platform: :mri
|
25
15
|
gem 'benchmark-ips'
|
26
|
-
gem 'guard'
|
27
|
-
gem 'guard-rspec'
|
28
|
-
gem 'guard-rubocop'
|
29
16
|
end
|
data/README.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
[gem]: https://rubygems.org/gems/transproc
|
2
2
|
[travis]: https://travis-ci.org/solnic/transproc
|
3
|
-
[gemnasium]: https://gemnasium.com/solnic/transproc
|
4
3
|
[codeclimate]: https://codeclimate.com/github/solnic/transproc
|
5
4
|
[coveralls]: https://coveralls.io/r/solnic/transproc
|
6
5
|
[inchpages]: http://inch-ci.org/github/solnic/transproc
|
@@ -9,7 +8,6 @@
|
|
9
8
|
|
10
9
|
[][gem]
|
11
10
|
[][travis]
|
12
|
-
[][gemnasium]
|
13
11
|
[][codeclimate]
|
14
12
|
[][codeclimate]
|
15
13
|
[][inchpages]
|
@@ -197,9 +195,9 @@ transformation = t(:camel_case)
|
|
197
195
|
transformation.call 'i_am_a_camel'
|
198
196
|
# => "IAmACamel"
|
199
197
|
|
200
|
-
transformation = t(:map_array,
|
201
|
-
|
202
|
-
|
198
|
+
transformation = t(:map_array, (
|
199
|
+
t(:symbolize_keys).>> t(:rename_keys, user_name: :user)
|
200
|
+
)).>> t(:wrap, :address, [:city, :street, :zipcode])
|
203
201
|
|
204
202
|
transformation.call(
|
205
203
|
[
|
data/Rakefile
CHANGED
data/lib/transproc.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'transproc/version'
|
4
|
+
require 'transproc/constants'
|
2
5
|
require 'transproc/function'
|
3
6
|
require 'transproc/functions'
|
4
7
|
require 'transproc/composer'
|
@@ -8,9 +11,5 @@ require 'transproc/registry'
|
|
8
11
|
require 'transproc/transformer'
|
9
12
|
require 'transproc/support/deprecations'
|
10
13
|
|
11
|
-
module Transproc
|
12
|
-
Undefined = Object.new.freeze
|
13
|
-
end
|
14
|
-
|
15
14
|
require 'transproc/array'
|
16
15
|
require 'transproc/hash'
|
data/lib/transproc/all.rb
CHANGED
data/lib/transproc/array.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'transproc/coercions'
|
2
4
|
require 'transproc/hash'
|
3
5
|
require 'transproc/array/combine'
|
@@ -65,7 +67,7 @@ module Transproc
|
|
65
67
|
# Group array values using provided root key and value keys
|
66
68
|
#
|
67
69
|
# @example
|
68
|
-
# fn = Transproc(:group, :tags, [:
|
70
|
+
# fn = Transproc(:group, :tags, [:tag])
|
69
71
|
#
|
70
72
|
# fn.call [
|
71
73
|
# { task: 'Group it', tag: 'task' },
|
@@ -98,10 +100,10 @@ module Transproc
|
|
98
100
|
# Ungroup array values using provided root key and value keys
|
99
101
|
#
|
100
102
|
# @example
|
101
|
-
# fn = Transproc(:
|
103
|
+
# fn = Transproc(:ungroup, :tags, [:tag])
|
102
104
|
#
|
103
105
|
# fn.call [
|
104
|
-
# { task: 'Group it', tags: [{ tag: 'task' }, { tag: 'important' }]
|
106
|
+
# { task: 'Group it', tags: [{ tag: 'task' }, { tag: 'important' }] }
|
105
107
|
# ]
|
106
108
|
# # => [
|
107
109
|
# { task: 'Group it', tag: 'task' },
|
data/lib/transproc/class.rb
CHANGED
data/lib/transproc/coercions.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Transproc
|
4
|
+
# @api private
|
5
|
+
class Compiler
|
6
|
+
InvalidFunctionNameError = Class.new(StandardError)
|
7
|
+
|
8
|
+
attr_reader :registry, :transformer
|
9
|
+
|
10
|
+
def initialize(registry, transformer = nil)
|
11
|
+
@registry = registry
|
12
|
+
@transformer = transformer
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(ast)
|
16
|
+
ast.map(&method(:visit)).reduce(:>>)
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit(node)
|
20
|
+
id, *rest = node
|
21
|
+
public_send(:"visit_#{id}", *rest)
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit_fn(node)
|
25
|
+
name, rest = node
|
26
|
+
args = rest.map { |arg| visit(arg) }
|
27
|
+
|
28
|
+
if registry.contain?(name)
|
29
|
+
registry[name, *args]
|
30
|
+
elsif transformer.respond_to?(name)
|
31
|
+
Function.new(transformer.method(name), name: name, args: args)
|
32
|
+
else
|
33
|
+
raise InvalidFunctionNameError, "function name +#{name}+ is not valid"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def visit_arg(arg)
|
38
|
+
arg
|
39
|
+
end
|
40
|
+
|
41
|
+
def visit_t(node)
|
42
|
+
call(node)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/transproc/composer.rb
CHANGED
data/lib/transproc/composite.rb
CHANGED
data/lib/transproc/error.rb
CHANGED
data/lib/transproc/function.rb
CHANGED
data/lib/transproc/functions.rb
CHANGED
data/lib/transproc/hash.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'transproc/coercions'
|
2
4
|
|
3
5
|
module Transproc
|
@@ -17,20 +19,26 @@ module Transproc
|
|
17
19
|
module HashTransformations
|
18
20
|
extend Registry
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
if RUBY_VERSION >= '2.5'
|
23
|
+
# Map all keys in a hash with the provided transformation function
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# Transproc(:map_keys, -> s { s.upcase })['name' => 'Jane']
|
27
|
+
# # => {"NAME" => "Jane"}
|
28
|
+
#
|
29
|
+
# @param [Hash]
|
30
|
+
#
|
31
|
+
# @return [Hash]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def self.map_keys(source_hash, fn)
|
35
|
+
Hash[source_hash].transform_keys!(&fn)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
def self.map_keys(source_hash, fn)
|
39
|
+
Hash[source_hash].tap do |hash|
|
40
|
+
hash.keys.each { |key| hash[fn[key]] = hash.delete(key) }
|
41
|
+
end
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
@@ -94,20 +102,55 @@ module Transproc
|
|
94
102
|
map_keys(hash, Coercions[:to_string].fn)
|
95
103
|
end
|
96
104
|
|
97
|
-
#
|
105
|
+
# Stringify keys in a hash recursively
|
98
106
|
#
|
99
107
|
# @example
|
100
|
-
#
|
101
|
-
#
|
108
|
+
# input = { :foo => "bar", :baz => [{ :one => 1 }] }
|
109
|
+
#
|
110
|
+
# t(:deep_stringify_keys)[input]
|
111
|
+
# # => { "foo" => "bar", "baz" => [{ "one" => 1 }] }
|
102
112
|
#
|
103
113
|
# @param [Hash]
|
104
114
|
#
|
105
115
|
# @return [Hash]
|
106
116
|
#
|
107
117
|
# @api public
|
108
|
-
def self.
|
109
|
-
|
110
|
-
|
118
|
+
def self.deep_stringify_keys(hash)
|
119
|
+
hash.each_with_object({}) do |(key, value), output|
|
120
|
+
output[key.to_s] =
|
121
|
+
case value
|
122
|
+
when Hash
|
123
|
+
deep_stringify_keys(value)
|
124
|
+
when Array
|
125
|
+
value.map { |item|
|
126
|
+
item.is_a?(Hash) ? deep_stringify_keys(item) : item
|
127
|
+
}
|
128
|
+
else
|
129
|
+
value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
if RUBY_VERSION >= '2.4'
|
135
|
+
# Map all values in a hash using transformation function
|
136
|
+
#
|
137
|
+
# @example
|
138
|
+
# Transproc(:map_values, -> v { v.upcase })[:name => 'Jane']
|
139
|
+
# # => {"name" => "JANE"}
|
140
|
+
#
|
141
|
+
# @param [Hash]
|
142
|
+
#
|
143
|
+
# @return [Hash]
|
144
|
+
#
|
145
|
+
# @api public
|
146
|
+
def self.map_values(source_hash, fn)
|
147
|
+
Hash[source_hash].transform_values!(&fn)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
def self.map_values(source_hash, fn)
|
151
|
+
Hash[source_hash].tap do |hash|
|
152
|
+
hash.each { |key, value| hash[key] = fn[value] }
|
153
|
+
end
|
111
154
|
end
|
112
155
|
end
|
113
156
|
|
@@ -167,20 +210,26 @@ module Transproc
|
|
167
210
|
Hash[hash].reject { |k, _| keys.include?(k) }
|
168
211
|
end
|
169
212
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
213
|
+
if RUBY_VERSION >= '2.5'
|
214
|
+
# Accepts specified keys from a hash
|
215
|
+
#
|
216
|
+
# @example
|
217
|
+
# Transproc(:accept_keys, [:name])[name: 'Jane', email: 'jane@doe.org']
|
218
|
+
# # => {:name=>"Jane"}
|
219
|
+
#
|
220
|
+
# @param [Hash] hash The input hash
|
221
|
+
# @param [Array] keys The keys to be accepted
|
222
|
+
#
|
223
|
+
# @return [Hash]
|
224
|
+
#
|
225
|
+
# @api public
|
226
|
+
def self.accept_keys(hash, keys)
|
227
|
+
Hash[hash].slice(*keys)
|
228
|
+
end
|
229
|
+
else
|
230
|
+
def self.accept_keys(hash, keys)
|
231
|
+
reject_keys(hash, hash.keys - keys)
|
232
|
+
end
|
184
233
|
end
|
185
234
|
|
186
235
|
# Map a key in a hash with the provided transformation function
|