thirtythirty 0.0.2 → 0.0.3

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/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