trick_serial 0.2.0 → 0.3.0
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.
- 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
|