trick_serial 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/.rspec +1 -1
- data/Gemfile +4 -16
- data/Rakefile +17 -36
- data/lib/trick_serial.rb +2 -0
- data/lib/trick_serial/serializer.rb +30 -11
- data/lib/trick_serial/serializer/cgi_session.rb +1 -1
- data/lib/trick_serial/serializer/simple.rb +50 -60
- data/lib/trick_serial/version.rb +3 -0
- data/spec/spec_helper.rb +2 -18
- data/spec/trick_serial/cgi_session_spec.rb +2 -2
- data/spec/trick_serial/serializer_simple_spec.rb +63 -5
- data/spec/trick_serial/serializer_spec.rb +117 -1
- data/trick_serial.gemspec +36 -0
- metadata +67 -152
data/.gitignore
ADDED
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color
|
1
|
+
-f d --color
|
data/Gemfile
CHANGED
@@ -1,17 +1,5 @@
|
|
1
|
-
source
|
2
|
-
|
3
|
-
#
|
4
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in trick_serial.gemspec
|
4
|
+
gemspec
|
5
5
|
|
6
|
-
# Add dependencies to develop your gem here.
|
7
|
-
# Include everything needed to run rake, tests, features, etc.
|
8
|
-
group :development do
|
9
|
-
gem "rspec", "~> 2.3.0"
|
10
|
-
gem "yard", "~> 0.6.0"
|
11
|
-
gem "bundler", "~> 1.1.0"
|
12
|
-
gem "jeweler", "~> 1.8.0"
|
13
|
-
gem "rcov", ">= 0"
|
14
|
-
gem 'ruby-debug', ">= 0"
|
15
|
-
gem 'rails', "~> 1.2.6"
|
16
|
-
gem 'memcache-client', ">= 1.7.0"
|
17
|
-
end
|
data/Rakefile
CHANGED
@@ -1,43 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require 'bundler'
|
3
|
-
begin
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'rake'
|
11
|
-
|
12
|
-
require 'jeweler'
|
13
|
-
Jeweler::Tasks.new do |gem|
|
14
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
-
gem.name = "trick_serial"
|
16
|
-
gem.homepage = "http://github.com/kstephens/trick_serial"
|
17
|
-
gem.license = "MIT"
|
18
|
-
gem.summary = %Q{A Serialization Framework.}
|
19
|
-
gem.description = %Q{Trick Serializers using Proxies.}
|
20
|
-
gem.email = "ks.github@kurtstephens.com"
|
21
|
-
gem.authors = ["Kurt Stephens"]
|
22
|
-
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
-
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
-
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
-
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
-
end
|
27
|
-
Jeweler::RubygemsDotOrgTasks.new
|
1
|
+
require "bundler/gem_tasks"
|
28
2
|
|
29
|
-
|
3
|
+
gem 'rspec'
|
30
4
|
require 'rspec/core/rake_task'
|
31
|
-
|
32
|
-
|
5
|
+
|
6
|
+
desc "Run specs"
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
9
|
+
# Put spec opts in a file named .rspec in root
|
33
10
|
end
|
34
11
|
|
35
|
-
|
36
|
-
|
37
|
-
|
12
|
+
desc "Generate code coverage"
|
13
|
+
RSpec::Core::RakeTask.new(:coverage) do |t|
|
14
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
15
|
+
t.rcov = true
|
16
|
+
t.rcov_opts = ['--exclude', 'spec']
|
38
17
|
end
|
39
18
|
|
40
|
-
|
19
|
+
desc "default => test"
|
20
|
+
task :default => :test
|
21
|
+
|
22
|
+
desc "test => spec"
|
23
|
+
task :test => :spec
|
41
24
|
|
42
|
-
require 'yard'
|
43
|
-
YARD::Rake::YardocTask.new
|
data/lib/trick_serial.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'trick_serial'
|
2
2
|
|
3
|
+
require 'ostruct' # OpenStruct
|
4
|
+
|
3
5
|
module TrickSerial
|
4
6
|
# Serializes objects using proxies for classes defined in #proxy_class_map.
|
5
7
|
# Instances of the keys in #proxy_class_map are replaced by proxies if
|
@@ -110,7 +112,7 @@ module TrickSerial
|
|
110
112
|
def proxyable
|
111
113
|
unless @proxyable
|
112
114
|
@proxyable = @class_option_map.keys.select{|cls| ! @class_option_map[cls][:do_not_traverse]}
|
113
|
-
@do_not_traverse ||= @class_option_map.keys.select{|cls| @class_option_map[cls][:do_not_traverse]}
|
115
|
+
@do_not_traverse ||= @class_option_map.keys.select{|cls| @class_option_map[cls][:do_not_traverse]}
|
114
116
|
@class_option_cache ||= { }
|
115
117
|
@proxyable.freeze
|
116
118
|
end
|
@@ -138,7 +140,6 @@ module TrickSerial
|
|
138
140
|
o = x
|
139
141
|
x = _copy_with_extensions(x)
|
140
142
|
@visited[o.object_id] = [ x, o ]
|
141
|
-
x = o
|
142
143
|
x.class.members.each do | m |
|
143
144
|
v = x.send(m)
|
144
145
|
v = _encode! v
|
@@ -152,10 +153,16 @@ module TrickSerial
|
|
152
153
|
o = x
|
153
154
|
x = _copy_with_extensions(x)
|
154
155
|
@visited[o.object_id] = [ x, o ]
|
155
|
-
|
156
|
+
extended = false
|
156
157
|
t = x.instance_variable_get("@table")
|
157
|
-
t.each do | k
|
158
|
-
|
158
|
+
t.keys.to_a.each do | k |
|
159
|
+
v = t._get_without_trick_serial(k)
|
160
|
+
v = _encode! v
|
161
|
+
if ! extended && ObjectProxy === v
|
162
|
+
t.extend ProxySwizzlingHash
|
163
|
+
extended = true
|
164
|
+
end
|
165
|
+
x.send(:"#{k}=", v)
|
159
166
|
end
|
160
167
|
|
161
168
|
when Array
|
@@ -166,13 +173,14 @@ module TrickSerial
|
|
166
173
|
x = _copy_with_extensions(x)
|
167
174
|
@visited[o.object_id] = [ x, o ]
|
168
175
|
extended = false
|
169
|
-
x.
|
176
|
+
x.size.times do | i |
|
177
|
+
v = x._get_without_trick_serial(i)
|
170
178
|
v = _encode! v
|
171
179
|
if ! extended && ObjectProxy === v
|
172
180
|
x.extend ProxySwizzlingArray
|
173
181
|
extended = true
|
174
182
|
end
|
175
|
-
v
|
183
|
+
x[i] = v
|
176
184
|
end
|
177
185
|
|
178
186
|
when Hash
|
@@ -185,7 +193,7 @@ module TrickSerial
|
|
185
193
|
extended = false
|
186
194
|
x.keys.to_a.each do | k |
|
187
195
|
# pp [ :Hash_key, k ] if @debug >= 1
|
188
|
-
v = x[k] = _encode!(x
|
196
|
+
v = x[k] = _encode!(x._get_without_trick_serial(k))
|
189
197
|
if ! extended && ObjectProxy === v
|
190
198
|
x.extend ProxySwizzlingHash
|
191
199
|
extended = true
|
@@ -297,7 +305,7 @@ module TrickSerial
|
|
297
305
|
|
298
306
|
def resolve_class
|
299
307
|
@resolve_class ||=
|
300
|
-
|
308
|
+
@cls.to_s.split('::').inject(Object){|m, n| m.const_get(n)}
|
301
309
|
end
|
302
310
|
|
303
311
|
def object= x
|
@@ -335,13 +343,15 @@ module TrickSerial
|
|
335
343
|
def class
|
336
344
|
method_missing :class
|
337
345
|
end
|
338
|
-
|
346
|
+
|
339
347
|
alias :_proxy_object_id :object_id
|
340
348
|
def object_id
|
341
349
|
method_missing :object_id
|
342
350
|
end
|
343
351
|
|
344
|
-
|
352
|
+
if respond_to?(:id)
|
353
|
+
alias :_proxy_id :id
|
354
|
+
end
|
345
355
|
def id
|
346
356
|
method_missing :id
|
347
357
|
end
|
@@ -424,4 +434,13 @@ module TrickSerial
|
|
424
434
|
end # class
|
425
435
|
end # module
|
426
436
|
|
437
|
+
class Array
|
438
|
+
alias :_get_without_trick_serial :[]
|
439
|
+
end
|
440
|
+
|
441
|
+
# Get values without triggering ProxySwizzling.
|
442
|
+
class Hash
|
443
|
+
alias :_get_without_trick_serial :[]
|
444
|
+
end
|
445
|
+
|
427
446
|
|
@@ -9,119 +9,109 @@ class Serializer
|
|
9
9
|
# Ivar swizzling is not used.
|
10
10
|
class Simple < self
|
11
11
|
def _encode! x
|
12
|
-
|
12
|
+
@traverse_mode = :_encode!
|
13
|
+
_traverse! x
|
14
|
+
end
|
15
|
+
|
16
|
+
def _decode! x
|
17
|
+
@traverse_mode = :_decode!
|
18
|
+
_traverse! x
|
19
|
+
end
|
20
|
+
|
21
|
+
def _traverse! x
|
22
|
+
# pp [ :_traverse!, @traverse_mode, x.class, x ] if @debug >= 1
|
13
23
|
|
14
24
|
case x
|
25
|
+
when *@do_not_traverse
|
26
|
+
# NOTHING
|
27
|
+
|
15
28
|
when ObjectProxy
|
16
|
-
|
29
|
+
if @traverse_mode == :_decode!
|
30
|
+
x = x.object
|
31
|
+
end
|
17
32
|
|
18
|
-
when
|
33
|
+
when Struct
|
19
34
|
if o = @visited[x.object_id]
|
20
35
|
return o.first
|
21
36
|
end
|
22
|
-
extended = false
|
23
37
|
o = x
|
24
|
-
x = x
|
38
|
+
x = _copy_with_extensions(x)
|
25
39
|
@visited[o.object_id] = [ x, o ]
|
26
|
-
x.
|
27
|
-
|
40
|
+
x.class.members.each do | m |
|
41
|
+
v = x.send(m)
|
42
|
+
v = _traverse! v
|
43
|
+
x.send(:"#{m}=", v)
|
28
44
|
end
|
29
45
|
|
30
|
-
when
|
46
|
+
when OpenStruct
|
31
47
|
if o = @visited[x.object_id]
|
32
48
|
return o.first
|
33
49
|
end
|
34
|
-
extended = false
|
35
50
|
o = x
|
36
|
-
x = x
|
51
|
+
x = _copy_with_extensions(x)
|
37
52
|
@visited[o.object_id] = [ x, o ]
|
38
|
-
x.
|
39
|
-
|
53
|
+
t = x.instance_variable_get("@table")
|
54
|
+
t.keys.to_a.each do | k |
|
55
|
+
v = t._get_without_trick_serial(k)
|
56
|
+
v = _traverse! v
|
57
|
+
x.send(:"#{k}=", v)
|
40
58
|
end
|
41
59
|
|
42
|
-
when *@proxyable
|
43
|
-
if proxy = @object_to_proxy_map[x.object_id]
|
44
|
-
return proxy.first
|
45
|
-
end
|
46
|
-
# debugger
|
47
|
-
o = x
|
48
|
-
proxy_cls = nil
|
49
|
-
if class_option = self._class_option(x)
|
50
|
-
proxy_cls = class_option[:proxy_class]
|
51
|
-
# Deeply encode instance vars?
|
52
|
-
if ivs = class_option[:instance_vars]
|
53
|
-
ivs = x.instance_variables if ivs == true
|
54
|
-
x = x.dup if @copy
|
55
|
-
@object_to_proxy_map[o.object_id] = [ x, o ]
|
56
|
-
ivs.each do | ivar |
|
57
|
-
v = x.instance_variable_get(ivar)
|
58
|
-
v = _encode!(v)
|
59
|
-
x.instance_variable_set(ivar, v)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
x = _make_proxy o, x, proxy_cls
|
65
|
-
end
|
66
|
-
|
67
|
-
x
|
68
|
-
end # def
|
69
|
-
|
70
|
-
def _decode! x
|
71
|
-
case x
|
72
|
-
when ObjectProxy
|
73
|
-
x = x.object
|
74
|
-
|
75
60
|
when Array
|
76
61
|
if o = @visited[x.object_id]
|
77
62
|
return o.first
|
78
63
|
end
|
79
|
-
extended = false
|
80
64
|
o = x
|
81
|
-
x = x
|
65
|
+
x = _copy_with_extensions(x)
|
82
66
|
@visited[o.object_id] = [ x, o ]
|
83
67
|
x.map! do | v |
|
84
|
-
|
68
|
+
_traverse! v
|
85
69
|
end
|
86
|
-
|
70
|
+
|
87
71
|
when Hash
|
88
72
|
if o = @visited[x.object_id]
|
89
73
|
return o.first
|
90
74
|
end
|
91
|
-
extended = false
|
92
75
|
o = x
|
93
|
-
x = x
|
76
|
+
x = _copy_with_extensions(x)
|
94
77
|
@visited[o.object_id] = [ x, o ]
|
95
78
|
x.keys.to_a.each do | k |
|
96
|
-
x[k] =
|
79
|
+
x[k] = _traverse!(x[k])
|
97
80
|
end
|
98
|
-
|
81
|
+
|
99
82
|
when *@proxyable
|
100
83
|
if proxy = @object_to_proxy_map[x.object_id]
|
101
84
|
return proxy.first
|
102
85
|
end
|
103
86
|
# debugger
|
104
87
|
o = x
|
105
|
-
|
88
|
+
proxy_cls = nil
|
89
|
+
if class_option = self._class_option(x)
|
90
|
+
proxy_cls = class_option[:proxy_class]
|
106
91
|
# Deeply encode instance vars?
|
107
92
|
if ivs = class_option[:instance_vars]
|
108
93
|
ivs = x.instance_variables if ivs == true
|
109
|
-
x = x
|
94
|
+
x = _copy_with_extensions(x)
|
110
95
|
@object_to_proxy_map[o.object_id] = [ x, o ]
|
111
96
|
ivs.each do | ivar |
|
112
97
|
v = x.instance_variable_get(ivar)
|
113
|
-
|
114
|
-
v = _decode!(v)
|
98
|
+
v = _traverse!(v)
|
115
99
|
x.instance_variable_set(ivar, v)
|
116
100
|
end
|
117
101
|
end
|
118
102
|
end
|
119
|
-
@
|
103
|
+
if @traverse_mode == :_decode!
|
104
|
+
@object_to_proxy_map[o.object_id] ||= [ x, o ]
|
105
|
+
else
|
106
|
+
x = _make_proxy o, x, proxy_cls
|
107
|
+
end
|
120
108
|
end # case
|
121
|
-
|
109
|
+
|
110
|
+
# pp [ :_traverse!, @traverse_mode, :RESULT, x.class, x ] if @debug >= 2
|
111
|
+
|
122
112
|
x
|
123
113
|
end # def
|
124
|
-
|
114
|
+
|
125
115
|
end # class
|
126
116
|
end # class
|
127
117
|
end # module
|
data/spec/spec_helper.rb
CHANGED
@@ -1,24 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
2
|
+
$:.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rspec'
|
4
4
|
require 'trick_serial'
|
5
5
|
|
6
|
-
# Requires supporting files with custom matchers and macros, etc,
|
7
|
-
# in ./support/ and its subdirectories.
|
8
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
-
|
10
|
-
=begin
|
11
|
-
if $DEBUG || ENV['DEBUG']
|
12
|
-
require 'rubygems'
|
13
|
-
gem 'ruby-debug'
|
14
|
-
require 'ruby-debug'
|
15
|
-
end
|
16
|
-
=end
|
17
|
-
|
18
|
-
RSpec.configure do |config|
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
6
|
######################################################################
|
23
7
|
# Common test helpers
|
24
8
|
#
|
@@ -15,8 +15,8 @@ begin
|
|
15
15
|
require 'action_controller/session/mem_cache_store'
|
16
16
|
require 'trick_serial/serializer/cgi_session'
|
17
17
|
$have_mem_cache_store = true
|
18
|
-
rescue
|
19
|
-
|
18
|
+
rescue LoadError => err
|
19
|
+
# NOTHING
|
20
20
|
end
|
21
21
|
|
22
22
|
|
@@ -16,11 +16,13 @@ describe "TrickSerial::Serializer::Simple" do
|
|
16
16
|
t::B => { :instance_vars => [ "@x" ] },
|
17
17
|
}
|
18
18
|
TrickSerial::Serializer::Test::PhonyActiveRecord.find_map.clear
|
19
|
-
|
19
|
+
# Note: Structs are anonymous Classes and cannot be Marshal'ed.
|
20
|
+
@struct = Struct.new :sm, :sa, :sb
|
20
21
|
@m = TrickSerial::Serializer::Test::Model.new(123)
|
21
22
|
@m2 = TrickSerial::Serializer::Test::Model.new(456)
|
22
23
|
@m_unsaved = TrickSerial::Serializer::Test::Model.new(:unsaved)
|
23
24
|
@m_unsaved.id = nil
|
25
|
+
@os = OpenStruct.new
|
24
26
|
@h = {
|
25
27
|
:a => 1,
|
26
28
|
'b' => 2,
|
@@ -28,7 +30,11 @@ describe "TrickSerial::Serializer::Simple" do
|
|
28
30
|
:m => @m,
|
29
31
|
:a => [ 0, 1, @m, 3, 4, @m ],
|
30
32
|
:m_unsaved => @m_unsaved,
|
33
|
+
:os => @os,
|
31
34
|
}
|
35
|
+
@os.osm = @m
|
36
|
+
@os.osa = @h
|
37
|
+
@os.osb = 'b'
|
32
38
|
@h[:a2] = @h[:a]
|
33
39
|
@h[:h2] = @h
|
34
40
|
end
|
@@ -62,7 +68,38 @@ describe "TrickSerial::Serializer::Simple" do
|
|
62
68
|
result.object_id.should == @h.object_id
|
63
69
|
end
|
64
70
|
|
65
|
-
it "should proxy
|
71
|
+
it "should proxy saved models directly" do
|
72
|
+
@s.debug = 0
|
73
|
+
|
74
|
+
@o = @s.encode!(@m)
|
75
|
+
@o.object_id.should_not == @m.object_id
|
76
|
+
@o.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
77
|
+
@o.cls.should == @m.class.name.to_sym
|
78
|
+
@o.id.should == @m.id
|
79
|
+
|
80
|
+
@o = @s.decode!(@o)
|
81
|
+
|
82
|
+
@o.object_id.should_not == @m.object_id
|
83
|
+
@o.class.should == @m.class
|
84
|
+
@o.id.should == @m.id
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not proxy saved models twice" do
|
88
|
+
@s.debug = 0
|
89
|
+
|
90
|
+
@o = @s.encode!(@m)
|
91
|
+
@o.object_id.should_not == @m.object_id
|
92
|
+
@o.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
93
|
+
@o.cls.should == @m.class.name.to_sym
|
94
|
+
@o.id.should == @m.id
|
95
|
+
|
96
|
+
@o1 = @o
|
97
|
+
@o = @s.encode!(@o)
|
98
|
+
@o.object_id.should == @o1.object_id
|
99
|
+
@o.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should proxy saved models" do
|
66
103
|
@o = @s.encode!(@h)
|
67
104
|
@o = @s.decode!(@o)
|
68
105
|
@o[:m].object_id.should_not == @m.object_id
|
@@ -154,6 +191,27 @@ describe "TrickSerial::Serializer::Simple" do
|
|
154
191
|
a.should == p
|
155
192
|
end
|
156
193
|
|
194
|
+
it "should handle encode/decode through OpenStruct" do
|
195
|
+
@o = @s.encode!(@os)
|
196
|
+
@o.osm.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
197
|
+
@o = @s.decode!(@o)
|
198
|
+
@o.object_id.should == @os.object_id
|
199
|
+
@o.osm.class.should == TrickSerial::Serializer::Test::Model
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should handle encode/decode through OpenStruct" do
|
203
|
+
s = @struct.new
|
204
|
+
s.sm = @m
|
205
|
+
s.sa = 'a'
|
206
|
+
s.sb = :b
|
207
|
+
|
208
|
+
@o = @s.encode!(s)
|
209
|
+
@o.sm.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
210
|
+
@o = @s.decode!(@o)
|
211
|
+
@o.object_id.should == s.object_id
|
212
|
+
@o.sm.class.should == TrickSerial::Serializer::Test::Model
|
213
|
+
end
|
214
|
+
|
157
215
|
it "should lazily traverse proxies" do
|
158
216
|
fm = TrickSerial::Serializer::Test::PhonyActiveRecord.find_map
|
159
217
|
|
@@ -229,7 +287,7 @@ describe "TrickSerial::Serializer::Simple" do
|
|
229
287
|
e.instance_variable_get("@x").class.should == TrickSerial::Serializer::ActiveRecordProxy
|
230
288
|
e.instance_variable_get("@y").class.should == TrickSerial::Serializer::ActiveRecordProxy
|
231
289
|
|
232
|
-
@s.verbose = @s.debug =
|
290
|
+
@s.verbose = true; @s.debug = 0
|
233
291
|
obj = @s.decode!(e)
|
234
292
|
# $stderr.puts "marshal = #{str.inspect}"
|
235
293
|
|
@@ -241,7 +299,7 @@ describe "TrickSerial::Serializer::Simple" do
|
|
241
299
|
obj = t::B.new
|
242
300
|
obj.x = @m # should be encoded
|
243
301
|
obj.y = @m # should not be encoded
|
244
|
-
@s.verbose = @s.debug =
|
302
|
+
@s.verbose = false; @s.debug = 0
|
245
303
|
obj = @s.encode!(obj)
|
246
304
|
e = Marshal.load(str = Marshal.dump(obj))
|
247
305
|
|
@@ -249,7 +307,7 @@ describe "TrickSerial::Serializer::Simple" do
|
|
249
307
|
e.instance_variable_get("@x").class.should == TrickSerial::Serializer::ActiveRecordProxy
|
250
308
|
e.instance_variable_get("@y").class.should == TrickSerial::Serializer::Test::Model
|
251
309
|
|
252
|
-
@s.verbose = @s.debug =
|
310
|
+
@s.verbose = true; @s.debug = 0
|
253
311
|
obj = @s.decode!(e)
|
254
312
|
# $stderr.puts "marshal = #{str.inspect}"
|
255
313
|
|
@@ -62,6 +62,7 @@ describe "TrickSerial::Serializer" do
|
|
62
62
|
|
63
63
|
result.object_id.should == @h.object_id
|
64
64
|
result[:s].class.should == @struct
|
65
|
+
result[:s].sm.object_id.should_not == @m2.object_id
|
65
66
|
result[:s].sm.id.should == @m2.id
|
66
67
|
result[:s].sm.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
67
68
|
result[:s].sa.object_id.should == @h.object_id
|
@@ -69,20 +70,82 @@ describe "TrickSerial::Serializer" do
|
|
69
70
|
result[:s].sb.object_id.should == result[:s].object_id
|
70
71
|
end
|
71
72
|
|
73
|
+
it "should handle #encode of Struct" do
|
74
|
+
@h[:s].sm.should == @m2
|
75
|
+
@h[:s].sa.should == @h
|
76
|
+
@h[:s].sb = @h[:s] # self-reference
|
77
|
+
|
78
|
+
result = @s.encode(@h)
|
79
|
+
|
80
|
+
result.object_id.should_not == @h.object_id
|
81
|
+
result[:s].class.should == @struct
|
82
|
+
result[:s].sm.object_id.should_not == @m2.object_id
|
83
|
+
result[:s].sm.id.should == @m2.id
|
84
|
+
result[:s].sm.class.should == TrickSerial::Serializer::ActiveRecordProxy
|
85
|
+
result[:s].sa.object_id.should_not == @h.object_id
|
86
|
+
result[:s].sb.object_id.should_not == @h[:s].sb.object_id
|
87
|
+
result[:s].sb.object_id.should == result[:s].object_id
|
88
|
+
end
|
89
|
+
|
72
90
|
it "should handle #encode! of OpenStruct" do
|
73
91
|
@h[:os].osm.should == @m
|
74
92
|
@h[:os].osa.should == @h
|
75
93
|
@h[:os].osos = @h[:os] # self-reference
|
94
|
+
os = @h[:os]
|
95
|
+
|
96
|
+
os.respond_to?(:osm).should == true
|
97
|
+
os.respond_to?(:osa).should == true
|
98
|
+
os.respond_to?(:osos).should == true
|
76
99
|
|
77
100
|
result = @s.encode!(@h)
|
78
101
|
|
79
102
|
result.object_id.should == @h.object_id
|
80
103
|
result[:os].class.should == @h[:os].class
|
104
|
+
|
105
|
+
# Validate OpenStruct @table encoding.
|
106
|
+
osh = result[:os].instance_variable_get("@table")
|
107
|
+
osh._get_without_trick_serial(:osm).class.should == TrickSerial::Serializer::ActiveRecordProxy
|
108
|
+
# Force OpenStruct @table Hash Swizzling.
|
81
109
|
result[:os].osm.id.should == @m.id
|
82
|
-
result[:os].osm.class.should == TrickSerial::Serializer::
|
110
|
+
result[:os].osm.class.should == TrickSerial::Serializer::Test::Model
|
111
|
+
# Validate OpenStruct @table HashHash Swizzling.
|
112
|
+
osh._get_without_trick_serial(:osm).class.should == TrickSerial::Serializer::Test::Model
|
113
|
+
|
83
114
|
result[:os].osa.object_id.should == @h.object_id
|
84
115
|
result[:os].osb.object_id.should == @h[:os].osb.object_id
|
85
116
|
result[:os].osos.object_id.should == result[:os].object_id
|
117
|
+
|
118
|
+
os = result[:os]
|
119
|
+
os.respond_to?(:osm).should == true
|
120
|
+
os.respond_to?(:osa).should == true
|
121
|
+
os.respond_to?(:osos).should == true
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should handle #encode of OpenStruct" do
|
125
|
+
@h[:os].osm.should == @m
|
126
|
+
@h[:os].osa.should == @h
|
127
|
+
@h[:os].osos = @h[:os] # self-reference
|
128
|
+
os = @h[:os]
|
129
|
+
|
130
|
+
os.respond_to?(:osm).should == true
|
131
|
+
os.respond_to?(:osa).should == true
|
132
|
+
os.respond_to?(:osos).should == true
|
133
|
+
|
134
|
+
result = @s.encode(@h)
|
135
|
+
|
136
|
+
result.object_id.should_not == @h.object_id
|
137
|
+
result[:os].class.should == @h[:os].class
|
138
|
+
result[:os].object_id.should_not == @h[:os].object_id
|
139
|
+
result[:os].osm.id.should == @m.id
|
140
|
+
result[:os].osm.class.should == TrickSerial::Serializer::Test::Model
|
141
|
+
result[:os].osa.object_id.should_not == @h.object_id
|
142
|
+
result[:os].osb.object_id.should == @h[:os].osb.object_id
|
143
|
+
# result[:os].osos.object_id.should == result[:os].object_id
|
144
|
+
|
145
|
+
os = result[:os]
|
146
|
+
os.respond_to?(:osm).should == true
|
147
|
+
os.respond_to?(:osa).should == true
|
148
|
+
os.respond_to?(:osos).should == true
|
86
149
|
end
|
87
150
|
|
88
151
|
it "should honor #enabled?" do
|
@@ -167,6 +230,26 @@ describe "TrickSerial::Serializer" do
|
|
167
230
|
a.should == p
|
168
231
|
end
|
169
232
|
|
233
|
+
it "should handle proxy swizzling through OpenStruct" do
|
234
|
+
m = @h[:m]
|
235
|
+
os = OpenStruct.new
|
236
|
+
os.m = m
|
237
|
+
# pp os
|
238
|
+
|
239
|
+
@s.encode!(os)
|
240
|
+
osd = Marshal.dump(os) # save state
|
241
|
+
|
242
|
+
os.m.class.should == m.class
|
243
|
+
os.m.object_id.should_not == m.object_id
|
244
|
+
|
245
|
+
os = Marshal.load(osd)
|
246
|
+
# pp os
|
247
|
+
|
248
|
+
osh = os.instance_variable_get('@table')
|
249
|
+
os.m.class.should == m.class
|
250
|
+
os.m.object_id.should_not == m.object_id
|
251
|
+
end
|
252
|
+
|
170
253
|
it "should lazily traverse proxies" do
|
171
254
|
fm = TrickSerial::Serializer::Test::PhonyActiveRecord.find_map
|
172
255
|
|
@@ -192,6 +275,39 @@ describe "TrickSerial::Serializer" do
|
|
192
275
|
fm.keys.size.should == 1
|
193
276
|
end
|
194
277
|
|
278
|
+
it "should encode/decode proxies only once" do
|
279
|
+
fm = TrickSerial::Serializer::Test::PhonyActiveRecord.find_map
|
280
|
+
|
281
|
+
fm[@m.id].should == nil
|
282
|
+
|
283
|
+
# Encode once.
|
284
|
+
@s.encode!(@h)
|
285
|
+
|
286
|
+
# Note: Structs are anonymous Classes and cannot be Marshal'ed.
|
287
|
+
@h[:s] = nil
|
288
|
+
@h = Marshal.load(Marshal.dump(@h))
|
289
|
+
|
290
|
+
fm[@m.id].should == nil
|
291
|
+
|
292
|
+
# Encode again.
|
293
|
+
@s.encode!(@h)
|
294
|
+
@h = Marshal.load(Marshal.dump(@h))
|
295
|
+
|
296
|
+
fm[@m.id].should == nil
|
297
|
+
|
298
|
+
# ProxySwizzling occurs only once.
|
299
|
+
p = @h[:m]
|
300
|
+
|
301
|
+
fm[@m.id].should == 1
|
302
|
+
|
303
|
+
@h[:m].object_id.should == p.object_id
|
304
|
+
@h[:a][2].object_id.should == p.object_id
|
305
|
+
@h[:a][5].object_id.should == p.object_id
|
306
|
+
|
307
|
+
fm[@m.id].should == 1
|
308
|
+
fm.keys.size.should == 1
|
309
|
+
end
|
310
|
+
|
195
311
|
it "should preserve object identity" do
|
196
312
|
@s.encode!(@h)
|
197
313
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
lib = File.expand_path('../lib', __FILE__)
|
7
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
8
|
+
require 'trick_serial/version'
|
9
|
+
|
10
|
+
Gem::Specification.new do |s|
|
11
|
+
gem = s
|
12
|
+
s.name = %q{trick_serial}
|
13
|
+
s.version = TrickSerial::VERSION
|
14
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
15
|
+
s.authors = ["Kurt Stephens"]
|
16
|
+
s.description = %q{Trick Serializers using Proxies.}
|
17
|
+
s.summary = %q{Trick Serializers using Proxies.}
|
18
|
+
s.homepage = %q{http://github.com/kstephens/trick_serial}
|
19
|
+
s.email = %q{ks.github@kurtstephens.com}
|
20
|
+
|
21
|
+
gem.files = `git ls-files`.split($/)
|
22
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
23
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
24
|
+
gem.require_paths = ["lib"]
|
25
|
+
|
26
|
+
s.extra_rdoc_files = [
|
27
|
+
"LICENSE.txt",
|
28
|
+
"README.rdoc"
|
29
|
+
]
|
30
|
+
s.licenses = ["MIT"]
|
31
|
+
|
32
|
+
gem.add_development_dependency 'rake', '>= 0.9.0'
|
33
|
+
gem.add_development_dependency 'rspec', '~> 2.12.0'
|
34
|
+
gem.add_development_dependency 'simplecov', '>= 0.1'
|
35
|
+
end
|
36
|
+
|
metadata
CHANGED
@@ -1,158 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: trick_serial
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 0
|
10
|
-
version: 0.2.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Kurt Stephens
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
12
|
+
date: 2012-12-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 3
|
32
|
-
- 0
|
33
|
-
version: 2.3.0
|
34
|
-
name: rspec
|
35
|
-
requirement: *id001
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.0
|
36
22
|
type: :development
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
23
|
prerelease: false
|
39
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
25
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
- 0
|
49
|
-
version: 0.6.0
|
50
|
-
name: yard
|
51
|
-
requirement: *id002
|
52
|
-
type: :development
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
prerelease: false
|
55
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
56
33
|
none: false
|
57
|
-
requirements:
|
34
|
+
requirements:
|
58
35
|
- - ~>
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
segments:
|
62
|
-
- 1
|
63
|
-
- 1
|
64
|
-
- 0
|
65
|
-
version: 1.1.0
|
66
|
-
name: bundler
|
67
|
-
requirement: *id003
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.12.0
|
68
38
|
type: :development
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
39
|
prerelease: false
|
71
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
41
|
none: false
|
73
|
-
requirements:
|
42
|
+
requirements:
|
74
43
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
- 0
|
81
|
-
version: 1.8.0
|
82
|
-
name: jeweler
|
83
|
-
requirement: *id004
|
84
|
-
type: :development
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
prerelease: false
|
87
|
-
version_requirements: &id005 !ruby/object:Gem::Requirement
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.12.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: simplecov
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
88
49
|
none: false
|
89
|
-
requirements:
|
90
|
-
- -
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
version: "0"
|
96
|
-
name: rcov
|
97
|
-
requirement: *id005
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.1'
|
98
54
|
type: :development
|
99
|
-
- !ruby/object:Gem::Dependency
|
100
55
|
prerelease: false
|
101
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
57
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
segments:
|
108
|
-
- 0
|
109
|
-
version: "0"
|
110
|
-
name: ruby-debug
|
111
|
-
requirement: *id006
|
112
|
-
type: :development
|
113
|
-
- !ruby/object:Gem::Dependency
|
114
|
-
prerelease: false
|
115
|
-
version_requirements: &id007 !ruby/object:Gem::Requirement
|
116
|
-
none: false
|
117
|
-
requirements:
|
118
|
-
- - ~>
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
hash: 19
|
121
|
-
segments:
|
122
|
-
- 1
|
123
|
-
- 2
|
124
|
-
- 6
|
125
|
-
version: 1.2.6
|
126
|
-
name: rails
|
127
|
-
requirement: *id007
|
128
|
-
type: :development
|
129
|
-
- !ruby/object:Gem::Dependency
|
130
|
-
prerelease: false
|
131
|
-
version_requirements: &id008 !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
|
-
requirements:
|
134
|
-
- - ">="
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
hash: 11
|
137
|
-
segments:
|
138
|
-
- 1
|
139
|
-
- 7
|
140
|
-
- 0
|
141
|
-
version: 1.7.0
|
142
|
-
name: memcache-client
|
143
|
-
requirement: *id008
|
144
|
-
type: :development
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
145
62
|
description: Trick Serializers using Proxies.
|
146
63
|
email: ks.github@kurtstephens.com
|
147
64
|
executables: []
|
148
|
-
|
149
65
|
extensions: []
|
150
|
-
|
151
|
-
extra_rdoc_files:
|
66
|
+
extra_rdoc_files:
|
152
67
|
- LICENSE.txt
|
153
68
|
- README.rdoc
|
154
|
-
files:
|
69
|
+
files:
|
155
70
|
- .document
|
71
|
+
- .gitignore
|
156
72
|
- .rspec
|
157
73
|
- Gemfile
|
158
74
|
- LICENSE.txt
|
@@ -165,43 +81,42 @@ files:
|
|
165
81
|
- lib/trick_serial/serializer/cgi_session.rb
|
166
82
|
- lib/trick_serial/serializer/rails.rb
|
167
83
|
- lib/trick_serial/serializer/simple.rb
|
84
|
+
- lib/trick_serial/version.rb
|
168
85
|
- spec/spec_helper.rb
|
169
86
|
- spec/trick_serial/cgi_session_spec.rb
|
170
87
|
- spec/trick_serial/serializer_simple_spec.rb
|
171
88
|
- spec/trick_serial/serializer_spec.rb
|
172
|
-
|
89
|
+
- trick_serial.gemspec
|
173
90
|
homepage: http://github.com/kstephens/trick_serial
|
174
|
-
licenses:
|
91
|
+
licenses:
|
175
92
|
- MIT
|
176
93
|
post_install_message:
|
177
94
|
rdoc_options: []
|
178
|
-
|
179
|
-
require_paths:
|
95
|
+
require_paths:
|
180
96
|
- lib
|
181
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
182
98
|
none: false
|
183
|
-
requirements:
|
184
|
-
- -
|
185
|
-
- !ruby/object:Gem::Version
|
186
|
-
|
187
|
-
segments:
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
segments:
|
188
104
|
- 0
|
189
|
-
|
190
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
hash: -1879002801800302150
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
107
|
none: false
|
192
|
-
requirements:
|
193
|
-
- -
|
194
|
-
- !ruby/object:Gem::Version
|
195
|
-
|
196
|
-
segments:
|
197
|
-
- 0
|
198
|
-
version: "0"
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
199
112
|
requirements: []
|
200
|
-
|
201
113
|
rubyforge_project:
|
202
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.8.24
|
203
115
|
signing_key:
|
204
116
|
specification_version: 3
|
205
|
-
summary:
|
206
|
-
test_files:
|
207
|
-
|
117
|
+
summary: Trick Serializers using Proxies.
|
118
|
+
test_files:
|
119
|
+
- spec/spec_helper.rb
|
120
|
+
- spec/trick_serial/cgi_session_spec.rb
|
121
|
+
- spec/trick_serial/serializer_simple_spec.rb
|
122
|
+
- spec/trick_serial/serializer_spec.rb
|