thirtythirty 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -8,18 +8,18 @@ Selectively marshal objects without the fancy ruby 1.9 marshalling:
8
8
  extend Thirtythirty
9
9
 
10
10
  marshalled_accessor :attr1, :attr2
11
- attr_accessor :volatile_attr
11
+ attr_accessor :transient_attr
12
12
  end
13
13
 
14
14
  original = Marshalled.new
15
15
  original.attr1 = "value1"
16
- original.volatile_attr = "non-marshalled"
16
+ original.transient_attr = "non-marshalled"
17
17
 
18
18
  marshalled = Marshal.dump(original)
19
19
 
20
20
  reloaded = Marshal.load(marshalled)
21
21
 
22
22
  reloaded.attr1 # => "value1"
23
- reloaded.volatile_attr # => nil
23
+ reloaded.transient_attr # => nil
24
24
 
25
25
  Note: Custom marshalling will only be activated by calling one of the marshalling methods (marshal, marshalled_reader, marshalled_writer, marshalled_accessor), not by extending Thirtythirty alone.
data/lib/thirtythirty.rb CHANGED
@@ -4,37 +4,31 @@ module Thirtythirty
4
4
 
5
5
  # Activates marshalling for the given attributes - you have to implement getters/setters yourself!
6
6
  def marshal(*attributes)
7
- configure_marshalling(attributes)
7
+ unless defined?(@marshalled_attributes)
8
+ extend ClassMethods
9
+ send :include, InstanceMethods
10
+ @marshalled_attributes = []
11
+ end
12
+ @marshalled_attributes = (@marshalled_attributes.map | attributes.flatten.map(&:to_sym).uniq).freeze
8
13
  end
9
14
 
10
15
  # Activates marshalling for the given attributes and generates getters - you have to implement setters yourself!
11
16
  def marshalled_reader(*attributes)
12
- attr_reader *configure_marshalling(attributes)
17
+ attr_reader *marshal(attributes)
13
18
  end
14
19
 
15
20
  # Activates marshalling for the given attributes and generates setters - you have to implement getters yourself!
16
21
  def marshalled_writer(*attributes)
17
- attr_writer *configure_marshalling(attributes)
22
+ attr_writer *marshal(attributes)
18
23
  end
19
24
 
20
25
  # Activates marshalling for the given attributes and generates getters/setters.
21
26
  def marshalled_accessor(*attributes)
22
- attr_accessor *configure_marshalling(attributes)
27
+ attr_accessor *marshal(attributes)
23
28
  end
24
29
 
25
30
  private
26
31
 
27
- def configure_marshalling(attributes)
28
- unless defined?(@marshalled_attributes)
29
- extend ClassMethods
30
- send :include, InstanceMethods
31
- @marshalled_attributes = []
32
- end
33
- attributes = attributes.flatten.map(&:to_s).uniq
34
- @marshalled_attributes = (@marshalled_attributes | attributes).sort.freeze
35
- attributes.map(&:to_sym)
36
- end
37
-
38
32
  module ClassMethods
39
33
 
40
34
  attr_reader :marshalled_attributes
@@ -45,7 +39,7 @@ private
45
39
  data = JSON.parse(dumped)
46
40
  obj = new
47
41
  marshalled_attributes.each do |attr|
48
- obj.send(:"#{attr}=", Marshal.load(data[attr]))
42
+ obj.send(:"#{attr}=", Marshal.load(data[attr.to_s]))
49
43
  end
50
44
  obj
51
45
  end
@@ -55,10 +49,31 @@ private
55
49
  module InstanceMethods
56
50
 
57
51
  def _dump(*args)
52
+ build_marshalled_attributes_hash {|v| Marshal.dump(v)}.to_json
53
+ end
54
+
55
+ def marshalled_attributes
56
+ build_marshalled_attributes_hash {|v| retrieve_marshalled_attributes_of(v)}
57
+ end
58
+
59
+ private
60
+
61
+ def build_marshalled_attributes_hash(&block)
58
62
  self.class.marshalled_attributes.inject({}) do |hash, attr|
59
- hash[attr] = Marshal.dump(self.send(attr.to_sym))
63
+ value = self.send(attr)
64
+ hash[attr] = block.call(value)
60
65
  hash
61
- end.to_json
66
+ end
67
+ end
68
+
69
+ def retrieve_marshalled_attributes_of(obj)
70
+ if obj.is_a?(Array)
71
+ obj.map {|v| retrieve_marshalled_attributes_of(v)}
72
+ elsif obj.respond_to?(:marshalled_attributes)
73
+ obj.marshalled_attributes
74
+ else
75
+ obj
76
+ end
62
77
  end
63
78
 
64
79
  end
data/spec/spec_helper.rb CHANGED
@@ -3,29 +3,3 @@ require 'bundler'
3
3
  Bundler.require(:default, :development)
4
4
 
5
5
  Dir[File.expand_path '../support/*.rb', __FILE__].each {|f| require f}
6
-
7
-
8
- class ThirtythirtyBase
9
- extend Thirtythirty
10
- end
11
-
12
- class BlogPost < ThirtythirtyBase
13
- marshal :title, :description, :comments
14
- attr_accessor :title, :description, :comments, :secret_password
15
- def initialize(attributes={})
16
- self.title = attributes[:title] || 'My first blog post'
17
- self.description = attributes[:description] || "This is a very short description of the things i've done yesterday"
18
- self.comments = attributes[:comments] || [Comment.new, Comment.new(:author => 'bennyb', :comment => 'Ponies and Unicorns!')]
19
- self.secret_password = attributes[:secret_password] || "SECRET!"
20
- end
21
- end
22
-
23
- class Comment < ThirtythirtyBase
24
- marshal :author, :body, :date
25
- attr_accessor :author, :body, :date
26
- def initialize(attributes={})
27
- self.author = attributes[:author] || 'tomj'
28
- self.body = attributes[:body] || "Very nice article!"
29
- self.date = attributes[:date] || Time.now
30
- end
31
- end
@@ -0,0 +1,3 @@
1
+ class ThirtythirtyBase
2
+ extend Thirtythirty
3
+ end
@@ -0,0 +1,4 @@
1
+ class ThirtythirtyTree < ThirtythirtyBase
2
+ marshalled_accessor :persistent, :parent, :children
3
+ attr_accessor :transient
4
+ end
@@ -6,13 +6,13 @@ describe Thirtythirty do
6
6
 
7
7
  subject do
8
8
  cls = Class.new(ThirtythirtyBase) do
9
- marshal :attr1, :attr3
9
+ marshal :attr1, "attr3"
10
10
  marshal [:attr1, :attr2]
11
11
  end
12
12
  end
13
13
 
14
- it "should add given attributes to marshalled attributes (stringified, unique, sorted, frozen)" do
15
- subject.marshalled_attributes.should == %w(attr1 attr2 attr3)
14
+ it "should add given attributes to marshalled attributes (symbolized, unique, frozen)" do
15
+ subject.marshalled_attributes.should =~ [:attr1, :attr2, :attr3]
16
16
  subject.marshalled_attributes.should be_frozen
17
17
  end
18
18
 
@@ -22,13 +22,13 @@ describe Thirtythirty do
22
22
 
23
23
  subject do
24
24
  Class.new(ThirtythirtyBase) do
25
- marshalled_reader :attr1, :attr3
25
+ marshalled_reader :attr1, "attr3"
26
26
  marshalled_reader [:attr1, :attr2]
27
27
  end
28
28
  end
29
29
 
30
- it "should add given attributes to marshalled attributes (stringified, unique, sorted, frozen)" do
31
- subject.marshalled_attributes.should == %w(attr1 attr2 attr3)
30
+ it "should add given attributes to marshalled attributes (symbolized, unique, frozen)" do
31
+ subject.marshalled_attributes.should =~ [:attr1, :attr2, :attr3]
32
32
  subject.marshalled_attributes.should be_frozen
33
33
  end
34
34
 
@@ -48,13 +48,13 @@ describe Thirtythirty do
48
48
 
49
49
  subject do
50
50
  Class.new(ThirtythirtyBase) do
51
- marshalled_writer :attr1, :attr3
51
+ marshalled_writer :attr1, "attr3"
52
52
  marshalled_writer [:attr1, :attr2]
53
53
  end
54
54
  end
55
55
 
56
- it "should add given attributes to marshalled attributes (stringified, unique, sorted, frozen)" do
57
- subject.marshalled_attributes.should == %w(attr1 attr2 attr3)
56
+ it "should add given attributes to marshalled attributes (symbolized, unique, frozen)" do
57
+ subject.marshalled_attributes.should =~ [:attr1, :attr2, :attr3]
58
58
  subject.marshalled_attributes.should be_frozen
59
59
  end
60
60
 
@@ -74,13 +74,13 @@ describe Thirtythirty do
74
74
 
75
75
  subject do
76
76
  Class.new(ThirtythirtyBase) do
77
- marshalled_accessor :attr1, :attr3
77
+ marshalled_accessor :attr1, "attr3"
78
78
  marshalled_accessor :attr1, :attr2
79
79
  end
80
80
  end
81
81
 
82
- it "should add given attributes to marshalled attributes (stringified, unique, sorted, frozen)" do
83
- subject.marshalled_attributes.should == %w(attr1 attr2 attr3)
82
+ it "should add given attributes to marshalled attributes (symbolized, unique, frozen)" do
83
+ subject.marshalled_attributes.should =~ [:attr1, :attr2, :attr3]
84
84
  subject.marshalled_attributes.should be_frozen
85
85
  end
86
86
 
@@ -96,45 +96,114 @@ describe Thirtythirty do
96
96
 
97
97
  end
98
98
 
99
- describe "marshalling" do
99
+ describe "#marshalled_attributes" do
100
100
 
101
- describe "#_dump" do
101
+ it "should give all marshalled attributes" do
102
+ obj = ThirtythirtyTree.new
103
+ obj.persistent = "p"
104
+ obj.transient = "t"
105
+ obj.marshalled_attributes.should == {:persistent => "p", :parent => nil, :children => nil}
106
+ end
107
+
108
+ it "should recursively give marshalled attributes of a single relation" do
109
+ obj = ThirtythirtyTree.new
110
+ obj.persistent = "middle"
111
+ obj.parent = ThirtythirtyTree.new
112
+ obj.parent.persistent = "parent"
113
+ obj.marshalled_attributes.should == {
114
+ :persistent => "middle",
115
+ :parent => {:persistent => "parent", :parent => nil, :children => nil},
116
+ :children => nil
117
+ }
118
+ end
119
+
120
+ it "should recursively give marshalled attributes of a collection relation" do
121
+ obj = ThirtythirtyTree.new
122
+ obj.persistent = "middle"
123
+ obj.children = [ThirtythirtyTree.new]
124
+ obj.children.first.persistent = "child1"
125
+ obj.marshalled_attributes.should == {
126
+ :persistent => "middle",
127
+ :parent => nil,
128
+ :children => [{:persistent => "child1", :parent => nil, :children => nil}]
129
+ }
130
+ end
131
+
132
+ end
133
+
134
+ describe "marshalling (#_dump/._load)" do
135
+
136
+ before do
137
+ @obj = ThirtythirtyTree.new
138
+ end
139
+
140
+ it "should dump a string" do
141
+ Marshal.dump(@obj).should be_a(String)
142
+ end
143
+
144
+ it "should restore a ThirtythirtyTree" do
145
+ Marshal.load(Marshal.dump(@obj)).should be_a(ThirtythirtyTree)
146
+ end
102
147
 
103
- it "should only dump attributes that should be exposed" do
104
- password = "VERY SECRET!"
105
- blog_post = BlogPost.new(:secret_password => password)
106
- marshalled_blog_post = Marshal.dump(blog_post)
107
- marshalled_blog_post.should_not match(Regexp.new(password))
148
+ it "should dump/restore marshalled attributes" do
149
+ @obj.persistent = "data"
150
+ restored = Marshal.load(Marshal.dump(@obj))
151
+ restored.persistent.should == "data"
152
+ end
153
+
154
+ it "should not dump/restore unmarshalled attributes" do
155
+ @obj.transient = "data"
156
+ restored = Marshal.load(Marshal.dump(@obj))
157
+ restored.transient.should be_nil
158
+ end
159
+
160
+ context "with a single relation" do
161
+
162
+ before do
163
+ @obj.parent = ThirtythirtyTree.new
164
+ end
165
+
166
+ it "should restore a ThirtythirtyTree" do
167
+ Marshal.load(Marshal.dump(@obj)).parent.should be_a(ThirtythirtyTree)
108
168
  end
109
169
 
110
- it "should also serialize nested objects so that these objects can also be retrieved by loading the main object" do
111
- blog_post = BlogPost.new(:comments => [Comment.new(:author => 'tomj'), Comment.new(:author => 'bennyb')])
112
- marshalled_blog_post = Marshal.dump(blog_post)
113
- marshalled_blog_post.should match(/bennyb/)
114
- marshalled_blog_post.should match(/tomj/)
170
+ it "should dump/restore marshalled attributes" do
171
+ @obj.parent.persistent = "data"
172
+ restored = Marshal.load(Marshal.dump(@obj))
173
+ restored.parent.persistent.should == "data"
174
+ end
175
+
176
+ it "should not dump/restore unmarshalled attributes" do
177
+ @obj.parent.transient = "data"
178
+ restored = Marshal.load(Marshal.dump(@obj))
179
+ restored.parent.transient.should be_nil
115
180
  end
116
181
 
117
182
  end
118
183
 
119
- describe "._load" do
184
+ context "with a collection relation" do
185
+
186
+ before do
187
+ @obj.children = [ThirtythirtyTree.new]
188
+ end
189
+
190
+ it "should restore an array of ThirtythirtyTrees" do
191
+ children = Marshal.load(Marshal.dump(@obj)).children
192
+ children.should be_a(Array)
193
+ children.size.should == 1
194
+ children.first.should be_a(ThirtythirtyTree)
195
+ end
120
196
 
121
- it "should return a fully deserialized object" do
122
- blog_post = BlogPost.new(:comments => [], :title => 'blau is happy')
123
- marshalled_blog_post = Marshal.dump(blog_post)
124
- deserialized_blog_post = Marshal.load(marshalled_blog_post)
125
- deserialized_blog_post.should be_kind_of(BlogPost)
126
- deserialized_blog_post.title.should == 'blau is happy'
197
+ it "should dump/restore marshalled attributes" do
198
+ @obj.children.first.persistent = "data"
199
+ restored = Marshal.load(Marshal.dump(@obj))
200
+ restored.children.first.persistent.should == "data"
127
201
  end
128
202
 
129
- it "should return a fully deserialized object and nested objects" do
130
- nice_comment = Comment.new(:author => 'tomj', :body => 'nice article, dude!')
131
- blog_post = BlogPost.new(:comments => [nice_comment])
132
- marshalled_blog_post = Marshal.dump(blog_post)
133
- deserialized_blog_post = Marshal.load(marshalled_blog_post)
134
- retrieved_comment = deserialized_blog_post.comments.first
135
- retrieved_comment.should be_kind_of(Comment)
136
- retrieved_comment.author.should == 'tomj'
137
- retrieved_comment.body.should == 'nice article, dude!'
203
+ it "should not dump/restore unmarshalled attributes" do
204
+ @obj.children.first.transient = "data"
205
+ restored = Marshal.load(Marshal.dump(@obj))
206
+ restored.children.first.transient.should be_nil
138
207
  end
139
208
 
140
209
  end
data/thirtythirty.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "thirtythirty"
4
- s.version = "0.0.2"
4
+ s.version = "0.0.3"
5
5
  s.date = Time.now
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ["Benjamin Behr", "Thomas Jachmann"]
metadata CHANGED
@@ -1,76 +1,56 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thirtythirty
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
5
+ version: 0.0.3
11
6
  platform: ruby
12
7
  authors:
13
- - Benjamin Behr
14
- - Thomas Jachmann
8
+ - Benjamin Behr
9
+ - Thomas Jachmann
15
10
  autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
13
 
19
- date: 2011-02-04 00:00:00 +01:00
14
+ date: 2011-02-08 00:00:00 +01:00
20
15
  default_executable:
21
16
  dependencies:
22
- - !ruby/object:Gem::Dependency
23
- name: ci_reporter
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
26
- none: false
27
- requirements:
28
- - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 9
31
- segments:
32
- - 1
33
- - 6
34
- - 3
35
- version: 1.6.3
36
- type: :development
37
- version_requirements: *id001
38
- - !ruby/object:Gem::Dependency
39
- name: rspec
40
- prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
42
- none: false
43
- requirements:
44
- - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 31
47
- segments:
48
- - 2
49
- - 4
50
- - 0
51
- version: 2.4.0
52
- type: :development
53
- version_requirements: *id002
54
- - !ruby/object:Gem::Dependency
55
- name: json
56
- prerelease: false
57
- requirement: &id003 !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
60
- - - ~>
61
- - !ruby/object:Gem::Version
62
- hash: 1
63
- segments:
64
- - 1
65
- - 5
66
- - 1
67
- version: 1.5.1
68
- type: :runtime
69
- version_requirements: *id003
17
+ - !ruby/object:Gem::Dependency
18
+ name: ci_reporter
19
+ prerelease: false
20
+ requirement: &id001 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ~>
24
+ - !ruby/object:Gem::Version
25
+ version: 1.6.3
26
+ type: :development
27
+ version_requirements: *id001
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ prerelease: false
31
+ requirement: &id002 !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: 2.4.0
37
+ type: :development
38
+ version_requirements: *id002
39
+ - !ruby/object:Gem::Dependency
40
+ name: json
41
+ prerelease: false
42
+ requirement: &id003 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.5.1
48
+ type: :runtime
49
+ version_requirements: *id003
70
50
  description: This gem allows for customization of which data to marshal, especially useful for selective session data serialization.
71
51
  email:
72
- - benny@digitalbehr.de
73
- - self@thomasjachmann.com
52
+ - benny@digitalbehr.de
53
+ - self@thomasjachmann.com
74
54
  executables: []
75
55
 
76
56
  extensions: []
@@ -78,15 +58,17 @@ extensions: []
78
58
  extra_rdoc_files: []
79
59
 
80
60
  files:
81
- - .gitignore
82
- - .rspec
83
- - Gemfile
84
- - README.rdoc
85
- - Rakefile
86
- - lib/thirtythirty.rb
87
- - spec/spec_helper.rb
88
- - spec/thirtythirty_spec.rb
89
- - thirtythirty.gemspec
61
+ - .gitignore
62
+ - .rspec
63
+ - Gemfile
64
+ - README.rdoc
65
+ - Rakefile
66
+ - lib/thirtythirty.rb
67
+ - spec/spec_helper.rb
68
+ - spec/support/thirtythirty_base.rb
69
+ - spec/support/tree.rb
70
+ - spec/thirtythirty_spec.rb
71
+ - thirtythirty.gemspec
90
72
  has_rdoc: true
91
73
  homepage: http://github.com/blaulabs/thirtythirty
92
74
  licenses: []
@@ -95,25 +77,19 @@ post_install_message:
95
77
  rdoc_options: []
96
78
 
97
79
  require_paths:
98
- - lib
80
+ - lib
99
81
  required_ruby_version: !ruby/object:Gem::Requirement
100
82
  none: false
101
83
  requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- hash: 3
105
- segments:
106
- - 0
107
- version: "0"
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
108
87
  required_rubygems_version: !ruby/object:Gem::Requirement
109
88
  none: false
110
89
  requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- hash: 3
114
- segments:
115
- - 0
116
- version: "0"
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
117
93
  requirements: []
118
94
 
119
95
  rubyforge_project: thirtythirty
@@ -122,5 +98,7 @@ signing_key:
122
98
  specification_version: 3
123
99
  summary: Marshalling customization
124
100
  test_files:
125
- - spec/spec_helper.rb
126
- - spec/thirtythirty_spec.rb
101
+ - spec/spec_helper.rb
102
+ - spec/support/thirtythirty_base.rb
103
+ - spec/support/tree.rb
104
+ - spec/thirtythirty_spec.rb