kanade 0.1.0.beta1 → 0.1.0.beta2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dba2011d31645033e7e65d4d964804457e84a7ff
4
- data.tar.gz: 0c762aaa23b5e9d9d491a9ab79a9bb410b1aa2fb
3
+ metadata.gz: 25723d77b3f99e8994da9fd4aa44eba091198831
4
+ data.tar.gz: 9458dddba1f8fdff1041ab11cd79a5c83e9c8183
5
5
  SHA512:
6
- metadata.gz: bf867ed2aef8b77e996ec53596abb54cb38ddbf960862e9980b528fafa7714efe7b87fdb82d281cb83f357421dec047013630d314958b09947d4d3095c366b09
7
- data.tar.gz: 0befa0235c6abdfe73090c88a7309b7a596a5f7cdffa170df670a479bce3019faa511068b73b30e2be87e5fe3229bf9094d2d66469cca6d8a9bdc1ff27c54c83
6
+ metadata.gz: 66d8f6cdb94ce27c648957e5089d7884101b0087a5916da253acfab3f4c2905b31ac8117282c1b73785fcad7d0589ce4c0692e6147609402e0f0cbdbffe4ddd1
7
+ data.tar.gz: b5b0884a344d5f26b314231d569e6c300ead110eac7dd47217f396378c9ecc9573c35af615c23bbe0779880c03e5bee3973e9692ce813fa4ecdc6d84a7a38390
data/.editorconfig CHANGED
@@ -4,6 +4,7 @@
4
4
  root = true
5
5
 
6
6
  [*]
7
+ end_of_line = lf
7
8
  charset = utf-8
8
9
  trim_trailing_whitespace = true
9
10
  insert_final_newline = true
data/.gitignore CHANGED
@@ -5,8 +5,10 @@
5
5
  doc
6
6
  .yardoc
7
7
 
8
+ # Development file
9
+ .devel
10
+ pkg
11
+
8
12
  # IDE-specific
9
13
  *.swp
10
14
 
11
- # Development file
12
- .devel
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kanade (0.1.0.beta1)
4
+ kanade (0.1.0.beta2)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -1,22 +1,24 @@
1
- module Kanade
2
- module Converter
3
- class Bool < Base
4
- Engine.register_converter!(self)
5
-
6
- def serialize(term, _)
7
- return nil if term.nil?
8
- term.to_s
9
- end
10
- def deserialize(term, _)
11
- return nil if term.nil?
12
- return term if term.is_a?(FalseClass)
13
- return term if term.is_a?(TrueClass)
14
- term ? true : false
15
- end
16
-
17
- def from_string(term)
18
- term.downcase === 'true'
19
- end
20
- end
21
- end
22
- end
1
+ module Kanade
2
+ module Converter
3
+ class Bool < Base
4
+ Engine.register_converter!(self)
5
+
6
+ def serialize(term, _)
7
+ return nil if term.nil?
8
+ return true if term.is_a?(TrueClass)
9
+ return false if term.is_a?(FalseClass)
10
+ raise NotSupportedError.new("Trying to serialize a bool, but given unknown object")
11
+ end
12
+ def deserialize(term, _)
13
+ return nil if term.nil?
14
+ return term if term.is_a?(FalseClass)
15
+ return term if term.is_a?(TrueClass)
16
+ term ? true : false
17
+ end
18
+
19
+ def from_string(term)
20
+ term.downcase === 'true'
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ module Kanade
2
+ module Converter
3
+ class Dto < Base
4
+ Engine.register_converter!(self)
5
+
6
+ def serialize(term, field_info)
7
+ term
8
+ end
9
+
10
+ def deserialize(term, field_info)
11
+ return nil if term.nil?
12
+ raise NotSupportedError.new('DTO-based field only can be filled with nil / respective DTO object') unless term.is_a?(field_info.options[:of])
13
+ return term
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,14 +3,31 @@ module Kanade
3
3
  class List < Base
4
4
  Engine.register_converter!(self)
5
5
 
6
- def serialize(term, _)
6
+ def serialize(term, field_info)
7
7
  return nil if term.nil?
8
- term.to_s
9
8
  end
10
- def deserialize(term, _)
9
+ def deserialize(term, field_info)
11
10
  return nil if term.nil?
12
- return term if term.is_a?(BigDecimal)
13
- ::BigDecimal.new(term)
11
+ #binding.pry unless term.is_a?(Array)
12
+ raise NotSupportedError.new("Value must be array or nil!") unless term.is_a?(Array)
13
+
14
+ term.map do |t|
15
+ conversion_method =
16
+ if field_info.options[:of].is_a?(Class) and field_info.options[:of] < Kanade::Dto
17
+ :dto
18
+ else
19
+ field_info.options[:of]
20
+ end
21
+
22
+ # Kalau begini caranya, field_info bisa enggak konsisten.
23
+ # Ada yang nyimpen informasinya dirinya sendiri, ada juga
24
+ # yang nyimpen informasi parent-nya.
25
+ converter = Engine.converter(conversion_method)
26
+ binding.pry if converter.nil?
27
+ raise NotSupportedError.new("Unregistered conversion method: #{conversion_method}") if converter.nil?
28
+ converter.deserialize(t, field_info)
29
+ end
30
+
14
31
  end
15
32
  end
16
33
  end
@@ -1,25 +1,26 @@
1
- require 'time'
2
-
3
- module Kanade
4
- module Converter
5
- class Time < Base
6
- Engine.register_converter!(self)
7
-
8
- def serialize(term, _)
9
- return nil if term.nil?
10
- term.iso8601(0)
11
- end
12
- def deserialize(term, _)
13
- return nil if term.nil?
14
- return term if term.is_a?(Time)
15
- return term if term.is_a?(Date)
16
- # WARNING: Parse does not really parse TZ!
17
- # Consider using ActiveSupport?
18
- ::Time.parse(term)
19
- end
20
-
21
- configurable :time_format, :iso8601
22
- configurable :time_msec_round, 0
23
- end
24
- end
25
- end
1
+ require 'time'
2
+
3
+ module Kanade
4
+ module Converter
5
+ class Time < Base
6
+ Engine.register_converter!(self)
7
+
8
+ def serialize(term, _)
9
+ return nil if term.nil?
10
+ term.iso8601(0)
11
+ end
12
+ def deserialize(term, _)
13
+ return nil if term.nil?
14
+ return term if term.is_a?(::Time)
15
+ return term if term.is_a?(Date)
16
+ # WARNING: Parse does not really parse TZ!
17
+ # Consider using ActiveSupport?
18
+
19
+ ::Time.parse(term)
20
+ end
21
+
22
+ configurable :time_format, :iso8601
23
+ configurable :time_msec_round, 0
24
+ end
25
+ end
26
+ end
data/lib/kanade/dto.rb CHANGED
@@ -1,47 +1,56 @@
1
- module Kanade
2
- class Dto
3
- class_attribute :__fields
4
- class_attribute :__definer
5
-
6
- def self.field(name_sym, *options)
7
- raise NotSupportedError.new('Field must be a symbol!') unless name_sym.is_a?(Symbol)
8
- raise NotSupportedError.new('Cant use reserved name (__fields)') if name == :__fields
9
-
10
- if self.__definer != self.name
11
- self.__fields = array_dup(self.__fields) || []
12
- self.__definer = self.name
13
- end
14
-
15
- name = name_sym.to_s.freeze
16
- variable_ref = "@#{name}".freeze
17
- option = options.last
18
- converter = Engine.converter(option[:as])
19
- key_name = option[:with]
20
-
21
- raise Kanade::NotSupportedError.new("Converter #{option[:as]} is not registered") if converter.nil?
22
-
23
- field = FieldInfo.new
24
- field.converter = converter
25
- field.key_json = key_name
26
- field.key_ruby = name
27
- field.sym = name_sym
28
- field.options = option
29
-
30
- define_method "#{name}=" do |value|
31
- instance_variable_set(variable_ref, field.convert(value))
32
- end
33
-
34
- define_method "#{name}" do
35
- instance_variable_get(variable_ref)
36
- end
37
-
38
- self.__fields << field
39
- end
40
-
41
- private
42
- def self.array_dup(arr)
43
- return nil if arr.nil?
44
- arr.map(&:dup)
45
- end
46
- end
47
- end
1
+ module Kanade
2
+ class Dto
3
+ class_attribute :__fields
4
+ class_attribute :__definer
5
+
6
+ def self.field(name_sym, *options)
7
+ raise NotSupportedError.new('Field must be a symbol!') unless name_sym.is_a?(Symbol)
8
+ raise NotSupportedError.new('Cant use reserved name (__fields)') if name == :__fields
9
+
10
+ if self.__definer != self.name
11
+ self.__fields = array_dup(self.__fields) || []
12
+ self.__definer = self.name
13
+ end
14
+
15
+ option = options.last
16
+
17
+ conversion_method = option[:as]
18
+
19
+ if option[:as].is_a?(Class) and option[:as] < Dto
20
+ conversion_method = :dto
21
+ option[:of] = option[:as]
22
+ option[:as] = :dto
23
+ end
24
+
25
+ name = name_sym.to_s.freeze
26
+ variable_ref = "@#{name}".freeze
27
+ converter = Engine.converter(conversion_method)
28
+ key_name = option[:with]
29
+
30
+ raise Kanade::NotSupportedError.new("Converter #{conversion_method} is not registered") if converter.nil?
31
+
32
+ field = FieldInfo.new
33
+ field.converter = converter
34
+ field.key_json = key_name
35
+ field.key_ruby = name
36
+ field.sym = name_sym
37
+ field.options = option
38
+
39
+ define_method "#{name}=" do |value|
40
+ instance_variable_set(variable_ref, field.convert(value))
41
+ end
42
+
43
+ define_method "#{name}" do
44
+ instance_variable_get(variable_ref)
45
+ end
46
+
47
+ self.__fields << field
48
+ end
49
+
50
+ private
51
+ def self.array_dup(arr)
52
+ return nil if arr.nil?
53
+ arr.map(&:dup)
54
+ end
55
+ end
56
+ end
data/lib/kanade/engine.rb CHANGED
@@ -1,87 +1,149 @@
1
- require 'json'
2
-
3
- module Kanade
4
- class Engine
5
- @@converters = {}
6
- @@name_resolvers = {}
7
-
8
- def initialize(configuration=nil)
9
- @config = configuration || Kanade::Config.default
10
- end
11
-
12
- def configure
13
- yield @config
14
- end
15
-
16
- def serialize(object)
17
- traverse_field(object).to_json
18
- end
19
-
20
- def traverse_field(object)
21
- raise NotSupportedError.new("Serializer only works for Kanade::Dto, and #{object.class.name} does not extend Kanade::Dto") unless object.is_a?(Kanade::Dto)
22
-
23
- stacks = []
24
- result = {}
25
- stacks += object.__fields
26
-
27
- object.__fields.each do |field|
28
- name = field.key_json || name_to_json(field.sym)
29
- value = field.converter.serialize(object.send(field.sym), field)
30
- result[name] = value
31
- end
32
-
33
- result
34
- end
35
-
36
- def deserialize(definition, json)
37
- raise NotSupportedError.new("Can not process non-class!") unless definition.is_a?(Class)
38
- raise NotSupportedError.new("Can not process other than DTO!") unless definition < Dto
39
- result = definition.new
40
- raw = JSON.parse json
41
- result.__fields.each do |field|
42
- name = field.key_json || name_to_json(field.sym)
43
- value = raw[name]
44
- next if value.nil?
45
-
46
- result.send("#{field.key_ruby}=", value)
47
- end
48
- result
49
- end
50
-
51
- def self.register_converter!(klass)
52
- key = klass.name.split('::').last.underscore.to_sym
53
-
54
- return if key === :base
55
-
56
- # We don't support multiple converter for now
57
- raise NotSupportedError.new("#{key} registered twice") if not @@converters[key].nil?
58
-
59
- @@converters[key] = klass.new
60
- end
61
-
62
- def self.register_name_resolver!(klass)
63
- key = klass.name.split('::').last.underscore.to_sym
64
-
65
- return if key === :base
66
-
67
- # We don't support multiple converter for now
68
- raise NotSupportedError.new("#{key} registered twice") if not @@name_resolvers[key].nil?
69
-
70
- @@name_resolvers[key] = klass.new
71
- end
72
-
73
- def name_to_ruby(string)
74
- strategy = @config.contract
75
- @@name_resolvers[strategy].deserialize(string)
76
- end
77
-
78
- def name_to_json(sym)
79
- strategy = @config.contract
80
- @@name_resolvers[strategy].serialize(sym)
81
- end
82
-
83
- def self.converter(sym)
84
- @@converters[sym]
85
- end
86
- end
87
- end
1
+ require 'json'
2
+
3
+ module Kanade
4
+ class Engine
5
+ @@converters = {}
6
+ @@name_resolvers = {}
7
+
8
+ def initialize(configuration=nil)
9
+ @config = configuration || Kanade::Config.default
10
+ end
11
+
12
+ def configure
13
+ yield @config
14
+ end
15
+
16
+ def serialize(object)
17
+ traverse_field(object).to_json
18
+ end
19
+
20
+ def traverse_field(object)
21
+ return nil if object.nil?
22
+ raise NotSupportedError.new("Serializer only works for Kanade::Dto, and #{object.class.name} does not extend Kanade::Dto") unless object.class < Kanade::Dto
23
+
24
+ result = {}
25
+
26
+ object.__fields.each do |field|
27
+ name = field.key_json || name_to_json(field.sym)
28
+
29
+ if field.options[:as] == :list
30
+ value = serialize_list(object.send(field.sym), field)
31
+ elsif field.options[:as] == :dto
32
+ value = traverse_field(object.send(field.sym))
33
+ else
34
+ value = field.converter.serialize(object.send(field.sym), field)
35
+ end
36
+ result[name] = value
37
+ end
38
+
39
+ result
40
+ end
41
+
42
+ def serialize_list(list, field_info)
43
+ return nil if list.nil?
44
+ list.map do |entry|
45
+ if field_info.options[:of].is_a?(Class) and field_info.options[:of] < Dto
46
+ traverse_field(entry)
47
+ else
48
+ conversion_method = field_info.options[:of]
49
+ # TODO how to refer to static field?
50
+ converter = Engine.converter(conversion_method)
51
+
52
+ raise NotSupportedError.new("Can not process unknown converter! #{conversion_method}") if converter.nil?
53
+
54
+ converter.serialize(entry, field_info)
55
+ end
56
+ end
57
+ end
58
+
59
+ def deserialize(definition, json)
60
+ raise NotSupportedError.new("Can not process non-class!") unless definition.is_a?(Class)
61
+ raise NotSupportedError.new("Can not process other than DTO!") unless definition < Dto
62
+
63
+ hash = JSON.parse(json)
64
+ deserialize_object(definition, hash)
65
+ end
66
+
67
+ # IF engine contains deserialization logic, we can no more
68
+ # unit test the converters. Seems like, the conversion logic
69
+ # must be outsourced to its respective converter
70
+ def deserialize_object(definition, hash)
71
+ return nil if hash.nil?
72
+ result = definition.new
73
+ result.__fields.each do |field|
74
+ name = field.key_json || name_to_json(field.sym)
75
+
76
+ if field.options[:as] == :list
77
+ value = deserialize_list(hash[name], field)
78
+ elsif field.options[:as] == :dto
79
+ value = deserialize_object(field.options[:of], hash[name])
80
+ else
81
+ value = hash[name]
82
+ end
83
+
84
+ next if value.nil?
85
+
86
+ result.send("#{field.key_ruby}=", value)
87
+ end
88
+ result
89
+ end
90
+
91
+ def deserialize_list(value, field_info)
92
+ return nil if value.nil?
93
+
94
+ # Catatan pribadi: Jadi "of" itu harusnya mengandung field definition?
95
+ # bukan of: Product, tapi of: {as: :dto, of: Product}
96
+ # dengan field definition ini, kita bisa membuat hal yang lebih konfleks, misal:
97
+ # of: {as: :symbol, mapping: {success: 'RES_SUCCESS'}}
98
+ value.map do |v|
99
+ if field_info.options[:of].is_a?(Class) and field_info.options[:of] < Dto
100
+ deserialize_object(field_info.options[:of], v)
101
+ else
102
+ conversion_method = field_info.options[:of]
103
+ # TODO how to refer to static field?
104
+ converter = Engine.converter(conversion_method)
105
+
106
+ raise NotSupportedError.new("Can not process unknown converter! #{conversion_method}") if converter.nil?
107
+
108
+ converter.deserialize(v, field_info)
109
+ end
110
+ end
111
+ end
112
+
113
+ def self.register_converter!(klass)
114
+ key = klass.name.split('::').last.underscore.to_sym
115
+
116
+ return if key === :base
117
+
118
+ # We don't support multiple converter for now
119
+ raise NotSupportedError.new("#{key} registered twice") if not @@converters[key].nil?
120
+
121
+ @@converters[key] = klass.new
122
+ end
123
+
124
+ def self.register_name_resolver!(klass)
125
+ key = klass.name.split('::').last.underscore.to_sym
126
+
127
+ return if key === :base
128
+
129
+ # We don't support multiple converter for now
130
+ raise NotSupportedError.new("#{key} registered twice") if not @@name_resolvers[key].nil?
131
+
132
+ @@name_resolvers[key] = klass.new
133
+ end
134
+
135
+ def name_to_ruby(string)
136
+ strategy = @config.contract
137
+ @@name_resolvers[strategy].deserialize(string)
138
+ end
139
+
140
+ def name_to_json(sym)
141
+ strategy = @config.contract
142
+ @@name_resolvers[strategy].serialize(sym)
143
+ end
144
+
145
+ def self.converter(sym)
146
+ @@converters[sym]
147
+ end
148
+ end
149
+ end
@@ -1,3 +1,3 @@
1
1
  module Kanade
2
- VERSION = '0.1.0.beta1'
2
+ VERSION = '0.1.0.beta2'
3
3
  end
@@ -1,19 +1,20 @@
1
- {
2
- "id": 3,
3
- "products": [
4
- {
5
- "id": 100,
6
- "name": "Cat Plushie",
7
- "expireAt": null,
8
- "price": "19.95",
9
- "available": true
10
- },
11
- {
12
- "id": 101,
13
- "name": "Taco",
14
- "expireAt": "2016-09-21 13:52:44 +0700",
15
- "price": "5.0",
16
- "available": true
17
- }
18
- ]
19
- }
1
+ {
2
+ "id": 3,
3
+ "serials": [100, 105, 444],
4
+ "products": [
5
+ {
6
+ "id": 100,
7
+ "name": "Cat Plushie",
8
+ "expireAt": null,
9
+ "price": "19.95",
10
+ "available": true
11
+ },
12
+ {
13
+ "id": 101,
14
+ "name": "Taco",
15
+ "expireAt": "2016-09-21T13:52:44+07:00",
16
+ "price": "5.0",
17
+ "available": true
18
+ }
19
+ ]
20
+ }
@@ -6,5 +6,10 @@
6
6
  "expireAt": "2019-03-30T06:52:44+09:00",
7
7
  "price": "99.95",
8
8
  "available": true
9
+ },
10
+ "addendumReport" : {
11
+ "ID": 1234,
12
+ "affectedProduct": null,
13
+ "addendumReport": null
9
14
  }
10
15
  }
@@ -1,4 +1,5 @@
1
- class RefundReport
1
+ class RefundReport < Kanade::Dto
2
2
  field :refund_id, as: :fixnum, with: 'ID'
3
3
  field :affected_product, as: Product
4
+ field :addendum_report, as: RefundReport
4
5
  end
@@ -0,0 +1,5 @@
1
+ RSpec.describe 'Serialization Integration' do
2
+ it 'tests should be exist' do
3
+ skip 'TODO'
4
+ end
5
+ end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require_relative '../fixtures/product'
3
3
  require_relative '../fixtures/product_wrong'
4
+ require_relative '../fixtures/refund_report'
5
+ require_relative '../fixtures/catalog'
4
6
 
5
7
  RSpec.describe 'Deserialization Integration' do
6
8
 
@@ -53,6 +55,70 @@ RSpec.describe 'Deserialization Integration' do
53
55
  end
54
56
 
55
57
  context 'Array of products' do
58
+ let(:object) do
59
+ @engine.deserialize(Catalog, json_of(:catalog_camel_case))
60
+ end
61
+
62
+ subject do
63
+ object
64
+ end
65
+
66
+ it 'has correct id' do
67
+ expect(subject.id).to eq(3)
68
+ expect(subject.id).to_not eq('3')
69
+ end
70
+
71
+ it 'has serials of fixnum' do
72
+ expect(subject.serials).to eq([100, 105, 444])
73
+ expect(subject.serials).to_not eq([100, '105', 444])
74
+ end
75
+
76
+ it 'has multiple products' do
77
+ expect(subject.products.count).to eq(2)
78
+ end
79
+
80
+ it 'has correct order of products' do
81
+ expect(subject.products[0].id).to eq(100)
82
+ expect(subject.products[0].name).to eq('Cat Plushie')
83
+ expect(subject.products[0].expire_at).to be_nil
84
+ expect(subject.products[0].price).to eq(BigDecimal.new('19.95'))
85
+ expect(subject.products[0].price).to_not eq('19.95')
86
+ expect(subject.products[0].available).to eq(true)
87
+
88
+ expect(subject.products[1].id).to eq(101)
89
+ expect(subject.products[1].name).to eq('Taco')
90
+ expect(subject.products[1].expire_at).to eq(Time.parse('2016-09-21T13:52:44+07:00'))
91
+ expect(subject.products[1].price).to eq(BigDecimal.new('5.0'))
92
+ expect(subject.products[1].price).to_not eq('5.0')
93
+ expect(subject.products[1].available).to eq(true)
94
+ end
95
+ end
96
+
97
+ context 'Nested object' do
98
+ let(:object) do
99
+ @engine.deserialize(RefundReport, json_of(:refund_report))
100
+ end
101
+
102
+ subject do
103
+ object
104
+ end
105
+
106
+ it 'has correct ID' do
107
+ expect(subject.refund_id).to eq(9321)
108
+ end
56
109
 
110
+ it 'has correct nested product' do
111
+ expect(subject.affected_product.id).to eq(451)
112
+ expect(subject.affected_product.name).to eq('Digital Camera')
113
+ expect(subject.affected_product.expire_at).to eq(Time.parse('2019-03-30T06:52:44+09:00'))
114
+ expect(subject.affected_product.price).to eq(BigDecimal.new('99.95'))
115
+ expect(subject.affected_product.available).to eq(true)
116
+ end
117
+
118
+ it 'has correct addendum report' do
119
+ expect(subject.addendum_report.refund_id).to eq(1234)
120
+ expect(subject.addendum_report.affected_product).to be_nil
121
+ expect(subject.addendum_report.addendum_report).to be_nil
122
+ end
57
123
  end
58
124
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
+ require_relative '../fixtures/catalog'
2
3
  require_relative '../fixtures/product'
3
4
  require_relative '../fixtures/product_wrong'
5
+ require_relative '../fixtures/refund_report'
4
6
 
5
7
  RSpec.describe 'Serialization Integration' do
6
8
 
@@ -69,6 +71,58 @@ RSpec.describe 'Serialization Integration' do
69
71
  end
70
72
 
71
73
  context 'Array of products' do
74
+ subject { @engine.serialize(target) }
72
75
 
76
+ let(:target) do
77
+ catalog = Catalog.new
78
+ catalog.serials = [100, 105, 444]
79
+ catalog.id = 3
80
+
81
+ product1 = Product.new
82
+ product1.id = 100
83
+ product1.name = 'Cat Plushie'
84
+ product1.expire_at = nil
85
+ product1.price = '19.95'
86
+ product1.available = true
87
+
88
+ product2 = Product.new
89
+ product2.id = 101
90
+ product2.name = 'Taco'
91
+ product2.expire_at = '2016-09-21T13:52:44+07:00'
92
+ product2.price = 5
93
+ product2.available = true
94
+
95
+ catalog.products = []
96
+ catalog.products << product1
97
+ catalog.products << product2
98
+ catalog
99
+ end
100
+
101
+ it { is_expected.to be_json_of(:catalog_camel_case) }
102
+ end
103
+
104
+ context 'Nested object' do
105
+ subject { @engine.serialize(target) }
106
+
107
+ let(:target) do
108
+ report = RefundReport.new
109
+ report.refund_id = '9321'
110
+
111
+ product = Product.new
112
+ product.id = 451
113
+ product.name = 'Digital Camera'
114
+ product.expire_at = Time.parse('2019-03-30T06:52:44+09:00')
115
+ product.price = BigDecimal.new('99.95')
116
+ product.available = true
117
+
118
+ addendum_report = RefundReport.new
119
+ addendum_report.refund_id = 1234
120
+
121
+ report.addendum_report = addendum_report
122
+ report.affected_product = product
123
+ report
124
+ end
125
+
126
+ it { is_expected.to be_json_of :refund_report }
73
127
  end
74
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kanade
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta1
4
+ version: 0.1.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mufid Afif
@@ -133,6 +133,7 @@ files:
133
133
  - lib/kanade/converter/base.rb
134
134
  - lib/kanade/converter/big_decimal.rb
135
135
  - lib/kanade/converter/bool.rb
136
+ - lib/kanade/converter/dto.rb
136
137
  - lib/kanade/converter/fixnum.rb
137
138
  - lib/kanade/converter/float.rb
138
139
  - lib/kanade/converter/list.rb
@@ -157,6 +158,7 @@ files:
157
158
  - spec/fixtures/refund_report.rb
158
159
  - spec/fixtures/simple_product.json
159
160
  - spec/integration/class_consistency_spec.rb
161
+ - spec/integration/ignore_unknown_field_spec.rb
160
162
  - spec/integration/simple_deserialization_integration_spec.rb
161
163
  - spec/integration/simple_serialization_integration_spec.rb
162
164
  - spec/matchers/json_matcher.rb
@@ -200,6 +202,7 @@ test_files:
200
202
  - spec/fixtures/refund_report.rb
201
203
  - spec/fixtures/simple_product.json
202
204
  - spec/integration/class_consistency_spec.rb
205
+ - spec/integration/ignore_unknown_field_spec.rb
203
206
  - spec/integration/simple_deserialization_integration_spec.rb
204
207
  - spec/integration/simple_serialization_integration_spec.rb
205
208
  - spec/matchers/json_matcher.rb