arsettings 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ require File.dirname(__FILE__) + '/_helper'
2
+
3
+ class InitializingSettingsClasses < Test::Unit::TestCase
4
+
5
+ # can't lazy load so that error only shows up if you try to use it
6
+ # because we need to read the table immediately to load propagated settings
7
+ verify 'raises error if db does not support the class' do
8
+ assert_raises(ActiveRecord::StatementInvalid) { ARSettings.create_settings_class 'NotInTheDatabase' }
9
+ end
10
+
11
+ verify 'raises error if the constant already exists' do
12
+ assert_nothing_raised { ARSettings.create_settings_class 'Setting2' }
13
+ assert_raises(ARSettings::AlreadyDefinedError) { ARSettings.create_settings_class 'Setting2' }
14
+ end
15
+
16
+ verify 'loads up values previously stored in the db' do
17
+ $sql_executor.silent_execute "insert into predefined_values (name,value,package,volatile) values ('predefined_value','#{ARSettings.serialize(12)}','PredefinedValues','f')"
18
+ $sql_executor.silent_execute "insert into predefined_values (name,value,package,volatile) values ('predefined_value','#{ARSettings.serialize(13)}','String','f')"
19
+ ARSettings.create_settings_class :PredefinedValues
20
+ # make sure it loads the value
21
+ assert_equal 2 , PredefinedValues.count
22
+ assert PredefinedValues.package(PredefinedValues).setting?(:predefined_value)
23
+ assert PredefinedValues.package(String).setting?(:predefined_value)
24
+ assert_equal 12 , PredefinedValues.predefined_value
25
+ assert_equal 13 , PredefinedValues.package(String).predefined_value
26
+ PredefinedValues.add :predefined_value , :default => 20
27
+ assert_equal 12 , PredefinedValues.predefined_value
28
+ end
29
+
30
+ verify 'can specify a volatility default' do
31
+ ARSettings.create_settings_class :VolatileTest , :volatile => true
32
+ VolatileTest.add :abcd , :default => 1 , :volatile => false
33
+ VolatileTest.add :efgh , :default => 10 , :volatile => true
34
+ VolatileTest.add :ijkl , :default => 100
35
+ assert_equal 1 , VolatileTest.abcd
36
+ assert_equal 10 , VolatileTest.efgh
37
+ assert_equal 100 , VolatileTest.ijkl
38
+ $sql_executor.silent_execute "update volatile_tests set value='#{ARSettings.serialize(2)}' where name='abcd'"
39
+ $sql_executor.silent_execute "update volatile_tests set value='#{ARSettings.serialize(20)}' where name='efgh'"
40
+ $sql_executor.silent_execute "update volatile_tests set value='#{ARSettings.serialize(200)}' where name='ijkl'"
41
+ assert_equal 1 , VolatileTest.abcd
42
+ assert_equal 20 , VolatileTest.efgh
43
+ assert_equal 200 , VolatileTest.ijkl
44
+ end
45
+
46
+ verify 'create_settings_class should return the class' do
47
+ result = ARSettings.create_settings_class :ThisShouldBeReturned
48
+ assert_equal ThisShouldBeReturned , result
49
+ end
50
+
51
+ verify 'cannot reload from db' do
52
+ begin
53
+ flag = false
54
+ Setting.load_from_db
55
+ flag = true
56
+ rescue Exception
57
+ assert !flag
58
+ end
59
+ end
60
+
61
+ verify 'default MAX_CHARS is 30' do
62
+ ARSettings.create_settings_class :Setting4
63
+ assert_equal 30 , Setting4.MAX_CHARS
64
+ end
65
+
66
+ # leave it up to the user to ensure they are not speciying more than their DB's string class
67
+ # if that is the case, they could switch it out with text
68
+ verify 'can specify MAX_CHARS' do
69
+ ARSettings.create_settings_class :Setting5 , :max_chars => 50
70
+ assert_equal 50 , Setting5.MAX_CHARS
71
+ end
72
+
73
+ verify 'raises errors if values loaded from the db violate maxlength' do
74
+ $sql_executor.silent_execute "insert into setting10s (name,value,package,volatile) values ('abc','#{ARSettings.serialize(12)}','Setting10','f')"
75
+ assert_raises(ARSettings::InvalidNameError) { ARSettings.create_settings_class :Setting10 , :max_chars => 2 }
76
+ end
77
+
78
+ context 'ARSettings.default_class' do
79
+ verify 'ARSettings will set the new class to the default if no default exists' do
80
+ ARSettings.default_class = nil
81
+ ARSettings.create_settings_class :Setting14s
82
+ assert_equal Setting14s , ARSettings.default_class
83
+ end
84
+ end
85
+
86
+ verify "doesn't raise error for valid options" do
87
+ assert_nothing_raised do
88
+ ARSettings.create_settings_class :Setting17s , :max_chars => 50 , :volatile => false
89
+ end
90
+ end
91
+
92
+ verify "does raise error if it receives any invalid options" do
93
+ [ [ :Setting18s , :package , String ],
94
+ [ :Setting19s , :settings_class , Setting ],
95
+ [ :Setting20s , :lkjdsf , true ],
96
+ [ :Setting21s , :abcd , true ],
97
+ [ :Setting22s , :instance , true ],
98
+ [ :Setting24s , :default , true ],
99
+ ].each do |klass,key,value|
100
+ assert_raises ARSettings::InvalidOptionError do
101
+ ARSettings.create_settings_class klass , key => value
102
+ end
103
+ end
104
+ end
105
+
106
+ verify 'create should be an alias for create_settings_class' do
107
+ ARSettings.create :Setting25s
108
+ Setting25s.add :howdy , :default => 0
109
+ assert_equal 0 , Setting25s.howdy
110
+ assert_equal 1 , Setting25s.count
111
+ end
112
+
113
+ end
@@ -0,0 +1,203 @@
1
+ require File.dirname(__FILE__) + '/_helper'
2
+
3
+ class SettingTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Setting.reset_all
7
+ end
8
+
9
+ verify 'can query whether a setting exists with setting?, and can declare settings with add, or has_setting' do
10
+ assert !Setting.setting?(:a)
11
+ assert !Setting.setting?(:b)
12
+ Setting.add :a
13
+ Setting.has_setting :b
14
+ assert Setting.setting?(:a)
15
+ assert Setting.setting?(:b)
16
+ end
17
+
18
+ verify 'has_setting is an alias for add' do
19
+ # the later versions can verify that it is correct, but comment it out so early versions don't fail
20
+ assert_equal Setting.method(:add) , Setting.method(:has_setting) unless RUBY_VERSION < '1.9.1'
21
+ end
22
+
23
+ verify 'can add default when creating' do
24
+ Setting.add :a , :default => 123
25
+ assert_equal 123 , Setting.a
26
+ end
27
+
28
+ verify 'can pass proc to handle postprocessing' do
29
+ Setting.add :a , :default => '123' do |setting|
30
+ setting.to_i
31
+ end
32
+ assert_equal 123 , Setting.a
33
+ Setting.a = '456'
34
+ assert_equal 456 , Setting.a
35
+ end
36
+
37
+ verify 'adds record to the db' do
38
+ assert_count 0
39
+ Setting.add :a , :default => /abc/
40
+ assert_count 1
41
+ setting = Setting.find_by_sql("select * from settings").first
42
+ assert_equal 'a' , setting.name
43
+ assert_equal( /abc/ , setting.value )
44
+ end
45
+
46
+ verify 'does not raise error if the setting already exists' do
47
+ assert_nothing_raised { Setting.add :a }
48
+ assert_nothing_raised {
49
+ # begin
50
+ Setting.add :a
51
+ # rescue Exception
52
+ # puts $@
53
+ # end
54
+ }
55
+ end
56
+
57
+ verify 'does not overwrite current value with default when added repeatedly' do
58
+ Setting.add :a , :default => 12
59
+ assert_equal 12 , Setting.a
60
+ Setting.add 'a' , :default => 13
61
+ assert_equal 12 , Setting.a
62
+ Setting.add 'b' , :default => 14
63
+ assert_equal 14 , Setting.b
64
+ Setting.add :b , :default => 15
65
+ assert_equal 14 , Setting.b
66
+ end
67
+
68
+
69
+ verify 'get a list of settings' do
70
+ Setting.add :abc
71
+ Setting.add :def
72
+ Setting.add :ghi
73
+ assert_equal [:abc,:def,:ghi] , Setting.settings.sort_by { |name| name.to_s }
74
+ end
75
+
76
+ verify 'get a list of settings and values' do
77
+ Setting.add :abc , :default => 1
78
+ Setting.add :def , :default => 2
79
+ Setting.add :ghi , :default => 3
80
+ assert_equal [[:abc,1],[:def,2],[:ghi,3]] , Setting.settings_with_values.sort_by { |name,value| name.to_s }
81
+ end
82
+
83
+ verify 'can specify that object should reload from db each time' do
84
+ Setting.add :abcd , :default => 1
85
+ Setting.add :efgh , :default => 10 , :volatile => true
86
+ assert_equal 1 , Setting.abcd
87
+ assert_equal 10 , Setting.efgh
88
+ $sql_executor.silent_execute "update settings set value='#{ARSettings.serialize(2)}' where name='abcd'"
89
+ $sql_executor.silent_execute "update settings set value='#{ARSettings.serialize(20)}' where name='efgh'"
90
+ assert_equal 1 , Setting.abcd
91
+ assert_equal 20 , Setting.efgh
92
+ end
93
+
94
+ verify 'retains postprocessing after a reload' do
95
+ Setting.add( :abcd , :default => 1 , :volatile => true ) { |val| val.to_i }
96
+ assert_equal 1 , Setting.abcd
97
+ $sql_executor.silent_execute "update settings set value='#{ARSettings.serialize(2)}' where name='abcd'"
98
+ assert_equal 2 , Setting.abcd
99
+ Setting.abcd = "3"
100
+ assert_equal 3 , Setting.abcd
101
+ end
102
+
103
+ verify 'readding the setting allows you to update volatility' do
104
+ Setting.add( :abcd , :default => "12.5" , :volatile => false ) { |val| val.to_f }
105
+ assert_equal 12.5 , Setting.abcd
106
+ $sql_executor.silent_execute "update settings set value='#{ARSettings.serialize(5.5)}' where name='abcd'"
107
+ assert_equal 12.5 , Setting.abcd
108
+ Setting.add :abcd , :volatile => true
109
+ assert_equal 5.5 , Setting.abcd
110
+ end
111
+
112
+ verify 'postprocessing only occurs when inserting the data' do
113
+ Setting.add( :abcd , :default => "12.5" , :volatile => false ) { |val| val.to_f }
114
+ assert_equal 12.5 , Setting.abcd
115
+ Setting.add( :abcd ) { |val| val.to_i }
116
+ assert_equal 12.5 , Setting.abcd
117
+ end
118
+
119
+ verify 'readding the setting allows you to update postprocessing' do
120
+ Setting.add( :abcd , :default => 0 ) { |val| val.to_f }
121
+ Setting.abcd = "12.5"
122
+ assert_equal 12.5 , Setting.abcd
123
+ Setting.add( :abcd ) { |val| val.to_i }
124
+ Setting.abcd = "12.5"
125
+ assert_equal 12 , Setting.abcd
126
+ end
127
+
128
+ verify 'defaults get run through the postprocessor' do
129
+ Setting.add( :abcd , :default => "5" ) { |i| i.to_i }
130
+ assert_equal 5 , Setting.abcd
131
+ end
132
+
133
+ verify 'raises NoSuchSettingError when invoking nonexistent setting' do
134
+ assert_raises(ARSettings::NoSuchSettingError) { Setting.hjk }
135
+ assert_raises(ARSettings::NoSuchSettingError) { Setting.hjk = 1 }
136
+ end
137
+
138
+ verify 'raises InvalidSetting for settings with over MAX_NAME chars' do
139
+ assert_nothing_raised { Setting.add 'a' * Setting.MAX_CHARS }
140
+ assert_invalid_name { Setting.add 'a' * Setting.MAX_CHARS.next }
141
+ end
142
+
143
+ verify 'raises Invalid name error if the setting is not a valid method name' do
144
+ [ '123' , '1abc' , '.abc' , 'Constant' , 'ab-c' , 'ab.c' , 'ab)c' , 'ab@c' , 'a:b' ].each do |invalid_name|
145
+ assert_invalid_name { Setting.add invalid_name }
146
+ end
147
+ end
148
+
149
+ verify 'add returns the package' do
150
+ assert_equal Setting.package(Setting) , Setting.add( :a , :default => 100)
151
+ assert_equal Setting.package(String) , Setting.package(String).add( :b , :default => 101)
152
+ assert_equal Setting.package(String) , Setting.package(String).add( :b , :default => 102)
153
+ end
154
+
155
+
156
+ context 'new default handling' do
157
+ verify "if a default is passed, saves the default" do
158
+ seen = nil
159
+ Setting.add :hunted , :default => 5 do |val| seen = val end
160
+ assert_equal seen , 5
161
+ assert_equal 5, Setting.first.value
162
+ assert_equal 5, Setting.hunted
163
+ end
164
+
165
+ verify "if no default is passed, waits for initial setting" do
166
+ seen = nil
167
+ Setting.add :down do |val| seen = val end
168
+ Setting.down = 6
169
+ assert_equal seen , 6
170
+ assert_equal 6, Setting.first.value
171
+ assert_equal 6, Setting.down
172
+ end
173
+
174
+ verify "if no default is passed, raises an error if not initialized by first access" do
175
+ seen = nil
176
+ Setting.add :like do |val| seen = val end
177
+ assert_equal nil , seen
178
+ assert_raises(ARSettings::UninitializedSettingError) { Setting.like }
179
+ end
180
+ end
181
+
182
+ verify 'it adds ? methods' do
183
+ Setting.add :ten , :default => 3
184
+ assert_equal TrueClass , Setting.ten?.class
185
+ assert_equal 3 , Setting.ten
186
+ end
187
+
188
+ verify 'it raises error if accessing uninitialized boolean' do
189
+ Setting.add :cent
190
+ assert_raises(ARSettings::UninitializedSettingError) { Setting.cent? }
191
+ end
192
+
193
+ verify 'resetting removes teh boolean getter' do
194
+ Setting.add :blues
195
+ Setting.blues = 5
196
+ assert_equal true , Setting.blues?
197
+ Setting.reset_all
198
+ assert_raises(ARSettings::NoSuchSettingError) { Setting.blues? }
199
+ end
200
+
201
+ end
202
+
203
+
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arsettings
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 17
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
- - 0
8
8
  - 1
9
- version: 1.0.1
9
+ - 1
10
+ version: 1.1.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Joshua Cheek
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-11-07 01:00:00 -05:00
18
+ date: 2010-11-16 00:00:00 -06:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -25,28 +26,46 @@ dependencies:
25
26
  requirements:
26
27
  - - ">="
27
28
  - !ruby/object:Gem::Version
29
+ hash: 5
28
30
  segments:
29
31
  - 2
30
32
  - 3
31
- - 8
32
- version: 2.3.8
33
+ - 3
34
+ version: 2.3.3
33
35
  type: :runtime
34
36
  version_requirements: *id001
35
37
  - !ruby/object:Gem::Dependency
36
- name: sqlite-ruby
38
+ name: rake
37
39
  prerelease: false
38
40
  requirement: &id002 !ruby/object:Gem::Requirement
39
41
  none: false
40
42
  requirements:
41
- - - ">="
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 49
46
+ segments:
47
+ - 0
48
+ - 8
49
+ - 7
50
+ version: 0.8.7
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: sqlite3-ruby
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
42
60
  - !ruby/object:Gem::Version
61
+ hash: 25
43
62
  segments:
44
63
  - 1
45
64
  - 3
46
65
  - 1
47
66
  version: 1.3.1
48
67
  type: :development
49
- version_requirements: *id002
68
+ version_requirements: *id003
50
69
  description: ActiveRecord has a lot of support for tables of similar values. But what about those one time only values, like site settings? This is what ARSettings is intended for. One line to add settings to your ActiveRecord classes. Two to non-ActiveRecord classes. And you can have settings that are not defined on any class as well.
51
70
  email: josh.cheek@gmail.com
52
71
  executables: []
@@ -58,11 +77,30 @@ extra_rdoc_files:
58
77
  files:
59
78
  - Rakefile
60
79
  - Readme.mdown
61
- - lib/arsettings/activerecord.rb
80
+ - examples/generic_settings.rb
81
+ - examples/helper.rb
82
+ - examples/namespaced.rb
83
+ - examples/on_activerecord_class.rb
84
+ - examples/on_any_class.rb
85
+ - test/_helper.rb
86
+ - test/_in_memory_db.rb
87
+ - test/_make_gemsets.sh
88
+ - test/_rcov.sh
89
+ - test/_reek.sh
90
+ - test/_run_all.sh
91
+ - test/_run_one.rb
92
+ - test/activerecord_integration_test.rb
93
+ - test/arbitrary_class_test.rb
94
+ - test/packaged_test.rb
95
+ - test/reset_test.rb
96
+ - test/setting_choose_name_test.rb
97
+ - test/setting_initialize_test.rb
98
+ - test/setting_test.rb
62
99
  - lib/arsettings/arsettings.rb
100
+ - lib/arsettings/has_settings.rb
63
101
  - lib/arsettings/packaged.rb
64
- - lib/arsettings/settings_class_methods.rb
65
- - lib/arsettings/settings_instance_methods.rb
102
+ - lib/arsettings/settings_class/class_methods.rb
103
+ - lib/arsettings/settings_class/instance_methods.rb
66
104
  - lib/arsettings.rb
67
105
  has_rdoc: true
68
106
  homepage: https://github.com/JoshCheek/ARSettings
@@ -79,6 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
117
  requirements:
80
118
  - - ">="
81
119
  - !ruby/object:Gem::Version
120
+ hash: 3
82
121
  segments:
83
122
  - 0
84
123
  version: "0"
@@ -87,6 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
126
  requirements:
88
127
  - - ">="
89
128
  - !ruby/object:Gem::Version
129
+ hash: 3
90
130
  segments:
91
131
  - 0
92
132
  version: "0"
@@ -1,23 +0,0 @@
1
- class ActiveRecord::Base
2
-
3
- def self.has_setting( name , options=Hash.new , &block)
4
- raise NoDefaultPackageError.new("No default settings class is set (make sure you have already invoked create_settings_class)") unless ARSettings.default_class
5
- ARSettings.validate_options options , :default , :volatile , :instance
6
- package = ARSettings.default_class.package(self)
7
- getter = name
8
- setter = "#{name}="
9
- boolean_getter = "#{name}?"
10
- (class << self ; self ; end).instance_eval do
11
- define_method getter do package.send getter end
12
- define_method boolean_getter do package.send boolean_getter end
13
- define_method setter do |arg| package.send setter , arg end
14
- end
15
- if options.delete :instance
16
- define_method getter do package.send getter end
17
- define_method boolean_getter do package.send boolean_getter end
18
- define_method setter do |arg| package.send setter , arg end
19
- end
20
- package.add name , options , &block
21
- end
22
-
23
- end
@@ -1,53 +0,0 @@
1
- module ARSettings
2
- module SettingsClass_ClassMethods
3
-
4
- def reset_all # :nodoc:
5
- Packaged.instances(self).each { |name,package| package.reset }
6
- end
7
-
8
- # get a Package (aka namespace or scope or group)
9
- # to package settings together with
10
- #
11
- # email_settings = Settings.package :email
12
- #
13
- # email_settings.add :enabled , :default => false
14
- #
15
- # ProfileSettings = Settings.package :profile_settings
16
- #
17
- # ProfileSettings.add :enabled , :default => true
18
- def package(name)
19
- Packaged.instance self , name
20
- end
21
-
22
- # add a setting to the settings class, it will be packaged under the settings class itself
23
- #
24
- #--
25
- # FIXME: Document the options and proc
26
- def add( name , options={} , &proc )
27
- options = name if name.is_a? Hash
28
- if options[:package]
29
- package options.delete(:package)
30
- else
31
- package self
32
- end.add( name , options , &proc )
33
- end
34
-
35
- private
36
-
37
- def method_missing(name,*args) # :nodoc:
38
- if name =~ /\A[A-Z]/
39
- const_get name , *args
40
- elsif name.to_s !~ /=$/ || ( name.to_s =~ /=$/ && args.size == 1 )
41
- package(self).send name , *args
42
- else
43
- super
44
- end
45
- end
46
-
47
- def load_from_db # :nodoc:
48
- reset_all
49
- all.each { |instance| add :record => instance , :package => instance.package }
50
- end
51
-
52
- end
53
- end
@@ -1,45 +0,0 @@
1
- module ARSettings
2
-
3
- module SettingsClass_InstanceMethods # :nodoc: all
4
-
5
- # unfortunately, can't serialize a proc. I tried both yaml and marshal
6
- # so will have to keep it in memory and just be sure to set it each time app loads
7
- attr_accessor :postprocessing
8
-
9
-
10
- def value=(new_value)
11
- @deserialized_value = new_value
12
- @value_is_deserialized = true
13
- super ARSettings.serialize(new_value)
14
- save
15
- end
16
-
17
- def value
18
- if @value_is_deserialized && !volatile?
19
- @deserialized_value
20
- else
21
- raise UninitializedSettingError.new("#{package}##{name} has not been initialized.") unless super
22
- reload
23
- @value_is_deserialized = true
24
- @deserialized_value = ARSettings.deserialize(super)
25
- @deserialized_value
26
- end
27
- end
28
-
29
- def volatile=(value)
30
- super
31
- save
32
- end
33
-
34
- def package
35
- @package ||= super.to_sym
36
- end
37
-
38
- def package=(pkg)
39
- super pkg.to_s
40
- end
41
-
42
- end
43
-
44
- end
45
-