active_service_mapper 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.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ .idea/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_service_mapper.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Bhaskar Sundarraj
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ # ActiveServiceMapper
2
+
3
+ This gem will convert the json responses received from the web services to ruby hash.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_service_mapper'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_service_mapper
18
+
19
+ ## Usage
20
+ #service response in jso format
21
+
22
+ 1. response = {"FirstName"=>"Bob", "LastName"=>"Newhart"}
23
+
24
+ # convert the json response to a hash with symbols.
25
+
26
+ 2. response = Person.convert_response(response)
27
+
28
+ 3. puts response #{:first_name=>"Bob", :last_name=>"Newhart"}
29
+
30
+
31
+ 4. we can use plain_old_model gem and the person calss can be
32
+
33
+ class Person < PlainOldModel::Base
34
+ attr_accessor :first_name, :last_name
35
+ end
36
+
37
+ 5. @person = Person.new(response)
38
+
39
+ ## TODO
40
+ # add complex mapping, i.e when the service response keys are different from the class attribute names.
41
+ #
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ # If you want to make this the default task
8
+ task :default => :spec
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_service_mapper/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "active_service_mapper"
8
+ gem.version = ActiveServiceMapper::VERSION
9
+ gem.authors = ["Bhaskar Sundarraj"]
10
+ gem.email = ["bhaskar.sundarraj@gmail.com"]
11
+ gem.description = %q{This gem will provide a mapping functionality (like automapping service layer to the model) for projects which deal with services- preferably json responses.}
12
+ gem.summary = %q{This gem will provide a mapping functionality (like automapping service layer to the model) for projects which deal with services- preferably json responses.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_dependency 'plain_old_model'
20
+ gem.add_dependency 'activesupport'
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'rspec-core'
24
+ end
@@ -0,0 +1,7 @@
1
+ require 'plain_old_model'
2
+ require_relative 'phone_number'
3
+ class BillingAddress < PlainOldModel::Base
4
+ attr_accessor :address1, :address2
5
+ has_one :phone_number
6
+
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_service_mapper'
2
+ require 'plain_old_model/base'
3
+ require_relative 'billing_address'
4
+
5
+ class Person < PlainOldModel::Base
6
+ attr_accessor :first_name, :last_name
7
+ has_one :billing_address
8
+
9
+ extend ActiveServiceMapper
10
+ def self.convert_response(response,options={})
11
+ convert_to_symbol(response,options={})
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require 'plain_old_model/base'
2
+ class PhoneNumber < PlainOldModel::Base
3
+ attr_accessor :phone, :ext
4
+ end
@@ -0,0 +1,54 @@
1
+ require "active_service_mapper/version"
2
+ require 'plain_old_model/base'
3
+ module ActiveServiceMapper
4
+ extend self
5
+ def convert_to_symbol(response,options={})
6
+ keys_to_symbol(response, options={})
7
+ end
8
+
9
+
10
+ def keys_to_symbol(response, options)
11
+ new_hash = {}
12
+ response.each do |key,value|
13
+ if value.class == Hash
14
+ new_hash[key_to_symbol(key,options={})] = keys_to_symbol(value,options)
15
+ elsif value.class == Array
16
+ new_hash[key_to_symbol(key,options={})] = keys_to_symbol_array(value)
17
+ else #if value.class == String || value.class == Fixnum || value.class == Float
18
+ new_hash[key_to_symbol(key,options={})] = value
19
+ end
20
+ end
21
+ return new_hash
22
+ end
23
+
24
+ def key_to_symbol(key,options={})
25
+ key.to_s.underscore.to_sym
26
+ end
27
+
28
+ def keys_to_symbol_array(array)
29
+ new_array = []
30
+ array.each do |item|
31
+ if item.class == Hash
32
+ new_array << keys_to_symbol(item,options={})
33
+ elsif item.class == Array
34
+ new_array << keys_to_symbol_array(item)
35
+ else
36
+ new_array << item
37
+ end
38
+ end
39
+ return new_array
40
+ end
41
+
42
+
43
+ end
44
+
45
+
46
+ # simple case - just convert the response keys to rails format.
47
+
48
+ # somewhat complex
49
+ # - The hash has nested hash and arrays.
50
+ # - Do the same as simple case.
51
+
52
+ # complex : When the service response keys don't match up with the model's attributes.
53
+ # 3rd case option 1: A dsl implementation at the class level , which does indicate the mapping level
54
+ # 3rd case option 2 : A Config file which tells the mapper that certain fields from certain class map to certain field in the response.
@@ -0,0 +1,6 @@
1
+ module ActiveServiceMapper
2
+ class Base
3
+
4
+ end
5
+
6
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveServiceMapper
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+ #require 'json'
3
+
4
+
5
+ describe ActiveServiceMapper::Base do
6
+ extend ActiveServiceMapper
7
+ #describe "Version" do
8
+ #it "should return the correct version" do
9
+ # ActiveServiceMapper::VERSION.should == '0.0.1'
10
+ #end
11
+ #end
12
+
13
+ describe "Parsing json responses to rails hash format " do
14
+ it"should convert simple response values to a hash" do
15
+ simple_response = {"FirstName"=>"Bob", "LastName"=>"Newhart"}
16
+ Person.convert_response(simple_response).should == {:first_name=>"Bob", :last_name=>"Newhart"}
17
+ end
18
+
19
+ it"should convert response's with nested array values to a hash" do
20
+ not_simple_response = {"TestMe" => [{"Id"=> "one", "Desc" =>"Test"},{"Id"=> "two", "Desc" =>"test2"}]}
21
+ Person.convert_response(not_simple_response).should == {:test_me => [{:id => "one", :desc =>"Test"},{:id => "two", :desc =>"test2"}]}
22
+ end
23
+
24
+ it"should convert responses with nested hash values to a hash format" do
25
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two"}}
26
+ Person.convert_response(response_with_nested_attributes).should == {:first_name=>"Bob", :last_name=>"Newhart", :billing_address => {:address1 => "one", :address2 => "Two"}}
27
+ end
28
+ it"should convert responses with one level deep nested values to the proper hash format" do
29
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two", "PhoneNumber" => {"Phone" => "123456789","Ext" => "2313"}}}
30
+ Person.convert_response(response_with_nested_attributes).should == {:first_name=>"Bob", :last_name=>"Newhart", :billing_address=>{:address1=>"one", :address2=>"Two",:phone_number=>{:phone=>"123456789", :ext=>"2313"}} }
31
+ end
32
+ it"should convert responses with multi level nested values to hash format" do
33
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two", "PhoneNumber" => {"Phone" => "123456789","Ext" => "2313", "TestMe" => [{"Id"=> "one", "Desc" =>"test"},{"Id"=> "two", "Desc" =>"test2"} ]}}}
34
+ Person.convert_response(response_with_nested_attributes).should == {:first_name=>"Bob", :last_name=>"Newhart",:billing_address=>{:address1=>"one", :address2=>"Two",:phone_number => {:phone => "123456789",:ext => "2313", :test_me => [{:id => "one", :desc =>"test"},{:id => "two", :desc =>"test2"} ]}}}
35
+ end
36
+ it"should assign the responses with deep nested hashes and arrays to proper hash" do
37
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two", "PhoneNumber" => {"Phone" => "123456789","Ext" => "2313", "TestMe" => [{"Id"=> "one", "Desc" =>"test", "Test" => [{"ID" => "identity"}]},{"Id"=> "two", "Desc" =>"test2"} ]}}}
38
+ Person.convert_response(response_with_nested_attributes).should == {:first_name=>"Bob", :last_name=>"Newhart", :billing_address=>{:address1=>"one", :address2=>"Two", :phone_number=>{:phone=>"123456789", :ext=>"2313", :test_me=>[{:id=>"one", :desc=>"test", :test=>[{:id=>"identity"}]}, {:id=>"two", :desc=>"test2"}]}}}
39
+ end
40
+
41
+ end
42
+
43
+ describe "response mapping to class" do
44
+ it"should assign the simple response values to a hash" do
45
+ simple_response = {"FirstName"=>"Bob", "LastName"=>"Newhart"}
46
+ Person.convert_response(simple_response).should == {:first_name=>"Bob", :last_name=>"Newhart"}
47
+ @person = Person.new(Person.convert_to_symbol(simple_response))
48
+ @person.first_name.should == "Bob"
49
+ @person.last_name.should == "Newhart"
50
+ end
51
+ it"should assign the response's nested array values to a hash" do
52
+ not_simple_response = {"TestMe" => [{"Id"=> "one", "Desc" =>"Test"},{"Id"=> "two", "Desc" =>"test2"}]}
53
+ response = Person.convert_response(not_simple_response)
54
+ response.should == {:test_me => [{:id => "one", :desc =>"Test"},{:id => "two", :desc =>"test2"}]}
55
+ @person = Person.new(response)
56
+ end
57
+ it"should assign the responses with nested hash values to a hash" do
58
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two"}}
59
+ response = Person.convert_response(response_with_nested_attributes)
60
+ response.should == {:first_name=>"Bob", :last_name=>"Newhart", :billing_address => {:address1 => "one", :address2 => "Two"}}
61
+ #@person = Person.new(response)
62
+ #@person.billing_address.should == {:address1 => "one", :address2 => "Two"}
63
+ #puts @person.billing_address.class
64
+
65
+ end
66
+ it"should assign the responses with multi level nested values to the class attribute" do
67
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two", "PhoneNumber" => {"Phone" => "123456789","Ext" => "2313", "TestMe" => [{"Id"=> "one", "Desc" =>"test"},{"Id"=> "two", "Desc" =>"test2"} ]}}}
68
+ response = Person.convert_response(response_with_nested_attributes)
69
+ response.should == {:first_name=>"Bob", :last_name=>"Newhart",:billing_address=>{:address1=>"one", :address2=>"Two",:phone_number => {:phone => "123456789",:ext => "2313", :test_me => [{:id => "one", :desc =>"test"},{:id => "two", :desc =>"test2"} ]}}}
70
+ #@person = Person.new(response)
71
+ #@person.billing_address.should == {:address1=>"one", :address2=>"Two", :phone_number=>{:phone=>"123456789", :ext=>"2313", :test_me=>[{:id=>"one", :desc=>"test"}, {:id=>"two", :desc=>"test2"}]}}
72
+ #@billing_address = @person.billing_address
73
+ ##@phone = @billing_address.phone_number
74
+ end
75
+ it"should assign the responses with multi level nested values to the class attribute" do
76
+ response_with_nested_attributes = {"FirstName"=>"Bob", "LastName"=>"Newhart", "BillingAddress" => {"Address1" => "one", "Address2" => "Two", "PhoneNumber" => {"Phone" => "123456789","Ext" => "2313", "TestMe" => [{"Id"=> "one", "Desc" =>"test", "Test" => [{"ID" => "identity"}]},{"Id"=> "two", "Desc" =>"test2"} ]}}}
77
+ Person.convert_response(response_with_nested_attributes).should == {:first_name=>"Bob", :last_name=>"Newhart", :billing_address=>{:address1=>"one", :address2=>"Two", :phone_number=>{:phone=>"123456789", :ext=>"2313", :test_me=>[{:id=>"one", :desc=>"test", :test=>[{:id=>"identity"}]}, {:id=>"two", :desc=>"test2"}]}}}
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+
85
+
86
+ # mapper , a config file which tells what to map to where . i.e like class.attribute = service.attribute
87
+ #
88
+ #
89
+
90
+ require 'plain_old_model/base'
91
+ require 'active_service_mapper'
92
+ class Person < PlainOldModel::Base
93
+ require_relative '../../example/billing_address'
94
+ attr_accessor :first_name, :last_name
95
+ has_one :billing_address
96
+
97
+ extend ActiveServiceMapper
98
+ def self.convert_response(response,options={})
99
+ convert_to_symbol(response,options={})
100
+ end
101
+ end
102
+
103
+ class BillingAddress < PlainOldModel::Base
104
+ attr_accessor :address1, :address2
105
+ has_one :phone_number
106
+
107
+ end
108
+
109
+ class PhoneNumber < PlainOldModel::Base
110
+ attr_accessor :phone, :ext
111
+ end
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'active_service_mapper'
8
+ require 'active_service_mapper/version'
9
+ require 'active_service_mapper/base'
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_service_mapper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bhaskar Sundarraj
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: plain_old_model
16
+ requirement: &70147494836600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70147494836600
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70147494835860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70147494835860
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70147494835200 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70147494835200
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70147494846700 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70147494846700
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec-core
60
+ requirement: &70147494845220 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70147494845220
69
+ description: This gem will provide a mapping functionality (like automapping service
70
+ layer to the model) for projects which deal with services- preferably json responses.
71
+ email:
72
+ - bhaskar.sundarraj@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .rspec
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - active_service_mapper.gemspec
84
+ - example/billing_address.rb
85
+ - example/person.rb
86
+ - example/phone_number.rb
87
+ - lib/active_service_mapper.rb
88
+ - lib/active_service_mapper/base.rb
89
+ - lib/active_service_mapper/version.rb
90
+ - spec/lib/base_spec.rb
91
+ - spec/spec_helper.rb
92
+ homepage: ''
93
+ licenses: []
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.8.17
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: This gem will provide a mapping functionality (like automapping service layer
116
+ to the model) for projects which deal with services- preferably json responses.
117
+ test_files:
118
+ - spec/lib/base_spec.rb
119
+ - spec/spec_helper.rb