durable_hash 1.0.1
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/Gemfile +14 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README +0 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/durable_hash.gemspec +56 -0
- data/init.rb +1 -0
- data/lib/durable_hash.rb +115 -0
- data/test/durable_hash_test.rb +208 -0
- metadata +122 -0
data/Gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem 'activerecord', ENV['ACTIVE_RECORD_VERSION']
|
|
4
|
+
|
|
5
|
+
# Add dependencies to develop your gem here.
|
|
6
|
+
# Include everything needed to run rake, tests, features, etc.
|
|
7
|
+
group :development do
|
|
8
|
+
gem "bundler", "~> 1.0.0"
|
|
9
|
+
gem "jeweler", "~> 1.6.0"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
group :test do
|
|
13
|
+
gem 'sqlite3'
|
|
14
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
activerecord (2.3.10)
|
|
5
|
+
activesupport (= 2.3.10)
|
|
6
|
+
activesupport (2.3.10)
|
|
7
|
+
git (1.2.5)
|
|
8
|
+
jeweler (1.6.0)
|
|
9
|
+
bundler (~> 1.0.0)
|
|
10
|
+
git (>= 1.2.5)
|
|
11
|
+
rake
|
|
12
|
+
rake (0.8.7)
|
|
13
|
+
sqlite3 (1.3.3)
|
|
14
|
+
|
|
15
|
+
PLATFORMS
|
|
16
|
+
ruby
|
|
17
|
+
|
|
18
|
+
DEPENDENCIES
|
|
19
|
+
activerecord
|
|
20
|
+
bundler (~> 1.0.0)
|
|
21
|
+
jeweler (~> 1.6.0)
|
|
22
|
+
sqlite3
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2011 Francis Hwang
|
|
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.
|
data/README
ADDED
|
File without changes
|
data/Rakefile
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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 = "durable_hash"
|
|
18
|
+
gem.homepage = "http://github.com/fhwang/durable_hash"
|
|
19
|
+
gem.license = "MIT"
|
|
20
|
+
gem.summary = %Q{Maybe you want something that acts like a hash but is backed by ActiveRecord.}
|
|
21
|
+
gem.description = %Q{Maybe you want something that acts like a hash but is backed by ActiveRecord.}
|
|
22
|
+
gem.email = "francis.hwang@profitably.com"
|
|
23
|
+
gem.authors = ["Francis Hwang"]
|
|
24
|
+
# dependencies defined in Gemfile
|
|
25
|
+
end
|
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
|
27
|
+
|
|
28
|
+
ActiveRecordVersions = %w(3.0.7 2.3.10)
|
|
29
|
+
|
|
30
|
+
desc "Run all tests"
|
|
31
|
+
task :test do
|
|
32
|
+
ActiveRecordVersions.each do |ar_version|
|
|
33
|
+
cmd = "ACTIVE_RECORD_VERSION=#{ar_version} ruby test/durable_hash_test.rb"
|
|
34
|
+
puts cmd
|
|
35
|
+
puts `cd . && #{cmd}`
|
|
36
|
+
puts
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
task :default => :test
|
|
41
|
+
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.1
|
|
@@ -0,0 +1,56 @@
|
|
|
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 = %q{durable_hash}
|
|
8
|
+
s.version = "1.0.1"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Francis Hwang"]
|
|
12
|
+
s.date = %q{2011-05-29}
|
|
13
|
+
s.description = %q{Maybe you want something that acts like a hash but is backed by ActiveRecord.}
|
|
14
|
+
s.email = %q{francis.hwang@profitably.com}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE.txt",
|
|
17
|
+
"README"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
"Gemfile",
|
|
21
|
+
"Gemfile.lock",
|
|
22
|
+
"LICENSE.txt",
|
|
23
|
+
"README",
|
|
24
|
+
"Rakefile",
|
|
25
|
+
"VERSION",
|
|
26
|
+
"durable_hash.gemspec",
|
|
27
|
+
"init.rb",
|
|
28
|
+
"lib/durable_hash.rb",
|
|
29
|
+
"test/durable_hash_test.rb"
|
|
30
|
+
]
|
|
31
|
+
s.homepage = %q{http://github.com/fhwang/durable_hash}
|
|
32
|
+
s.licenses = ["MIT"]
|
|
33
|
+
s.require_paths = ["lib"]
|
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
|
35
|
+
s.summary = %q{Maybe you want something that acts like a hash but is backed by ActiveRecord.}
|
|
36
|
+
|
|
37
|
+
if s.respond_to? :specification_version then
|
|
38
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
39
|
+
s.specification_version = 3
|
|
40
|
+
|
|
41
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
42
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
|
43
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
44
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
|
|
45
|
+
else
|
|
46
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
47
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
48
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
52
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
data/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/lib/durable_hash"
|
data/lib/durable_hash.rb
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module DurableHash
|
|
2
|
+
mattr_accessor :deserializers
|
|
3
|
+
self.deserializers = Hash.new { |h,durable_hash_class|
|
|
4
|
+
h[durable_hash_class] = {}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
def self.deserializer(durable_hash_class, value_class)
|
|
8
|
+
deserializer = deserializers[durable_hash_class][value_class]
|
|
9
|
+
unless deserializer
|
|
10
|
+
match_class = deserializers[durable_hash_class].keys.detect { |klass|
|
|
11
|
+
value_class < klass
|
|
12
|
+
}
|
|
13
|
+
deserializer = deserializers[durable_hash_class][match_class]
|
|
14
|
+
end
|
|
15
|
+
deserializer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
mattr_accessor :serializers
|
|
19
|
+
self.serializers = Hash.new { |h,durable_hash_class|
|
|
20
|
+
h[durable_hash_class] = {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def self.serializer(durable_hash_class, value_class)
|
|
24
|
+
serializer = serializers[durable_hash_class][value_class]
|
|
25
|
+
unless serializer
|
|
26
|
+
match_class = serializers[durable_hash_class].keys.detect { |klass|
|
|
27
|
+
value_class < klass
|
|
28
|
+
}
|
|
29
|
+
serializer = serializers[durable_hash_class][match_class]
|
|
30
|
+
end
|
|
31
|
+
serializer
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.included(includer)
|
|
35
|
+
def includer.acts_as_durable_hash
|
|
36
|
+
self.validates_uniqueness_of :key
|
|
37
|
+
self.validates_presence_of :key, :value_class
|
|
38
|
+
self.serialize :value
|
|
39
|
+
|
|
40
|
+
def self.[](key)
|
|
41
|
+
if record = find_by_key(key.to_s)
|
|
42
|
+
record.value
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.[]=(key, value)
|
|
47
|
+
if record = find_by_key(key.to_s)
|
|
48
|
+
record.value = value
|
|
49
|
+
record.save!
|
|
50
|
+
else
|
|
51
|
+
create! :key => key.to_s, :value => value
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
self.before_validation do |record|
|
|
56
|
+
record.value_class = record.value.class.name
|
|
57
|
+
serializer = DurableHash.serializer(record.class, record.value.class)
|
|
58
|
+
record.value = serializer.call(record.value) if serializer
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if ActiveRecord::VERSION::MAJOR == 3
|
|
62
|
+
define_method(:durable_hash_after_find) do
|
|
63
|
+
if attributes['value_class']
|
|
64
|
+
serializer = DurableHash.deserializer(
|
|
65
|
+
self.class, value_class.constantize
|
|
66
|
+
)
|
|
67
|
+
if serializer
|
|
68
|
+
self.value = serializer.call self.value
|
|
69
|
+
elsif value_class == 'Fixnum'
|
|
70
|
+
self.value = self.value.to_i
|
|
71
|
+
elsif value_class == 'Float'
|
|
72
|
+
self.value = self.value.to_f
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
self.after_find :durable_hash_after_find
|
|
77
|
+
else
|
|
78
|
+
define_method(:after_find) do
|
|
79
|
+
if attributes['value_class']
|
|
80
|
+
serializer = DurableHash.deserializer(
|
|
81
|
+
self.class, value_class.constantize
|
|
82
|
+
)
|
|
83
|
+
if serializer
|
|
84
|
+
self.value = serializer.call self.value
|
|
85
|
+
elsif value_class == 'Fixnum'
|
|
86
|
+
self.value = self.value.to_i
|
|
87
|
+
elsif value_class == 'Float'
|
|
88
|
+
self.value = self.value.to_f
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if block_given?
|
|
95
|
+
yield DurableHash::Builder.new(self)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
class Builder
|
|
101
|
+
def initialize(klass); @klass = klass; end
|
|
102
|
+
|
|
103
|
+
def deserialize(value_class, &block)
|
|
104
|
+
DurableHash.deserializers[@klass][value_class] = block
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def serialize(value_class, &block)
|
|
108
|
+
DurableHash.serializers[@klass][value_class] = block
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class ActiveRecord::Base
|
|
114
|
+
include DurableHash
|
|
115
|
+
end
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
RAILS_ENV = 'test'
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'active_record'
|
|
4
|
+
require 'active_record/base'
|
|
5
|
+
require 'active_support/core_ext/logger'
|
|
6
|
+
require File.dirname(__FILE__) + '/../lib/durable_hash'
|
|
7
|
+
require 'test/unit'
|
|
8
|
+
|
|
9
|
+
# Configure ActiveRecord
|
|
10
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/test.log')
|
|
11
|
+
ActiveRecord::Base.establish_connection(
|
|
12
|
+
'timeout' => 5000, 'adapter' => 'sqlite3', 'database' => 'test/test.sqlite3',
|
|
13
|
+
'pool' => 5
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Create the DB schema
|
|
17
|
+
silence_stream(STDOUT) do
|
|
18
|
+
ActiveRecord::Schema.define do
|
|
19
|
+
create_table 'application_settings', :force => true do |app_setting|
|
|
20
|
+
app_setting.string 'key'
|
|
21
|
+
app_setting.string 'value'
|
|
22
|
+
app_setting.string 'value_class'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
create_table 'customized_settings', :force => true do |app_setting|
|
|
26
|
+
app_setting.string 'key'
|
|
27
|
+
app_setting.string 'value'
|
|
28
|
+
app_setting.string 'value_class'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Define some sample classes
|
|
34
|
+
class ApplicationSetting < ActiveRecord::Base
|
|
35
|
+
acts_as_durable_hash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module WrapperModule
|
|
39
|
+
class Custom
|
|
40
|
+
attr_accessor :value
|
|
41
|
+
|
|
42
|
+
def initialize(value); @value = value; end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class SonOfCustom < Custom
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class CustomizedSetting < ActiveRecord::Base
|
|
50
|
+
acts_as_durable_hash do |dh|
|
|
51
|
+
dh.serialize(WrapperModule::Custom) do |custom|
|
|
52
|
+
custom.value
|
|
53
|
+
end
|
|
54
|
+
dh.deserialize(WrapperModule::Custom) do |data|
|
|
55
|
+
WrapperModule::Custom.new data
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Finally some tests
|
|
61
|
+
class EmptyApplicationSettingTestCase < Test::Unit::TestCase
|
|
62
|
+
def setup
|
|
63
|
+
ApplicationSetting.destroy_all
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_should_return_nil_for_most_everything
|
|
67
|
+
assert_nil(ApplicationSetting['foo'])
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class ApplicationSettingReadingTestCase < Test::Unit::TestCase
|
|
72
|
+
def setup
|
|
73
|
+
as = ApplicationSetting.find_or_create_by_key 'foo'
|
|
74
|
+
as.value = 'bar'
|
|
75
|
+
as.save!
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_should_return_the_value
|
|
79
|
+
assert_equal(ApplicationSetting['foo'], 'bar')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_should_return_the_value_with_a_symbol_too
|
|
83
|
+
assert_equal(ApplicationSetting[:foo], 'bar')
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class ApplicationSettingCreatingTestCase < Test::Unit::TestCase
|
|
88
|
+
def setup
|
|
89
|
+
ApplicationSetting.destroy_all
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def test_it_should_handle_a_write
|
|
93
|
+
ApplicationSetting['foo'] = 'bar'
|
|
94
|
+
assert_equal(ApplicationSetting['foo'], 'bar')
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_should_handle_a_write_with_a_symbol
|
|
98
|
+
ApplicationSetting[:foo] = 'bar'
|
|
99
|
+
assert_equal(ApplicationSetting['foo'], 'bar')
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class ApplicationSettingUpdatingTestCase < Test::Unit::TestCase
|
|
104
|
+
def setup
|
|
105
|
+
ApplicationSetting.destroy_all
|
|
106
|
+
ApplicationSetting.create! :key => 'foo', :value => 'bar'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_should_handle_a_write
|
|
110
|
+
ApplicationSetting['foo'] = 'baz'
|
|
111
|
+
assert_equal(ApplicationSetting['foo'], 'baz')
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class ApplicationSettingUniquenessTestCase < Test::Unit::TestCase
|
|
116
|
+
def setup
|
|
117
|
+
ApplicationSetting.destroy_all
|
|
118
|
+
ApplicationSetting.create! :key => 'foo', :value => 'bar'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_should_be_set_on_key_automatically
|
|
122
|
+
assert_raises(ActiveRecord::RecordInvalid) {
|
|
123
|
+
ApplicationSetting.create!(:key => 'foo', :value => 'baz')
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_should_prevent_new_instances_from_being_seen_as_valid
|
|
128
|
+
assert(!ApplicationSetting.new(:key => 'foo', :value => 'baz').valid?)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
class ApplicationSettingWithAnIntegerTestCase < Test::Unit::TestCase
|
|
133
|
+
def setup
|
|
134
|
+
ApplicationSetting.destroy_all
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_should_read_and_write_as_an_integer
|
|
138
|
+
ApplicationSetting['foo'] = 123
|
|
139
|
+
assert_equal(ApplicationSetting['foo'], 123)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class ApplicationSettingWithAFloatTestCase < Test::Unit::TestCase
|
|
144
|
+
def setup
|
|
145
|
+
ApplicationSetting.destroy_all
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_should_read_and_write_as_a_float
|
|
149
|
+
ApplicationSetting['foo'] = 123.0
|
|
150
|
+
assert_equal(ApplicationSetting['foo'].class, Float)
|
|
151
|
+
assert_in_delta(123.0, ApplicationSetting['foo'], 0.00001)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
class ApplicationSettingWithAnArrayTestCase < Test::Unit::TestCase
|
|
156
|
+
def setup
|
|
157
|
+
ApplicationSetting.destroy_all
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_should_read_and_write_as_a_float
|
|
161
|
+
ApplicationSetting['foo'] = [1,2,3]
|
|
162
|
+
assert_equal(ApplicationSetting['foo'], [1,2,3])
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class ApplicationSettingValidForANewInstanceCase < Test::Unit::TestCase
|
|
167
|
+
def setup
|
|
168
|
+
ApplicationSetting.destroy_all
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_should_not_need_a_value_class_to_be_explicitly_set
|
|
172
|
+
app_setting = ApplicationSetting.new :key => 'username', :value => 'bob'
|
|
173
|
+
assert(app_setting.valid?)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
class CustomizedSettingCustomSerializationTestCase < Test::Unit::TestCase
|
|
178
|
+
def setup
|
|
179
|
+
CustomizedSetting.destroy_all
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_should_save_and_load_with_a_custom_serialization
|
|
183
|
+
value = WrapperModule::Custom.new('bar')
|
|
184
|
+
CustomizedSetting['foo'] = value
|
|
185
|
+
value_prime = CustomizedSetting['foo']
|
|
186
|
+
# let's make sure there's no in-Ruby caching going on which could give this
|
|
187
|
+
# test a false positive
|
|
188
|
+
assert_not_equal(value.object_id, value_prime.object_id)
|
|
189
|
+
assert_equal(value_prime.class, WrapperModule::Custom)
|
|
190
|
+
assert_equal(value_prime.value, 'bar')
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_should_not_try_to_mess_with_a_normal_value
|
|
194
|
+
CustomizedSetting['baz'] = 'fiz'
|
|
195
|
+
assert_equal(CustomizedSetting['baz'], 'fiz')
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_should_use_custom_serialization_for_any_subclasses_of_Custom_too
|
|
199
|
+
value = WrapperModule::SonOfCustom.new('bar')
|
|
200
|
+
CustomizedSetting['foo'] = value
|
|
201
|
+
value_prime = CustomizedSetting['foo']
|
|
202
|
+
# let's make sure there's no in-Ruby caching going on which could give this
|
|
203
|
+
# test a false positive
|
|
204
|
+
assert_not_equal(value.object_id, value_prime.object_id)
|
|
205
|
+
assert_equal(value_prime.class, WrapperModule::Custom)
|
|
206
|
+
assert_equal(value_prime.value, 'bar')
|
|
207
|
+
end
|
|
208
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: durable_hash
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 21
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 1.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Francis Hwang
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-05-29 00:00:00 -04:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
23
|
+
none: false
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
hash: 3
|
|
28
|
+
segments:
|
|
29
|
+
- 0
|
|
30
|
+
version: "0"
|
|
31
|
+
type: :runtime
|
|
32
|
+
name: activerecord
|
|
33
|
+
prerelease: false
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
- !ruby/object:Gem::Dependency
|
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
37
|
+
none: false
|
|
38
|
+
requirements:
|
|
39
|
+
- - ~>
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
hash: 23
|
|
42
|
+
segments:
|
|
43
|
+
- 1
|
|
44
|
+
- 0
|
|
45
|
+
- 0
|
|
46
|
+
version: 1.0.0
|
|
47
|
+
type: :development
|
|
48
|
+
name: bundler
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: *id002
|
|
51
|
+
- !ruby/object:Gem::Dependency
|
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
53
|
+
none: false
|
|
54
|
+
requirements:
|
|
55
|
+
- - ~>
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
hash: 15
|
|
58
|
+
segments:
|
|
59
|
+
- 1
|
|
60
|
+
- 6
|
|
61
|
+
- 0
|
|
62
|
+
version: 1.6.0
|
|
63
|
+
type: :development
|
|
64
|
+
name: jeweler
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: *id003
|
|
67
|
+
description: Maybe you want something that acts like a hash but is backed by ActiveRecord.
|
|
68
|
+
email: francis.hwang@profitably.com
|
|
69
|
+
executables: []
|
|
70
|
+
|
|
71
|
+
extensions: []
|
|
72
|
+
|
|
73
|
+
extra_rdoc_files:
|
|
74
|
+
- LICENSE.txt
|
|
75
|
+
- README
|
|
76
|
+
files:
|
|
77
|
+
- Gemfile
|
|
78
|
+
- Gemfile.lock
|
|
79
|
+
- LICENSE.txt
|
|
80
|
+
- README
|
|
81
|
+
- Rakefile
|
|
82
|
+
- VERSION
|
|
83
|
+
- durable_hash.gemspec
|
|
84
|
+
- init.rb
|
|
85
|
+
- lib/durable_hash.rb
|
|
86
|
+
- test/durable_hash_test.rb
|
|
87
|
+
has_rdoc: true
|
|
88
|
+
homepage: http://github.com/fhwang/durable_hash
|
|
89
|
+
licenses:
|
|
90
|
+
- MIT
|
|
91
|
+
post_install_message:
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
|
|
94
|
+
require_paths:
|
|
95
|
+
- lib
|
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
hash: 3
|
|
102
|
+
segments:
|
|
103
|
+
- 0
|
|
104
|
+
version: "0"
|
|
105
|
+
required_rubygems_version: !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
|
+
requirements: []
|
|
115
|
+
|
|
116
|
+
rubyforge_project:
|
|
117
|
+
rubygems_version: 1.3.7
|
|
118
|
+
signing_key:
|
|
119
|
+
specification_version: 3
|
|
120
|
+
summary: Maybe you want something that acts like a hash but is backed by ActiveRecord.
|
|
121
|
+
test_files: []
|
|
122
|
+
|