transformers 0.0.1
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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +97 -0
- data/LICENSE +21 -0
- data/README.md +114 -0
- data/Rakefile +12 -0
- data/TODO.md +0 -0
- data/lib/rspec/support/convert_to_matcher.rb +18 -0
- data/lib/rspec/transformers.rb +1 -0
- data/lib/transformers.rb +31 -0
- data/lib/transformers/boolean.rb +9 -0
- data/lib/transformers/extensions/action_controller.rb +20 -0
- data/lib/transformers/extensions/hash.rb +37 -0
- data/lib/transformers/method_call.rb +17 -0
- data/lib/transformers/missing_option.rb +7 -0
- data/lib/transformers/rails.rb +1 -0
- data/lib/transformers/unknown_transformer.rb +7 -0
- data/lib/transformers/version.rb +3 -0
- data/spec/rails_spec_helper.rb +12 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/transformers/boolean_spec.rb +13 -0
- data/spec/transformers/extensions/action_controller_spec.rb +47 -0
- data/spec/transformers/extensions/hash_spec.rb +193 -0
- data/spec/transformers/method_call_spec.rb +11 -0
- data/spec/transformers_spec.rb +48 -0
- data/transformers.gemspec +24 -0
- metadata +178 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
transformers (0.0.1)
|
5
|
+
activesupport (~> 3.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
abstract (1.0.0)
|
11
|
+
actionmailer (3.0.5)
|
12
|
+
actionpack (= 3.0.5)
|
13
|
+
mail (~> 2.2.15)
|
14
|
+
actionpack (3.0.5)
|
15
|
+
activemodel (= 3.0.5)
|
16
|
+
activesupport (= 3.0.5)
|
17
|
+
builder (~> 2.1.2)
|
18
|
+
erubis (~> 2.6.6)
|
19
|
+
i18n (~> 0.4)
|
20
|
+
rack (~> 1.2.1)
|
21
|
+
rack-mount (~> 0.6.13)
|
22
|
+
rack-test (~> 0.5.7)
|
23
|
+
tzinfo (~> 0.3.23)
|
24
|
+
activemodel (3.0.5)
|
25
|
+
activesupport (= 3.0.5)
|
26
|
+
builder (~> 2.1.2)
|
27
|
+
i18n (~> 0.4)
|
28
|
+
activerecord (3.0.5)
|
29
|
+
activemodel (= 3.0.5)
|
30
|
+
activesupport (= 3.0.5)
|
31
|
+
arel (~> 2.0.2)
|
32
|
+
tzinfo (~> 0.3.23)
|
33
|
+
activeresource (3.0.5)
|
34
|
+
activemodel (= 3.0.5)
|
35
|
+
activesupport (= 3.0.5)
|
36
|
+
activesupport (3.0.5)
|
37
|
+
arel (2.0.9)
|
38
|
+
builder (2.1.2)
|
39
|
+
diff-lcs (1.1.2)
|
40
|
+
erubis (2.6.6)
|
41
|
+
abstract (>= 1.0.0)
|
42
|
+
i18n (0.5.0)
|
43
|
+
mail (2.2.17)
|
44
|
+
activesupport (>= 2.3.6)
|
45
|
+
i18n (>= 0.4.0)
|
46
|
+
mime-types (~> 1.16)
|
47
|
+
treetop (~> 1.4.8)
|
48
|
+
mime-types (1.16)
|
49
|
+
mocha (0.9.12)
|
50
|
+
polyglot (0.3.1)
|
51
|
+
rack (1.2.2)
|
52
|
+
rack-mount (0.6.14)
|
53
|
+
rack (>= 1.0.0)
|
54
|
+
rack-test (0.5.7)
|
55
|
+
rack (>= 1.0)
|
56
|
+
rails (3.0.5)
|
57
|
+
actionmailer (= 3.0.5)
|
58
|
+
actionpack (= 3.0.5)
|
59
|
+
activerecord (= 3.0.5)
|
60
|
+
activeresource (= 3.0.5)
|
61
|
+
activesupport (= 3.0.5)
|
62
|
+
bundler (~> 1.0)
|
63
|
+
railties (= 3.0.5)
|
64
|
+
railties (3.0.5)
|
65
|
+
actionpack (= 3.0.5)
|
66
|
+
activesupport (= 3.0.5)
|
67
|
+
rake (>= 0.8.7)
|
68
|
+
thor (~> 0.14.4)
|
69
|
+
rake (0.8.7)
|
70
|
+
rspec (2.5.0)
|
71
|
+
rspec-core (~> 2.5.0)
|
72
|
+
rspec-expectations (~> 2.5.0)
|
73
|
+
rspec-mocks (~> 2.5.0)
|
74
|
+
rspec-core (2.5.1)
|
75
|
+
rspec-expectations (2.5.0)
|
76
|
+
diff-lcs (~> 1.1.2)
|
77
|
+
rspec-mocks (2.5.0)
|
78
|
+
rspec-rails (2.5.0)
|
79
|
+
actionpack (~> 3.0)
|
80
|
+
activesupport (~> 3.0)
|
81
|
+
railties (~> 3.0)
|
82
|
+
rspec (~> 2.5.0)
|
83
|
+
thor (0.14.6)
|
84
|
+
treetop (1.4.9)
|
85
|
+
polyglot (>= 0.3.1)
|
86
|
+
tzinfo (0.3.26)
|
87
|
+
|
88
|
+
PLATFORMS
|
89
|
+
ruby
|
90
|
+
|
91
|
+
DEPENDENCIES
|
92
|
+
activesupport (~> 3.0.0)
|
93
|
+
mocha (~> 0.9.10)
|
94
|
+
rails (~> 3.0.0)
|
95
|
+
rspec (~> 2.5.0)
|
96
|
+
rspec-rails (~> 2.5.0)
|
97
|
+
transformers!
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Deepak N
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
Transformers [](http://travis-ci.org/endeepak/transformers)
|
2
|
+
============
|
3
|
+
|
4
|
+
Transformers is an extension to hash to allow various transformations using simple DSL. It also has optional rails extension to dry up frequently applied transformations on controller params.
|
5
|
+
|
6
|
+
Install
|
7
|
+
=======
|
8
|
+
|
9
|
+
[not yet released]
|
10
|
+
|
11
|
+
Usage
|
12
|
+
=====
|
13
|
+
|
14
|
+
gem install transformers
|
15
|
+
|
16
|
+
OR Add dependency in gem file for projects using bundler
|
17
|
+
|
18
|
+
gem transformers
|
19
|
+
|
20
|
+
Available Transformations
|
21
|
+
=========================
|
22
|
+
|
23
|
+
* Convert values
|
24
|
+
|
25
|
+
hash = {:foo => 'bar'}
|
26
|
+
|
27
|
+
hash.convert :eric, :to => lambda { |value| value.upcase }
|
28
|
+
|
29
|
+
OR use short hand notation to call a method on the value
|
30
|
+
|
31
|
+
hash.convert :foo, :to => :upcase
|
32
|
+
|
33
|
+
* Combine keys
|
34
|
+
|
35
|
+
hash.convert :begin, :end, :as => :range
|
36
|
+
|
37
|
+
* Rename keys
|
38
|
+
|
39
|
+
hash.rename :foo, :to => :bar
|
40
|
+
|
41
|
+
OR
|
42
|
+
|
43
|
+
hash.convert :foo, :as => :bar
|
44
|
+
|
45
|
+
* Alias key
|
46
|
+
|
47
|
+
hash.copy :foo, :to => :bar
|
48
|
+
|
49
|
+
* Convert and combine
|
50
|
+
|
51
|
+
hash.convert :first_name, :last_name, :as => :name, :to => lambda { |first_name, last_name| first_name + ' '+ last_name }
|
52
|
+
|
53
|
+
* Conversion using type converters
|
54
|
+
|
55
|
+
hash = {:foo => 'true'}
|
56
|
+
|
57
|
+
hash.convert :foo, :to => :boolean #built-in
|
58
|
+
|
59
|
+
* Using Custom converters : You can pass a lambda or define a module or an object which has a call method. This method will receive values for given keys and should return the converted value.
|
60
|
+
|
61
|
+
module Transformers::Name
|
62
|
+
def self.call(first_name, last_name)
|
63
|
+
return first_name + ' '+ last_name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
Register the converter
|
68
|
+
|
69
|
+
Transformers.register(:name, Transformers::Name)
|
70
|
+
|
71
|
+
Usage
|
72
|
+
|
73
|
+
hash.convert :first_name, :last_name, :as => :name, :to => :name
|
74
|
+
|
75
|
+
* Use them together in a transform block
|
76
|
+
|
77
|
+
hash.transform do
|
78
|
+
delete :unwanted
|
79
|
+
rename :foo, :to => :bar
|
80
|
+
convert :first_name, :last_name, :as => :name, :to => :name
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
Rails Extensions
|
85
|
+
================
|
86
|
+
|
87
|
+
To Include rails extensions add the below line in a config/initializer/transformers.rb. You can register the custom transformers in the same file.
|
88
|
+
|
89
|
+
require 'transformers/rails'
|
90
|
+
|
91
|
+
This adds _transform\_params_ extension to action controller. You can define the transformations for any action as,
|
92
|
+
|
93
|
+
transform_params :search, :only => :index do
|
94
|
+
convert :first_name, :last_name, :as => :name, :to => :name
|
95
|
+
end
|
96
|
+
|
97
|
+
This will add a before\_filter in the controller to apply transformations on params[:search]. If the first argument is omitted, the transformations will be applied directly on the params. The options for transform\_params are same as before\_filter options.
|
98
|
+
|
99
|
+
Rspec Matcher
|
100
|
+
=============
|
101
|
+
This gem has a rspec matcher for testing the custom converters. To use this, add the below line in the _spec\_helper_
|
102
|
+
|
103
|
+
require 'rspec/transformers'
|
104
|
+
|
105
|
+
The converter spec can be written as
|
106
|
+
|
107
|
+
describe Transformers::Boolean do
|
108
|
+
it { should convert('true').to(true)}
|
109
|
+
it { should convert('false').to(false)}
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require "rspec"
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new do |t|
|
8
|
+
t.rspec_opts = %w(--format documentation --color)
|
9
|
+
t.pattern = 'spec/**/*_spec.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => ["spec"]
|
data/TODO.md
ADDED
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec::Matchers.define :convert do |value|
|
2
|
+
chain :to do |expected_value|
|
3
|
+
@expected_value = expected_value
|
4
|
+
end
|
5
|
+
|
6
|
+
match do
|
7
|
+
@converted_value = subject.call(value)
|
8
|
+
@converted_value == @expected_value
|
9
|
+
end
|
10
|
+
|
11
|
+
failure_message_for_should do |model|
|
12
|
+
"expected #{subject} to convert #{value.inspect} to #{@expected_value.inspect} but was #{@converted_value.inspect}"
|
13
|
+
end
|
14
|
+
|
15
|
+
description do
|
16
|
+
"convert #{value.inspect} to #{@expected_value.inspect}"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'rspec/support/convert_to_matcher'
|
data/lib/transformers.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
|
3
|
+
require 'transformers/boolean'
|
4
|
+
require 'transformers/method_call'
|
5
|
+
require 'transformers/missing_option'
|
6
|
+
require 'transformers/unknown_transformer'
|
7
|
+
require 'transformers/extensions/hash'
|
8
|
+
|
9
|
+
module Transformers
|
10
|
+
STANDARD = { :boolean => Transformers::Boolean }.freeze
|
11
|
+
|
12
|
+
def self.custom
|
13
|
+
@custom ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all
|
17
|
+
custom.merge(STANDARD)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get(transformer)
|
21
|
+
case transformer
|
22
|
+
when Module, Proc: transformer
|
23
|
+
when Symbol: all.has_key?(transformer) ? all[transformer] : MethodCall.new(transformer)
|
24
|
+
else raise UnknownTransformer.new(transformer)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.register(name, transformer)
|
29
|
+
custom[name] = transformer
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "action_controller/railtie"
|
2
|
+
|
3
|
+
module Transformers
|
4
|
+
module Extensions
|
5
|
+
module ActionController
|
6
|
+
def self.included(klass)
|
7
|
+
klass.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def transform_params(*args, &block)
|
12
|
+
options = args.extract_options!
|
13
|
+
before_filter(options) { params.transform(args.first, &block) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
ActionController::Base.send(:include, Transformers::Extensions::ActionController)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Transformers
|
2
|
+
module Extensions
|
3
|
+
module Hash
|
4
|
+
def transform(key = nil, &block)
|
5
|
+
target = key.nil? ? self : self[key]
|
6
|
+
if target
|
7
|
+
raise TypeError.new("Can't apply transformations on #{target.inspect}. Expected a Hash") unless target.is_a?(Hash)
|
8
|
+
target.instance_eval(&block)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def convert(*keys)
|
13
|
+
options = keys.extract_options!
|
14
|
+
return unless keys.any? { |key| self.has_key?(key) }
|
15
|
+
new_key = options[:as] || keys.first
|
16
|
+
converter = options[:to]
|
17
|
+
values = keys.collect { |key| delete(key) }
|
18
|
+
new_value = converter ? Transformers.get(converter).call(*values) : (values.length == 1 ? values.first : values)
|
19
|
+
self[new_key] = new_value
|
20
|
+
end
|
21
|
+
|
22
|
+
def rename(key, options = {})
|
23
|
+
new_key = options[:to]
|
24
|
+
raise MissingOption.new(:to) if new_key.nil?
|
25
|
+
self[new_key] = self.delete(key)
|
26
|
+
end
|
27
|
+
|
28
|
+
def copy(key, options = {})
|
29
|
+
new_key = options[:to]
|
30
|
+
raise MissingOption.new(:to) if new_key.nil?
|
31
|
+
self[new_key] = self[key]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Hash.send(:include, Transformers::Extensions::Hash)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'transformers/extensions/action_controller'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
|
3
|
+
class Transformers::Application < Rails::Application
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'rspec/rails'
|
7
|
+
|
8
|
+
Transformers::Application.routes.draw do
|
9
|
+
match ':controller(/:action(/:id(.:format)))'
|
10
|
+
end
|
11
|
+
|
12
|
+
include Rails.application.routes.url_helpers
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Transformers::Boolean do
|
4
|
+
it { should convert('true').to(true)}
|
5
|
+
it { should convert(true).to(true)}
|
6
|
+
|
7
|
+
it { should convert(false).to(false)}
|
8
|
+
it { should convert('false').to(false)}
|
9
|
+
it { should convert(nil).to(false)}
|
10
|
+
it { should convert('').to(false)}
|
11
|
+
it { should convert(' ').to(false)}
|
12
|
+
it { should convert('anything else').to(false)}
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
#TODO: Find why adding transform_params in individual spec definition fails and fix it.
|
4
|
+
class TestActionController < ActionController::Base
|
5
|
+
transform_params { convert :foo, :to => :upcase }
|
6
|
+
|
7
|
+
transform_params :bar do
|
8
|
+
convert :foo, :to => :upcase
|
9
|
+
end
|
10
|
+
|
11
|
+
transform_params :baz, :only => :index do
|
12
|
+
convert :foo, :to => :upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
def index; head :ok; end
|
16
|
+
def show; head :ok; end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe TestActionController, :type => :controller do
|
20
|
+
describe "transform_params" do
|
21
|
+
context "without args" do
|
22
|
+
it "transforms params by default" do
|
23
|
+
get :index, :foo => "hello"
|
24
|
+
|
25
|
+
controller.params[:foo].should == "HELLO"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with a key name as param" do
|
30
|
+
it "transforms params[key]" do
|
31
|
+
get :index, :bar => {:foo => "hello"}
|
32
|
+
|
33
|
+
controller.params[:bar][:foo].should == "HELLO"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with additional options" do
|
38
|
+
it "should pass the options to before filter" do
|
39
|
+
get :index, :baz => {:foo => "hello"}
|
40
|
+
controller.params[:baz][:foo].should == "HELLO"
|
41
|
+
|
42
|
+
get :show, :baz => {:foo => "hello"}
|
43
|
+
controller.params[:baz][:foo].should == "hello"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
describe "#transform" do
|
5
|
+
context "without any arguments" do
|
6
|
+
it "should execute the transformations in the context of hash" do
|
7
|
+
hash = {:key => 'value'}
|
8
|
+
|
9
|
+
hash.transform { delete :key }
|
10
|
+
|
11
|
+
hash.should_not have_key(:key)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with key as argument" do
|
16
|
+
context "when value is not a hash" do
|
17
|
+
it "should execute the transformations in the context of value" do
|
18
|
+
hash = {:key => { :nested_key => 'value'} }
|
19
|
+
|
20
|
+
hash.transform(:key) { delete :nested_key }
|
21
|
+
|
22
|
+
hash[:key].should_not have_key(:nested_key)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when value in nil" do
|
27
|
+
it "should not execute any transformations" do
|
28
|
+
hash = {:key => nil }
|
29
|
+
|
30
|
+
hash.transform(:key) { delete :nested_key }
|
31
|
+
|
32
|
+
hash[:key].should be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when value is not a hash" do
|
37
|
+
it "should raise error" do
|
38
|
+
hash = {:key => 'value' }
|
39
|
+
|
40
|
+
expect {
|
41
|
+
hash.transform(:key) do
|
42
|
+
convert :foo, :as => :bar
|
43
|
+
end
|
44
|
+
}.should raise_error(/Can't apply transformations on "value". Expected a Hash/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#convert" do
|
51
|
+
context "with :as option" do
|
52
|
+
context "for single key" do
|
53
|
+
it "should rename the key" do
|
54
|
+
hash = {:stan => 'marsh'}
|
55
|
+
|
56
|
+
hash.convert :stan, :as => :eric
|
57
|
+
|
58
|
+
hash.should_not have_key(:stan)
|
59
|
+
hash.should have_key(:eric)
|
60
|
+
hash[:eric].should == 'marsh'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "for multiple keys" do
|
65
|
+
it "should combine the keys to single key" do
|
66
|
+
hash = {:begin => 12, :end => 22}
|
67
|
+
|
68
|
+
hash.convert :begin, :end, :as => :range
|
69
|
+
|
70
|
+
hash.should_not have_key(:begin)
|
71
|
+
hash.should_not have_key(:end)
|
72
|
+
hash.should have_key(:range)
|
73
|
+
hash[:range].should == [12, 22]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with :to option" do
|
79
|
+
it "should call 'call' on the converter obtained from transformer to set converted value" do
|
80
|
+
hash = {:key => :value}
|
81
|
+
converter = mock
|
82
|
+
Transformers.expects(:get).with(:converter).returns(converter)
|
83
|
+
converter.expects(:call).with(:value).returns(:converted_value)
|
84
|
+
|
85
|
+
hash.convert :key, :to => :converter
|
86
|
+
|
87
|
+
hash[:key].should == :converted_value
|
88
|
+
end
|
89
|
+
|
90
|
+
context "for single key" do
|
91
|
+
context "when key exists" do
|
92
|
+
it "should replace value with converted value" do
|
93
|
+
hash = {:eric => 'cartman'}
|
94
|
+
|
95
|
+
hash.convert :eric, :to => lambda { |value| value.upcase }
|
96
|
+
|
97
|
+
hash[:eric].should == 'CARTMAN'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when key does not exist" do
|
102
|
+
it "should not apply conversion" do
|
103
|
+
hash = {:eric => 'cartman'}
|
104
|
+
|
105
|
+
hash.convert :stan, :to => :kyle
|
106
|
+
|
107
|
+
hash[:eric].should == 'cartman'
|
108
|
+
hash.should_not have_key(:stan)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when hash has indifferent access" do
|
114
|
+
it "should apply conversion" do
|
115
|
+
hash = {'eric' => 'cartman'}.with_indifferent_access
|
116
|
+
|
117
|
+
hash.convert :eric, :to => :upcase
|
118
|
+
|
119
|
+
hash['eric'].should == 'CARTMAN'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "for multiple keys" do
|
124
|
+
context "when all keys exists" do
|
125
|
+
it "should pass multiple values to converter and set converted vlaue for key given in :as option" do
|
126
|
+
hash = {:first_name => 'eric', :last_name => 'cartman' }
|
127
|
+
|
128
|
+
hash.convert :first_name, :last_name, :as => :name, :to => lambda { |first_name, last_name| "#{first_name} #{last_name}" }
|
129
|
+
|
130
|
+
hash[:name].should == 'eric cartman'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "when one of keys exists" do
|
135
|
+
it "should pass multiple values to converter and set converted vlaue for key given in :as option" do
|
136
|
+
hash = {:first_name => 'eric' }
|
137
|
+
|
138
|
+
hash.convert :first_name, :last_name, :as => :name, :to => lambda { |first_name, last_name| "#{first_name} #{last_name}" }
|
139
|
+
|
140
|
+
hash[:name].should == 'eric '
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "when none of keys exists" do
|
145
|
+
it "should not apply conversion" do
|
146
|
+
hash = {}
|
147
|
+
|
148
|
+
hash.convert :first_name, :last_name, :as => :name, :to => lambda { |first_name, last_name| "#{first_name} #{last_name}" }
|
149
|
+
|
150
|
+
hash.should_not have_key(:name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "rename" do
|
158
|
+
it "should rename the key" do
|
159
|
+
hash = {:stan => 'marsh'}
|
160
|
+
|
161
|
+
hash.rename :stan, :to => :eric
|
162
|
+
|
163
|
+
hash.should_not have_key(:stan)
|
164
|
+
hash.should have_key(:eric)
|
165
|
+
hash[:eric].should == 'marsh'
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should raise error if :to option is missing" do
|
169
|
+
hash = {:stan => 'marsh'}
|
170
|
+
|
171
|
+
expect { hash.rename :stan }.should raise_error(/Missing options : :to/)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "copy" do
|
176
|
+
it "should copy the value to another key" do
|
177
|
+
hash = {:stan => 'southpark'}
|
178
|
+
|
179
|
+
hash.copy :stan, :to => :eric
|
180
|
+
|
181
|
+
hash.should have_key(:eric)
|
182
|
+
hash.should have_key(:stan)
|
183
|
+
hash[:eric].should == hash[:stan]
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should raise error if :to option is missing" do
|
187
|
+
hash = {:stan => 'marsh'}
|
188
|
+
|
189
|
+
expect { hash.copy :stan }.should raise_error(/Missing options : :to/)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Transformers::MethodCall do
|
4
|
+
context "with method name :upcase" do
|
5
|
+
subject { Transformers::MethodCall.new(:upcase) }
|
6
|
+
|
7
|
+
it { should convert('hello').to('HELLO') }
|
8
|
+
it { should == Transformers::MethodCall.new(:upcase) }
|
9
|
+
it { should == Transformers::MethodCall.new('upcase') }
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Transformers do
|
4
|
+
describe ".get" do
|
5
|
+
context "when key is a proc" do
|
6
|
+
it "should return proc" do
|
7
|
+
transformer = lambda { |value| return :converted_value }
|
8
|
+
|
9
|
+
Transformers.get(transformer).should == transformer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when key is a module" do
|
14
|
+
it "should return module" do
|
15
|
+
Transformers.get(Transformers::Boolean).should == Transformers::Boolean
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when key is symbol" do
|
20
|
+
context "standard transformer" do
|
21
|
+
it "should return standard transformer" do
|
22
|
+
Transformers.get(:boolean).should == Transformers::Boolean
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "registered transformer" do
|
27
|
+
it "should return registered transformer" do
|
28
|
+
transformer = lambda {|value| value.downcase }
|
29
|
+
Transformers.register(:downcase, transformer)
|
30
|
+
|
31
|
+
Transformers.get(:downcase).should == transformer
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "not registered" do
|
36
|
+
it "should return method call transformer" do
|
37
|
+
Transformers.get(:upcase).should == Transformers::MethodCall.new(:upcase)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when key is anything else" do
|
43
|
+
it "should raise error" do
|
44
|
+
expect { Transformers.get("UNKNOWN") }.should raise_error('The "UNKNOWN" transformer is not supported')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "transformers/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "transformers"
|
7
|
+
s.version = Transformers::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Deepak N"]
|
10
|
+
s.email = ["endeep123@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/endeepak/transformers"
|
12
|
+
s.summary = %q{DSL to transform a hash}
|
13
|
+
s.description = %q{An extension to hash to allow various transformations using simple DSL. Also has optional rails extension to dry up frequently applied transformations on controller params.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.add_runtime_dependency("activesupport", "~> 3.0.0")
|
20
|
+
s.add_development_dependency("rails", "~> 3.0.0")
|
21
|
+
s.add_development_dependency("rspec", "~> 2.5.0")
|
22
|
+
s.add_development_dependency("rspec-rails", "~> 2.5.0")
|
23
|
+
s.add_development_dependency("mocha", "~> 0.9.10")
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: transformers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Deepak N
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-15 00:00:00 +05:30
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activesupport
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 3.0.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rails
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 3
|
48
|
+
- 0
|
49
|
+
- 0
|
50
|
+
version: 3.0.0
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 27
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 5
|
65
|
+
- 0
|
66
|
+
version: 2.5.0
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 27
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 5
|
81
|
+
- 0
|
82
|
+
version: 2.5.0
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: mocha
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 47
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 9
|
97
|
+
- 10
|
98
|
+
version: 0.9.10
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
101
|
+
description: An extension to hash to allow various transformations using simple DSL. Also has optional rails extension to dry up frequently applied transformations on controller params.
|
102
|
+
email:
|
103
|
+
- endeep123@gmail.com
|
104
|
+
executables: []
|
105
|
+
|
106
|
+
extensions: []
|
107
|
+
|
108
|
+
extra_rdoc_files: []
|
109
|
+
|
110
|
+
files:
|
111
|
+
- .gitignore
|
112
|
+
- Gemfile
|
113
|
+
- Gemfile.lock
|
114
|
+
- LICENSE
|
115
|
+
- README.md
|
116
|
+
- Rakefile
|
117
|
+
- TODO.md
|
118
|
+
- lib/rspec/support/convert_to_matcher.rb
|
119
|
+
- lib/rspec/transformers.rb
|
120
|
+
- lib/transformers.rb
|
121
|
+
- lib/transformers/boolean.rb
|
122
|
+
- lib/transformers/extensions/action_controller.rb
|
123
|
+
- lib/transformers/extensions/hash.rb
|
124
|
+
- lib/transformers/method_call.rb
|
125
|
+
- lib/transformers/missing_option.rb
|
126
|
+
- lib/transformers/rails.rb
|
127
|
+
- lib/transformers/unknown_transformer.rb
|
128
|
+
- lib/transformers/version.rb
|
129
|
+
- spec/rails_spec_helper.rb
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
- spec/transformers/boolean_spec.rb
|
132
|
+
- spec/transformers/extensions/action_controller_spec.rb
|
133
|
+
- spec/transformers/extensions/hash_spec.rb
|
134
|
+
- spec/transformers/method_call_spec.rb
|
135
|
+
- spec/transformers_spec.rb
|
136
|
+
- transformers.gemspec
|
137
|
+
has_rdoc: true
|
138
|
+
homepage: https://github.com/endeepak/transformers
|
139
|
+
licenses: []
|
140
|
+
|
141
|
+
post_install_message:
|
142
|
+
rdoc_options: []
|
143
|
+
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
hash: 3
|
152
|
+
segments:
|
153
|
+
- 0
|
154
|
+
version: "0"
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
+
none: false
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
hash: 3
|
161
|
+
segments:
|
162
|
+
- 0
|
163
|
+
version: "0"
|
164
|
+
requirements: []
|
165
|
+
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 1.4.2
|
168
|
+
signing_key:
|
169
|
+
specification_version: 3
|
170
|
+
summary: DSL to transform a hash
|
171
|
+
test_files:
|
172
|
+
- spec/rails_spec_helper.rb
|
173
|
+
- spec/spec_helper.rb
|
174
|
+
- spec/transformers/boolean_spec.rb
|
175
|
+
- spec/transformers/extensions/action_controller_spec.rb
|
176
|
+
- spec/transformers/extensions/hash_spec.rb
|
177
|
+
- spec/transformers/method_call_spec.rb
|
178
|
+
- spec/transformers_spec.rb
|