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 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