perpetuity 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,147 +0,0 @@
1
- require 'perpetuity/data_injectable'
2
-
3
- module Perpetuity
4
- class Serializer
5
- include DataInjectable
6
-
7
- attr_reader :mapper, :mapper_registry
8
-
9
- def initialize(mapper)
10
- @mapper = mapper
11
- @class = mapper.mapped_class
12
- @mapper_registry = mapper.mapper_registry
13
- end
14
-
15
- def attribute_for object, attribute_name
16
- object.instance_variable_get("@#{attribute_name}")
17
- end
18
-
19
- def serialize object
20
- attrs = mapper.class.attribute_set.map do |attrib|
21
- value = attribute_for object, attrib.name
22
-
23
- serialized_value = if value.is_a? Reference
24
- serialize_reference value
25
- elsif value.is_a? Array
26
- serialize_array(value, attrib.embedded?)
27
- elsif mapper.data_source.can_serialize? value
28
- value
29
- elsif mapper_registry.has_mapper?(value.class)
30
- serialize_with_foreign_mapper(value, attrib.embedded?)
31
- else
32
- Marshal.dump(value)
33
- end
34
-
35
- [attrib.name.to_s, serialized_value]
36
- end
37
-
38
- Hash[attrs]
39
- end
40
-
41
- def unserialize data
42
- if data.is_a? Array
43
- unserialize_object_array data
44
- else
45
- object = unserialize_object(data)
46
- give_id_to object
47
- object
48
- end
49
- end
50
-
51
- def unserialize_object data, klass=@class
52
- if data.is_a? Hash
53
- object = klass.allocate
54
- data.each do |attr, value|
55
- inject_attribute object, attr, unserialize_attribute(value)
56
- end
57
- object
58
- else
59
- unserialize_attribute data
60
- end
61
- end
62
-
63
- def unserialize_object_array objects
64
- objects.map do |data|
65
- object = unserialize_object data
66
- give_id_to object
67
- object
68
- end
69
- end
70
-
71
- def unserialize_attribute data
72
- if data.is_a?(String) && data.start_with?("\u0004") # if it's marshaled
73
- Marshal.load(data)
74
- elsif data.is_a? Array
75
- data.map { |i| unserialize_attribute i }
76
- elsif data.is_a? Hash
77
- metadata = data.delete('__metadata__')
78
- if metadata
79
- klass = metadata['class'].split('::').inject(Kernel) do |scope, const_name|
80
- scope.const_get(const_name)
81
- end
82
- id = metadata['id']
83
-
84
- if id
85
- object = Reference.new(klass, id)
86
- else
87
- object = unserialize_object(data, klass)
88
- end
89
- else
90
- data
91
- end
92
- else
93
- data
94
- end
95
- end
96
-
97
- def serialize_with_foreign_mapper value, embedded = false
98
- if embedded
99
- value_mapper = mapper_registry[value.class]
100
- value_serializer = Serializer.new(value_mapper)
101
- attr = value_serializer.serialize(value)
102
- attr.merge '__metadata__' => { 'class' => value.class }
103
- else
104
- serialize_reference(value)
105
- end
106
- end
107
-
108
- def serialize_array enum, embedded
109
- enum.map do |value|
110
- if value.is_a? Array
111
- serialize_array(value)
112
- elsif mapper.data_source.can_serialize? value
113
- value
114
- elsif mapper_registry.has_mapper?(value.class)
115
- if embedded
116
- {
117
- '__metadata__' => {
118
- 'class' => value.class.to_s
119
- }
120
- }.merge mapper_registry[value.class].serialize(value)
121
- else
122
- serialize_reference value
123
- end
124
- else
125
- Marshal.dump(value)
126
- end
127
- end
128
- end
129
-
130
- def serialize_reference value
131
- if value.is_a? Reference
132
- reference = value
133
- else
134
- unless value.is_a? PersistedObject
135
- mapper_registry[value.class].insert value
136
- end
137
- reference = Reference.new(value.class.to_s, value.id)
138
- end
139
- {
140
- '__metadata__' => {
141
- 'class' => reference.klass.to_s,
142
- 'id' => reference.id
143
- }
144
- }
145
- end
146
- end
147
- end
@@ -1,86 +0,0 @@
1
- require 'perpetuity/serializer'
2
- require 'perpetuity/mapper'
3
- require 'perpetuity/mapper_registry'
4
- require 'support/test_classes/book'
5
- require 'support/test_classes/user'
6
-
7
- module Perpetuity
8
- describe Serializer do
9
- let(:dave) { User.new('Dave') }
10
- let(:andy) { User.new('Andy') }
11
- let(:authors) { [dave, andy] }
12
- let(:book) { Book.new('The Pragmatic Programmer', authors) }
13
- let(:mapper_registry) { MapperRegistry.new }
14
- let!(:book_mapper_class) do
15
- registry = mapper_registry
16
- Class.new(Perpetuity::Mapper) do
17
- map Book, registry
18
- attribute :title
19
- attribute :authors
20
- end
21
- end
22
- let!(:user_mapper_class) do
23
- registry = mapper_registry
24
- Class.new(Perpetuity::Mapper) do
25
- map User, registry
26
- attribute :name
27
- end
28
- end
29
- let(:data_source) { double('Data Source') }
30
- let(:serializer) { Serializer.new(mapper_registry[Book]) }
31
-
32
- before do
33
- dave.extend PersistedObject
34
- andy.extend PersistedObject
35
- user_mapper_class.stub(data_source: data_source)
36
- book_mapper_class.stub(data_source: data_source)
37
- end
38
-
39
- it 'serializes an array of non-embedded attributes as references' do
40
- data_source.should_receive(:can_serialize?).with(book.title).and_return true
41
- data_source.should_receive(:can_serialize?).with(dave).and_return false
42
- data_source.should_receive(:can_serialize?).with(andy).and_return false
43
- serializer.serialize(book).should be == {
44
- 'title' => book.title,
45
- 'authors' => [
46
- {
47
- '__metadata__' => {
48
- 'class' => 'User',
49
- 'id' => dave.id
50
- }
51
- },
52
- {
53
- '__metadata__' => {
54
- 'class' => 'User',
55
- 'id' => andy.id
56
- }
57
- }
58
- ]
59
- }
60
- end
61
-
62
- context 'with objects that have hashes as attributes' do
63
- let(:name_data) { {first_name: 'Jamie', last_name: 'Gaskins'} }
64
- let(:serialized_data) do
65
- {
66
- 'name' => name_data
67
- }
68
- end
69
- let(:user) { User.new(name_data) }
70
- let(:user_mapper) { mapper_registry[User] }
71
- let(:user_serializer) { Serializer.new(user_mapper) }
72
-
73
- before do
74
- data_source.stub(:can_serialize?).with(name_data) { true }
75
- end
76
-
77
- it 'serializes' do
78
- user_serializer.serialize(user).should be == serialized_data
79
- end
80
-
81
- it 'unserializes' do
82
- user_serializer.unserialize(serialized_data).name.should be == user.name
83
- end
84
- end
85
- end
86
- end