persistent_settings 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +5 -0
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/README.md +7 -6
- data/config/cucumber.yml +8 -0
- data/features/support/env.rb +11 -0
- data/lib/generators/persistent_settings/create_generator.rb +28 -0
- data/lib/generators/persistent_settings/templates/create_table.rb.erb +8 -0
- data/lib/generators/persistent_settings/templates/model.rb.erb +4 -0
- data/lib/persistent/settings/caching.rb +17 -0
- data/lib/persistent/settings/persistance.rb +29 -0
- data/lib/persistent/settings.rb +72 -0
- data/lib/persistent_settings/version.rb +1 -1
- data/lib/persistent_settings.rb +11 -4
- data/persistent_settings.gemspec +2 -0
- data/spec/generators/persistent_settings/create_generator_spec.rb +33 -0
- data/spec/lib/persistent/settings.rb +241 -0
- data/spec/lib/settings_spec.rb +77 -57
- data/spec/spec_helper.rb +10 -1
- data/spec/support/warnings_helper.rb +9 -0
- metadata +50 -9
- data/lib/generators/persistent_settings/migration_generator.rb +0 -17
- data/lib/generators/persistent_settings/templates/create_settings_table.rb +0 -12
- data/lib/settings.rb +0 -86
- data/spec/generators/persistent_settings/migration_generator_spec.rb +0 -17
data/.autotest
ADDED
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
-
|
1
|
+
-fp
|
2
2
|
-c
|
data/README.md
CHANGED
@@ -16,24 +16,25 @@ Install
|
|
16
16
|
|
17
17
|
bundle install
|
18
18
|
|
19
|
-
|
19
|
+
Use the generator to create a Config class, or whatever you want to call it, that
|
20
|
+
will include all the Persistent Settings functionality.
|
20
21
|
|
21
|
-
rails g persistent_settings:
|
22
|
+
rails g persistent_settings:create config
|
22
23
|
|
23
|
-
Run
|
24
|
+
Run migrations
|
24
25
|
|
25
26
|
rake db:migrate
|
26
27
|
|
27
28
|
## Usage
|
28
29
|
|
29
|
-
|
30
|
+
Assuming that your Persistent Settings class is named Config, it will automatically create new
|
30
31
|
keys as you assign a value to them.
|
31
32
|
|
32
|
-
|
33
|
+
Config.a_key = 'value'
|
33
34
|
|
34
35
|
Reload your app:
|
35
36
|
|
36
|
-
|
37
|
+
Config.a_key # => 'value'
|
37
38
|
|
38
39
|
It accepts all kinds of objects as the value
|
39
40
|
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
data/features/support/env.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'rails'
|
2
2
|
require 'persistent_settings'
|
3
|
+
require 'logger'
|
3
4
|
|
5
|
+
ActiveRecord::Migration.verbose = false
|
6
|
+
ActiveRecord::Base.logger = Logger.new("test.log")
|
4
7
|
::ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
5
8
|
::ActiveRecord::Schema.define(:version => 1) do
|
6
9
|
create_table :settings do |t|
|
@@ -8,3 +11,11 @@ require 'persistent_settings'
|
|
8
11
|
t.column :value, :string
|
9
12
|
end
|
10
13
|
end
|
14
|
+
|
15
|
+
module Rails
|
16
|
+
RAILS_CACHE = ActiveSupport::Cache::MemoryStore.new
|
17
|
+
end
|
18
|
+
|
19
|
+
class Settings < ActiveRecord::Base
|
20
|
+
include Persistent::Settings
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module PersistentSettings
|
5
|
+
class CreateGenerator < ::Rails::Generators::Base
|
6
|
+
include ::Rails::Generators::Migration
|
7
|
+
|
8
|
+
argument :class_name, :type => :string
|
9
|
+
argument :verbose, :type => :numeric, :default => 1
|
10
|
+
|
11
|
+
source_root File.expand_path('../templates', __FILE__)
|
12
|
+
|
13
|
+
def create_model
|
14
|
+
@klass_name = class_name.classify
|
15
|
+
template 'model.rb.erb', "models/#{class_name}.rb", :verbose => (verbose == 1)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_migration
|
19
|
+
@table_name = class_name.pluralize.gsub("/", "_")
|
20
|
+
@migration_class = @table_name.camelize
|
21
|
+
migration_template "create_table.rb.erb", "db/migrate/create_#{@table_name}_table.rb", :verbose => (verbose == 1)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.next_migration_number(path)
|
25
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Persistent
|
2
|
+
module Settings
|
3
|
+
module Caching
|
4
|
+
def cache_key_for(key)
|
5
|
+
"settings/#{key}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def write_to_cache(key, value)
|
9
|
+
::Rails.cache.write(cache_key_for(key), value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def read_from_cache(key)
|
13
|
+
::Rails.cache.fetch(cache_key_for(key))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Persistent
|
2
|
+
module Settings
|
3
|
+
module Persistance
|
4
|
+
def load_from_persistance!
|
5
|
+
self.all.each do |setting|
|
6
|
+
self.send("#{setting.var}=", setting.value)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def load_from_persistance
|
11
|
+
load_from_persistance! if ready?
|
12
|
+
end
|
13
|
+
|
14
|
+
def persist(getter, value)
|
15
|
+
setting = self.where(:var => getter).last
|
16
|
+
if setting
|
17
|
+
setting.update_attribute(:value, value)
|
18
|
+
else
|
19
|
+
self.create(:var => getter, :value => value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def read_from_persistance(key)
|
24
|
+
self.find_by_var(key).value
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Persistent
|
2
|
+
module Settings
|
3
|
+
include ActiveModel::Serialization
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.send :extend, Persistent::Settings::ClassMethods
|
7
|
+
base.send :extend, Persistent::Settings::Caching
|
8
|
+
base.send :extend, Persistent::Settings::Persistance
|
9
|
+
base.send :serialize, :value
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
@@mutex = Mutex.new
|
14
|
+
@@accessors = []
|
15
|
+
|
16
|
+
def method_missing(method_name, *args)
|
17
|
+
if assignation?(method_name)
|
18
|
+
self.define_setter_and_getter(method_name)
|
19
|
+
self.send(method_name, args.first)
|
20
|
+
elsif accessors.include?(method_name)
|
21
|
+
nil
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_setter_and_getter(method_name)
|
28
|
+
getter = method_name.to_s.chop
|
29
|
+
|
30
|
+
(class << self; self; end).instance_eval do
|
31
|
+
define_method method_name do |value|
|
32
|
+
@@mutex.synchronize do
|
33
|
+
persist(getter, value)
|
34
|
+
write_to_cache getter, value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method getter do
|
39
|
+
value = read_from_cache getter
|
40
|
+
unless value
|
41
|
+
value = read_from_persistance getter
|
42
|
+
write_to_cache getter, value
|
43
|
+
end
|
44
|
+
value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def assignation?(method_name)
|
50
|
+
method_name.to_s.match(/=$/)
|
51
|
+
end
|
52
|
+
|
53
|
+
def ready?
|
54
|
+
connected? && table_exists?
|
55
|
+
end
|
56
|
+
|
57
|
+
def keys
|
58
|
+
self.select(:var).collect { |s| s.var.to_sym }
|
59
|
+
end
|
60
|
+
|
61
|
+
def accessors
|
62
|
+
@@accessors
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def attr_accessor(*args)
|
67
|
+
@@accessors << args[0]
|
68
|
+
super(*args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/persistent_settings.rb
CHANGED
@@ -2,9 +2,16 @@ require "rails/version"
|
|
2
2
|
require "rails/engine"
|
3
3
|
require "active_record"
|
4
4
|
require "persistent_settings/version"
|
5
|
-
require "settings"
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
require "persistent_settings/rails/engine"
|
7
|
+
require "generators/persistent_settings/create_generator"
|
8
|
+
|
9
|
+
module Persistent
|
10
|
+
autoload :Settings, 'persistent/settings'
|
11
|
+
module Settings
|
12
|
+
autoload :Caching, 'persistent/settings/caching'
|
13
|
+
autoload :Persistance, 'persistent/settings/persistance'
|
14
|
+
end
|
10
15
|
end
|
16
|
+
|
17
|
+
module PersistentSettings ; end
|
data/persistent_settings.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_dependency 'railties', '~> 3.0'
|
22
22
|
s.add_dependency 'activerecord', '~> 3.0'
|
23
|
+
s.add_development_dependency "autotest"
|
24
|
+
s.add_development_dependency "autotest-growl"
|
23
25
|
s.add_development_dependency "cucumber" , "~> 1.1.4"
|
24
26
|
s.add_development_dependency "rake"
|
25
27
|
s.add_development_dependency "rspec" , "~> 2.7.0"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PersistentSettings::CreateGenerator do
|
4
|
+
let(:destination) { 'tmp'}
|
5
|
+
|
6
|
+
let(:model_path) do
|
7
|
+
File.join(destination, 'models', 'module/config.rb')
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:migration_path) do
|
11
|
+
File.join(destination, 'db', 'migrate', 'YYYYMMDDHHMM_create_module_configs_table.rb')
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
File.unlink(model_path) if File.exists?(model_path)
|
16
|
+
File.unlink(migration_path) if File.exists?(migration_path)
|
17
|
+
PersistentSettings::CreateGenerator.stub(:next_migration_number).
|
18
|
+
and_return('YYYYMMDDHHMM')
|
19
|
+
PersistentSettings::CreateGenerator.start(['module/config', 0], :destination_root => destination)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "creates the model file" do
|
23
|
+
File.exists?(model_path).should be_true
|
24
|
+
File.read(model_path).should match /Module::Config/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates the migration file" do
|
28
|
+
File.exists?(migration_path).should be_true
|
29
|
+
file = File.read(migration_path)
|
30
|
+
file.should match /CreateModuleConfigs/
|
31
|
+
file.should match /create_table :module_configs/
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Settings do
|
4
|
+
describe :assignation? do
|
5
|
+
context "the method name ends with =" do
|
6
|
+
it "returns true" do
|
7
|
+
Settings.assignation?("method=").should be_true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "the method name does not end with =" do
|
12
|
+
it "returns false" do
|
13
|
+
Settings.assignation?("method").should be_false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe :define_setter_and_getter do
|
19
|
+
before do
|
20
|
+
Settings.define_setter_and_getter(:method_name=)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "creates the setter and getter methods" do
|
24
|
+
Settings.should respond_to(:method_name=)
|
25
|
+
Settings.should respond_to(:method_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
context :getter_method do
|
29
|
+
context "value is persisted on cache" do
|
30
|
+
before do
|
31
|
+
Settings.should_receive(:read_from_cache).with('method_name').
|
32
|
+
and_return('value from cache')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "reads and returns value from cache" do
|
36
|
+
Settings.method_name.should == 'value from cache'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "value is not persisted on cache" do
|
41
|
+
before do
|
42
|
+
Settings.should_receive(:read_from_cache).with('method_name')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "reads and returns value from persistance, then saves to cache" do
|
46
|
+
Settings.should_receive(:read_from_persistance).with('method_name').
|
47
|
+
and_return 'value from persistance'
|
48
|
+
|
49
|
+
Settings.should_receive(:write_to_cache).
|
50
|
+
with('method_name', 'value from persistance')
|
51
|
+
|
52
|
+
Settings.method_name.should == 'value from persistance'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context :setter_method do
|
58
|
+
it "persists and writes to cache the key/value" do
|
59
|
+
Settings.should_receive(:persist).with('method_name', 'value')
|
60
|
+
Settings.should_receive(:write_to_cache).with('method_name', 'value')
|
61
|
+
Settings.method_name = 'value'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe :persist do
|
67
|
+
context "a value already persisted" do
|
68
|
+
before :each do
|
69
|
+
@setting = mock(Settings)
|
70
|
+
Settings.stub_chain(:where, :last).and_return(@setting)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "updates the setting" do
|
74
|
+
@setting.should_receive(:update_attribute).with(:value, :new_value)
|
75
|
+
Settings.persist('some_method', :new_value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "a value that is not persisted" do
|
80
|
+
it "creates the setting" do
|
81
|
+
Settings.stub_chain(:where, :last).and_return(nil)
|
82
|
+
Settings.should_receive(:create).with(:var => 'new_method', :value => 'value')
|
83
|
+
Settings.persist('new_method', 'value')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe :read_from_persistance do
|
89
|
+
it "reads the value from persistance" do
|
90
|
+
object = Settings.new :var => 'foo', :value => 'bar'
|
91
|
+
Settings.should_receive(:find_by_var).with('foo').and_return(object)
|
92
|
+
|
93
|
+
Settings.read_from_persistance('foo').should eq 'bar'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe :cache_key_for do
|
98
|
+
it "returns the name for the rails cache key" do
|
99
|
+
Settings.cache_key_for('foo').should eq('settings/foo')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "cache" do
|
104
|
+
let(:cache) { mock }
|
105
|
+
|
106
|
+
before do
|
107
|
+
Rails.should_receive(:cache).and_return cache
|
108
|
+
Settings.stub(:cache_key_for).with('foo').and_return 'settings/foo'
|
109
|
+
end
|
110
|
+
|
111
|
+
describe :write_to_cache do
|
112
|
+
it "writes the key, value to Rails cache" do
|
113
|
+
cache.should_receive(:write).with('settings/foo', 'bar')
|
114
|
+
Settings.write_to_cache('foo', 'bar')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe :read_from_cache do
|
119
|
+
it "reads the value from Rails cache" do
|
120
|
+
cache.should_receive(:fetch).with('settings/foo')
|
121
|
+
Settings.read_from_cache('foo')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe :method_missing do
|
127
|
+
context "A method ending with =" do
|
128
|
+
it "calls define_setter_and_getter" do
|
129
|
+
Settings.should_receive(:define_setter_and_getter).with(:new_method=)
|
130
|
+
Settings.should_receive(:new_method=).with('value')
|
131
|
+
Settings.method_missing(:new_method=, 'value')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "method that does not end with =" do
|
136
|
+
context "already persisted" do
|
137
|
+
before :each do
|
138
|
+
@setting = mock(Settings, :var => 'persisted_method', :value => 'some value')
|
139
|
+
Settings.stub(:all).and_return([@setting])
|
140
|
+
end
|
141
|
+
|
142
|
+
it "pulls the value from the database and creates its setter and getter" do
|
143
|
+
Settings.should_receive(:persisted_method=).with('some value')
|
144
|
+
Settings.load_from_persistance!
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "not persisited" do
|
149
|
+
it "blows up" do
|
150
|
+
lambda {
|
151
|
+
Settings.just_a_method
|
152
|
+
}.should raise_error(NoMethodError)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe :keys do
|
159
|
+
let(:settings) do
|
160
|
+
[ mock(:var => 'a_key'), mock(:var => 'another_key') ]
|
161
|
+
end
|
162
|
+
|
163
|
+
before do
|
164
|
+
Settings.should_receive(:select).with(:var).and_return(settings)
|
165
|
+
end
|
166
|
+
|
167
|
+
subject { Settings.keys }
|
168
|
+
|
169
|
+
specify { should include(:a_key) }
|
170
|
+
specify { should include(:another_key) }
|
171
|
+
end
|
172
|
+
|
173
|
+
describe :load_from_persistance! do
|
174
|
+
it "loads all settings from persistance and sets it up" do
|
175
|
+
settings = [ Settings.new(:var => 'foo', :value => 'bar') ]
|
176
|
+
Settings.should_receive(:all).and_return(settings)
|
177
|
+
Settings.should_receive("foo=").with('bar')
|
178
|
+
|
179
|
+
Settings.load_from_persistance!
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe :load_from_persistance do
|
184
|
+
context "is ready" do
|
185
|
+
before do
|
186
|
+
Settings.stub(:ready?).and_return true
|
187
|
+
end
|
188
|
+
|
189
|
+
it "calls load_from_persistance!" do
|
190
|
+
Settings.should_receive(:load_from_persistance!)
|
191
|
+
Settings.load_from_persistance
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "not ready" do
|
196
|
+
before do
|
197
|
+
Settings.stub(:ready?).and_return false
|
198
|
+
end
|
199
|
+
|
200
|
+
it "calls load_from_persistance!" do
|
201
|
+
Settings.should_not_receive(:load_from_persistance!)
|
202
|
+
Settings.load_from_persistance
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe :ready? do
|
208
|
+
context "AR is connected and table is created" do
|
209
|
+
before do
|
210
|
+
Settings.stub(:connected?).and_return true
|
211
|
+
Settings.stub(:table_exists?).and_return true
|
212
|
+
end
|
213
|
+
|
214
|
+
it "is true" do
|
215
|
+
Settings.ready?.should be_true
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "AR is not connected" do
|
220
|
+
before do
|
221
|
+
Settings.stub(:connected?).and_return false
|
222
|
+
Settings.stub(:table_exists?).and_return true
|
223
|
+
end
|
224
|
+
|
225
|
+
it "is false" do
|
226
|
+
Settings.ready?.should be_false
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "table is not created" do
|
231
|
+
before do
|
232
|
+
Settings.stub(:connected?).and_return false
|
233
|
+
Settings.stub(:table_exists?).and_return false
|
234
|
+
end
|
235
|
+
|
236
|
+
it "is false" do
|
237
|
+
Settings.ready?.should be_false
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
data/spec/lib/settings_spec.rb
CHANGED
@@ -1,64 +1,70 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Settings do
|
3
|
+
describe Persistent::Settings do
|
4
|
+
before do
|
5
|
+
klass = Class.new ActiveRecord::Base
|
6
|
+
suppress_warnings { ::Config = klass }
|
7
|
+
::Config.send :include, Persistent::Settings
|
8
|
+
end
|
9
|
+
|
4
10
|
describe :assignation? do
|
5
11
|
context "the method name ends with =" do
|
6
12
|
it "returns true" do
|
7
|
-
|
13
|
+
Config.assignation?("method=").should be_true
|
8
14
|
end
|
9
15
|
end
|
10
16
|
|
11
17
|
context "the method name does not end with =" do
|
12
18
|
it "returns false" do
|
13
|
-
|
19
|
+
Config.assignation?("method").should be_false
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
18
24
|
describe :define_setter_and_getter do
|
19
25
|
before do
|
20
|
-
|
26
|
+
Config.define_setter_and_getter(:method_name=)
|
21
27
|
end
|
22
28
|
|
23
29
|
it "creates the setter and getter methods" do
|
24
|
-
|
25
|
-
|
30
|
+
Config.should respond_to(:method_name=)
|
31
|
+
Config.should respond_to(:method_name)
|
26
32
|
end
|
27
33
|
|
28
34
|
context :getter_method do
|
29
35
|
context "value is persisted on cache" do
|
30
36
|
before do
|
31
|
-
|
37
|
+
Config.should_receive(:read_from_cache).with('method_name').
|
32
38
|
and_return('value from cache')
|
33
39
|
end
|
34
40
|
|
35
41
|
it "reads and returns value from cache" do
|
36
|
-
|
42
|
+
Config.method_name.should == 'value from cache'
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
46
|
context "value is not persisted on cache" do
|
41
47
|
before do
|
42
|
-
|
48
|
+
Config.should_receive(:read_from_cache).with('method_name')
|
43
49
|
end
|
44
50
|
|
45
51
|
it "reads and returns value from persistance, then saves to cache" do
|
46
|
-
|
52
|
+
Config.should_receive(:read_from_persistance).with('method_name').
|
47
53
|
and_return 'value from persistance'
|
48
54
|
|
49
|
-
|
55
|
+
Config.should_receive(:write_to_cache).
|
50
56
|
with('method_name', 'value from persistance')
|
51
57
|
|
52
|
-
|
58
|
+
Config.method_name.should == 'value from persistance'
|
53
59
|
end
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
63
|
context :setter_method do
|
58
64
|
it "persists and writes to cache the key/value" do
|
59
|
-
|
60
|
-
|
61
|
-
|
65
|
+
Config.should_receive(:persist).with('method_name', 'value')
|
66
|
+
Config.should_receive(:write_to_cache).with('method_name', 'value')
|
67
|
+
Config.method_name = 'value'
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
@@ -66,37 +72,37 @@ describe Settings do
|
|
66
72
|
describe :persist do
|
67
73
|
context "a value already persisted" do
|
68
74
|
before :each do
|
69
|
-
@setting = mock(
|
70
|
-
|
75
|
+
@setting = mock(Config)
|
76
|
+
Config.stub_chain(:where, :last).and_return(@setting)
|
71
77
|
end
|
72
78
|
|
73
79
|
it "updates the setting" do
|
74
80
|
@setting.should_receive(:update_attribute).with(:value, :new_value)
|
75
|
-
|
81
|
+
Config.persist('some_method', :new_value)
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
79
85
|
context "a value that is not persisted" do
|
80
86
|
it "creates the setting" do
|
81
|
-
|
82
|
-
|
83
|
-
|
87
|
+
Config.stub_chain(:where, :last).and_return(nil)
|
88
|
+
Config.should_receive(:create).with(:var => 'new_method', :value => 'value')
|
89
|
+
Config.persist('new_method', 'value')
|
84
90
|
end
|
85
91
|
end
|
86
92
|
end
|
87
93
|
|
88
94
|
describe :read_from_persistance do
|
89
95
|
it "reads the value from persistance" do
|
90
|
-
object =
|
91
|
-
|
96
|
+
object = Config.new :var => 'foo', :value => 'bar'
|
97
|
+
Config.should_receive(:find_by_var).with('foo').and_return(object)
|
92
98
|
|
93
|
-
|
99
|
+
Config.read_from_persistance('foo').should eq 'bar'
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
97
103
|
describe :cache_key_for do
|
98
104
|
it "returns the name for the rails cache key" do
|
99
|
-
|
105
|
+
Config.cache_key_for('foo').should eq('settings/foo')
|
100
106
|
end
|
101
107
|
end
|
102
108
|
|
@@ -105,20 +111,20 @@ describe Settings do
|
|
105
111
|
|
106
112
|
before do
|
107
113
|
Rails.should_receive(:cache).and_return cache
|
108
|
-
|
114
|
+
Config.stub(:cache_key_for).with('foo').and_return 'settings/foo'
|
109
115
|
end
|
110
116
|
|
111
117
|
describe :write_to_cache do
|
112
118
|
it "writes the key, value to Rails cache" do
|
113
119
|
cache.should_receive(:write).with('settings/foo', 'bar')
|
114
|
-
|
120
|
+
Config.write_to_cache('foo', 'bar')
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
118
124
|
describe :read_from_cache do
|
119
125
|
it "reads the value from Rails cache" do
|
120
126
|
cache.should_receive(:fetch).with('settings/foo')
|
121
|
-
|
127
|
+
Config.read_from_cache('foo')
|
122
128
|
end
|
123
129
|
end
|
124
130
|
end
|
@@ -126,33 +132,40 @@ describe Settings do
|
|
126
132
|
describe :method_missing do
|
127
133
|
context "A method ending with =" do
|
128
134
|
it "calls define_setter_and_getter" do
|
129
|
-
|
130
|
-
|
131
|
-
|
135
|
+
Config.should_receive(:define_setter_and_getter).with(:new_method=)
|
136
|
+
Config.should_receive(:new_method=).with('value')
|
137
|
+
Config.method_missing(:new_method=, 'value')
|
132
138
|
end
|
133
139
|
end
|
134
140
|
|
135
141
|
context "method that does not end with =" do
|
136
142
|
context "already persisted" do
|
137
143
|
before :each do
|
138
|
-
@setting = mock(
|
139
|
-
|
144
|
+
@setting = mock(Config, :var => 'persisted_method', :value => 'some value')
|
145
|
+
Config.stub(:all).and_return([@setting])
|
140
146
|
end
|
141
147
|
|
142
148
|
it "pulls the value from the database and creates its setter and getter" do
|
143
|
-
|
144
|
-
|
149
|
+
Config.should_receive(:persisted_method=).with('some value')
|
150
|
+
Config.load_from_persistance!
|
145
151
|
end
|
146
152
|
end
|
147
153
|
|
148
154
|
context "not persisited" do
|
149
155
|
it "blows up" do
|
150
156
|
lambda {
|
151
|
-
|
157
|
+
Config.just_a_method
|
152
158
|
}.should raise_error(NoMethodError)
|
153
159
|
end
|
154
160
|
end
|
155
161
|
end
|
162
|
+
|
163
|
+
context "method that does not exist but is an accessor" do
|
164
|
+
it "returns nil" do
|
165
|
+
Config.send(:attr_accessor, :bananas)
|
166
|
+
Config.bananas.should be_nil
|
167
|
+
end
|
168
|
+
end
|
156
169
|
end
|
157
170
|
|
158
171
|
describe :keys do
|
@@ -161,10 +174,10 @@ describe Settings do
|
|
161
174
|
end
|
162
175
|
|
163
176
|
before do
|
164
|
-
|
177
|
+
Config.should_receive(:select).with(:var).and_return(settings)
|
165
178
|
end
|
166
179
|
|
167
|
-
subject {
|
180
|
+
subject { Config.keys }
|
168
181
|
|
169
182
|
specify { should include(:a_key) }
|
170
183
|
specify { should include(:another_key) }
|
@@ -172,34 +185,34 @@ describe Settings do
|
|
172
185
|
|
173
186
|
describe :load_from_persistance! do
|
174
187
|
it "loads all settings from persistance and sets it up" do
|
175
|
-
settings = [
|
176
|
-
|
177
|
-
|
188
|
+
settings = [ Config.new(:var => 'foo', :value => 'bar') ]
|
189
|
+
Config.should_receive(:all).and_return(settings)
|
190
|
+
Config.should_receive("foo=").with('bar')
|
178
191
|
|
179
|
-
|
192
|
+
Config.load_from_persistance!
|
180
193
|
end
|
181
194
|
end
|
182
195
|
|
183
196
|
describe :load_from_persistance do
|
184
197
|
context "is ready" do
|
185
198
|
before do
|
186
|
-
|
199
|
+
Config.stub(:ready?).and_return true
|
187
200
|
end
|
188
201
|
|
189
202
|
it "calls load_from_persistance!" do
|
190
|
-
|
191
|
-
|
203
|
+
Config.should_receive(:load_from_persistance!)
|
204
|
+
Config.load_from_persistance
|
192
205
|
end
|
193
206
|
end
|
194
207
|
|
195
208
|
context "not ready" do
|
196
209
|
before do
|
197
|
-
|
210
|
+
Config.stub(:ready?).and_return false
|
198
211
|
end
|
199
212
|
|
200
213
|
it "calls load_from_persistance!" do
|
201
|
-
|
202
|
-
|
214
|
+
Config.should_not_receive(:load_from_persistance!)
|
215
|
+
Config.load_from_persistance
|
203
216
|
end
|
204
217
|
end
|
205
218
|
end
|
@@ -207,35 +220,42 @@ describe Settings do
|
|
207
220
|
describe :ready? do
|
208
221
|
context "AR is connected and table is created" do
|
209
222
|
before do
|
210
|
-
|
211
|
-
|
223
|
+
Config.stub(:connected?).and_return true
|
224
|
+
Config.stub(:table_exists?).and_return true
|
212
225
|
end
|
213
226
|
|
214
227
|
it "is true" do
|
215
|
-
|
228
|
+
Config.ready?.should be_true
|
216
229
|
end
|
217
230
|
end
|
218
231
|
|
219
232
|
context "AR is not connected" do
|
220
233
|
before do
|
221
|
-
|
222
|
-
|
234
|
+
Config.stub(:connected?).and_return false
|
235
|
+
Config.stub(:table_exists?).and_return true
|
223
236
|
end
|
224
237
|
|
225
238
|
it "is false" do
|
226
|
-
|
239
|
+
Config.ready?.should be_false
|
227
240
|
end
|
228
241
|
end
|
229
242
|
|
230
243
|
context "table is not created" do
|
231
244
|
before do
|
232
|
-
|
233
|
-
|
245
|
+
Config.stub(:connected?).and_return false
|
246
|
+
Config.stub(:table_exists?).and_return false
|
234
247
|
end
|
235
248
|
|
236
249
|
it "is false" do
|
237
|
-
|
250
|
+
Config.ready?.should be_false
|
238
251
|
end
|
239
252
|
end
|
240
253
|
end
|
254
|
+
|
255
|
+
describe :accessors do
|
256
|
+
it "returns accessors" do
|
257
|
+
Config.send(:attr_accessor, :access_key)
|
258
|
+
Config.accessors.should include(:access_key)
|
259
|
+
end
|
260
|
+
end
|
241
261
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
1
|
require 'persistent_settings'
|
2
|
+
require 'logger'
|
2
3
|
|
4
|
+
ActiveRecord::Migration.verbose = false
|
5
|
+
ActiveRecord::Base.logger = Logger.new("test.log")
|
3
6
|
::ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
4
7
|
|
8
|
+
Dir["./spec/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
5
10
|
::ActiveRecord::Schema.define(:version => 1) do
|
6
|
-
create_table "
|
11
|
+
create_table "configs", :force => true do |t|
|
7
12
|
t.string "var"
|
8
13
|
t.string "value"
|
9
14
|
end
|
10
15
|
end
|
16
|
+
|
17
|
+
#class Settings < ActiveRecord::Base
|
18
|
+
#include Persistent::Settings
|
19
|
+
#end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: persistent_settings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -43,6 +43,38 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '3.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: autotest
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: autotest-growl
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
46
78
|
- !ruby/object:Gem::Dependency
|
47
79
|
name: cucumber
|
48
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,25 +146,32 @@ executables: []
|
|
114
146
|
extensions: []
|
115
147
|
extra_rdoc_files: []
|
116
148
|
files:
|
149
|
+
- .autotest
|
117
150
|
- .gitignore
|
118
151
|
- .rspec
|
119
152
|
- .travis.yml
|
120
153
|
- Gemfile
|
121
154
|
- README.md
|
122
155
|
- Rakefile
|
156
|
+
- config/cucumber.yml
|
123
157
|
- features/settings.feature
|
124
158
|
- features/step_definitions/settings_steps.rb
|
125
159
|
- features/support/env.rb
|
126
|
-
- lib/generators/persistent_settings/
|
127
|
-
- lib/generators/persistent_settings/templates/
|
160
|
+
- lib/generators/persistent_settings/create_generator.rb
|
161
|
+
- lib/generators/persistent_settings/templates/create_table.rb.erb
|
162
|
+
- lib/generators/persistent_settings/templates/model.rb.erb
|
163
|
+
- lib/persistent/settings.rb
|
164
|
+
- lib/persistent/settings/caching.rb
|
165
|
+
- lib/persistent/settings/persistance.rb
|
128
166
|
- lib/persistent_settings.rb
|
129
167
|
- lib/persistent_settings/rails/engine.rb
|
130
168
|
- lib/persistent_settings/version.rb
|
131
|
-
- lib/settings.rb
|
132
169
|
- persistent_settings.gemspec
|
133
|
-
- spec/generators/persistent_settings/
|
170
|
+
- spec/generators/persistent_settings/create_generator_spec.rb
|
171
|
+
- spec/lib/persistent/settings.rb
|
134
172
|
- spec/lib/settings_spec.rb
|
135
173
|
- spec/spec_helper.rb
|
174
|
+
- spec/support/warnings_helper.rb
|
136
175
|
homepage: ''
|
137
176
|
licenses: []
|
138
177
|
post_install_message:
|
@@ -147,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
186
|
version: '0'
|
148
187
|
segments:
|
149
188
|
- 0
|
150
|
-
hash:
|
189
|
+
hash: 3906203279350267935
|
151
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
191
|
none: false
|
153
192
|
requirements:
|
@@ -156,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
195
|
version: '0'
|
157
196
|
segments:
|
158
197
|
- 0
|
159
|
-
hash:
|
198
|
+
hash: 3906203279350267935
|
160
199
|
requirements: []
|
161
200
|
rubyforge_project: persistent_settings
|
162
201
|
rubygems_version: 1.8.23
|
@@ -167,6 +206,8 @@ test_files:
|
|
167
206
|
- features/settings.feature
|
168
207
|
- features/step_definitions/settings_steps.rb
|
169
208
|
- features/support/env.rb
|
170
|
-
- spec/generators/persistent_settings/
|
209
|
+
- spec/generators/persistent_settings/create_generator_spec.rb
|
210
|
+
- spec/lib/persistent/settings.rb
|
171
211
|
- spec/lib/settings_spec.rb
|
172
212
|
- spec/spec_helper.rb
|
213
|
+
- spec/support/warnings_helper.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'rails/generators'
|
2
|
-
require 'rails/generators/migration'
|
3
|
-
|
4
|
-
module PersistentSettings
|
5
|
-
class MigrationGenerator < ::Rails::Generators::Base
|
6
|
-
include ::Rails::Generators::Migration
|
7
|
-
source_root File.expand_path('../templates', __FILE__)
|
8
|
-
|
9
|
-
def install
|
10
|
-
migration_template "create_settings_table.rb", "db/migrate/create_settings_table.rb"
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.next_migration_number(path)
|
14
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/settings.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
class Settings < ActiveRecord::Base
|
2
|
-
include ::PersistentSettings
|
3
|
-
@mutex = Mutex.new
|
4
|
-
|
5
|
-
serialize :value
|
6
|
-
|
7
|
-
def self.method_missing(method_name, *args)
|
8
|
-
if assignation?(method_name)
|
9
|
-
self.define_setter_and_getter(method_name)
|
10
|
-
self.send(method_name, args.first)
|
11
|
-
else
|
12
|
-
super
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.define_setter_and_getter(method_name)
|
17
|
-
getter = method_name.to_s.chop
|
18
|
-
|
19
|
-
(class << self; self; end).instance_eval do
|
20
|
-
define_method method_name do |value|
|
21
|
-
@mutex.synchronize do
|
22
|
-
persist(getter, value)
|
23
|
-
write_to_cache getter, value
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
define_method getter do
|
28
|
-
value = read_from_cache getter
|
29
|
-
unless value
|
30
|
-
value = read_from_persistance getter
|
31
|
-
write_to_cache getter, value
|
32
|
-
end
|
33
|
-
value
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.assignation?(method_name)
|
39
|
-
method_name.to_s.match(/=$/)
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.persist(getter, value)
|
43
|
-
setting = Settings.where(:var => getter).last
|
44
|
-
if setting
|
45
|
-
setting.update_attribute(:value, value)
|
46
|
-
else
|
47
|
-
Settings.create(:var => getter, :value => value)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.load_from_persistance!
|
52
|
-
self.all.each do |setting|
|
53
|
-
self.send("#{setting.var}=", setting.value)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.read_from_persistance(key)
|
58
|
-
Settings.find_by_var(key).value
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.load_from_persistance
|
62
|
-
load_from_persistance! if ready?
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.cache_key_for(key)
|
66
|
-
"settings/#{key}"
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.write_to_cache(key, value)
|
70
|
-
::Rails.cache.write(cache_key_for(key), value)
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.read_from_cache(key)
|
74
|
-
::Rails.cache.fetch(cache_key_for(key))
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.ready?
|
78
|
-
connected? && table_exists?
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.keys
|
82
|
-
Settings.select(:var).collect { |s| s.var.to_sym }
|
83
|
-
end
|
84
|
-
|
85
|
-
load_from_persistance
|
86
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe PersistentSettings::MigrationGenerator do
|
4
|
-
let(:destination) { 'tmp' }
|
5
|
-
let(:filename) { File.join(destination, 'db', 'migrate', 'YYYYMMDDHHMM_create_settings_table.rb') }
|
6
|
-
|
7
|
-
before do
|
8
|
-
File.unlink(filename) if File.exists?(filename)
|
9
|
-
PersistentSettings::MigrationGenerator.stub(:next_migration_number).
|
10
|
-
and_return('YYYYMMDDHHMM')
|
11
|
-
PersistentSettings::MigrationGenerator.start([], :destination_root => destination)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "creates the migration to create the settings table" do
|
15
|
-
File.exists?(filename).should be_true
|
16
|
-
end
|
17
|
-
end
|