firm 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,945 @@
1
+ begin
2
+ require 'bigdecimal'
3
+ rescue LoadError
4
+ end
5
+ begin
6
+ require 'nokogiri'
7
+ rescue LoadError
8
+ end
9
+ require 'firm'
10
+
11
+ module SerializerTestMixin
12
+
13
+ class PropTest
14
+
15
+ include FIRM::Serializable
16
+
17
+ property :prop_a
18
+ property prop_b: ->(obj, *val) { obj.instance_variable_set(:@prop_b, val.first) unless val.empty?; obj.instance_variable_get(:@prop_b) }
19
+ property prop_c: :serialize_prop_c
20
+ property(:prop_d, :prop_e) do |id, obj, *val|
21
+ case id
22
+ when :prop_d
23
+ obj.instance_variable_set('@prop_d', val.first) unless val.empty?
24
+ obj.instance_variable_get('@prop_d')
25
+ when :prop_e
26
+ obj.instance_variable_set('@prop_e', val.first) unless val.empty?
27
+ obj.instance_variable_get('@prop_e')
28
+ end
29
+ end
30
+ property :prop_f, :prop_g, handler: :serialize_props_f_and_g
31
+
32
+ def initialize
33
+ @prop_a = 'string'
34
+ @prop_b = 123
35
+ @prop_c = :symbol
36
+ @prop_d = 100.123
37
+ @prop_e = [1,2,3]
38
+ @prop_f = {_1: 1, _2: 2, _3: 3}
39
+ @prop_g = 1..10
40
+ end
41
+
42
+ attr_accessor :prop_a
43
+
44
+ def serialize_prop_c(*val)
45
+ @prop_c = val.first unless val.empty?
46
+ @prop_c
47
+ end
48
+ private :serialize_prop_c
49
+
50
+ def serialize_props_f_and_g(id, *val)
51
+ case id
52
+ when :prop_f
53
+ @prop_f = val.shift unless val.empty?
54
+ @prop_f
55
+ when :prop_g
56
+ @prop_g = val.shift unless val.empty?
57
+ @prop_g
58
+ end
59
+ end
60
+
61
+ def ==(other)
62
+ self.class === other &&
63
+ @prop_a == other.prop_a &&
64
+ @prop_b == other.instance_variable_get('@prop_b') &&
65
+ @prop_c == other.instance_variable_get('@prop_c') &&
66
+ @prop_d == other.instance_variable_get('@prop_d') &&
67
+ @prop_e == other.instance_variable_get('@prop_e') &&
68
+ @prop_g == other.instance_variable_get('@prop_g') &&
69
+ @prop_f == other.instance_variable_get('@prop_f')
70
+ end
71
+ end
72
+
73
+ def test_properties
74
+ obj = PropTest.new
75
+ obj_serial = obj.serialize
76
+ obj_new = nil
77
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
78
+ assert_instance_of(PropTest, obj_new)
79
+ assert_equal(obj, obj_new)
80
+ end
81
+
82
+ class Point
83
+
84
+ include Comparable
85
+
86
+ include FIRM::Serializable
87
+
88
+ properties :x, :y
89
+
90
+ def initialize(*args)
91
+ if args.empty?
92
+ @x = @y = 0
93
+ else
94
+ @x, @y = *args
95
+ end
96
+ end
97
+
98
+ attr_accessor :x, :y
99
+
100
+ def <=>(other)
101
+ if other.is_a?(self.class)
102
+ if @x == other.x
103
+ @y <=> other.y
104
+ else
105
+ @x <=> other.x
106
+ end
107
+ else
108
+ nil
109
+ end
110
+ end
111
+
112
+ def eql?(other)
113
+ other.is_a?(self.class) ? @x.eql?(other.x) && @y.eql?(other.y) : false
114
+ end
115
+
116
+ def hash
117
+ "#{@x}x#{@y}".hash
118
+ end
119
+
120
+ end
121
+
122
+ class Rect
123
+
124
+ include FIRM::Serializable
125
+
126
+ properties :x, :y, :width, :height
127
+
128
+ def initialize(x, y, w, h)
129
+ @x = x
130
+ @y = y
131
+ @width = w
132
+ @height = h
133
+ end
134
+
135
+ attr_reader :x, :y, :width, :height
136
+
137
+ def ==(other)
138
+ if other.is_a?(self.class)
139
+ @x == other.x && @y == other.y && @width == other.width && @height == other.height
140
+ else
141
+ false
142
+ end
143
+ end
144
+
145
+ # Noop
146
+ # @param [Hash] _hash ignored
147
+ # @return [self]
148
+ def from_serialized(_hash)
149
+ # no deserializing necessary
150
+ self
151
+ end
152
+ protected :from_serialized
153
+
154
+ def init_from_serialized(data)
155
+ initialize(data[:x], data[:y], data[:width], data[:height])
156
+ self
157
+ end
158
+ protected :init_from_serialized
159
+
160
+ end
161
+
162
+ class Colour
163
+
164
+ include FIRM::Serializable
165
+
166
+ property :colour => ->(col, *val) { col.set(*val.first) unless val.empty?; [col.red, col.green, col.blue, col.alpha] }
167
+
168
+ def initialize(*args)
169
+ if args.empty?
170
+ @red, @green, @blue, @alpha = *args
171
+ @alpha ||= 255
172
+ else
173
+ @red = @green = @blue = 0
174
+ @alpha = 255
175
+ end
176
+ end
177
+
178
+ def set(r, g, b, a)
179
+ @red = r
180
+ @green = g
181
+ @blue = b
182
+ @alpha = a
183
+ end
184
+
185
+ attr_reader :red, :green, :blue, :alpha
186
+
187
+ def ==(other)
188
+ if other.is_a?(self.class)
189
+ @red == other.red && @green == other.green && @blue == other.blue
190
+ else
191
+ false
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ def test_data
198
+ obj = Point.new(10, 90)
199
+ obj_serial = obj.serialize
200
+ obj_new = nil
201
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
202
+ assert_instance_of(Point, obj_new)
203
+ assert_equal(obj, obj_new)
204
+
205
+ obj = Rect.new(10, 20, 100, 900)
206
+ obj_serial = obj.serialize
207
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
208
+ assert_instance_of(Rect, obj_new)
209
+ assert_equal(obj, obj_new)
210
+
211
+ obj = Colour.new('red')
212
+ obj_serial = obj.serialize
213
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
214
+ assert_instance_of(Colour, obj_new)
215
+ assert_equal(obj, obj_new)
216
+ end
217
+
218
+ def test_core
219
+ obj = [Point.new(10, 90), Point.new(20, 80)]
220
+ obj_serial = obj.serialize
221
+ obj_new = nil
222
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
223
+ assert_equal(obj, obj_new)
224
+
225
+ obj = { '1' => Point.new(10, 90), '2' => Point.new(20, 80) }
226
+ obj_serial = obj.serialize
227
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
228
+ assert_equal(obj, obj_new)
229
+
230
+ Struct.new('MyStruct', :one, :two) unless defined? Struct::MyStruct
231
+ obj = Struct::MyStruct.new(one: Point.new(10, 90), two: Point.new(20, 80))
232
+ obj_serial = obj.serialize
233
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
234
+ assert_equal(obj, obj_new)
235
+
236
+ obj = ::Set.new(%i[one two three])
237
+ obj_serial = obj.serialize
238
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
239
+ assert_equal(obj, obj_new)
240
+
241
+ obj = OpenStruct.new(one: Point.new(10, 90), two: Point.new(20, 80))
242
+ obj_serial = obj.serialize
243
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
244
+ assert_equal(obj, obj_new)
245
+
246
+ obj = [1, nil, 2]
247
+ obj_serial = obj.serialize
248
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
249
+ assert_equal(obj, obj_new)
250
+
251
+ obj = (0..10)
252
+ obj_serial = obj.serialize
253
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
254
+ assert_equal(obj, obj_new)
255
+
256
+ obj = Rational(5, 3)
257
+ obj_serial = obj.serialize
258
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
259
+ assert_equal(obj, obj_new)
260
+
261
+ obj = /\Ahello.*/i
262
+ obj_serial = obj.serialize
263
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
264
+ assert_equal(obj, obj_new)
265
+
266
+ obj = Time.now - 999
267
+ obj_serial = obj.serialize
268
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
269
+ assert_equal(obj, obj_new)
270
+
271
+ obj = Date.today - 33
272
+ obj_serial = obj.serialize
273
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
274
+ assert_equal(obj, obj_new)
275
+
276
+ obj = DateTime.now
277
+ obj_serial = obj.serialize
278
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
279
+ assert_equal(obj, obj_new)
280
+
281
+ if ::Object.const_defined?(:BigDecimal)
282
+ obj = BigDecimal(2**64 + 0.1234, 4)
283
+ obj_serial = obj.serialize
284
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
285
+ assert_equal(obj, obj_new)
286
+ end
287
+
288
+ obj = Complex(0.5, 0.75)
289
+ obj_serial = obj.serialize
290
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
291
+ assert_equal(obj, obj_new)
292
+
293
+ end
294
+
295
+ class PointsOwner
296
+ include FIRM::Serializable
297
+
298
+ property :points
299
+
300
+ def initialize(points = [])
301
+ @points = points
302
+ end
303
+
304
+ attr_accessor :points
305
+
306
+ def ==(other)
307
+ self.class === other && @points == other.points
308
+ end
309
+ end
310
+
311
+ def test_composition
312
+ obj = PointsOwner.new([Point.new(10, 90), Point.new(20, 80)])
313
+ obj_serial = obj.serialize
314
+ obj_new = nil
315
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
316
+ assert_equal(obj, obj_new)
317
+ end
318
+
319
+ class SerializedBase
320
+ include FIRM::Serializable
321
+
322
+ property :a
323
+ property :b
324
+ property :c
325
+
326
+ def initialize(a=nil, b=nil, c=nil)
327
+ @a = a
328
+ @b = b
329
+ @c = c
330
+ end
331
+
332
+ attr_accessor :a, :b, :c
333
+
334
+ def ==(other)
335
+ self.class === other && self.a == other.a && self.b == other.b && self.c == other.c
336
+ end
337
+ end
338
+
339
+ class SerializedDerived < SerializedBase
340
+ contains :d
341
+ excludes :c
342
+
343
+ def initialize(a=nil, b=nil, d=nil)
344
+ super(a, b)
345
+ @d = d
346
+ self.c = 'FIXED'
347
+ end
348
+
349
+ attr_accessor :d
350
+
351
+ def ==(other)
352
+ super && self.d == other.d
353
+ end
354
+ end
355
+
356
+ def test_exclusion
357
+ obj = SerializedBase.new(1, :hello, 'World')
358
+ obj_serial = obj.serialize
359
+ obj_new = nil
360
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
361
+ assert_equal(obj, obj_new)
362
+
363
+ obj = SerializedDerived.new(2, :derived, 103.50)
364
+ obj_serial = obj.serialize
365
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
366
+ assert_equal(obj, obj_new)
367
+ end
368
+
369
+ class SerializedBase2
370
+ include FIRM::Serializable
371
+
372
+ property :list
373
+
374
+ def initialize(list = [])
375
+ @list = list
376
+ end
377
+
378
+ attr_reader :list
379
+
380
+ def set_list(list)
381
+ @list.insert(0, *(list || []))
382
+ end
383
+ private :set_list
384
+
385
+ def ==(other)
386
+ self.class === other && self.list == other.list
387
+ end
388
+ end
389
+
390
+ class SerializedDerived2 < SerializedBase2
391
+
392
+ def initialize(list = [])
393
+ super
394
+ @fixed_item = Point.new(30, 30)
395
+ @fixed_item.disable_serialize
396
+ self.list << @fixed_item
397
+ end
398
+
399
+ end
400
+
401
+ class SerializedDerived2_1 < SerializedBase2
402
+ property :extra_item, force: true
403
+
404
+ def initialize(list = [], extra = nil)
405
+ super(list)
406
+ set_extra_item(extra)
407
+ end
408
+
409
+ attr_reader :extra_item
410
+
411
+ def set_extra_item(extra)
412
+ @extra_item = extra
413
+ if @extra_item
414
+ @extra_item.disable_serialize
415
+ list << @extra_item
416
+ end
417
+ end
418
+ private :set_extra_item
419
+
420
+ def ==(other)
421
+ super(other) && @extra_item == other.extra_item
422
+ end
423
+ end
424
+
425
+ class SerializedBase3
426
+ include FIRM::Serializable
427
+
428
+ property :list
429
+
430
+ def initialize(list = ::Set.new)
431
+ @list = ::Set === list ? list : ::Set.new(list)
432
+ end
433
+
434
+ attr_reader :list
435
+
436
+ def set_list(list)
437
+ @list.merge(list || [])
438
+ end
439
+ private :set_list
440
+
441
+ def ==(other)
442
+ self.class === other && self.list == other.list
443
+ end
444
+ end
445
+
446
+ class SerializedDerived3 < SerializedBase3
447
+
448
+ def initialize(list = [])
449
+ super
450
+ @fixed_item = Point.new(30, 30)
451
+ @fixed_item.disable_serialize
452
+ self.list << @fixed_item
453
+ end
454
+
455
+ end
456
+
457
+ def test_disable
458
+ obj = SerializedBase2.new([Point.new(1,1), Point.new(2,2), Point.new(3,3)])
459
+ obj_serial = obj.serialize
460
+ obj_new = nil
461
+ assert_nothing_raised { obj_new = SerializedBase2.deserialize(obj_serial) }
462
+ assert_equal(obj, obj_new)
463
+
464
+ obj = SerializedDerived2.new([Point.new(1,1), Point.new(2,2), Point.new(3,3)])
465
+ obj_serial = obj.serialize
466
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
467
+ assert_equal(obj, obj_new)
468
+
469
+ obj = SerializedDerived2_1.new([Point.new(1,1), Point.new(2,2), Point.new(3,3)], Rect.new(1, 1, 40, 40))
470
+ obj_serial = obj.serialize
471
+ assert_nothing_raised { obj_new = SerializedDerived2_1.deserialize(obj_serial) }
472
+ assert_equal(obj, obj_new)
473
+
474
+ obj = SerializedDerived3.new([Point.new(1,1), Point.new(2,2), Point.new(3,3)])
475
+ obj_serial = obj.serialize
476
+ assert_nothing_raised { obj_new = SerializedDerived3.deserialize(obj_serial) }
477
+ assert_equal(obj, obj_new)
478
+ end
479
+
480
+ class Identifiable
481
+ include FIRM::Serializable
482
+
483
+ property :id, :sym
484
+
485
+ def initialize(sym = nil)
486
+ @id = sym ? FIRM::Serializable::ID.new : nil
487
+ @sym = sym
488
+ end
489
+
490
+ attr_accessor :sym
491
+ attr_reader :id
492
+
493
+ def set_id(id)
494
+ @id = id
495
+ end
496
+ private :set_id
497
+ end
498
+
499
+ class Container
500
+ include FIRM::Serializable
501
+
502
+ property :map
503
+
504
+ def initialize(map = {})
505
+ @map = map
506
+ end
507
+
508
+ attr_reader :map
509
+
510
+ def set_map(map)
511
+ @map.replace(map)
512
+ end
513
+ private :set_map
514
+ end
515
+
516
+ class RefUser
517
+ include FIRM::Serializable
518
+
519
+ property :ref1, :ref2, :ref3
520
+
521
+ def initialize(*rids)
522
+ @ref1, @ref2, @ref3 = *rids
523
+ end
524
+
525
+ attr_accessor :ref1, :ref2, :ref3
526
+ end
527
+
528
+ def test_ids
529
+ container = Container.new
530
+ id_obj = Identifiable.new(:one)
531
+ container.map[id_obj.id] = id_obj
532
+ id_obj = Identifiable.new(:two)
533
+ container.map[id_obj.id] = id_obj
534
+ id_obj = Identifiable.new(:three)
535
+ container.map[id_obj.id] = id_obj
536
+ ref_obj = RefUser.new(*container.map.keys)
537
+ obj_serial = [container, ref_obj].serialize
538
+ obj_new = nil
539
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
540
+ assert_instance_of(Array, obj_new)
541
+ assert_instance_of(Container, obj_new.first)
542
+ assert_instance_of(RefUser, obj_new.last)
543
+ assert_instance_of(FIRM::Serializable::ID, obj_new.last.ref1)
544
+ assert_instance_of(FIRM::Serializable::ID, obj_new.last.ref2)
545
+ assert_instance_of(FIRM::Serializable::ID, obj_new.last.ref3)
546
+ assert_equal(:one, obj_new.first.map[obj_new.last.ref1].sym)
547
+ assert_equal(:two, obj_new.first.map[obj_new.last.ref2].sym)
548
+ assert_equal(:three, obj_new.first.map[obj_new.last.ref3].sym)
549
+ end
550
+
551
+ class Aliasable
552
+ include FIRM::Serializable
553
+
554
+ property :name, :description
555
+
556
+ def initialize(*args)
557
+ @name, @description = *args
558
+ end
559
+
560
+ attr_accessor :name, :description
561
+ end
562
+
563
+ class DerivedAliasable < Aliasable
564
+
565
+ property :extra
566
+
567
+ def initialize(*args)
568
+ @extra = args.pop if args.size>2
569
+ super
570
+ end
571
+
572
+ attr_accessor :extra
573
+
574
+ end
575
+
576
+ def test_aliases
577
+ container = Container.new
578
+ container.map[:one] = Aliasable.new('one', 'First aliasable')
579
+ container.map[:two] = Aliasable.new('two', 'Second aliasable')
580
+ container.map[:three] = container.map[:one]
581
+ container.map[:four] = container.map[:two]
582
+ container.map[:five] = DerivedAliasable.new('three', 'Third aliasable', 'Derived aliasable')
583
+ container.map[:six] = container.map[:five]
584
+ obj_serial = container.serialize
585
+ obj_new = nil
586
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
587
+ assert_instance_of(Container, obj_new)
588
+ assert_instance_of(Aliasable, obj_new.map[:one])
589
+ assert_instance_of(Aliasable, obj_new.map[:two])
590
+ assert_instance_of(Aliasable, obj_new.map[:three])
591
+ assert_equal(obj_new.map[:one].object_id, obj_new.map[:three].object_id)
592
+ assert_instance_of(Aliasable, obj_new.map[:four])
593
+ assert_equal(obj_new.map[:two].object_id, obj_new.map[:four].object_id)
594
+ assert_instance_of(DerivedAliasable, obj_new.map[:five])
595
+ assert_instance_of(DerivedAliasable, obj_new.map[:six])
596
+ assert_equal(obj_new.map[:five].object_id, obj_new.map[:six].object_id)
597
+ end
598
+
599
+ class House
600
+
601
+ include FIRM::Serializable
602
+
603
+ attr_accessor :address, :city
604
+ attr_reader :owners
605
+
606
+ properties :address, :city, :owners
607
+
608
+ def initialize(*args)
609
+ @address, @city = *args
610
+ @owners = []
611
+ end
612
+
613
+ def add_owner(owner)
614
+ @owners << owner
615
+ owner.houses << self
616
+ end
617
+
618
+ def set_owners(owners)
619
+ @owners = owners
620
+ end
621
+ private :set_owners
622
+
623
+ end
624
+
625
+ class Person
626
+
627
+ include FIRM::Serializable
628
+
629
+ attr_accessor :name, :tax_id, :houses
630
+
631
+ properties :name, :tax_id, :houses
632
+
633
+ def initialize(*args)
634
+ @name, @tax_id = *args
635
+ @houses = []
636
+ end
637
+
638
+ end
639
+
640
+ def test_cyclic_references
641
+ person_a = Person.new('Max A', 123456)
642
+ person_b = Person.new('Joe B', 234567)
643
+
644
+ house_1 = House.new('The street 1', 'Nowhere')
645
+ house_1.add_owner(person_a)
646
+ house_2 = House.new('The lane 2', 'Somewhere')
647
+ house_2.add_owner(person_b)
648
+ house_3 = House.new('The promenade 3', 'ThisPlace')
649
+ house_3.add_owner(person_a)
650
+ house_3.add_owner(person_b)
651
+
652
+ obj_serial = [house_1, house_2, house_3].serialize
653
+ h1_new, h2_new, h3_new = nil
654
+ assert_nothing_raised { h1_new, h2_new, h3_new = *FIRM.deserialize(obj_serial) }
655
+ assert_instance_of(House, h1_new)
656
+ assert_instance_of(House, h2_new)
657
+ assert_instance_of(House, h3_new)
658
+ assert_true(house_1.address == h1_new.address && house_1.city == h1_new.city)
659
+ assert_true(house_2.address == h2_new.address && house_2.city == h2_new.city)
660
+ assert_true(house_3.address == h3_new.address && house_3.city == h3_new.city)
661
+ assert_equal(h1_new.owners[0].object_id, h3_new.owners[0].object_id)
662
+ assert_equal(h2_new.owners[0].object_id, h3_new.owners[1].object_id)
663
+ pa_new, pb_new = *h3_new.owners
664
+ assert_instance_of(Person, pa_new)
665
+ assert_instance_of(Person, pb_new)
666
+ assert_equal(h1_new.object_id, pa_new.houses[0].object_id)
667
+ assert_equal(h2_new.object_id, pb_new.houses[0].object_id)
668
+ assert_equal(h3_new.object_id, pa_new.houses[1].object_id)
669
+ assert_equal(h3_new.object_id, pb_new.houses[1].object_id)
670
+ end
671
+
672
+ CyclicTest = ::Struct.new(:list)
673
+
674
+ def test_cyclic_struct
675
+ struct = CyclicTest.new
676
+ struct.list = [struct]
677
+ obj_serial = struct.serialize
678
+ struct_new = nil
679
+ assert_nothing_raised { struct_new = FIRM.deserialize(obj_serial) }
680
+ assert_instance_of(CyclicTest, struct_new)
681
+ assert_equal(struct_new.object_id, struct_new.list[0].object_id)
682
+ end
683
+
684
+ def test_nested_hash_with_complex_keys
685
+ id_obj = Identifiable.new(:one)
686
+ id_obj2 = Identifiable.new(:two)
687
+ h = {
688
+ [
689
+ { id_obj.id => id_obj }
690
+ ] => 'one',
691
+ [
692
+ { id_obj2.id => id_obj2 }
693
+ ] => 'two'
694
+ }
695
+ obj_serial = h.serialize
696
+ obj_new = nil
697
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
698
+ assert_instance_of(::Hash, obj_new)
699
+ obj_new.each_pair do |k,v|
700
+ assert_instance_of(::Array, k)
701
+ assert_instance_of(::String, v)
702
+ assert_instance_of(::Hash, k.first)
703
+ assert_instance_of(FIRM::Serializable::ID, k.first.first.first)
704
+ assert_equal(v, k.first[k.first.first.first].sym.to_s)
705
+ end
706
+ end
707
+
708
+ class NestedSerializer
709
+ include FIRM::Serializable
710
+
711
+ property :nested, handler: :marshall_nested
712
+
713
+ def initialize(serializable=nil)
714
+ @nested = serializable
715
+ end
716
+
717
+ attr_reader :nested
718
+
719
+ protected
720
+
721
+ def marshall_nested(_id, *val)
722
+ if val.empty?
723
+ @nested.serialize
724
+ else
725
+ @nested = FIRM.deserialize(val.first)
726
+ nil
727
+ end
728
+ end
729
+
730
+ end
731
+
732
+ def test_nested_serialize
733
+ container = Container.new
734
+ container.map[:one] = Aliasable.new('one', 'First aliasable')
735
+ container.map[:two] = Aliasable.new('two', 'Second aliasable')
736
+ container.map[:three] = container.map[:one]
737
+ container.map[:four] = container.map[:two]
738
+ container.map[:five] = DerivedAliasable.new('three', 'Third aliasable', 'Derived aliasable')
739
+ container.map[:six] = container.map[:five]
740
+ id_obj = Identifiable.new(:seven)
741
+ container.map[id_obj.sym] = id_obj
742
+ id_obj = Identifiable.new(:eight)
743
+ container.map[id_obj.sym] = id_obj
744
+ id_obj = Identifiable.new(:nine)
745
+ container.map[id_obj.sym] = id_obj
746
+ ref_obj = RefUser.new(container.map[:seven].id, container.map[:eight].id, container.map[:nine].id)
747
+ container.map[:ten] = ref_obj
748
+ nest_obj = NestedSerializer.new(container)
749
+ obj_serial = [nest_obj, container.map[:one], container.map[:two], container.map[:five], [container.map[:three], container.map[:four], container.map[:six]], ref_obj].serialize(nil, pretty: true)
750
+ obj_new = nil
751
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
752
+ assert_instance_of(::Array, obj_new)
753
+ assert_instance_of(NestedSerializer, obj_new[0])
754
+ container = obj_new[0].nested
755
+ assert_instance_of(Container, container)
756
+ assert_instance_of(Aliasable, container.map[:one])
757
+ assert_instance_of(Aliasable, container.map[:two])
758
+ assert_instance_of(Aliasable, container.map[:three])
759
+ assert_equal(container.map[:one].object_id, container.map[:three].object_id)
760
+ assert_instance_of(Aliasable, container.map[:four])
761
+ assert_equal(container.map[:two].object_id, container.map[:four].object_id)
762
+ assert_instance_of(DerivedAliasable, container.map[:five])
763
+ assert_instance_of(DerivedAliasable, container.map[:six])
764
+ assert_equal(container.map[:five].object_id, container.map[:six].object_id)
765
+
766
+ assert_instance_of(RefUser, container.map[:ten])
767
+ assert_instance_of(FIRM::Serializable::ID, container.map[:ten].ref1)
768
+ assert_instance_of(FIRM::Serializable::ID, container.map[:ten].ref2)
769
+ assert_instance_of(FIRM::Serializable::ID, container.map[:ten].ref3)
770
+ assert_equal(:seven, container.map[:seven].sym)
771
+ assert_equal(container.map[:ten].ref1, container.map[:seven].id)
772
+ assert_equal(:eight, container.map[:eight].sym)
773
+ assert_equal(container.map[:ten].ref2, container.map[:eight].id)
774
+ assert_equal(:nine, container.map[:nine].sym)
775
+ assert_equal(container.map[:ten].ref3, container.map[:nine].id)
776
+
777
+ assert_instance_of(Aliasable, obj_new[1])
778
+ assert_instance_of(Aliasable, obj_new[2])
779
+ assert_instance_of(DerivedAliasable, obj_new[3])
780
+ assert_instance_of(::Array, obj_new[4])
781
+ assert_instance_of(Aliasable, obj_new[4][0])
782
+ assert_instance_of(Aliasable, obj_new[4][1])
783
+ assert_instance_of(DerivedAliasable, obj_new[4][2])
784
+ assert_equal(obj_new[1].object_id, obj_new[4][0].object_id)
785
+ assert_equal(obj_new[2].object_id, obj_new[4][1].object_id)
786
+ assert_equal(obj_new[3].object_id, obj_new[4][2].object_id)
787
+
788
+ assert_equal(container.map[:one].name, obj_new[4][0].name)
789
+ assert_not_equal(container.map[:one].object_id, obj_new[4][0].object_id)
790
+ assert_equal(container.map[:two].name, obj_new[4][1].name)
791
+ assert_not_equal(container.map[:two].object_id, obj_new[4][1].object_id)
792
+ assert_equal(container.map[:five].name, obj_new[4][2].name)
793
+ assert_not_equal(container.map[:five].object_id, obj_new[4][2].object_id)
794
+
795
+ assert_not_equal(container.map[:ten].ref1, obj_new.last.ref1)
796
+ assert_not_equal(container.map[:ten].ref2, obj_new.last.ref2)
797
+ assert_not_equal(container.map[:ten].ref3, obj_new.last.ref3)
798
+ end
799
+
800
+ class CreateFinalizer
801
+
802
+ include FIRM::Serializable
803
+
804
+ property :value
805
+
806
+ def initialize(val = nil)
807
+ @value = val
808
+ create if val
809
+ end
810
+
811
+ # default finalizer
812
+ def create
813
+ @symbol = case @value
814
+ when 1
815
+ :one
816
+ when 2
817
+ :two
818
+ when 3
819
+ :three
820
+ else
821
+ :none
822
+ end
823
+ end
824
+
825
+ attr_reader :value, :symbol
826
+
827
+ def set_value(v)
828
+ @value = v
829
+ end
830
+ private :set_value
831
+
832
+ end
833
+
834
+ class BlockFinalizer
835
+
836
+ include FIRM::Serializable
837
+
838
+ property :value
839
+
840
+ define_deserialize_finalizer do |obj|
841
+ obj.symbol = case obj.value
842
+ when 1
843
+ :one
844
+ when 2
845
+ :two
846
+ when 3
847
+ :three
848
+ else
849
+ :none
850
+ end
851
+ end
852
+
853
+ def initialize(val = 0)
854
+ @value = val
855
+ @symbol = case @value
856
+ when 1
857
+ :one
858
+ when 2
859
+ :two
860
+ when 3
861
+ :three
862
+ else
863
+ :none
864
+ end
865
+ end
866
+
867
+ attr_reader :value
868
+ attr_accessor :symbol
869
+
870
+ def set_value(v)
871
+ @value = v
872
+ end
873
+ private :set_value
874
+ end
875
+
876
+ class MethodFinalizer
877
+
878
+ include FIRM::Serializable
879
+
880
+ property :value
881
+
882
+ define_deserialize_finalizer :finalize_deserialize
883
+
884
+ def initialize(val = 0)
885
+ @value = val
886
+ @symbol = case @value
887
+ when 1
888
+ :one
889
+ when 2
890
+ :two
891
+ when 3
892
+ :three
893
+ else
894
+ :none
895
+ end
896
+ end
897
+
898
+ attr_reader :value, :symbol
899
+
900
+ # default finalizer
901
+ def finalize_deserialize
902
+ @symbol = case @value
903
+ when 1
904
+ :one
905
+ when 2
906
+ :two
907
+ when 3
908
+ :three
909
+ else
910
+ :none
911
+ end
912
+ end
913
+ private :finalize_deserialize
914
+
915
+ def set_value(v)
916
+ @value = v
917
+ end
918
+ private :set_value
919
+
920
+ end
921
+
922
+ def test_deserialize_finalizers
923
+ obj = CreateFinalizer.new(2)
924
+ obj_serial = obj.serialize
925
+ obj_new = nil
926
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
927
+ assert_equal(obj.value, obj_new.value)
928
+ assert_equal(obj.symbol, obj_new.symbol)
929
+
930
+ obj = BlockFinalizer.new(2)
931
+ obj_serial = obj.serialize
932
+ obj_new = nil
933
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
934
+ assert_equal(obj.value, obj_new.value)
935
+ assert_equal(obj.symbol, obj_new.symbol)
936
+
937
+ obj = MethodFinalizer.new(2)
938
+ obj_serial = obj.serialize
939
+ obj_new = nil
940
+ assert_nothing_raised { obj_new = FIRM.deserialize(obj_serial) }
941
+ assert_equal(obj.value, obj_new.value)
942
+ assert_equal(obj.symbol, obj_new.symbol)
943
+ end
944
+
945
+ end