perpetuity 0.4.7 → 0.4.8

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.
@@ -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