ixtlan-babel 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ixtlan-babel.rb CHANGED
@@ -1,4 +1,2 @@
1
1
  require 'ixtlan/babel/serializer'
2
- require 'ixtlan/babel/deserializer'
3
2
  require 'ixtlan/babel/factory'
4
- require 'ixtlan/babel/no_timestamp_serializer'
@@ -29,11 +29,11 @@ module Ixtlan
29
29
  @map.merge!(custom_serializers)
30
30
  end
31
31
 
32
- def add(clazz, &block)
33
- @map[clazz.to_s] = block
32
+ def add( clazz, &block )
33
+ @map[ clazz.to_s ] = block
34
34
  end
35
35
 
36
- def new(resource)
36
+ def new_serializer( resource )
37
37
  if resource.respond_to?(:model)
38
38
  model = resource.model
39
39
  elsif resource.respond_to? :collect
@@ -41,16 +41,25 @@ module Ixtlan
41
41
  return EmptyArraySerializer.new
42
42
  else
43
43
  r = resource.first
44
- model = r.respond_to?(:model) ? r.model : r.class
44
+ model = r.respond_to?( :model ) ? r.model : r.class
45
45
  end
46
46
  else
47
47
  model = resource.class
48
48
  end
49
- ser = const_retrieve("#{model}Serializer").new(resource)
50
- ser.add_custom_serializers(@map)
49
+ ser = const_retrieve( "#{model}Serializer" ).new( resource )
50
+ ser.add_custom_serializers( @map )
51
51
  ser
52
52
  end
53
53
 
54
+ def new( resource )
55
+ warn 'DEPRECATED use new_serializer instead'
56
+ new_serializer( resource )
57
+ end
58
+
59
+ def new_filter( clazz )
60
+ const_retrieve( "#{clazz}Filter" ).new( clazz )
61
+ end
62
+
54
63
  def const_retrieve( const )
55
64
  obj = Object
56
65
  const.split(/::/).each do |part|
@@ -0,0 +1,57 @@
1
+ require 'ixtlan/babel/hash_filter'
2
+ require 'ixtlan/babel/filter_config'
3
+
4
+ module Ixtlan
5
+ module Babel
6
+ class ParamsFilter
7
+
8
+ def initialize( model_class )
9
+ @model_class = model_class
10
+ end
11
+
12
+ private
13
+
14
+ def self.config
15
+ @config ||= FilterConfig.new
16
+ end
17
+
18
+ def filter
19
+ @filter ||= HashFilter.new
20
+ end
21
+
22
+ protected
23
+
24
+ def self.default_context_key(default)
25
+ config.default_context_key(default)
26
+ end
27
+
28
+ def self.add_context(key, options = {})
29
+ config[key] = options
30
+ end
31
+
32
+ def self.root( root )
33
+ config.root = root
34
+ end
35
+
36
+ public
37
+
38
+ def use(context_or_options)
39
+ @context_or_options = context_or_options
40
+ self
41
+ end
42
+ def filter_it( data )
43
+ filter.options = self.class.config.single_options( @context_or_options )
44
+ data = data[ filter.options[ :root ] ] if filter.options[ :root ]
45
+ keeps = {}
46
+ ( filter.options[ :keep ] || [] ).each do |k|
47
+ keeps[ k.to_s ] = data[ k.to_s ] || data[ k.to_sym ]
48
+ end
49
+ [ filter.filter( data ), keeps ]
50
+ end
51
+
52
+ def new( data )
53
+ @model_class.new( filter( data ) )
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ require 'ixtlan/babel/hash_filter'
2
+ require 'ixtlan/babel/filter_config'
3
+
4
+ module Ixtlan
5
+ module Babel
6
+ class ParamsFilter
7
+
8
+ def initialize( model_class )
9
+ @model_class = model_class
10
+ end
11
+
12
+ private
13
+
14
+ def self.config
15
+ @config ||= FilterConfig.new
16
+ end
17
+
18
+ def filter
19
+ @filter ||= HashFilter.new
20
+ end
21
+
22
+ protected
23
+
24
+ def self.default_context_key(default)
25
+ config.default_context_key(default)
26
+ end
27
+
28
+ def self.add_context(key, options = {})
29
+ config[key] = options
30
+ end
31
+
32
+ def self.root( root )
33
+ config.root = root
34
+ end
35
+
36
+ public
37
+
38
+ def use(context_or_options)
39
+ @context_or_options = context_or_options
40
+ self
41
+ end
42
+ def filter_it( data )
43
+ filter.options = self.class.config.single_options( @context_or_options )
44
+ data = data[ self.class.config.root ] if self.class.config.root
45
+ keeps = {}
46
+ ( filter.options[ :keep ] || [] ).each do |k|
47
+ keeps[ k.to_s ] = data[ k.to_s ]
48
+ end
49
+ [ filter.filter( data ), keeps ]
50
+ end
51
+
52
+ def new( data )
53
+ @model_class.new( filter( data ) )
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'ixtlan/babel/deserializer'
2
3
 
3
4
  class Hash
4
5
  def attributes
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'virtus'
3
+ require 'ixtlan/babel/deserializer'
3
4
 
4
5
  class Address
5
6
  include Virtus
@@ -82,15 +83,23 @@ describe Ixtlan::Babel::ModelFilter do
82
83
  json = serializer.to_json(:except => ['id'])
83
84
  result = deserializer.from_json(json, :except => ['id'])
84
85
 
86
+ expected = Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
87
+
85
88
  # travis sees empty array and locally it is nil :(
86
- result.attributes[ :phone_numbers ] ||= []
87
- result.attributes.must_equal Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
89
+ result.phone_numbers ||= []
90
+
91
+ result.attributes.keys.dup.each do |k|
92
+ result.attributes[ k ].must_equal expected[ k ]
93
+ end
88
94
 
89
95
  result = deserializer.from_json(json)
90
96
 
91
97
  # travis sees empty array and locally it is nil :(
92
- result.attributes[ :phone_numbers ] ||= []
93
- result.attributes.must_equal Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
98
+ result.phone_numbers ||= []
99
+
100
+ result.attributes.keys.dup.each do |k|
101
+ result.attributes[ k ].must_equal expected[ k ]
102
+ end
94
103
  end
95
104
 
96
105
  it 'should serialize and deserialize with only' do
@@ -98,14 +107,20 @@ describe Ixtlan::Babel::ModelFilter do
98
107
  result = deserializer.from_json(json, :only => ['name'])
99
108
 
100
109
  # travis sees empty array and locally it is nil :(
101
- result.attributes[ :phone_numbers ] ||= []
102
- result.attributes.must_equal Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
110
+ result.phone_numbers ||= []
111
+
112
+ expected = Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
113
+ result.attributes.keys.dup.each do |k|
114
+ result.attributes[ k ].must_equal expected[ k ]
115
+ end
103
116
 
104
117
  result = deserializer.from_json(json)
105
118
 
106
119
  # travis sees empty array and locally it is nil :(
107
- result.attributes[ :phone_numbers ] ||= []
108
- result.attributes.must_equal Hash[:name => person['name'], :address=>nil, :phone_numbers=>[], :id => nil]
120
+ result.phone_numbers ||= []
121
+ result.attributes.keys.dup.each do |k|
122
+ result.attributes[ k ].must_equal expected[ k ]
123
+ end
109
124
  end
110
125
 
111
126
  it 'should serialize and deserialize with nested only' do
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+ require 'ixtlan/babel/params_filter'
3
+
4
+ class A; end
5
+ class AFilter < Ixtlan::Babel::ParamsFilter
6
+
7
+ end
8
+
9
+ class Hash
10
+ def attributes
11
+ self
12
+ end
13
+ def method_missing(method)
14
+ self[method.to_s]
15
+ end
16
+ end
17
+
18
+ describe Ixtlan::Babel::ParamsFilter do
19
+ let(:data) do
20
+ {
21
+ 'id' => 987,
22
+ 'name' => 'me and the corner',
23
+ 'address' => { 'street' => 'Foo 12', 'zipcode' => '12345' },
24
+ 'phone_numbers' => {
25
+ 'prefix' => 12,
26
+ 'number' => '123',
27
+ 'area' => { 'code' => '001', 'iso' => 'us'}
28
+ }
29
+ }
30
+ end
31
+
32
+ let(:factory) { Ixtlan::Babel::Factory.new }
33
+ let(:filter) { factory.new_filter( A ) }
34
+ let(:deserializer) { Ixtlan::Babel::Deserializer.new(Hash) }
35
+
36
+ it 'should filter a hash' do
37
+ json = filter.filter_it( data )
38
+ json[0].must_equal Hash[ 'id' => data['id'], 'name' => data['name'] ]
39
+ json[1].must_equal Hash[]
40
+ end
41
+
42
+ it 'should filter a hash with keep' do
43
+ json = filter.use( :keep => ['id'] ).filter_it( data )
44
+ json[0].must_equal Hash[ 'id' => data['id'], 'name' => data['name'] ]
45
+ json[1].must_equal Hash[ 'id' => data['id'] ]
46
+ end
47
+
48
+ it 'should filter a hash with root' do
49
+ json = filter.use( :root => 'my' ).filter_it( 'my' => data )
50
+ json[0].must_equal Hash[ 'id' => data['id'], 'name' => data['name'] ]
51
+ json[1].must_equal Hash[]
52
+ end
53
+
54
+ it 'should filter a hash with include list' do
55
+ json = filter.use( :include => ['address', 'phone_numbers'] ).filter_it( data )
56
+
57
+ data['phone_numbers'].delete('area')
58
+ json[0].must_equal Hash[data]
59
+ json[1].must_equal Hash[]
60
+ end
61
+
62
+ it 'should filter a hash with except' do
63
+ json = filter.use( :except => ['id'] ).filter_it( data )
64
+ json[0].must_equal Hash['name' => data['name']]
65
+ json[1].must_equal Hash[]
66
+ end
67
+
68
+ it 'should filter a hash with except and keep' do
69
+ json = filter.use( :except => ['id'], :keep => ['id'] ).filter_it( data )
70
+ json[0].must_equal Hash['name' => data['name']]
71
+ json[1].must_equal Hash['id' => data['id']]
72
+ end
73
+
74
+ it 'should filter a hash with only' do
75
+ json = filter.use( :only => ['name'] ).filter_it( data )
76
+ json[0].must_equal Hash['name' => data['name']]
77
+ json[1].must_equal Hash[]
78
+ end
79
+
80
+ it 'should filter a hash with only and keep' do
81
+ json = filter.use( :only => ['name'], :keep => ['id'] ).filter_it( data )
82
+ json[0].must_equal Hash['name' => data['name']]
83
+ json[1].must_equal Hash['id' => data['id']]
84
+ end
85
+
86
+ it 'should filter a hash with nested only' do
87
+ json = filter.use( :include => { 'address' => {:only => ['street']}} ).filter_it( data )
88
+ data.delete('phone_numbers')
89
+ data['address'].delete('zipcode')
90
+ json[0].must_equal Hash[data]
91
+ json[1].must_equal Hash[]
92
+ end
93
+
94
+ it 'should filter a hash with nested except' do
95
+ json = filter.use( :include => { 'address' => {:except => ['zipcode']}} ).filter_it( data )
96
+ data.delete('phone_numbers')
97
+ data['address'].delete('zipcode')
98
+ json[0].must_equal Hash[data]
99
+ json[1].must_equal Hash[]
100
+ end
101
+
102
+ it 'should filter a hash with nested include' do
103
+ json = filter.use( :include => { 'address' => {}, 'phone_numbers' => { :include => ['area']}} ).filter_it( data )
104
+ json[0].must_equal Hash[data]
105
+ json[1].must_equal Hash[]
106
+ end
107
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ class Hash
4
+ def attributes
5
+ self
6
+ end
7
+ def method_missing(method)
8
+ self[method.to_s]
9
+ end
10
+ end
11
+
12
+ describe Ixtlan::Babel::HashFilter do
13
+ let(:data) do
14
+ data = {
15
+ 'id' => 987,
16
+ 'name' => 'me and the corner',
17
+ 'address' => { 'street' => 'Foo 12', 'zipcode' => '12345' },
18
+ 'phone_numbers' => {
19
+ 'prefix' => 12,
20
+ 'number' => '123',
21
+ 'area' => { 'code' => '001', 'iso' => 'us'}
22
+ }
23
+ }
24
+ class Hash
25
+ def self.new(hash = nil, &block)
26
+ if hash
27
+ self[hash]
28
+ else
29
+ super &block
30
+ end
31
+ end
32
+ end
33
+ data
34
+ end
35
+
36
+ let(:serializer) { Ixtlan::Babel::Serializer.new(data) }
37
+ let(:deserializer) { Ixtlan::Babel::Deserializer.new(Hash) }
38
+
39
+ it 'should serialize and deserialize a hash' do
40
+ json = serializer.to_json
41
+ result = deserializer.from_json(json)
42
+ result.must_equal Hash['id' => data['id'], 'name' => data['name']]
43
+ end
44
+
45
+ it 'should serialize and deserialize a hash with root' do
46
+ json = serializer.to_json :root => 'my'
47
+ result = deserializer.from_json(json, :root => 'my')
48
+ result.must_equal Hash['id' => data['id'], 'name' => data['name']]
49
+ end
50
+
51
+ it 'should serialize and deserialize a hash with include list' do
52
+ json = serializer.to_json(:include => ['address', 'phone_numbers'])
53
+ result = deserializer.from_json(json, :include => ['address', 'phone_numbers'])
54
+ data['phone_numbers'].delete('area')
55
+ result.must_equal Hash[data]
56
+ end
57
+
58
+ it 'should serialize and deserialize a hash with except' do
59
+ json = serializer.to_json(:except => ['id'])
60
+ result = deserializer.from_json(json, :except => ['id'])
61
+ result.must_equal Hash['name' => data['name']]
62
+ result = deserializer.from_json(json)
63
+ result.must_equal Hash['name' => data['name']]
64
+ end
65
+
66
+ it 'should serialize and deserialize a hash with only' do
67
+ json = serializer.to_json(:only => ['name'])
68
+ result = deserializer.from_json(json, :only => ['name'])
69
+ result.must_equal Hash['name' => data['name']]
70
+ result = deserializer.from_json(json)
71
+ result.must_equal Hash['name' => data['name']]
72
+ end
73
+
74
+ it 'should serialize and deserialize a hash with nested only' do
75
+ json = serializer.to_json(:include => { 'address' => {:only => ['street']}})
76
+ data.delete('phone_numbers')
77
+ data['address'].delete('zipcode')
78
+ result = deserializer.from_json(json, :include => { 'address' => {:only => ['street']}})
79
+ result.must_equal data
80
+ result = deserializer.from_json(json, :include => ['address'])
81
+ result.must_equal data
82
+ end
83
+
84
+ it 'should serialize and deserialize a hash with nested except' do
85
+ json = serializer.to_json(:include => { 'address' => {:except => ['zipcode']}})
86
+ data.delete('phone_numbers')
87
+ data['address'].delete('zipcode')
88
+ result = deserializer.from_json(json, :include => { 'address' => {:except => ['zipcode']}})
89
+ result.must_equal data
90
+ result = deserializer.from_json(json, :include => ['address'])
91
+ result.must_equal data
92
+ end
93
+
94
+ it 'should serialize and deserialize a hash with nested include' do
95
+ json = serializer.to_json(:include => { 'address' => {}, 'phone_numbers' => { :include => ['area']}})
96
+ result = deserializer.from_json(json, :include => { 'address' => {}, 'phone_numbers' => { :include => ['area']}})
97
+ result.must_equal data
98
+ end
99
+ end
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ixtlan-babel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
- - Kristian Meier
13
+ - Christian Meier
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-12-29 00:00:00 Z
18
+ date: 2013-01-19 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rake
@@ -34,18 +34,19 @@ dependencies:
34
34
  type: :development
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: json_pure
37
+ name: copyright-header
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
43
43
  - !ruby/object:Gem::Version
44
- hash: 3
44
+ hash: 25
45
45
  segments:
46
46
  - 1
47
- - 6
48
- version: "1.6"
47
+ - 0
48
+ - 7
49
+ version: 1.0.7
49
50
  type: :development
50
51
  version_requirements: *id002
51
52
  - !ruby/object:Gem::Dependency
@@ -80,6 +81,21 @@ dependencies:
80
81
  version: 0.5.0
81
82
  type: :development
82
83
  version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: json
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ hash: 1
93
+ segments:
94
+ - 1
95
+ - 7
96
+ version: "1.7"
97
+ type: :development
98
+ version_requirements: *id005
83
99
  description: babel offers a filter for hashes and with that comes json/yaml/xml de/serialization of models which provides a hash representationi. possible models are activerecord, activemodel, resources from datamapper, virtus
84
100
  email:
85
101
  - m.kristian@web.de
@@ -93,9 +109,11 @@ files:
93
109
  - lib/ixtlan-babel.rb
94
110
  - lib/ixtlan/babel/deserializer.rb
95
111
  - lib/ixtlan/babel/hash_filter.rb
112
+ - lib/ixtlan/babel/params_filter.rb
96
113
  - lib/ixtlan/babel/abstract_filter.rb
97
114
  - lib/ixtlan/babel/no_timestamp_serializer.rb
98
115
  - lib/ixtlan/babel/filter_config.rb
116
+ - lib/ixtlan/babel/params_filter.rb~
99
117
  - lib/ixtlan/babel/context.rb
100
118
  - lib/ixtlan/babel/factory.rb
101
119
  - lib/ixtlan/babel/model_filter.rb~
@@ -112,17 +130,18 @@ files:
112
130
  - spec/model_filter_spec.rb~
113
131
  - spec/model_filter_spec.rb
114
132
  - spec/model_filter_with_methods_spec.rb~
133
+ - spec/params_filter_spec.rb
115
134
  - spec/hash_filter_spec.rb
116
135
  - spec/hash_filter_spec.rb~
117
136
  - spec/spec_helper.rb
118
137
  - spec/model_filter_with_methods_spec.rb
138
+ - spec/params_filter_spec.rb~
119
139
  - MIT-LICENSE
120
140
  - README.md
121
141
  - Gemfile
122
- - Gemfile.lock
123
142
  homepage: https://github.com/mkristian/ixtlan-babel
124
- licenses: []
125
-
143
+ licenses:
144
+ - MIT
126
145
  post_install_message:
127
146
  rdoc_options: []
128
147
 
@@ -155,5 +174,6 @@ specification_version: 3
155
174
  summary: babel offers a filter for hashes and with that comes json/yaml/xml de/serialization of models which provides a hash representation
156
175
  test_files:
157
176
  - spec/model_filter_spec.rb
177
+ - spec/params_filter_spec.rb
158
178
  - spec/hash_filter_spec.rb
159
179
  - spec/model_filter_with_methods_spec.rb
data/Gemfile.lock DELETED
@@ -1,24 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ixtlan-babel (0.2.1)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- backports (2.6.2)
10
- json_pure (1.6.1)
11
- minitest (4.3.2)
12
- rake (10.0.3)
13
- virtus (0.5.1)
14
- backports (~> 2.6.1)
15
-
16
- PLATFORMS
17
- ruby
18
-
19
- DEPENDENCIES
20
- ixtlan-babel!
21
- json_pure (~> 1.6)
22
- minitest (~> 4.3.0)
23
- rake (~> 10.0.0)
24
- virtus (~> 0.5.0)