persistent_settings 1.2.0 → 1.3.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/.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
|