serialbox 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.8.7@serialbox --create
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source :rubygems
2
+
3
+ gem 'json'
4
+ gem 'activesupport'
5
+
6
+ group :development do
7
+ # SPECS
8
+ gem 'rspec'
9
+
10
+ # DOCS
11
+ gem 'yard'
12
+ gem 'redcarpet'
13
+
14
+ # DEVELOPMENT
15
+ gem 'bundler'
16
+ gem 'jeweler'
17
+ end
@@ -0,0 +1,41 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.10)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ diff-lcs (1.1.3)
8
+ git (1.2.5)
9
+ i18n (0.6.1)
10
+ jeweler (1.8.4)
11
+ bundler (~> 1.0)
12
+ git (>= 1.2.5)
13
+ rake
14
+ rdoc
15
+ json (1.7.6)
16
+ multi_json (1.5.0)
17
+ rake (10.0.3)
18
+ rdoc (3.12)
19
+ json (~> 1.4)
20
+ redcarpet (2.2.2)
21
+ rspec (2.12.0)
22
+ rspec-core (~> 2.12.0)
23
+ rspec-expectations (~> 2.12.0)
24
+ rspec-mocks (~> 2.12.0)
25
+ rspec-core (2.12.2)
26
+ rspec-expectations (2.12.1)
27
+ diff-lcs (~> 1.1.3)
28
+ rspec-mocks (2.12.1)
29
+ yard (0.8.3)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ activesupport
36
+ bundler
37
+ jeweler
38
+ json
39
+ redcarpet
40
+ rspec
41
+ yard
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Tim Morgan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ # SerialBox
2
+
3
+ Provides a simple, well-defined way to specify how your objects are serialized
4
+ and deserialized into primitive types (say, for JSON serialization). Here's an
5
+ example object:
6
+
7
+ ```` ruby
8
+ class Car
9
+ attr_accessor :seats, :color
10
+
11
+ include SerialBox
12
+ serialize_with :JSON
13
+ serialize_fields do |s|
14
+ s.serialize :seats
15
+ s.serialize :color
16
+ end
17
+ end
18
+ ````
19
+
20
+ By calling `serialize_with :JSON`, your class now gets `#to_json`, `#as_json`,
21
+ and `.json_create` methods making it work seamlessly with the `json` gem. If you
22
+ have more complicated data structures or accessors, this gem works with that
23
+ too:
24
+
25
+ ```` ruby
26
+ class Color
27
+ attr_accessor :r, :g, :b
28
+
29
+ include SerialBox
30
+ serialize_with :JSON
31
+ serialize_fields do |s|
32
+ s.serialize :r, :g, :b
33
+ end
34
+ end
35
+
36
+ class Car
37
+ attr_accessor :color # string
38
+
39
+ include SerialBox
40
+ serialize_with :JSON
41
+ serialize_fields do |s|
42
+ s.serializer 'color', :get_color
43
+ s.deserializer 'color', :set_color
44
+ end
45
+
46
+ def get_color
47
+ if color.r == 255 && color.g == 0 && color.b == 0
48
+ 'red'
49
+ elsif color.r == 0 && color.g == 255 && color.b == 0
50
+ 'green'
51
+ elsif color.r == 0 && color.g == 0 && color.b == 255
52
+ 'blue'
53
+ end
54
+ end
55
+
56
+ def set_color(name)
57
+ case name
58
+ when 'red' then Color.new(255, 0, 0)
59
+ when 'green' then Color.new(0, 255, 0)
60
+ when 'blue' then Color.new(0, 0, 255)
61
+ end
62
+ end
63
+ end
64
+ ````
65
+
66
+ The `.serialize_fields` method lets you define serializers and deserializers
67
+ using simple to complex syntax, depending on your needs. Here are the supported
68
+ syntaxes:
69
+
70
+ ```` ruby
71
+ serialize_fields do |s|
72
+ s.serialize :foo # uses #foo and #foo=, JSON field named "foo"
73
+ s.serialize :foo, :into => 'bar' # uses #foo and #foo=, JSON field named "bar"
74
+ s.serialize :@foo # reads and writes directly using @foo
75
+
76
+ s.serializer 'foo', :bar # the JSON field "foo" will have the value returned by #bar
77
+ s.deserializer 'foo', :bar= # the value in JSON field "foo" will be sent to #bar=
78
+
79
+ s.serializer('foo') { bar.to_s } # the JSON field "foo" will have the value returned by the block
80
+ s.deserializer('foo') { |value| self.bar = value.to_sym } # the block will be passed the value stored in JSON field "foo"; you must write it to your object
81
+ end
82
+ ````
83
+
84
+ **Important Note:** Right now the only serializer implemented is `:JSON`. Other
85
+ serializers should be easy to write by following its example.
86
+
87
+ ## Installation
88
+
89
+ To use, add this gem to your Gemfile:
90
+
91
+ ```` ruby
92
+ gem 'serialbox'
93
+ ````
94
+
95
+ then include the `SerialBox` module in your class, following one of the examples
96
+ above.
97
+
98
+ ## Documentation
99
+
100
+ Comprehensive documentation is available by running `rake doc`.
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "serialbox"
18
+ gem.homepage = "http://github.com/riscfuture/serialbox"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Define how your object is serialized and deserialized, and this gem handles the rest.}
21
+ gem.description = %Q{This gem allows you to define how your object is serialized and deserialized. Then it's a simple matter of telling it which formats you want to support, and the serialization methods are automatically created for you.}
22
+ gem.email = "rubygems@timothymorgan.info"
23
+ gem.authors = ["Tim Morgan"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ task :default => :spec
35
+
36
+ require 'yard'
37
+
38
+ # bring sexy back (sexy == tables)
39
+ module YARD::Templates::Helpers::HtmlHelper
40
+ def html_markup_markdown(text)
41
+ markup_class(:markdown).new(text, :gh_blockcode, :fenced_code, :autolink, :tables).to_html
42
+ end
43
+ end
44
+
45
+ YARD::Rake::YardocTask.new('doc') do |doc|
46
+ doc.options << '-m' << 'markdown' << '-M' << 'redcarpet'
47
+ doc.options << '--protected' << '--no-private'
48
+ doc.options << '-r' << 'README.md'
49
+ doc.options << '-o' << 'doc'
50
+ doc.options << '--title' << "SerialBox Documentation"
51
+
52
+ doc.files = %w( lib/**/*.rb README.md )
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,191 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ Dir.glob(File.dirname(__FILE__) + '/serializers/*').each { |f| require f }
4
+
5
+ # Mixin that adds the ability for you to define a serializable representation of
6
+ # your object. `include` this module into your class and call
7
+ # {ClassMethods#serialize_fields} and {ClassMethods#serialize_with} to
8
+ # configure.
9
+
10
+ module SerialBox
11
+ extend ActiveSupport::Concern
12
+
13
+ # Methods added to the class that this module is mixed into.
14
+
15
+ module ClassMethods
16
+
17
+ # Call this method to define how your object is serialized. This method
18
+ # yields an object on which you call methods to define your serialization.
19
+ #
20
+ # @yield [serializer] A block where you can define how your object is
21
+ # serialized.
22
+ # @yieldparam [SerialBox::Serializer] serializer An object you can use to
23
+ # define your serialization strategy.
24
+
25
+ def serialize_fields
26
+ @_serialbox_serializer = Serializer.new(self)
27
+ yield @_serialbox_serializer
28
+ end
29
+
30
+ # @overload serialize_with(serializer, ...)
31
+ # Call this method to specify which serialization formats to use.
32
+ #
33
+ # @param [Symbol, Class] serializer A serialization format adapter or the
34
+ # name of such adapter under the `SerialBox::Serializers` namespace. See
35
+ # the classes under {SerialBox::Serializers} for a list of possible
36
+ # values.
37
+
38
+ def serialize_with(*serializers)
39
+ serializers.map! do |s|
40
+ case s
41
+ when Class
42
+ s
43
+ when Symbol, String
44
+ SerialBox::Serializers.const_get(s.to_sym)
45
+ else
46
+ raise ArgumentError, "Unknown serializer #{s.inspect}"
47
+ end
48
+ end
49
+
50
+ serializers.each { |serializer| include serializer }
51
+ end
52
+
53
+ # @private
54
+ def _serialbox_serializer() @_serialbox_serializer end
55
+ end
56
+
57
+
58
+ # An object that is used to define how a class is serialized. The methods of
59
+ # this object can be called within a block given to
60
+ # {SerialBox::ClassMethods#serialize_fields}.
61
+
62
+ class Serializer
63
+ # @private
64
+ attr_reader :serialization_operations, :deserialization_operations, :object
65
+
66
+ # @private
67
+ def initialize(object)
68
+ @serialization_operations = Array.new
69
+ @deserialization_operations = Array.new
70
+ @object = object
71
+ end
72
+
73
+ # @overload serialize(field, ..., options={})
74
+ #
75
+ # Specifies that one or more fields should be serialized in the most
76
+ # obvious manner. This is suitable when serializing a simple getter/setter
77
+ # pair or an instance variable.
78
+ #
79
+ # @param [Symbol] field The name of a method (or instance variable with
80
+ # "@" sigil) that will be serialized.
81
+ # @param [Hash] options Additional options controlling how the field is
82
+ # serialized.
83
+ # @option options [String] :into If given, specifies that the field should
84
+ # be serialized into a key with a different name. Can only be provided
85
+ # if a single field is given.
86
+
87
+ def serialize(*fields)
88
+ options = fields.extract_options!
89
+ if options[:into] && fields.size > 1
90
+ raise ArgumentError, "Can't specify :into option with multiple fields"
91
+ end
92
+
93
+ fields.each do |field|
94
+ if field.to_s[0, 1] == '@'
95
+ field = field.to_s[1..-1]
96
+ json_field = options[:into] || field
97
+ serializer(json_field) { instance_variable_get :"@#{field}" }
98
+ deserializer(json_field) { |value| instance_variable_set :"@#{field}", value }
99
+ else
100
+ json_field = options[:into] || field
101
+ serializer json_field, field
102
+ deserializer json_field, :"#{field}="
103
+ end
104
+ end
105
+ end
106
+
107
+ # Defines how a field is handled when an object is prepared for
108
+ # serialization.
109
+ #
110
+ # @overload serializer(json_field, object_method)
111
+ # Specifies that the method `object_method` should be called and its
112
+ # result should be stored in a field named `json_field` as part of
113
+ # serialization.
114
+ # @param [String] json_field The field to store the resulting value in.
115
+ # @param [Symbol] object_method The method to call to retrieve a value.
116
+ #
117
+ # @overload serializer(json_field)
118
+ # Specifies that a block should be called in the context of the instance
119
+ # being serialized, and the result should be stored in a field named
120
+ # `json_field`.
121
+ # @param [String] json_field The field to store the resulting value in in
122
+ # the JSON representation.
123
+ # @yield A block that returns the value to serialize.
124
+ # @yieldreturn The value to serialize into `json_field`.
125
+
126
+ def serializer(json_field, object_method=nil, &block)
127
+ if block_given?
128
+ @serialization_operations << BlockSerialization.new(json_field, block)
129
+ elsif object_method
130
+ @serialization_operations << BlockSerialization.new(json_field, lambda { send object_method })
131
+ else
132
+ raise ArgumentError, "Must provide the name of a method or a block that returns a value to serialize"
133
+ end
134
+ end
135
+
136
+ # Defines how a field is handled when an object is deserialized from its
137
+ # primitive representation.
138
+ #
139
+ # @overload deserializer(json_field, object_method)
140
+ # Specifies that the value in `json_field` should be passed to
141
+ # `object_method` during deserialization.
142
+ # @param [String] json_field The field to retrieve the value from.
143
+ # @param [Symbol] object_method The method to call to store the value
144
+ # into the object.
145
+ #
146
+ # @overload deserializer(json_field)
147
+ # Specifies that the value stored in `json_field` should be passed to the
148
+ # block provided, which will store that value into the object being
149
+ # deserialized.
150
+ # @param [String] json_field The field to retrieve the value from in the
151
+ # JSON representation.
152
+ # @yield [value] A block that stores the value into the object. This block
153
+ # is executed in the context of the object.
154
+ # @yieldparam value The value to store.
155
+
156
+ def deserializer(json_field, object_method=nil, &block)
157
+ if block_given?
158
+ @deserialization_operations << BlockDeserialization.new(json_field, block, object)
159
+ elsif object_method
160
+ @deserialization_operations << BlockDeserialization.new(json_field, lambda { |value| send object_method, value }, object)
161
+ else
162
+ raise ArgumentError, "Must provide the name of a method or a block that sets a field from a deserialized value"
163
+ end
164
+ end
165
+
166
+ # @private
167
+ class BlockSerialization
168
+ def initialize(field, block)
169
+ @field = field
170
+ @block = block
171
+ end
172
+
173
+ def apply(caller, json)
174
+ json[@field] = caller.instance_eval(&@block)
175
+ end
176
+ end
177
+
178
+ # @private
179
+ class BlockDeserialization
180
+ def initialize(field, block, klass)
181
+ @field = field
182
+ @method_name = "_block_deserialization_#{object_id}"
183
+ klass.send :define_method, @method_name, &block
184
+ end
185
+
186
+ def apply(caller, json)
187
+ caller.send @method_name, json[@field.to_s]
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,65 @@
1
+ require 'json'
2
+
3
+ module SerialBox
4
+
5
+ # Container module for all {SerialBox} serializers.
6
+
7
+ module Serializers
8
+
9
+ # JSON adapter for {SerialBox}. Defines the following methods when included
10
+ # in a class:
11
+ #
12
+ # * `#as_json`
13
+ # * `#to_json`
14
+ # * `.json_create`
15
+ #
16
+ # This gives the class total ability to work with `JSON.parse` and
17
+ # `#to_json`.
18
+
19
+ module JSON
20
+ extend ActiveSupport::Concern
21
+
22
+ # @private
23
+ JSON_CREATE_ID = JSON.respond_to?(:create_id) ? JSON.create_id : 'json_class'
24
+
25
+ # Converts this object into primitives suitable for JSON serialization.
26
+ #
27
+ # @return [Hash, Array] A JSON-serializable object.
28
+
29
+ def as_json(*)
30
+ hsh = {SerialBox::Serializers::JSON::JSON_CREATE_ID => self.class.name}
31
+ self.class._serialbox_serializer.serialization_operations.each do |operation|
32
+ operation.apply self, hsh
33
+ end
34
+ return hsh
35
+ end
36
+
37
+ # Serializes this object as JSON.
38
+ #
39
+ # @return [String] The JSON representation of this object.
40
+
41
+ def to_json(*args) as_json.to_json(*args) end
42
+
43
+ module ClassMethods
44
+
45
+ # Converts a primitive object (deserialized from JSON) into an instance
46
+ # of this class.
47
+ #
48
+ # **Note:** You should not call this method directly. You should use
49
+ # `JSON.parse` to ensure recursive deserialization works properly.
50
+ #
51
+ # @param [Array, Hash] object The JSON-ready primitive represnetation of
52
+ # an instance of this class.
53
+ # @return An instance of this class derived from the JSON.
54
+
55
+ def json_create(object)
56
+ instance = allocate
57
+ _serialbox_serializer.deserialization_operations.each do |operation|
58
+ operation.apply instance, object
59
+ end
60
+ return instance
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,70 @@
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
+ Gem::Specification.new do |s|
7
+ s.name = "serialbox"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tim Morgan"]
12
+ s.date = "2013-01-08"
13
+ s.description = "This gem allows you to define how your object is serialized and deserialized. Then it's a simple matter of telling it which formats you want to support, and the serialization methods are automatically created for you."
14
+ s.email = "rubygems@timothymorgan.info"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.md",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "lib/serialbox.rb",
30
+ "lib/serializers/json.rb",
31
+ "spec/json_spec.rb",
32
+ "spec/spec_helper.rb"
33
+ ]
34
+ s.homepage = "http://github.com/riscfuture/serialbox"
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = "1.8.24"
38
+ s.summary = "Define how your object is serialized and deserialized, and this gem handles the rest."
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<json>, [">= 0"])
45
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
46
+ s.add_development_dependency(%q<rspec>, [">= 0"])
47
+ s.add_development_dependency(%q<yard>, [">= 0"])
48
+ s.add_development_dependency(%q<redcarpet>, [">= 0"])
49
+ s.add_development_dependency(%q<bundler>, [">= 0"])
50
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<json>, [">= 0"])
53
+ s.add_dependency(%q<activesupport>, [">= 0"])
54
+ s.add_dependency(%q<rspec>, [">= 0"])
55
+ s.add_dependency(%q<yard>, [">= 0"])
56
+ s.add_dependency(%q<redcarpet>, [">= 0"])
57
+ s.add_dependency(%q<bundler>, [">= 0"])
58
+ s.add_dependency(%q<jeweler>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<json>, [">= 0"])
62
+ s.add_dependency(%q<activesupport>, [">= 0"])
63
+ s.add_dependency(%q<rspec>, [">= 0"])
64
+ s.add_dependency(%q<yard>, [">= 0"])
65
+ s.add_dependency(%q<redcarpet>, [">= 0"])
66
+ s.add_dependency(%q<bundler>, [">= 0"])
67
+ s.add_dependency(%q<jeweler>, [">= 0"])
68
+ end
69
+ end
70
+
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ generate_tester_classes 'JSON', :JSON
4
+
5
+ describe SerialBox::Serializers::JSON do
6
+ context "[basic schema]" do
7
+ it "should serialize using #serialize with a method" do
8
+ obj = JSONSerializeMethodTester.new('value')
9
+ JSON.parse(obj.to_json, :create_additions => false).should eql({'json_class' => 'JSONSerializeMethodTester', 'var' => 'value'})
10
+
11
+ obj = JSON.parse('{"json_class":"JSONSerializeMethodTester","var":"value"}')
12
+ obj.var.should eql('value')
13
+ end
14
+
15
+ it "should serialize using #serialize with an instance variable" do
16
+ obj = JSONSerializeIvarTester.new('value')
17
+ JSON.parse(obj.to_json, :create_additions => false).should eql({'json_class' => 'JSONSerializeIvarTester', 'var' => 'value'})
18
+
19
+ obj = JSON.parse('{"json_class":"JSONSerializeIvarTester","var":"value"}')
20
+ obj.instance_variable_get(:@var).should eql('value')
21
+ end
22
+
23
+ it "should serialize into a custom JSON key" do
24
+ obj = JSONSerializeIntoTester.new('value')
25
+ JSON.parse(obj.to_json, :create_additions => false).should eql({'json_class' => 'JSONSerializeIntoTester', 'custom' => 'value'})
26
+
27
+ obj = JSON.parse('{"json_class":"JSONSerializeIntoTester","custom":"value"}')
28
+ obj.var.should eql('value')
29
+ end
30
+
31
+ it "should serialize using #serializer and #deserializer with object methods" do
32
+ obj = JSONSerializerMethodTester.new('value')
33
+ JSON.parse(obj.to_json, :create_additions => false).should eql({'json_class' => 'JSONSerializerMethodTester', 'var_json' => 'value'})
34
+
35
+ obj = JSON.parse('{"json_class":"JSONSerializerMethodTester","var_json":"value"}')
36
+ obj.var_getter.should eql('value')
37
+ end
38
+
39
+ it "should serialize using #serializer and #deserializer with blocks" do
40
+ obj = JSONSerializerBlockTester.new('value')
41
+ JSON.parse(obj.to_json, :create_additions => false).should eql({'json_class' => 'JSONSerializerBlockTester', 'var_json' => 'value'})
42
+
43
+ obj = JSON.parse('{"json_class":"JSONSerializerBlockTester","var_json":"value"}')
44
+ obj.instance_variable_get(:@var).should eql('value')
45
+ end
46
+ end
47
+
48
+ context "[sub-objects]" do
49
+ it "should correctly serialize and deserialize sub-objects" do
50
+ subobj = JSONSerializeMethodTester.new('value')
51
+ obj = JSONSerializeMethodTester.new(subobj)
52
+ JSON.parse(obj.to_json, :create_additions => false).should eql({
53
+ 'json_class' => 'JSONSerializeMethodTester',
54
+ 'var' => {'json_class' => 'JSONSerializeMethodTester',
55
+ 'var' => 'value'}})
56
+
57
+ obj = JSON.parse('{"json_class":"JSONSerializeMethodTester","var":{"json_class":"JSONSerializeMethodTester","var":"value"}}')
58
+ obj.var.should be_kind_of(JSONSerializeMethodTester)
59
+ obj.var.var.should eql('value')
60
+ end
61
+
62
+ it "should correctly serialize and deserialize special objects in generic objects" do
63
+ obj = [JSONSerializeMethodTester.new('value')]
64
+ JSON.parse(obj.to_json, :create_additions => false).should eql([{'json_class' => 'JSONSerializeMethodTester',
65
+ 'var' => 'value'}])
66
+
67
+ obj = JSON.parse('[{"json_class":"JSONSerializeMethodTester","var":"value"}]')
68
+ obj.should be_kind_of(Array)
69
+ obj.first.should be_kind_of(JSONSerializeMethodTester)
70
+ obj.first.var.should eql('value')
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,67 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'serialbox'
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
+ RSpec.configure do |config|
11
+
12
+ end
13
+
14
+ def generate_tester_classes(prefix, serialize_with)
15
+ eval <<-RUBY
16
+ class #{prefix}SerializeMethodTester
17
+ attr_accessor :var
18
+ def initialize(var) self.var = var end
19
+
20
+ include SerialBox
21
+ serialize_with #{serialize_with.inspect}
22
+ serialize_fields { |s| s.serialize :var }
23
+ end
24
+
25
+ class #{prefix}SerializeIvarTester
26
+ def initialize(var) @var = var end
27
+
28
+ include SerialBox
29
+ serialize_with #{serialize_with.inspect}
30
+ serialize_fields { |s| s.serialize :@var }
31
+ end
32
+
33
+ class #{prefix}SerializeIntoTester
34
+ attr_accessor :var
35
+ def initialize(var) self.var = var end
36
+
37
+ include SerialBox
38
+ serialize_with #{serialize_with.inspect}
39
+ serialize_fields { |s| s.serialize :var, :into => :custom }
40
+ end
41
+
42
+
43
+ class #{prefix}SerializerMethodTester
44
+ def initialize(var) @var = var end
45
+ def var_setter(val) @var = val end
46
+ def var_getter() @var end
47
+
48
+ include SerialBox
49
+ serialize_with #{serialize_with.inspect}
50
+ serialize_fields do |s|
51
+ s.serializer 'var_json', :var_getter
52
+ s.deserializer 'var_json', :var_setter
53
+ end
54
+ end
55
+
56
+ class #{prefix}SerializerBlockTester
57
+ def initialize(var) @var = var end
58
+
59
+ include SerialBox
60
+ serialize_with #{serialize_with.inspect}
61
+ serialize_fields do |s|
62
+ s.serializer('var_json') { @var }
63
+ s.deserializer('var_json') { |val| @var = val }
64
+ end
65
+ end
66
+ RUBY
67
+ end
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: serialbox
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Tim Morgan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-01-08 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ version_requirements: *id001
31
+ name: json
32
+ prerelease: false
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ version_requirements: *id002
45
+ name: activesupport
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ version_requirements: *id003
59
+ name: rspec
60
+ prerelease: false
61
+ type: :development
62
+ - !ruby/object:Gem::Dependency
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ version_requirements: *id004
73
+ name: yard
74
+ prerelease: false
75
+ type: :development
76
+ - !ruby/object:Gem::Dependency
77
+ requirement: &id005 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ version_requirements: *id005
87
+ name: redcarpet
88
+ prerelease: false
89
+ type: :development
90
+ - !ruby/object:Gem::Dependency
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ version_requirements: *id006
101
+ name: bundler
102
+ prerelease: false
103
+ type: :development
104
+ - !ruby/object:Gem::Dependency
105
+ requirement: &id007 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ version_requirements: *id007
115
+ name: jeweler
116
+ prerelease: false
117
+ type: :development
118
+ description: This gem allows you to define how your object is serialized and deserialized. Then it's a simple matter of telling it which formats you want to support, and the serialization methods are automatically created for you.
119
+ email: rubygems@timothymorgan.info
120
+ executables: []
121
+
122
+ extensions: []
123
+
124
+ extra_rdoc_files:
125
+ - LICENSE.txt
126
+ - README.md
127
+ files:
128
+ - .document
129
+ - .rspec
130
+ - .rvmrc
131
+ - Gemfile
132
+ - Gemfile.lock
133
+ - LICENSE.txt
134
+ - README.md
135
+ - Rakefile
136
+ - VERSION
137
+ - lib/serialbox.rb
138
+ - lib/serializers/json.rb
139
+ - serialbox.gemspec
140
+ - spec/json_spec.rb
141
+ - spec/spec_helper.rb
142
+ homepage: http://github.com/riscfuture/serialbox
143
+ licenses:
144
+ - MIT
145
+ post_install_message:
146
+ rdoc_options: []
147
+
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ requirements: []
169
+
170
+ rubyforge_project:
171
+ rubygems_version: 1.8.24
172
+ signing_key:
173
+ specification_version: 3
174
+ summary: Define how your object is serialized and deserialized, and this gem handles the rest.
175
+ test_files: []
176
+