kanade 0.1.0.beta1 → 0.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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