preferences 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,10 @@
1
1
  == master
2
2
 
3
+ == 0.4.1 / 2010-03-07
4
+
5
+ * Add support for per-group default preferences
6
+ * Fix unsaved boolean preferences getting overridden by defaults if value is false
7
+
3
8
  == 0.4.0 / 2010-03-07
4
9
 
5
10
  * Add {preference}_changed?, {preference}_was, {preference}_changed, {preference}_will_change!, and reset_{preference}!
data/README.rdoc CHANGED
@@ -60,7 +60,7 @@ To define the preferences for a model, you can do so right within the model:
60
60
  preference :dark_chocolate, :default => true
61
61
  preference :color, :string
62
62
  preference :favorite_number
63
- preference :language, :string, :default => 'English'
63
+ preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Spanish'}
64
64
  end
65
65
 
66
66
  In the above model, 5 preferences have been defined:
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
6
6
 
7
7
  spec = Gem::Specification.new do |s|
8
8
  s.name = 'preferences'
9
- s.version = '0.4.0'
9
+ s.version = '0.4.1'
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.summary = 'Adds support for easily creating custom preferences for ActiveRecord models'
12
12
  s.description = s.summary
data/lib/preferences.rb CHANGED
@@ -51,6 +51,9 @@ module Preferences
51
51
  #
52
52
  # Configuration options:
53
53
  # * <tt>:default</tt> - The default value for the preference. Default is nil.
54
+ # * <tt>:group_defaults</tt> - Defines the default values to use for various
55
+ # groups. This should map group_name -> defaults. For ActiveRecord groups,
56
+ # use the class name.
54
57
  #
55
58
  # == Examples
56
59
  #
@@ -59,7 +62,7 @@ module Preferences
59
62
  #
60
63
  # class User < ActiveRecord::Base
61
64
  # preference :notifications, :default => false
62
- # preference :color, :string, :default => 'red'
65
+ # preference :color, :string, :default => 'red', :group_defaults => {:car => 'black'}
63
66
  # preference :favorite_number, :integer
64
67
  # preference :data, :any # Allows any data type to be stored
65
68
  # end
@@ -152,9 +155,6 @@ module Preferences
152
155
  class_inheritable_hash :preference_definitions
153
156
  self.preference_definitions = {}
154
157
 
155
- class_inheritable_hash :default_preferences
156
- self.default_preferences = {}
157
-
158
158
  has_many :stored_preferences, :as => :owner, :class_name => 'Preference'
159
159
 
160
160
  after_save :update_preferences
@@ -171,7 +171,6 @@ module Preferences
171
171
  name = name.to_s
172
172
  definition = PreferenceDefinition.new(name, *args)
173
173
  self.preference_definitions[name] = definition
174
- self.default_preferences[name] = definition.default_value
175
174
 
176
175
  # Create short-hand accessor methods, making sure that the name
177
176
  # is method-safe in terms of what characters are allowed
@@ -249,11 +248,12 @@ module Preferences
249
248
  end
250
249
 
251
250
  preferences.each do |(group, preference), value|
251
+ group_id, group_type = Preference.split_group(group)
252
252
  preference = preference.to_s
253
- value = preference_definitions[preference.to_s].type_cast(value)
254
- is_default = default_preferences[preference.to_s] == value
253
+ definition = preference_definitions[preference.to_s]
254
+ value = definition.type_cast(value)
255
+ is_default = definition.default_value(group_type) == value
255
256
 
256
- group_id, group_type = Preference.split_group(group)
257
257
  table = "preferences_#{group_id}_#{group_type}_#{preference}"
258
258
 
259
259
  # Since each preference is a different record, they need their own
@@ -303,19 +303,21 @@ module Preferences
303
303
  # user.preferences(:cars)
304
304
  # => {"language=>"English", "color"=>"red"}
305
305
  def preferences(group = nil)
306
+ preferences = preferences_group(group)
307
+
306
308
  unless preferences_group_loaded?(group)
307
- preferences = preferences_group(group)
308
-
309
309
  group_id, group_type = Preference.split_group(group)
310
310
  find_preferences(:group_id => group_id, :group_type => group_type).each do |preference|
311
- preferences[preference.name] ||= preference.value
311
+ preferences[preference.name] = preference.value unless preferences.include?(preference.name)
312
312
  end
313
313
 
314
314
  # Add defaults
315
- preferences.reverse_merge!(self.class.default_preferences.dup)
315
+ preference_definitions.each do |name, definition|
316
+ preferences[name] = definition.default_value(group_type) unless preferences.include?(name)
317
+ end
316
318
  end
317
319
 
318
- preferences_group(group).dup
320
+ preferences.dup
319
321
  end
320
322
 
321
323
  # Queries whether or not a value is present for the given preference.
@@ -374,7 +376,7 @@ module Preferences
374
376
  group_id, group_type = Preference.split_group(group)
375
377
  preference = find_preferences(:name => name, :group_id => group_id, :group_type => group_type).first unless preferences_group_loaded?(group)
376
378
 
377
- value = preference ? preference.value : preference_definitions[name].default_value
379
+ value = preference ? preference.value : preference_definitions[name].default_value(group_type)
378
380
  preferences_group(group)[name] = value
379
381
  end
380
382
 
@@ -6,12 +6,17 @@ module Preferences
6
6
 
7
7
  def initialize(name, *args) #:nodoc:
8
8
  options = args.extract_options!
9
- options.assert_valid_keys(:default)
9
+ options.assert_valid_keys(:default, :group_defaults)
10
10
 
11
11
  @type = args.first ? args.first.to_sym : :boolean
12
12
 
13
13
  # Create a column that will be responsible for typecasting
14
14
  @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s)
15
+
16
+ @group_defaults = (options[:group_defaults] || {}).inject({}) do |defaults, (group, default)|
17
+ defaults[group.is_a?(Symbol) ? group.to_s : group] = type_cast(default)
18
+ defaults
19
+ end
15
20
  end
16
21
 
17
22
  # The name of the preference
@@ -21,8 +26,8 @@ module Preferences
21
26
 
22
27
  # The default value to use for the preference in case none have been
23
28
  # previously defined
24
- def default_value
25
- @column.default
29
+ def default_value(group = nil)
30
+ @group_defaults.include?(group) ? @group_defaults[group] : @column.default
26
31
  end
27
32
 
28
33
  # Determines whether column backing this preference stores numberic values
@@ -6,7 +6,6 @@ class ModelPreferenceTest < ActiveRecord::TestCase
6
6
 
7
7
  def teardown
8
8
  User.preference_definitions.clear
9
- User.default_preferences.clear
10
9
  end
11
10
  end
12
11
 
@@ -15,10 +14,6 @@ class ModelWithoutPreferencesTest < ActiveRecord::TestCase
15
14
  assert !Car.respond_to?(:preference_definitions)
16
15
  end
17
16
 
18
- def test_should_not_create_default_preferences
19
- assert !Car.respond_to?(:default_preferences)
20
- end
21
-
22
17
  def test_should_not_create_stored_preferences_association
23
18
  assert !Car.new.respond_to?(:stored_preferences)
24
19
  end
@@ -39,10 +34,6 @@ class PreferencesAfterFirstBeingDefinedTest < ModelPreferenceTest
39
34
  assert User.respond_to?(:preference_definitions)
40
35
  end
41
36
 
42
- def test_should_create_default_preferences
43
- assert User.respond_to?(:default_preferences)
44
- end
45
-
46
37
  def test_should_create_preference_scopes
47
38
  assert User.respond_to?(:with_preferences)
48
39
  assert User.respond_to?(:without_preferences)
@@ -136,10 +127,6 @@ class PreferencesAfterBeingDefinedTest < ModelPreferenceTest
136
127
  def test_should_include_new_definitions_in_preference_definitions
137
128
  assert_equal e = {'notifications' => @definition}, User.preference_definitions
138
129
  end
139
-
140
- def test_should_include_default_value_in_default_preferences
141
- assert_equal e = {'notifications' => nil}, User.default_preferences
142
- end
143
130
  end
144
131
 
145
132
  class PreferencesByDefaultTest < ModelPreferenceTest
@@ -156,10 +143,6 @@ class PreferencesByDefaultTest < ModelPreferenceTest
156
143
  assert_nil @definition.default_value
157
144
  end
158
145
 
159
- def test_should_include_in_default_preferences
160
- assert_equal e = {'notifications' => nil}, User.default_preferences
161
- end
162
-
163
146
  def test_should_only_have_default_preferences
164
147
  assert_equal e = {'notifications' => nil}, @user.preferences
165
148
  end
@@ -203,10 +186,6 @@ class PreferencesWithCustomTypeTest < ModelPreferenceTest
203
186
  assert_nil @definition.default_value
204
187
  end
205
188
 
206
- def test_should_include_in_default_preferences
207
- assert_equal e = {'vehicle_id' => nil}, User.default_preferences
208
- end
209
-
210
189
  def test_should_only_have_default_preferences
211
190
  assert_equal e = {'vehicle_id' => nil}, @user.preferences
212
191
  end
@@ -226,10 +205,6 @@ class PreferencesWithCustomDefaultTest < ModelPreferenceTest
226
205
  assert_equal 'red', @definition.default_value
227
206
  end
228
207
 
229
- def test_should_include_in_default_preferences
230
- assert_equal e = {'color' => 'red'}, User.default_preferences
231
- end
232
-
233
208
  def test_should_only_have_default_preferences
234
209
  assert_equal e = {'color' => 'red'}, @user.preferences
235
210
  end
@@ -242,10 +217,6 @@ class PreferencesWithMultipleDefinitionsTest < ModelPreferenceTest
242
217
  @user = new_user
243
218
  end
244
219
 
245
- def test_should_include_all_in_default_preferences
246
- assert_equal e = {'notifications' => true, 'color' => 'red'}, User.default_preferences
247
- end
248
-
249
220
  def test_should_only_have_default_preferences
250
221
  assert_equal e = {'notifications' => true, 'color' => 'red'}, @user.preferences
251
222
  end
@@ -277,6 +248,11 @@ class PreferencesReaderTest < ModelPreferenceTest
277
248
  assert_equal true, @user.preferred(:notifications)
278
249
  end
279
250
 
251
+ def test_should_use_group_default_value_if_not_stored
252
+ User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
253
+ assert_equal 'English', @user.preferred(:language)
254
+ end
255
+
280
256
  def test_should_use_stored_value_if_stored
281
257
  create_preference(:owner => @user, :name => 'notifications', :value => false)
282
258
  assert_equal false, @user.preferred(:notifications)
@@ -320,10 +296,15 @@ class PreferencesGroupReaderTest < ModelPreferenceTest
320
296
  @user = create_user
321
297
  end
322
298
 
323
- def test_use_default_value_if_not_stored
299
+ def test_should_use_default_value_if_not_stored
324
300
  assert_equal true, @user.preferred(:notifications, :chat)
325
301
  end
326
302
 
303
+ def test_should_use_group_default_value_if_not_stored
304
+ User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
305
+ assert_equal 'Latin', @user.preferred(:language, :chat)
306
+ end
307
+
327
308
  def test_should_use_stored_value_if_stored
328
309
  create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
329
310
  assert_equal false, @user.preferred(:notifications, :chat)
@@ -956,7 +937,7 @@ end
956
937
  class PreferencesLookupTest < ModelPreferenceTest
957
938
  def setup
958
939
  User.preference :notifications, :boolean, :default => true
959
- User.preference :language, :string, :default => 'English'
940
+ User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
960
941
 
961
942
  @user = create_user
962
943
  end
@@ -982,9 +963,9 @@ class PreferencesLookupTest < ModelPreferenceTest
982
963
  end
983
964
 
984
965
  def test_should_use_unsaved_changes_over_stored_preferences
985
- create_preference(:owner => @user, :name => 'notifications', :value => false)
986
- @user.write_preference(:notifications, true)
987
- assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences
966
+ create_preference(:owner => @user, :name => 'notifications', :value => true)
967
+ @user.write_preference(:notifications, false)
968
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences
988
969
  end
989
970
 
990
971
  def test_should_cache_results
@@ -1013,29 +994,29 @@ end
1013
994
  class PreferencesGroupLookupTest < ModelPreferenceTest
1014
995
  def setup
1015
996
  User.preference :notifications, :boolean, :default => true
1016
- User.preference :language, :string, :default => 'English'
997
+ User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'}
1017
998
 
1018
999
  @user = create_user
1019
1000
  end
1020
1001
 
1021
1002
  def test_should_only_have_defaults_if_nothing_customized
1022
- assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(:chat)
1003
+ assert_equal e = {'notifications' => true, 'language' => 'Latin'}, @user.preferences(:chat)
1023
1004
  end
1024
1005
 
1025
1006
  def test_should_merge_defaults_with_unsaved_changes
1026
1007
  @user.write_preference(:notifications, false, :chat)
1027
- assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(:chat)
1008
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
1028
1009
  end
1029
1010
 
1030
1011
  def test_should_merge_defaults_with_saved_changes
1031
1012
  create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
1032
- assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(:chat)
1013
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
1033
1014
  end
1034
1015
 
1035
1016
  def test_should_merge_stored_preferences_with_unsaved_changes
1036
1017
  create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
1037
- @user.write_preference(:language, 'Latin', :chat)
1038
- assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
1018
+ @user.write_preference(:language, 'Spanish', :chat)
1019
+ assert_equal e = {'notifications' => false, 'language' => 'Spanish'}, @user.preferences(:chat)
1039
1020
  end
1040
1021
 
1041
1022
  def test_should_cache_results
@@ -1252,6 +1233,14 @@ class PreferencesWithScopeTest < ModelPreferenceTest
1252
1233
  assert_equal [@user], User.with_preferences(:chat => {:language => 'English'})
1253
1234
  end
1254
1235
 
1236
+ def test_should_find_with_customized_default_group_preference
1237
+ User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'}
1238
+ @customized_user.preferred_country = 'US', :chat
1239
+ @customized_user.save!
1240
+
1241
+ assert_equal [@user], User.with_preferences(:chat => {:country => 'UK'})
1242
+ end
1243
+
1255
1244
  def test_should_find_with_multiple_default_group_preferences
1256
1245
  assert_equal [@user], User.with_preferences(:chat => {:notifications => nil, :language => 'English'})
1257
1246
  end
@@ -1328,6 +1317,14 @@ class PreferencesWithoutScopeTest < ModelPreferenceTest
1328
1317
  assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin'})
1329
1318
  end
1330
1319
 
1320
+ def test_should_find_with_customized_default_group_preference
1321
+ User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'}
1322
+ @customized_user.preferred_country = 'US', :chat
1323
+ @customized_user.save!
1324
+
1325
+ assert_equal [@user], User.without_preferences(:chat => {:country => 'US'})
1326
+ end
1327
+
1331
1328
  def test_should_find_with_multiple_default_group_preferences
1332
1329
  assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin', :notifications => false})
1333
1330
  end
@@ -42,6 +42,24 @@ class PreferenceDefinitionWithDefaultValueTest < ActiveSupport::TestCase
42
42
  end
43
43
  end
44
44
 
45
+ class PreferenceDefinitionWithGroupDefaultsTest < ActiveSupport::TestCase
46
+ def setup
47
+ @definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, :default => 1, :group_defaults => {:chat => 0})
48
+ end
49
+
50
+ def test_should_use_default_for_default_group
51
+ assert_equal true, @definition.default_value
52
+ end
53
+
54
+ def test_should_use_default_for_unknown_group
55
+ assert_equal true, @definition.default_value('email')
56
+ end
57
+
58
+ def test_should_use_group_default_for_known_group
59
+ assert_equal false, @definition.default_value('chat')
60
+ end
61
+ end
62
+
45
63
  class PreferenceDefinitionWithStringifiedTypeTest < ActiveSupport::TestCase
46
64
  def setup
47
65
  @definition = Preferences::PreferenceDefinition.new(:notifications, 'any')
@@ -157,7 +157,6 @@ class PreferenceAfterBeingCreatedTest < ActiveSupport::TestCase
157
157
 
158
158
  def teardown
159
159
  User.preference_definitions.delete('notifications')
160
- User.default_preferences.delete('notifications')
161
160
  end
162
161
  end
163
162
 
@@ -210,7 +209,6 @@ class PreferenceWithBooleanTypeTest < ActiveSupport::TestCase
210
209
 
211
210
  def teardown
212
211
  User.preference_definitions.delete('notifications')
213
- User.default_preferences.delete('notifications')
214
212
  end
215
213
  end
216
214
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: preferences
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Pfeifer