ixtlan-babel 0.5.0 → 0.7.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.
@@ -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