birkirb-acts_as_serializable 0.1.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/README.rdoc +77 -0
- data/Rakefile +115 -0
- data/init.rb +1 -0
- data/lib/acts_as_serializable.rb +109 -0
- data/lib/version.rb +83 -0
- data/lib/versions.rb +31 -0
- data/spec/acts_as_serializable_spec.rb +168 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/version_spec.rb +75 -0
- data/spec/versions_spec.rb +19 -0
- metadata +91 -0
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= acts_as_serializable
|
2
|
+
|
3
|
+
by Birkir A. Barkarson <birkirb@stoicviking.net>
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
A gem/rails plugin for handling versioning of serialization methods (to_xml, to_json).
|
8
|
+
Uses the builder pattern for a one stop multi-format serialization method, which can be
|
9
|
+
versioned in-class, in a module or in seperately managed class files.
|
10
|
+
|
11
|
+
== Installation from source
|
12
|
+
|
13
|
+
git clone git://github.com/birkirb/acts_as_serializable.git
|
14
|
+
cd acts_as_serializable
|
15
|
+
rake install
|
16
|
+
|
17
|
+
=== Gem Installation
|
18
|
+
|
19
|
+
gem install birkirb-acts_as_serializable --source http://gems.github.com
|
20
|
+
|
21
|
+
== Examples
|
22
|
+
|
23
|
+
First:
|
24
|
+
|
25
|
+
require 'rubygems'
|
26
|
+
require 'acts_as_serializable'
|
27
|
+
|
28
|
+
|
29
|
+
Define your own serialization method:
|
30
|
+
|
31
|
+
class SimpleClass
|
32
|
+
include Serializable
|
33
|
+
acts_as_serializable
|
34
|
+
|
35
|
+
def serialize(builder, options)
|
36
|
+
builder.root do
|
37
|
+
builder.text 'hello world'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
SimpleClass.new.to_xml => "<root><text>hello world</text></root>"
|
43
|
+
SimpleClass.new.to_hash => {:text=>"hello world"}
|
44
|
+
SimpleClass.new.to_json => "{\"text\": \"hello world\"}"
|
45
|
+
|
46
|
+
Use versioned serialization methods:
|
47
|
+
|
48
|
+
class SimpleClass
|
49
|
+
include Serializable
|
50
|
+
|
51
|
+
def serialize_to_version_1_0(builder, options)
|
52
|
+
builder.root do
|
53
|
+
builder.text 'hello world'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def serialize_to_version_2_0(builder, options)
|
58
|
+
builder.texts do
|
59
|
+
builder.text "It's a brave new world"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
acts_as_serializable
|
64
|
+
end
|
65
|
+
|
66
|
+
SimpleClass.new.to_xml => "<texts><text>It's a brave new world</text></texts>"
|
67
|
+
SimpleClass.new.to_hash(:version => '1.0') => {:text=>"hello world"}
|
68
|
+
|
69
|
+
Use classes containing versioned serialization methods:
|
70
|
+
|
71
|
+
WIP
|
72
|
+
|
73
|
+
== Copyright
|
74
|
+
|
75
|
+
Author:: Birkir A. Barkarson <birkirb@stoicviking.net>
|
76
|
+
Copyright:: Copyright (c) 2009
|
77
|
+
License:: MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
7
|
+
t.spec_opts = ["-f specdoc", "-c"]
|
8
|
+
t.spec_files = FileList['spec/*_spec.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
rescue LoadError
|
12
|
+
desc 'Spec rake task not available'
|
13
|
+
task :spec do
|
14
|
+
abort 'Spec rake task is not available. Be sure to install rspec as a gem or plugin'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'cucumber'
|
20
|
+
require 'cucumber/rake/task'
|
21
|
+
|
22
|
+
|
23
|
+
desc "Run Cucumber feature tests"
|
24
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
25
|
+
t.cucumber_opts = "--format pretty"
|
26
|
+
end
|
27
|
+
|
28
|
+
rescue LoadError
|
29
|
+
desc 'Cucumber rake task not available'
|
30
|
+
task :features do
|
31
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'spec/rake/spectask'
|
37
|
+
require 'cucumber'
|
38
|
+
require 'cucumber/rake/task'
|
39
|
+
require 'spec/rake/verify_rcov'
|
40
|
+
|
41
|
+
task :test do
|
42
|
+
Rake::Task[:spec].invoke
|
43
|
+
Rake::Task[:features].invoke
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Run tests with RCov"
|
47
|
+
namespace :rcov do
|
48
|
+
rm "coverage.data" if File.exist?("coverage.data")
|
49
|
+
|
50
|
+
desc "Run Features with RCov"
|
51
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
52
|
+
t.rcov = true
|
53
|
+
t.rcov_opts = %w{ --exclude osx\/objc,gems\/,spec\/,features\/ --aggregate coverage.data}
|
54
|
+
t.rcov_opts << %[-o "coverage"]
|
55
|
+
end
|
56
|
+
|
57
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
58
|
+
t.spec_opts = ["-f specdoc", "-c"]
|
59
|
+
t.spec_files = FileList['spec/*_spec.rb']
|
60
|
+
t.rcov = true
|
61
|
+
t.rcov_opts = %w{--exclude "spec/*,gems/*,features/*" --aggregate "coverage.data"}
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Run both specs and features to generate aggregated coverage"
|
65
|
+
task :all do |t|
|
66
|
+
Rake::Task["rcov:spec"].invoke
|
67
|
+
Rake::Task["rcov:features"].invoke
|
68
|
+
end
|
69
|
+
|
70
|
+
RCov::VerifyTask.new(:verify => 'rcov:all') do |t|
|
71
|
+
t.threshold = 100.0
|
72
|
+
t.index_html = 'coverage/index.html'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
rescue LoadError
|
76
|
+
desc 'Rcov rake task not available'
|
77
|
+
task :rcov do
|
78
|
+
abort 'rcov rake task is not available. Be sure to install rspec, rcov and cucumber as a gem or plugin'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
begin
|
83
|
+
require 'metric_fu'
|
84
|
+
|
85
|
+
MetricFu::Configuration.run do |config|
|
86
|
+
#define which metrics you want to use
|
87
|
+
config.metrics = [:churn, :flog, :flay, :reek, :roodi]
|
88
|
+
config.flay = { :dirs_to_flay => ['app', 'lib'] }
|
89
|
+
config.flog = { :dirs_to_flog => ['app', 'lib'] }
|
90
|
+
config.reek = { :dirs_to_reek => ['app', 'lib'] }
|
91
|
+
config.roodi = { :dirs_to_roodi => ['app', 'lib'] }
|
92
|
+
config.saikuro = { :output_directory => 'scratch_directory/saikuro',
|
93
|
+
:input_directory => ['app', 'lib'],
|
94
|
+
:cyclo => "",
|
95
|
+
:filter_cyclo => "0",
|
96
|
+
:warn_cyclo => "5",
|
97
|
+
:error_cyclo => "7",
|
98
|
+
:formater => "text"} #this needs to be set to "text"
|
99
|
+
config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10}
|
100
|
+
config.rcov = { :test_files => ['test/**/*_test.rb',
|
101
|
+
'spec/**/*_spec.rb'],
|
102
|
+
:rcov_opts => ["--sort coverage",
|
103
|
+
"--no-html",
|
104
|
+
"--text-coverage",
|
105
|
+
"--no-color",
|
106
|
+
"--profile",
|
107
|
+
"--rails",
|
108
|
+
"--exclude /gems/,/Library/,spec"]}
|
109
|
+
end
|
110
|
+
|
111
|
+
rescue LoadError
|
112
|
+
# Too bad
|
113
|
+
end
|
114
|
+
|
115
|
+
task :default => [:test]
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'lib/acts_as_serializable'
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'builder/xmlmarkup'
|
2
|
+
require 'jsonbuilder'
|
3
|
+
require 'active_support'
|
4
|
+
require 'find'
|
5
|
+
require 'versions'
|
6
|
+
require 'version'
|
7
|
+
|
8
|
+
module Serializable
|
9
|
+
SERIALIZE_TO_VERSION_REGEXP = /^serialize_to_version_((:?\d+_?)+)$/
|
10
|
+
SERIALIZED_CLASS_NAME_REGEXP = /\/version_((:?\d+_?)+)\.rb$/
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def acts_as_serializable
|
18
|
+
include Serializable::InstanceMethods
|
19
|
+
extend Serializable::SingletonMethods
|
20
|
+
@serialization_versions = Versions.new
|
21
|
+
find_local_serialization_methods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module SingletonMethods
|
26
|
+
def find_project_serialization_classes(project_path)
|
27
|
+
klass_name = self.name
|
28
|
+
serialization_directory = File.join(project_path, 'serializations', klass_name.underscore)
|
29
|
+
Find.find(serialization_directory) do |path|
|
30
|
+
if File.file?(path) && versioned_klass = path.match(SERIALIZED_CLASS_NAME_REGEXP)
|
31
|
+
require path
|
32
|
+
klass = Serializable.const_get("#{klass_name}").const_get("Version_#{versioned_klass[1]}")
|
33
|
+
if klass && klass.respond_to?(:serialize)
|
34
|
+
define_local_serialization_method(versioned_klass[1])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@default_serialization_version = @serialization_versions.last
|
39
|
+
end
|
40
|
+
|
41
|
+
def serialization_versions
|
42
|
+
@serialization_versions
|
43
|
+
end
|
44
|
+
|
45
|
+
def default_serialization_version
|
46
|
+
@default_serialization_version
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_serialization_version=(new_version)
|
50
|
+
if new_version.is_a?(Version)
|
51
|
+
@default_serialization_version = new_version
|
52
|
+
else
|
53
|
+
@default_serialization_version = Version.new(new_version)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def find_local_serialization_methods
|
60
|
+
self.instance_methods.each do |method_name|
|
61
|
+
if method_name = method_name.match(SERIALIZE_TO_VERSION_REGEXP)
|
62
|
+
@serialization_versions << Version.new(method_name[1])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
@default_serialization_version = @serialization_versions.last
|
66
|
+
end
|
67
|
+
|
68
|
+
def define_local_serialization_method(method_version)
|
69
|
+
class_eval <<-EOV
|
70
|
+
def serialize_to_version_#{method_version}(builder, options)
|
71
|
+
Serializable::#{self.name}::Version_#{method_version}.serialize(self, builder, options)
|
72
|
+
end
|
73
|
+
EOV
|
74
|
+
@serialization_versions << Version.new(method_version)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# This module contains instance methods
|
79
|
+
module InstanceMethods
|
80
|
+
def to_hash(options = {})
|
81
|
+
serialize(Builder::Hash.new, options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_json(options = {})
|
85
|
+
serialize(Builder::Json.new, options)
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_xml(options = {})
|
89
|
+
serialize(Builder::XmlMarkup.new, options)
|
90
|
+
end
|
91
|
+
|
92
|
+
def serialize(builder, options = {})
|
93
|
+
if version_number = options[:version]
|
94
|
+
if version = self.class.serialization_versions.find_version(Version.new(version_number))
|
95
|
+
return self.send("serialize_to_version_#{version.to_s_underscored}", builder, options)
|
96
|
+
else
|
97
|
+
raise "Version #{version_number} given but no serialization method found"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
if version = self.class.default_serialization_version
|
101
|
+
return self.send("serialize_to_version_#{version.to_s_underscored}", builder, options)
|
102
|
+
else
|
103
|
+
raise "No serialization method found"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
module Serializable
|
2
|
+
class Version
|
3
|
+
|
4
|
+
def initialize(version_string)
|
5
|
+
version_string = version_string.gsub('_','.')
|
6
|
+
@levels = version_string.split('.')
|
7
|
+
|
8
|
+
@levels.each_with_index do |number, index|
|
9
|
+
@levels[index] = number.to_i
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def major
|
14
|
+
get_level(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def minor
|
18
|
+
get_level(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
get_level(2)
|
23
|
+
end
|
24
|
+
|
25
|
+
def revision
|
26
|
+
get_level(3)
|
27
|
+
end
|
28
|
+
|
29
|
+
def <(rhs)
|
30
|
+
(self <=> rhs) < 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def >(rhs)
|
34
|
+
(self <=> rhs) > 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def ==(rhs)
|
38
|
+
(self <=> rhs) == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def <=>(rhs)
|
42
|
+
max_levels = @levels.size - 1
|
43
|
+
max_levels = rhs.levels.size - 1 if rhs.levels.size > max_levels
|
44
|
+
|
45
|
+
(0..max_levels).each do |level|
|
46
|
+
lhs_level = @levels[level] || 0
|
47
|
+
rhs_level = rhs.levels[level] || 0
|
48
|
+
|
49
|
+
if lhs_level == rhs_level
|
50
|
+
next
|
51
|
+
else
|
52
|
+
return lhs_level <=> rhs_level
|
53
|
+
end
|
54
|
+
end
|
55
|
+
0 # Ended on an equality
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s(seperator = '.')
|
59
|
+
@levels.join(seperator)
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s_underscored
|
63
|
+
to_s('_')
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def levels
|
69
|
+
@levels
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def get_level(level)
|
75
|
+
if @levels.size > level
|
76
|
+
@levels[level]
|
77
|
+
else
|
78
|
+
0
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
data/lib/versions.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Serializable
|
2
|
+
class Versions < Array
|
3
|
+
|
4
|
+
def <<(object)
|
5
|
+
super(object)
|
6
|
+
self.sort!
|
7
|
+
end
|
8
|
+
|
9
|
+
def push(object)
|
10
|
+
super(object)
|
11
|
+
self.sort!
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_version(seeking_version)
|
15
|
+
previous_version = nil
|
16
|
+
|
17
|
+
if seeking_version.is_a?(Version)
|
18
|
+
self.each do |version|
|
19
|
+
if version < seeking_version
|
20
|
+
previous_version = version
|
21
|
+
elsif version > seeking_version
|
22
|
+
return previous_version
|
23
|
+
else
|
24
|
+
return version
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
previous_version
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
class SerializableObject
|
4
|
+
include Serializable
|
5
|
+
|
6
|
+
def serialize_to_version_1_0_0(builder, options)
|
7
|
+
"This is version 1.0.0"
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize_to_version_1_5(builder, options)
|
11
|
+
"This is version 1.5.0"
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize_to_version_2_1(builder, options)
|
15
|
+
"This is version 2.1"
|
16
|
+
end
|
17
|
+
|
18
|
+
acts_as_serializable
|
19
|
+
end
|
20
|
+
|
21
|
+
class WithSerialize < SerializableObject
|
22
|
+
include Serializable
|
23
|
+
acts_as_serializable
|
24
|
+
|
25
|
+
def serialize(builder, options)
|
26
|
+
builder
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class NoSerializationObject
|
31
|
+
include Serializable
|
32
|
+
acts_as_serializable
|
33
|
+
end
|
34
|
+
|
35
|
+
class TestModel
|
36
|
+
include Serializable
|
37
|
+
acts_as_serializable
|
38
|
+
find_project_serialization_classes(File.join(File.dirname(__FILE__)))
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Serializable, 'if included in a class, then that class' do
|
42
|
+
|
43
|
+
it 'should respond to #to_xml(options)' do
|
44
|
+
klass = SerializableObject.new
|
45
|
+
klass.respond_to?("to_xml").should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should respond to #to_json(options)' do
|
49
|
+
klass = SerializableObject.new
|
50
|
+
klass.respond_to?("to_hash").should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should respond to #to_hash(options)' do
|
54
|
+
klass = SerializableObject.new
|
55
|
+
klass.respond_to?("to_json").should be_true
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with the serialized method overriden to return the builder' do
|
59
|
+
|
60
|
+
it '#to_xml should return an Builder::XmlMarkup' do
|
61
|
+
klass = WithSerialize.new
|
62
|
+
klass.to_xml.test.should == "<test/>"
|
63
|
+
end
|
64
|
+
|
65
|
+
it '#to_hash should return an Builder::Hash' do
|
66
|
+
klass = WithSerialize.new
|
67
|
+
klass.to_hash.test('value').should == 'value'
|
68
|
+
end
|
69
|
+
|
70
|
+
it '#to_json should return an Builder::Json' do
|
71
|
+
klass = WithSerialize.new
|
72
|
+
klass.to_json.test('value').should == '"value"'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
describe Serializable, 'when included in a class that has multiple versioned serialization methods' do
|
79
|
+
|
80
|
+
context 'and a to_format method is called with a version option' do
|
81
|
+
|
82
|
+
it 'should execute that exact versioned serialization assuming it exists' do
|
83
|
+
klass = SerializableObject.new
|
84
|
+
|
85
|
+
klass.to_xml(:version => '1.0.0').should == "This is version 1.0.0"
|
86
|
+
klass.to_json(:version => '1.5.0').should == "This is version 1.5.0"
|
87
|
+
klass.to_hash(:version => '2.1.0').should == "This is version 2.1"
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should execute a lower version if an exact one does not exist' do
|
91
|
+
klass = SerializableObject.new
|
92
|
+
|
93
|
+
klass.to_xml(:version => '1.4.0').should == "This is version 1.0.0"
|
94
|
+
klass.to_json(:version => '3.1.0').should == "This is version 2.1"
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should raise an error if no corresponding version exists' do
|
98
|
+
klass = SerializableObject.new
|
99
|
+
|
100
|
+
lambda { klass.to_hash(:version => '0.1.0') }.should raise_error(RuntimeError, "Version 0.1.0 given but no serialization method found")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'and a to_format method is called with no version option' do
|
105
|
+
|
106
|
+
it 'should default to the most recent version if no global default is set' do
|
107
|
+
klass = SerializableObject.new
|
108
|
+
|
109
|
+
klass.to_xml.should == "This is version 2.1"
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should throw an error if no serialization method exists' do
|
113
|
+
klass = NoSerializationObject.new
|
114
|
+
|
115
|
+
lambda { klass.to_xml }.should raise_error(RuntimeError, "No serialization method found")
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should use the default method if it is set' do
|
119
|
+
SerializableObject.default_serialization_version = Serializable::Version.new('1.5')
|
120
|
+
klass = SerializableObject.new
|
121
|
+
|
122
|
+
klass.to_xml.should == "This is version 1.5.0"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe Serializable, 'when included in a class that has multiple serialization classes' do
|
128
|
+
|
129
|
+
context 'and a to_format method is called with a version option' do
|
130
|
+
|
131
|
+
it 'should execute that exact versioned serialization assuming it exists' do
|
132
|
+
klass = TestModel.new
|
133
|
+
|
134
|
+
klass.to_xml(:version => '1.0.0').should == "This is version 1.0.0 for TestModel"
|
135
|
+
klass.to_json(:version => '1.5.0').should == "This is version 1.5.0 for TestModel"
|
136
|
+
klass.to_hash(:version => '2.1.0').should == "This is version 2.1 for TestModel"
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should execute a lower version if an exact one does not exist' do
|
140
|
+
klass = TestModel.new
|
141
|
+
|
142
|
+
klass.to_xml(:version => '1.4.0').should == "This is version 1.0.0 for TestModel"
|
143
|
+
klass.to_json(:version => '3.1.0').should == "This is version 2.1 for TestModel"
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should raise an error if no corresponding version exists' do
|
147
|
+
klass = TestModel.new
|
148
|
+
|
149
|
+
lambda { klass.to_hash(:version => '0.1.0') }.should raise_error(RuntimeError, "Version 0.1.0 given but no serialization method found")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'and a to_format method is called with no version option' do
|
154
|
+
|
155
|
+
it 'should default to the most recent version if no global default is set' do
|
156
|
+
klass = TestModel.new
|
157
|
+
|
158
|
+
klass.to_xml.should == "This is version 2.1 for TestModel"
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should use the default method if it is set' do
|
162
|
+
TestModel.default_serialization_version = "1.5"
|
163
|
+
klass = TestModel.new
|
164
|
+
|
165
|
+
klass.to_xml.should == "This is version 1.5.0 for TestModel"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Serializable::Version, 'when created with a version numeric string' do
|
4
|
+
|
5
|
+
it 'should report the correct major, minor, build and revision numbers.' do
|
6
|
+
version = Serializable::Version.new('1.2.3.4')
|
7
|
+
version.major.should == 1
|
8
|
+
version.minor.should == 2
|
9
|
+
version.build.should == 3
|
10
|
+
version.revision.should == 4
|
11
|
+
end
|
12
|
+
|
13
|
+
it '#to_s should give the same version string.' do
|
14
|
+
version = Serializable::Version.new('2.1.2')
|
15
|
+
version.to_s.should == '2.1.2'
|
16
|
+
end
|
17
|
+
|
18
|
+
it '#to_s_underscored should give an underscored version string.' do
|
19
|
+
version = Serializable::Version.new('2.1.2')
|
20
|
+
version.to_s_underscored.should == '2_1_2'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should give 0 for all numbers not specified.' do
|
24
|
+
version = Serializable::Version.new('3')
|
25
|
+
version.major.should == 3
|
26
|
+
version.minor.should == 0
|
27
|
+
version.build.should == 0
|
28
|
+
version.revision.should == 0
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should support underscored versions' do
|
32
|
+
version = Serializable::Version.new('3_1_2_4')
|
33
|
+
version.major.should == 3
|
34
|
+
version.minor.should == 1
|
35
|
+
version.build.should == 2
|
36
|
+
version.revision.should == 4
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe Serializable::Version, 'when comparing two instances' do
|
41
|
+
|
42
|
+
it 'should correctly compare v1.0.0.1 > v.1.0.0.0' do
|
43
|
+
Serializable::Version.new('1.0.0.1').should > Serializable::Version.new('1.0')
|
44
|
+
Serializable::Version.new('1.0.0.1').should_not < Serializable::Version.new('1.0')
|
45
|
+
Serializable::Version.new('1.0.0.1').should_not == Serializable::Version.new('1.0')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should correctly compare v1.2.0.3 < v2.2.0.3' do
|
49
|
+
Serializable::Version.new('1.2.0.3').should < Serializable::Version.new('2.2.0.3')
|
50
|
+
Serializable::Version.new('1.2.0.3').should_not > Serializable::Version.new('2.2.0.3')
|
51
|
+
Serializable::Version.new('1.2.0.3').should_not == Serializable::Version.new('2.2.0.3')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should correctly compare v2.0.0.0.0.0.0 == v2' do
|
55
|
+
Serializable::Version.new('2.0.0.0.0.0.0.0').should == Serializable::Version.new('2')
|
56
|
+
Serializable::Version.new('2.0.0.0.0.0.0.0').should_not < Serializable::Version.new('2')
|
57
|
+
Serializable::Version.new('2.0.0.0.0.0.0.0').should_not > Serializable::Version.new('2')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Serializable::Version, 'when in an Array' do
|
62
|
+
|
63
|
+
it 'should be sortable' do
|
64
|
+
version_strings_unordered = ['1.20.0', '1.0.2', '1.0.0', '1.4.0', '1.0.1', '2', '1.0.10', '2.0.1', '1.0']
|
65
|
+
version_strings_ordered = ['1.0', '1.0.0', '1.0.1', '1.0.2', '1.0.10', '1.4.0', '1.20.0', '2', '2.0.1']
|
66
|
+
versions = Array.new
|
67
|
+
version_strings_unordered.each do |s|
|
68
|
+
versions << Serializable::Version.new(s)
|
69
|
+
end
|
70
|
+
|
71
|
+
versions.sort.each_with_index do |version, index|
|
72
|
+
version.to_s.should == version_strings_ordered[index]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Serializable::Versions do
|
4
|
+
|
5
|
+
it '#find_version should find a Version equal or less than the Version given ' do
|
6
|
+
version_strings_unordered = ['1.20.0', '1.0.2', '1.0.0', '1.4.0', '1.0.1', '2', '1.0.10', '2.0.1', '1.0']
|
7
|
+
versions = Serializable::Versions.new
|
8
|
+
version_strings_unordered.each do |s|
|
9
|
+
versions << Serializable::Version.new(s)
|
10
|
+
end
|
11
|
+
|
12
|
+
versions.push(Serializable::Version.new('1.3')) # Hmm..
|
13
|
+
|
14
|
+
versions.find_version(Serializable::Version.new('1.30')).should == Serializable::Version.new('1.20.0')
|
15
|
+
versions.find_version(Serializable::Version.new('1.15')).should == Serializable::Version.new('1.4.0')
|
16
|
+
versions.find_version(Serializable::Version.new('1.0.2')).should == Serializable::Version.new('1.0.2')
|
17
|
+
versions.find_version(Serializable::Version.new('3.1.5')).should == Serializable::Version.new('2.0.1')
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: birkirb-acts_as_serializable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Birkir A. Barkarson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-06 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: jsonbuilder
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "1.2"
|
34
|
+
version:
|
35
|
+
description: Easy versioning of serialization methods
|
36
|
+
email: birkirb@stoicviking.net
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- README.rdoc
|
45
|
+
- Rakefile
|
46
|
+
- init.rb
|
47
|
+
- lib/acts_as_serializable.rb
|
48
|
+
- lib/version.rb
|
49
|
+
- lib/versions.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/birkirb/acts_as_serializable
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options:
|
54
|
+
- --title
|
55
|
+
- acts_as_serializable documentation
|
56
|
+
- --charset
|
57
|
+
- utf-8
|
58
|
+
- --opname
|
59
|
+
- index.html
|
60
|
+
- --line-numbers
|
61
|
+
- --main
|
62
|
+
- README.rdoc
|
63
|
+
- --inline-source
|
64
|
+
- --exclude
|
65
|
+
- ^(examples)/
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.2.0
|
84
|
+
signing_key:
|
85
|
+
specification_version: 2
|
86
|
+
summary: Easy versioning of serialization methods
|
87
|
+
test_files:
|
88
|
+
- spec/acts_as_serializable_spec.rb
|
89
|
+
- spec/version_spec.rb
|
90
|
+
- spec/versions_spec.rb
|
91
|
+
- spec/spec_helper.rb
|