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 ADDED
@@ -0,0 +1,5 @@
1
+ require "autotest/growl"
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.add_exception %w{test.log .git}
5
+ end
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  tmp/
6
+ test.log
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- -fd
1
+ -fp
2
2
  -c
data/README.md CHANGED
@@ -16,24 +16,25 @@ Install
16
16
 
17
17
  bundle install
18
18
 
19
- Create the migrations
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:migration
22
+ rails g persistent_settings:create config
22
23
 
23
- Run those migrations
24
+ Run migrations
24
25
 
25
26
  rake db:migrate
26
27
 
27
28
  ## Usage
28
29
 
29
- The gem adds a new class called Settings. It will automatically create new
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
- Settings.a_key = 'value'
33
+ Config.a_key = 'value'
33
34
 
34
35
  Reload your app:
35
36
 
36
- Settings.a_key # => 'value'
37
+ Config.a_key # => 'value'
37
38
 
38
39
  It accepts all kinds of objects as the value
39
40
 
@@ -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
@@ -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,8 @@
1
+ class Create<%= @migration_class %>Table < ActiveRecord::Migration
2
+ def change
3
+ create_table :<%= @table_name %> do |t|
4
+ t.string :var
5
+ t.string :value
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ class <%= @klass_name %> < ActiveRecord::Base
2
+ include Persistent::Settings
3
+
4
+ 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
@@ -1,3 +1,3 @@
1
1
  module PersistentSettings
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -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
- unless Rails::VERSION::STRING < "3.1"
8
- require "persistent_settings/rails/engine"
9
- require "generators/persistent_settings/migration_generator"
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
@@ -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
@@ -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
- Settings.assignation?("method=").should be_true
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
- Settings.assignation?("method").should be_false
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
- Settings.define_setter_and_getter(:method_name=)
26
+ Config.define_setter_and_getter(:method_name=)
21
27
  end
22
28
 
23
29
  it "creates the setter and getter methods" do
24
- Settings.should respond_to(:method_name=)
25
- Settings.should respond_to(:method_name)
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
- Settings.should_receive(:read_from_cache).with('method_name').
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
- Settings.method_name.should == 'value from cache'
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
- Settings.should_receive(:read_from_cache).with('method_name')
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
- Settings.should_receive(:read_from_persistance).with('method_name').
52
+ Config.should_receive(:read_from_persistance).with('method_name').
47
53
  and_return 'value from persistance'
48
54
 
49
- Settings.should_receive(:write_to_cache).
55
+ Config.should_receive(:write_to_cache).
50
56
  with('method_name', 'value from persistance')
51
57
 
52
- Settings.method_name.should == 'value from persistance'
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
- Settings.should_receive(:persist).with('method_name', 'value')
60
- Settings.should_receive(:write_to_cache).with('method_name', 'value')
61
- Settings.method_name = 'value'
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(Settings)
70
- Settings.stub_chain(:where, :last).and_return(@setting)
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
- Settings.persist('some_method', :new_value)
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
- 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')
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 = Settings.new :var => 'foo', :value => 'bar'
91
- Settings.should_receive(:find_by_var).with('foo').and_return(object)
96
+ object = Config.new :var => 'foo', :value => 'bar'
97
+ Config.should_receive(:find_by_var).with('foo').and_return(object)
92
98
 
93
- Settings.read_from_persistance('foo').should eq 'bar'
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
- Settings.cache_key_for('foo').should eq('settings/foo')
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
- Settings.stub(:cache_key_for).with('foo').and_return 'settings/foo'
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
- Settings.write_to_cache('foo', 'bar')
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
- Settings.read_from_cache('foo')
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
- 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')
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(Settings, :var => 'persisted_method', :value => 'some value')
139
- Settings.stub(:all).and_return([@setting])
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
- Settings.should_receive(:persisted_method=).with('some value')
144
- Settings.load_from_persistance!
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
- Settings.just_a_method
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
- Settings.should_receive(:select).with(:var).and_return(settings)
177
+ Config.should_receive(:select).with(:var).and_return(settings)
165
178
  end
166
179
 
167
- subject { Settings.keys }
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 = [ Settings.new(:var => 'foo', :value => 'bar') ]
176
- Settings.should_receive(:all).and_return(settings)
177
- Settings.should_receive("foo=").with('bar')
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
- Settings.load_from_persistance!
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
- Settings.stub(:ready?).and_return true
199
+ Config.stub(:ready?).and_return true
187
200
  end
188
201
 
189
202
  it "calls load_from_persistance!" do
190
- Settings.should_receive(:load_from_persistance!)
191
- Settings.load_from_persistance
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
- Settings.stub(:ready?).and_return false
210
+ Config.stub(:ready?).and_return false
198
211
  end
199
212
 
200
213
  it "calls load_from_persistance!" do
201
- Settings.should_not_receive(:load_from_persistance!)
202
- Settings.load_from_persistance
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
- Settings.stub(:connected?).and_return true
211
- Settings.stub(:table_exists?).and_return true
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
- Settings.ready?.should be_true
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
- Settings.stub(:connected?).and_return false
222
- Settings.stub(:table_exists?).and_return true
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
- Settings.ready?.should be_false
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
- Settings.stub(:connected?).and_return false
233
- Settings.stub(:table_exists?).and_return false
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
- Settings.ready?.should be_false
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 "settings", :force => true do |t|
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
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ def suppress_warnings
3
+ original_verbosity = $VERBOSE
4
+ $VERBOSE = nil
5
+ result = yield
6
+ $VERBOSE = original_verbosity
7
+ return result
8
+ end
9
+ 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.2.0
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-09-22 00:00:00.000000000 Z
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/migration_generator.rb
127
- - lib/generators/persistent_settings/templates/create_settings_table.rb
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/migration_generator_spec.rb
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: 4009893083530099684
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: 4009893083530099684
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/migration_generator_spec.rb
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
@@ -1,12 +0,0 @@
1
- class CreateSettingsTable < ActiveRecord::Migration
2
- def self.up
3
- create_table :settings do |t|
4
- t.string :var
5
- t.string :value
6
- end
7
- end
8
-
9
- def self.down
10
- drop_table :settings
11
- end
12
- 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