firm 0.9.1

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,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