ixtlan-babel 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,158 @@
1
+ require_relative 'spec_helper'
2
+ require 'ixtlan/babel/model_serializer'
3
+ require 'virtus'
4
+ require 'multi_json'
5
+ require 'json'
6
+
7
+ class Address
8
+ include Virtus
9
+
10
+ attribute :street, String
11
+ attribute :zipcode, String
12
+ end
13
+ class Area
14
+ include Virtus
15
+
16
+ attribute :code, String
17
+ attribute :iso, String
18
+ end
19
+ class PhoneNumber
20
+ include Virtus
21
+
22
+ attribute :prefix, Integer
23
+ attribute :number, String
24
+ attribute :area, Area
25
+ end
26
+ class Person
27
+ include Virtus
28
+
29
+ attribute :id, String
30
+ attribute :name, String
31
+ attribute :address, Address
32
+
33
+ attr_accessor :phone_numbers, :age, :children_names
34
+
35
+ def phone_numbers
36
+ @phone_numbers ||= [PhoneNumber.new(
37
+ :prefix => 12,
38
+ :number => '123',
39
+ :area => Area.new( :code => '001', :iso => 'us' ) )]
40
+ end
41
+
42
+ def age
43
+ @age ||= 123
44
+ end
45
+
46
+ def children_names
47
+ @children_names ||= ['anna', 'jack', 'rama', 'mia']
48
+ end
49
+
50
+ def children_ages
51
+ @children_ages ||= [12, 3, 6, 9]
52
+ end
53
+ end
54
+
55
+ class ASerializer
56
+ include Ixtlan::Babel::ModelSerializer
57
+ attributes :id, :name
58
+ end
59
+
60
+ class MethodsSerializer < ASerializer
61
+ attributes :age, :children_names, :children_ages
62
+ end
63
+
64
+ class PhoneSerializer
65
+ include Ixtlan::Babel::ModelSerializer
66
+ attributes :prefix, :number
67
+ end
68
+
69
+ class AddressSerializer
70
+ include Ixtlan::Babel::ModelSerializer
71
+ attributes :street, :zipcode
72
+ end
73
+
74
+ class NestedListSerializer < ASerializer
75
+ attribute :address, AddressSerializer
76
+ attribute :phone_numbers, Array[PhoneSerializer]
77
+ end
78
+ class AreaSerializer
79
+ include Ixtlan::Babel::ModelSerializer
80
+ attributes :code, :iso
81
+ end
82
+
83
+ class Phone2Serializer < PhoneSerializer
84
+ attribute :area, AreaSerializer
85
+ end
86
+ class DeepNestedSerializer < NestedListSerializer
87
+ attribute :phone_numbers, Array[Phone2Serializer]
88
+ end
89
+
90
+ describe Ixtlan::Babel::ModelSerializer do
91
+ let( :person ) do
92
+ Person.new( :id => 987,
93
+ :name => 'me and the corner',
94
+ :address => Address.new( :street => 'Foo 12',
95
+ :zipcode => '12345' ) )
96
+ end
97
+
98
+ it 'should serialize with methods' do
99
+ data = MethodsSerializer.new( person )
100
+ result = MultiJson.load(data.to_json)
101
+ result.must_equal Hash[ "id"=>"987",
102
+ "name"=>"me and the corner",
103
+ "age"=>123,
104
+ "children_names"=> [ "anna",
105
+ "jack",
106
+ "rama",
107
+ "mia" ],
108
+ "children_ages"=>[ 12, 3, 6, 9 ] ]
109
+ data.id.must_equal person.id
110
+ data.name.must_equal person.name
111
+ data.age.must_equal person.age
112
+ data.children_ages.must_equal person.children_ages
113
+ end
114
+
115
+ it 'should serialize' do
116
+ data = ASerializer.new( person )
117
+ result = MultiJson.load(data.to_json)
118
+ result.must_equal Hash[ "id"=>"987", "name"=>"me and the corner" ]
119
+ data.id.must_equal person.id
120
+ data.name.must_equal person.name
121
+ data.age.must_equal person.age
122
+ end
123
+
124
+ it 'should serialize with nested list' do
125
+ data = NestedListSerializer.new( person )
126
+ result = MultiJson.load( data.to_json )
127
+ result.must_equal Hash[ "id"=>"987", "name"=>"me and the corner" ,
128
+ "address"=> {
129
+ "street"=>"Foo 12",
130
+ "zipcode"=>"12345"
131
+ },
132
+ "phone_numbers"=> [ { "prefix"=>12,
133
+ "number"=>"123" } ] ]
134
+ data.phone_numbers[0].prefix.must_equal result['phone_numbers'][0]['prefix']
135
+ data.phone_numbers[0].number.must_equal result['phone_numbers'][0]['number']
136
+ end
137
+
138
+ it 'should serialize and deserialize with nested include' do
139
+ data = DeepNestedSerializer.new( person )
140
+ result = MultiJson.load( data.to_json )
141
+ result.must_equal Hash[ "id"=>"987", "name"=>"me and the corner" ,
142
+ "address"=> {
143
+ "street"=>"Foo 12",
144
+ "zipcode"=>"12345"
145
+ },
146
+ "phone_numbers"=> [ { "prefix"=>12,
147
+ "number"=>"123",
148
+ "area"=> {
149
+ "code"=>"001",
150
+ "iso"=>"us"
151
+ }
152
+ } ] ]
153
+ data.phone_numbers[0].prefix.must_equal result['phone_numbers'][0]['prefix']
154
+ data.phone_numbers[0].number.must_equal result['phone_numbers'][0]['number']
155
+ data.phone_numbers[0].area.code.must_equal result['phone_numbers'][0]['area']['code']
156
+ data.phone_numbers[0].area.iso.must_equal result['phone_numbers'][0]['area']['iso']
157
+ end
158
+ end
@@ -1,5 +1,7 @@
1
- $LOAD_PATH << File.expand_path(File.join(__FILE__, '..', '..', 'lib'))
1
+ # single spec setup
2
+ $LOAD_PATH.unshift File.expand_path( '../../lib', __FILE__ )
3
+
4
+ #require 'awesome_print'
5
+
2
6
  gem 'minitest'
3
7
  require 'minitest/autorun'
4
- require 'json'
5
- require 'ixtlan-babel'
@@ -0,0 +1,8 @@
1
+ # single spec setup
2
+ $LOAD_PATH.unshift File.expand_path( '../../lib', __FILE__ )
3
+
4
+ require 'pry'
5
+ require 'awesome_print'
6
+
7
+ gem 'minitest'
8
+ require 'minitest/autorun'
metadata CHANGED
@@ -1,157 +1,138 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ixtlan-babel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
- - Christian Meier
8
- autorequire:
7
+ - mkristian
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-12 00:00:00.000000000 Z
11
+ date: 2014-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
- version_requirements: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: '10.0'
20
15
  requirement: !ruby/object:Gem::Requirement
21
16
  requirements:
22
- - - ~>
17
+ - - "~>"
23
18
  - !ruby/object:Gem::Version
24
- version: '10.0'
25
- prerelease: false
19
+ version: '10.3'
26
20
  type: :development
27
- - !ruby/object:Gem::Dependency
28
- name: minitest
21
+ prerelease: false
29
22
  version_requirements: !ruby/object:Gem::Requirement
30
23
  requirements:
31
- - - ~>
24
+ - - "~>"
32
25
  - !ruby/object:Gem::Version
33
- version: '4.0'
26
+ version: '10.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
34
29
  requirement: !ruby/object:Gem::Requirement
35
30
  requirements:
36
- - - ~>
31
+ - - "~>"
37
32
  - !ruby/object:Gem::Version
38
- version: '4.0'
39
- prerelease: false
33
+ version: '5.3'
40
34
  type: :development
41
- - !ruby/object:Gem::Dependency
42
- name: virtus
35
+ prerelease: false
43
36
  version_requirements: !ruby/object:Gem::Requirement
44
37
  requirements:
45
- - - ~>
38
+ - - "~>"
46
39
  - !ruby/object:Gem::Version
47
- version: '0.5'
40
+ version: '5.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
48
43
  requirement: !ruby/object:Gem::Requirement
49
44
  requirements:
50
- - - ~>
45
+ - - "~>"
51
46
  - !ruby/object:Gem::Version
52
- version: '0.5'
53
- prerelease: false
47
+ version: '1.10'
54
48
  type: :development
55
- - !ruby/object:Gem::Dependency
56
- name: multi_json
49
+ prerelease: false
57
50
  version_requirements: !ruby/object:Gem::Requirement
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
- version: '1.6'
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: virtus
62
57
  requirement: !ruby/object:Gem::Requirement
63
58
  requirements:
64
- - - ~>
59
+ - - "~>"
65
60
  - !ruby/object:Gem::Version
66
- version: '1.6'
67
- prerelease: false
61
+ version: '1.0'
68
62
  type: :development
69
- - !ruby/object:Gem::Dependency
70
- name: json
63
+ prerelease: false
71
64
  version_requirements: !ruby/object:Gem::Requirement
72
65
  requirements:
73
- - - ~>
74
- - !ruby/object:Gem::Version
75
- version: '1.7'
76
- requirement: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - ~>
66
+ - - "~>"
79
67
  - !ruby/object:Gem::Version
80
- version: '1.7'
81
- prerelease: false
82
- type: :development
83
- 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
68
+ version: '1.0'
69
+ description: filter for hashes and serialization of POROs into a hash representation.
70
+ both the filter and hash reprensentation use a similar DSL to define which attributes
71
+ are used/allowed
84
72
  email:
85
73
  - m.kristian@web.de
86
74
  executables: []
87
75
  extensions: []
88
76
  extra_rdoc_files: []
89
77
  files:
78
+ - MIT-LICENSE
79
+ - README.md
90
80
  - lib/ixtlan-babel.rb
81
+ - lib/ixtlan-babel.rb~
91
82
  - lib/ixtlan/babel/config.rb~
92
- - lib/ixtlan/babel/filter_config.rb
93
83
  - lib/ixtlan/babel/params_filter.rb~
94
- - lib/ixtlan/babel/model_filter.rb
84
+ - lib/ixtlan/babel/common_filters.rb
85
+ - lib/ixtlan/babel/common_filters.rb~
95
86
  - lib/ixtlan/babel/dm_validation_errors_serializer.rb~
96
87
  - lib/ixtlan/babel/hash_filter.rb~
97
- - lib/ixtlan/babel/params_filter.rb
98
88
  - lib/ixtlan/babel/serializer.rb~
99
89
  - lib/ixtlan/babel/factory.rb
100
90
  - lib/ixtlan/babel/abstract_filter.rb~
101
91
  - lib/ixtlan/babel/hash_only_filter.rb~
102
- - lib/ixtlan/babel/context.rb
103
- - lib/ixtlan/babel/dm_validation_errors_serializer.rb
92
+ - lib/ixtlan/babel/model_serializer.rb
104
93
  - lib/ixtlan/babel/model_filter.rb~
105
- - lib/ixtlan/babel/serializer.rb
94
+ - lib/ixtlan/babel/model_serializer.rb~
106
95
  - lib/ixtlan/babel/filter_config.rb~
107
96
  - lib/ixtlan/babel/context.rb~
108
- - lib/ixtlan/babel/abstract_filter.rb
109
97
  - lib/ixtlan/babel/factory.rb~
110
98
  - lib/ixtlan/babel/hash_filter.rb
111
- - spec/params_filter_dsl_spec.rb
112
99
  - spec/model_filter_spec.rb~
113
100
  - spec/params_filter_spec.rb~
114
101
  - spec/model_filter_with_methods_spec.rb~
115
- - spec/params_filter_spec.rb
116
102
  - spec/params_filter_dsl_spec.rb~
117
103
  - spec/hash_filter_spec.rb~
118
- - spec/model_filter_with_dsl_spec.rb
119
- - spec/model_filter_with_methods_spec.rb
104
+ - spec/model_serializer_spec.rb~
105
+ - spec/spec_helper.rb~
120
106
  - spec/spec_helper.rb
121
107
  - spec/hash_filter_spec.rb
122
108
  - spec/model_filter_with_methods.spec.rb~
123
- - spec/model_filter_spec.rb
124
- - MIT-LICENSE
125
- - README.md
109
+ - spec/model_serializer_spec.rb
110
+ - Rakefile
126
111
  - Gemfile
127
- homepage: https://github.com/mkristian/ixtlan-babel
112
+ homepage: http://github.com/mkristian/ixtlan-babel
128
113
  licenses:
129
114
  - MIT
130
115
  metadata: {}
131
- post_install_message:
116
+ post_install_message:
132
117
  rdoc_options: []
133
118
  require_paths:
134
119
  - lib
135
120
  required_ruby_version: !ruby/object:Gem::Requirement
136
121
  requirements:
137
- - - '>='
122
+ - - ">="
138
123
  - !ruby/object:Gem::Version
139
124
  version: '0'
140
125
  required_rubygems_version: !ruby/object:Gem::Requirement
141
126
  requirements:
142
- - - '>='
127
+ - - ">="
143
128
  - !ruby/object:Gem::Version
144
129
  version: '0'
145
130
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.1.9
148
- signing_key:
131
+ rubyforge_project:
132
+ rubygems_version: 2.0.14
133
+ signing_key:
149
134
  specification_version: 4
150
- summary: babel offers a filter for hashes and with that comes json/yaml/xml de/serialization of models which provides a hash representation
135
+ summary: filter for hashes and serialization of POROs into a hash representation
151
136
  test_files:
152
- - spec/params_filter_dsl_spec.rb
153
- - spec/params_filter_spec.rb
154
- - spec/model_filter_with_dsl_spec.rb
155
- - spec/model_filter_with_methods_spec.rb
156
137
  - spec/hash_filter_spec.rb
157
- - spec/model_filter_spec.rb
138
+ - spec/model_serializer_spec.rb
@@ -1,46 +0,0 @@
1
- #
2
- # Copyright (C) 2013 Christian Meier
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- # this software and associated documentation files (the "Software"), to deal in
6
- # the Software without restriction, including without limitation the rights to
7
- # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
- # the Software, and to permit persons to whom the Software is furnished to do so,
9
- # subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
- # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
- # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
- # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
- #
21
- require 'ixtlan/babel/context'
22
- module Ixtlan
23
- module Babel
24
- class AbstractFilter
25
-
26
- attr_accessor :options
27
-
28
- def options
29
- @options || {}
30
- end
31
-
32
- def add_custom_serializers( map )
33
- @map = map
34
- end
35
-
36
- def serialize( data )
37
- if @map && ser = @map[ data.class.to_s ]
38
- ser.call(data)
39
- else
40
- data
41
- end
42
- end
43
-
44
- end
45
- end
46
- end
@@ -1,67 +0,0 @@
1
- #
2
- # Copyright (C) 2013 Christian Meier
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
- # this software and associated documentation files (the "Software"), to deal in
6
- # the Software without restriction, including without limitation the rights to
7
- # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
- # the Software, and to permit persons to whom the Software is furnished to do so,
9
- # subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
- # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
- # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
- # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
- #
21
- module Ixtlan
22
- module Babel
23
- class Context
24
-
25
- def initialize( options )
26
- @only = options[ :only ].collect { |o| o.to_s } if options[ :only ]
27
- @except = ( options[:except] || [] ).collect { |e| e.to_s }
28
-
29
- opts = options[ :include ]
30
- @include = case opts
31
- when Array
32
- opts.collect { |i| i.to_s }
33
- when Hash
34
- Hash[ opts.collect { |k,v| [ k.to_s, v ] } ]
35
- else
36
- []
37
- end
38
- @methods = (options[:methods] || []).collect { |m| m.to_s }
39
- end
40
-
41
- def methods
42
- @methods + ( @include.is_a?( Array ) ? @include : @include.keys )
43
- end
44
-
45
- def allowed?( key )
46
- ( @only && @only.include?( key ) ) || ( @only.nil? && !@except.include?( key ) ) || @methods.include?( key )
47
- end
48
-
49
- def include?( key )
50
- @include.include?( key ) || @methods.include?( key )
51
- end
52
-
53
- def array?
54
- @include.is_a?( Array )
55
- end
56
-
57
- def []( key )
58
- if @include.include?( key )
59
- self.class.new( @include.is_a?( Array ) ? {} : @include[ key ] )
60
- else
61
- self.class.new( @methods.is_a?( Array ) ? {} : @methods[ key ] )
62
- end
63
- end
64
-
65
- end
66
- end
67
- end