From ca85268d7220f0a9790c1e1bdbebc0291bbc549d Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Thu, 13 Jul 2017 19:12:48 +0000 Subject: [PATCH] Update with PRs #1, #2, and #12, plus rubocopisms --- .rubocop.yml | 29 + .rubocop_todo.yml | 74 ++ Gemfile | 4 +- README.rdoc | 39 +- Rakefile | 8 +- app/models/preference.rb | 43 +- generators/preferences/USAGE | 2 +- .../preferences/preferences_generator.rb | 7 - .../templates/001_create_preferences.rb | 14 +- init.rb | 1 - lib/generators/preferences_generator.rb | 17 + lib/preferences.rb | 494 +++++----- lib/preferences/engine.rb | 4 + lib/preferences/preference_definition.rb | 25 +- lib/preferences/version.rb | 2 +- preferences.gemspec | 23 +- test/app_root/app/models/user.rb | 12 +- test/app_root/db/migrate/001_create_users.rb | 4 +- test/app_root/db/migrate/002_create_cars.rb | 4 +- .../db/migrate/003_create_employees.rb | 4 +- .../004_migrate_preferences_to_version_1.rb | 2 +- test/factory.rb | 36 +- test/functional/preferences_test.rb | 845 +++++++++--------- test/test_helper.rb | 8 +- test/unit/preference_definition_test.rb | 92 +- test/unit/preference_test.rb | 120 +-- 26 files changed, 1038 insertions(+), 875 deletions(-) create mode 100644 .rubocop.yml create mode 100644 .rubocop_todo.yml delete mode 100644 generators/preferences/preferences_generator.rb create mode 100644 lib/generators/preferences_generator.rb create mode 100644 lib/preferences/engine.rb diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..f4e0375 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,29 @@ +inherit_from: .rubocop_todo.yml + +# Offense count: 7 +Metrics/AbcSize: + Max: 54 + +# Offense count: 1 +Metrics/CyclomaticComplexity: + Max: 8 + +# Offense count: 134 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https +Metrics/LineLength: + Max: 221 + +# Offense count: 7 +# Configuration parameters: CountComments. +Metrics/MethodLength: + Max: 48 + +# Offense count: 1 +# Configuration parameters: CountComments. +Metrics/ModuleLength: + Max: 143 + +# Offense count: 1 +Metrics/PerceivedComplexity: + Max: 10 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..29117fa --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,74 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2017-07-13 19:06:38 +0000 using RuboCop version 0.48.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 2 +Lint/AmbiguousBlockAssociation: + Exclude: + - 'lib/preferences.rb' + +# Offense count: 2 +Lint/DuplicateMethods: + Exclude: + - 'test/functional/preferences_test.rb' + +# Offense count: 1 +Lint/HandleExceptions: + Exclude: + - 'Rakefile' + +# Offense count: 2 +Lint/ShadowingOuterLocalVariable: + Exclude: + - 'lib/preferences.rb' + +# Offense count: 39 +Lint/UselessAssignment: + Exclude: + - 'test/functional/preferences_test.rb' + +# Offense count: 4 +Style/Documentation: + Exclude: + - 'spec/**/*' + - 'test/**/*' + - 'generators/preferences/templates/001_create_preferences.rb' + - 'lib/generators/preferences_generator.rb' + - 'lib/preferences.rb' + +# Offense count: 1 +Style/DoubleNegation: + Exclude: + - 'lib/preferences/preference_definition.rb' + +# Offense count: 1 +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: format, sprintf, percent +Style/FormatString: + Exclude: + - 'lib/generators/preferences_generator.rb' + +# Offense count: 2 +# Configuration parameters: AllowedVariables. +Style/GlobalVars: + Exclude: + - 'test/test_helper.rb' + +# Offense count: 1 +# Configuration parameters: MinBodyLength. +Style/GuardClause: + Exclude: + - 'lib/preferences.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles. +# SupportedStyles: predicate, comparison +Style/NumericPredicate: + Exclude: + - 'spec/**/*' + - 'lib/preferences.rb' diff --git a/Gemfile b/Gemfile index efec0db..2867be8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ -source "http://www.rubygems.org" - +source 'http://www.rubygems.org' + gemspec diff --git a/README.rdoc b/README.rdoc index 31c03ce..53bb3aa 100644 --- a/README.rdoc +++ b/README.rdoc @@ -123,6 +123,37 @@ Write method: user.write_preference(:hot_salsa, false) # => false user.write_preference(:language, "English") # => "English" +=== Accessible preferences + +If you want a preference to be accessible via the +attributes+ method on the +model, use the +accessible_preference+ method: + + class User < ActiveRecord::Base + accessible_preference :hot_salsa + accessible_preference :two_percent_milk + end + +Now, you can easily update all the preferences at once from your controllers: + +In the view: + + - form_for @user do |f| + = f.check_box :prefers_hot_salsa + = f.check_box :prefers_two_percent_milk + +In the controller: + + UsersController < ApplicationController + def update + @user = User.find(params[:id]) + @user.attributes = params[:user] + + flash.notice = 'Saved preferences' if @user.save + + render 'edit' + end + end + === Accessing all preferences To get the collection of all custom, stored preferences for a particular record, @@ -152,7 +183,7 @@ through an example: user = User.find(:first) car = Car.find(:first) - + user.preferred_color = 'red', car # user.write_preference(:color, 'red', car) # The generic way @@ -169,13 +200,13 @@ In addition to grouping preferences for a particular record, you can also group preferences by name. For example, user = User.find(:first) - + user.preferred_color = 'red', :automobiles user.preferred_color = 'tan', :clothing - + user.preferred_color(:automobiles) # => "red" user.preferred_color(:clothing) # => "tan" - + user.preferences(:automobiles) # => {"color"=>"red"} === Saving preferences diff --git a/Rakefile b/Rakefile index ea42bba..7780b4b 100644 --- a/Rakefile +++ b/Rakefile @@ -4,9 +4,9 @@ require 'rake/testtask' require 'rake/rdoctask' desc 'Default: run all tests.' -task :default => :test +task default: :test -desc "Test preferences." +desc 'Test preferences.' Rake::TestTask.new(:test) do |t| t.libs << 'lib' t.test_files = Dir['test/**/*_test.rb'] @@ -16,7 +16,7 @@ end begin require 'rcov/rcovtask' namespace :test do - desc "Test preferences with Rcov." + desc 'Test preferences with Rcov.' Rcov::RcovTask.new(:rcov) do |t| t.libs << 'lib' t.test_files = Dir['test/**/*_test.rb'] @@ -27,7 +27,7 @@ begin rescue LoadError end -desc "Generate documentation for preferences." +desc 'Generate documentation for preferences.' Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'preferences' diff --git a/app/models/preference.rb b/app/models/preference.rb index 8538721..3e5c0f3 100644 --- a/app/models/preference.rb +++ b/app/models/preference.rb @@ -1,41 +1,43 @@ # Represents a preferred value for a particular preference on a model. -# +# # == Grouped preferences -# +# # In addition to simple named preferences, preferences can also be grouped by # a particular value, be it a string or ActiveRecord object. For example, a # User may have a preferred color for a particular Car. In this case, the # +owner+ is the User record, the +name+ is "color", and the +group+ is the # Car record. This allows preferences to have a sort of context around them. class Preference < ActiveRecord::Base - belongs_to :owner, :polymorphic => true - belongs_to :group, :polymorphic => true - + belongs_to :owner, polymorphic: true + belongs_to :group, polymorphic: true + validates_presence_of :name, :owner_id, :owner_type - validates_presence_of :group_type, :if => :group_id? - + validates_presence_of :group_type, if: :group_id? + class << self # Splits the given group into its corresponding id and type. For simple # primitives, the id will be nil. For complex types, specifically # ActiveRecord objects, the id is the unique identifier stored in the # database for the record. - # + # # For example, - # + # # Preference.split_group('google') # => [nil, "google"] # Preference.split_group(1) # => [nil, 1] # Preference.split_group(User.find(1)) # => [1, "User"] def split_group(group = nil) if group.is_a?(ActiveRecord::Base) - group_id, group_type = group.id, group.class.base_class.name.to_s + group_id = group.id + group_type = group.class.base_class.name.to_s else - group_id, group_type = nil, group.is_a?(Symbol) ? group.to_s : group + group_id = nil + group_type = group.is_a?(Symbol) ? group.to_s : group end - + [group_id, group_type] end end - + # The definition of the preference as defined in the owner's model def definition # Optimize number of queries to the database by only looking up the actual @@ -43,23 +45,24 @@ def definition # stored owner type class owner_type && (find_definition(owner_type.constantize) || find_definition(owner.class)) end - + # Typecasts the value depending on the preference definition's declared type def value value = read_attribute(:value) value = definition.type_cast(value) if definition value end - + # Only searches for the group record if the group id is specified def group_with_optional_lookup group_id ? group_without_optional_lookup : group_type end alias_method_chain :group, :optional_lookup - + private - # Finds the definition for this preference in the given owner class. - def find_definition(owner_class) - owner_class.respond_to?(:preference_definitions) && owner_class.preference_definitions[name] - end + + # Finds the definition for this preference in the given owner class. + def find_definition(owner_class) + owner_class.respond_to?(:preference_definitions) && owner_class.preference_definitions[name] + end end diff --git a/generators/preferences/USAGE b/generators/preferences/USAGE index 3b403b3..be44596 100644 --- a/generators/preferences/USAGE +++ b/generators/preferences/USAGE @@ -1,5 +1,5 @@ Usage: - script/generate preferences + rails generate preferences This will create a migration that will add the proper table to store preferences. diff --git a/generators/preferences/preferences_generator.rb b/generators/preferences/preferences_generator.rb deleted file mode 100644 index 6a7f3bf..0000000 --- a/generators/preferences/preferences_generator.rb +++ /dev/null @@ -1,7 +0,0 @@ -class PreferencesGenerator < Rails::Generator::Base - def manifest - record do |m| - m.migration_template '001_create_preferences.rb', 'db/migrate', :migration_file_name => 'create_preferences' - end - end -end diff --git a/generators/preferences/templates/001_create_preferences.rb b/generators/preferences/templates/001_create_preferences.rb index a26adfc..4f048de 100644 --- a/generators/preferences/templates/001_create_preferences.rb +++ b/generators/preferences/templates/001_create_preferences.rb @@ -1,16 +1,12 @@ class CreatePreferences < ActiveRecord::Migration - def self.up + def change create_table :preferences do |t| - t.string :name, :null => false - t.references :owner, :polymorphic => true, :null => false - t.references :group, :polymorphic => true + t.string :name, null: false + t.references :owner, polymorphic: true, null: false + t.references :group, polymorphic: true t.string :value t.timestamps end - add_index :preferences, [:owner_id, :owner_type, :name, :group_id, :group_type], :unique => true, :name => 'index_preferences_on_owner_and_name_and_preference' - end - - def self.down - drop_table :preferences + add_index :preferences, %i[owner_id owner_type name group_id group_type], unique: true, name: 'index_preferences_on_owner_and_name_and_preference' end end diff --git a/init.rb b/init.rb index 98f262e..e69de29 100644 --- a/init.rb +++ b/init.rb @@ -1 +0,0 @@ -require 'preferences' diff --git a/lib/generators/preferences_generator.rb b/lib/generators/preferences_generator.rb new file mode 100644 index 0000000..038a4e2 --- /dev/null +++ b/lib/generators/preferences_generator.rb @@ -0,0 +1,17 @@ +class PreferencesGenerator < Rails::Generators::Base + include Rails::Generators::Migration + + source_root File.expand_path('../templates', __FILE__) + + def self.next_migration_number(dirname) + if ActiveRecord::Base.timestamped_migrations + Time.now.utc.strftime('%Y%m%d%H%M%S') + else + '%.3d' % (current_migration_number(dirname) + 1) + end + end + + def create_migration_file + migration_template 'create_preferences.rb', 'db/migrate/create_preferences.rb' + end +end diff --git a/lib/preferences.rb b/lib/preferences.rb index 23ae075..2762395 100644 --- a/lib/preferences.rb +++ b/lib/preferences.rb @@ -1,46 +1,48 @@ +require 'preferences/engine' require 'preferences/preference_definition' +require 'app/models/preference' # Adds support for defining preferences on ActiveRecord models. -# +# # == Saving preferences -# +# # Preferences are not automatically saved when they are set. You must save # the record that the preferences were set on. -# +# # For example, -# +# # class User < ActiveRecord::Base # preference :notifications # end -# +# # u = User.new(:login => 'admin', :prefers_notifications => false) # u.save! -# +# # u = User.find_by_login('admin') # u.attributes = {:prefers_notifications => true} # u.save! -# +# # == Validations -# +# # Since the generated accessors for a preference allow the preference to be # treated just like regular ActiveRecord attributes, they can also be # validated against in the same way. For example, -# +# # class User < ActiveRecord::Base # preference :color, :string -# +# # validates_presence_of :preferred_color # validates_inclusion_of :preferred_color, :in => %w(red green blue) # end -# +# # u = User.new # u.valid? # => false # u.errors.on(:preferred_color) # => "can't be blank" -# +# # u.preferred_color = 'white' # u.valid? # => false # u.errors.on(:preferred_color) # => "is not included in the list" -# +# # u.preferred_color = 'red' # u.valid? # => true module Preferences @@ -48,66 +50,66 @@ module MacroMethods # Defines a new preference for all records in the model. By default, # preferences are assumed to have a boolean data type, so all values will # be typecasted to true/false based on ActiveRecord rules. - # + # # Configuration options: # * :default - The default value for the preference. Default is nil. # * :group_defaults - Defines the default values to use for various # groups. This should map group_name -> defaults. For ActiveRecord groups, - # use the class name. - # + # use the class name. + # # == Examples - # + # # The example below shows the various ways to define a preference for a # particular model. - # + # # class User < ActiveRecord::Base # preference :notifications, :default => false # preference :color, :string, :default => 'red', :group_defaults => {:car => 'black'} # preference :favorite_number, :integer # preference :data, :any # Allows any data type to be stored # end - # + # # All preferences are also inherited by subclasses. - # + # # == Associations - # + # # After the first preference is defined, the following associations are # created for the model: # * +stored_preferences+ - A collection of all the custom preferences # specified for a record. This will not include default preferences # unless they have been explicitly set. - # + # # == Named scopes - # + # # In addition to the above associations, the following named scopes get # generated for the model: # * +with_preferences+ - Finds all records with a given set of preferences # * +without_preferences+ - Finds all records without a given set of preferences - # + # # In addition to utilizing preferences stored in the database, each of the # above scopes also take into account the defaults that have been defined # for each preference. - # + # # Example: - # + # # User.with_preferences(:notifications => true) # User.with_preferences(:notifications => true, :color => 'blue') - # + # # # Searching with group preferences # car = Car.find(:first) # User.with_preferences(car => {:color => 'blue'}) # User.with_preferences(:notifications => true, car => {:color => 'blue'}) - # + # # == Generated accessors - # + # # In addition to calling prefers? and +preferred+ on a record, # you can also use the shortcut accessor methods that are generated when a # preference is defined. For example, - # + # # class User < ActiveRecord::Base # preference :notifications # end - # + # # ...generates the following methods: # * prefers_notifications? - Whether a value has been specified, i.e. record.prefers?(:notifications) # * prefers_notifications - The actual value stored, i.e. record.prefers(:notifications) @@ -117,7 +119,7 @@ module MacroMethods # * prefers_notifications_change - A list of [original_value, new_value] if the preference has changed # * prefers_notifications_will_change! - Forces the preference to get updated # * reset_prefers_notifications! - Reverts any unsaved changes to the preference - # + # # ...and the equivalent +preferred+ methods: # * preferred_notifications? # * preferred_notifications @@ -127,107 +129,127 @@ module MacroMethods # * preferred_notifications_change # * preferred_notifications_will_change! # * reset_preferred_notifications! - # + # # Notice that there are two tenses used depending on the context of the # preference. Conventionally, prefers_notifications? is better # for accessing boolean preferences, while +preferred_color+ is better for # accessing non-boolean preferences. - # + # # Example: - # + # # user = User.find(:first) # user.prefers_notifications? # => false # user.prefers_notifications # => false # user.preferred_color? # => true # user.preferred_color # => 'red' # user.preferred_color = 'blue' # => 'blue' - # + # # user.prefers_notifications = true - # + # # car = Car.find(:first) # user.preferred_color = 'red', car # => 'red' # user.preferred_color(car) # => 'red' # user.preferred_color?(car) # => true - # + # # user.save! # => true def preference(name, *args) unless included_modules.include?(InstanceMethods) - class_inheritable_hash :preference_definitions + class_attribute :preference_definitions self.preference_definitions = {} - - has_many :stored_preferences, :as => :owner, :class_name => 'Preference' - + + has_many :stored_preferences, as: :owner, class_name: 'Preference' + after_save :update_preferences - + # Named scopes - named_scope :with_preferences, lambda {|preferences| build_preference_scope(preferences)} - named_scope :without_preferences, lambda {|preferences| build_preference_scope(preferences, true)} - + scope :with_preferences, ->(preferences) { build_preference_scope(preferences) } + scope :without_preferences, ->(preferences) { build_preference_scope(preferences, true) } + extend Preferences::ClassMethods include Preferences::InstanceMethods end - + # Create the definition name = name.to_s definition = PreferenceDefinition.new(name, *args) - self.preference_definitions[name] = definition - + preference_definitions[name] = definition + + attr_accessible :"prefers_#{name}" if definition.accessible? + # Create short-hand accessor methods, making sure that the name # is method-safe in terms of what characters are allowed name = name.gsub(/[^A-Za-z0-9_-]/, '').underscore - + # Query lookup define_method("preferred_#{name}?") do |*group| preferred?(name, group.first) end alias_method "prefers_#{name}?", "preferred_#{name}?" - + # Reader define_method("preferred_#{name}") do |*group| preferred(name, group.first) end alias_method "prefers_#{name}", "preferred_#{name}" - + # Writer define_method("preferred_#{name}=") do |*args| write_preference(*args.flatten.unshift(name)) end alias_method "prefers_#{name}=", "preferred_#{name}=" - + # Changes define_method("preferred_#{name}_changed?") do |*group| preference_changed?(name, group.first) end alias_method "prefers_#{name}_changed?", "preferred_#{name}_changed?" - + define_method("preferred_#{name}_was") do |*group| preference_was(name, group.first) end alias_method "prefers_#{name}_was", "preferred_#{name}_was" - + define_method("preferred_#{name}_change") do |*group| preference_change(name, group.first) end alias_method "prefers_#{name}_change", "preferred_#{name}_change" - + define_method("preferred_#{name}_will_change!") do |*group| preference_will_change!(name, group.first) end alias_method "prefers_#{name}_will_change!", "preferred_#{name}_will_change!" - + define_method("reset_preferred_#{name}!") do |*group| reset_preference!(name, group.first) end alias_method "reset_prefers_#{name}!", "reset_preferred_#{name}!" - + definition end + + # Defines a preference that is accessible via the attributes method. This + # works by calling attr_accessible for the preference. + # + # Example: + # + # class User < ActiveRecord::Base + # accessible_preference :notifications + # end + # + # This will add attr_accessible :prefers_notifications to the + # User model. + # + def accessible_preference(name, *args) + options = args.extract_options!.dup + options[:accessible] = true + preference name, *(args << options) + end end - + module ClassMethods #:nodoc: # Generates the scope for looking under records with a specific set of # preferences associated with them. - # + # # Note thate this is a bit more complicated than usual since the preference # definitions aren't in the database for joins, defaults need to be accounted # for, and querying for the the presence of multiple preferences requires @@ -236,26 +258,25 @@ def build_preference_scope(preferences, inverse = false) joins = [] statements = [] values = [] - + # Flatten the preferences for easier processing - preferences = preferences.inject({}) do |result, (group, value)| + preferences = preferences.each_with_object({}) do |(group, value), result| if value.is_a?(Hash) - value.each {|preference, value| result[[group, preference]] = value} + value.each { |preference, value| result[[group, preference]] = value } else result[[nil, group]] = value end - result end - + preferences.each do |(group, preference), value| group_id, group_type = Preference.split_group(group) preference = preference.to_s definition = preference_definitions[preference.to_s] value = definition.type_cast(value) is_default = definition.default_value(group_type) == value - + table = "preferences_#{group_id}_#{group_type}_#{preference}" - + # Since each preference is a different record, they need their own # join so that the proper conditions can be set joins << "LEFT JOIN preferences AS #{table} ON #{table}.owner_id = #{table_name}.#{primary_key} AND " + sanitize_sql( @@ -264,112 +285,111 @@ def build_preference_scope(preferences, inverse = false) "#{table}.group_type" => group_type, "#{table}.name" => preference ) - - if inverse - statements << "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NOT NULL' : ' != ?') + (!is_default ? " OR #{table}.id IS NULL" : '') - else - statements << "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NULL' : ' = ?') + (is_default ? " OR #{table}.id IS NULL" : '') - end + + statements << if inverse + "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NOT NULL' : ' != ?') + (!is_default ? " OR #{table}.id IS NULL" : '') + else + "#{table}.id IS NOT NULL AND #{table}.value " + (value.nil? ? ' IS NULL' : ' = ?') + (is_default ? " OR #{table}.id IS NULL" : '') + end values << value unless value.nil? end - - sql = statements.map! {|statement| "(#{statement})"} * ' AND ' - {:joins => joins, :conditions => values.unshift(sql)} + + sql = statements.map! { |statement| "(#{statement})" } * ' AND ' + { joins: joins, conditions: values.unshift(sql) } end end - + module InstanceMethods def self.included(base) #:nodoc: base.class_eval do alias_method :prefs, :preferences end end - + # Finds all preferences, including defaults, for the current record. If # looking up custom group preferences, then this will include all default # preferences within that particular group as well. - # + # # == Examples - # + # # A user with no stored values: - # + # # user = User.find(:first) # user.preferences # => {"language"=>"English", "color"=>nil} - # + # # A user with stored values for a particular group: - # + # # user.preferred_color = 'red', :cars # user.preferences(:cars) # => {"language=>"English", "color"=>"red"} def preferences(group = nil) preferences = preferences_group(group) - + unless preferences_group_loaded?(group) group_id, group_type = Preference.split_group(group) - find_preferences(:group_id => group_id, :group_type => group_type).each do |preference| + find_preferences(group_id: group_id, group_type: group_type).each do |preference| preferences[preference.name] = preference.value unless preferences.include?(preference.name) end - + # Add defaults preference_definitions.each do |name, definition| preferences[name] = definition.default_value(group_type) unless preferences.include?(name) end end - - preferences.inject({}) do |typed_preferences, (name, value)| + + preferences.each_with_object({}) do |(name, value), typed_preferences| typed_preferences[name] = value.nil? ? value : preference_definitions[name].type_cast(value) - typed_preferences end end - + # Queries whether or not a value is present for the given preference. # This is dependent on how the value is type-casted. - # + # # == Examples - # + # # class User < ActiveRecord::Base # preference :color, :string, :default => 'red' # end - # + # # user = User.create # user.preferred(:color) # => "red" # user.preferred?(:color) # => true # user.preferred?(:color, 'cars') # => true # user.preferred?(:color, Car.first) # => true - # + # # user.write_preference(:color, nil) # user.preferred(:color) # => nil # user.preferred?(:color) # => false def preferred?(name, group = nil) name = name.to_s assert_valid_preference(name) - + value = preferred(name, group) preference_definitions[name].query(value) end - alias_method :prefers?, :preferred? - + alias prefers? preferred? + # Gets the actual value stored for the given preference, or the default # value if nothing is present. - # + # # == Examples - # + # # class User < ActiveRecord::Base # preference :color, :string, :default => 'red' # end - # + # # user = User.create # user.preferred(:color) # => "red" # user.preferred(:color, 'cars') # => "red" # user.preferred(:color, Car.first) # => "red" - # + # # user.write_preference(:color, 'blue') # user.preferred(:color) # => "blue" def preferred(name, group = nil) name = name.to_s assert_valid_preference(name) - + if preferences_group(group).include?(name) # Value for this group/name has been written, but not saved yet: # grab from the pending values @@ -377,36 +397,36 @@ def preferred(name, group = nil) else # Grab the first preference; if it doesn't exist, use the default value group_id, group_type = Preference.split_group(group) - preference = find_preferences(:name => name, :group_id => group_id, :group_type => group_type).first unless preferences_group_loaded?(group) - + preference = find_preferences(name: name, group_id: group_id, group_type: group_type).first unless preferences_group_loaded?(group) + value = preference ? preference.value : preference_definitions[name].default_value(group_type) preferences_group(group)[name] = value end - + definition = preference_definitions[name] value = definition.type_cast(value) unless value.nil? value end - alias_method :prefers, :preferred - + alias prefers preferred + # Sets a new value for the given preference. The actual Preference record # is *not* created until this record is saved. In this way, preferences # act *exactly* the same as attributes. They can be written to and # validated against, but won't actually be written to the database until # the record is saved. - # + # # == Examples - # + # # user = User.find(:first) # user.write_preference(:color, 'red') # => "red" # user.save! - # + # # user.write_preference(:color, 'blue', Car.first) # => "blue" # user.save! def write_preference(name, value, group = nil) name = name.to_s assert_valid_preference(name) - + preferences_changed = preferences_changed_group(group) if preferences_changed.include?(name) old = preferences_changed[name] @@ -415,24 +435,24 @@ def write_preference(name, value, group = nil) old = clone_preference_value(name, group) preferences_changed[name] = old if preference_value_changed?(name, old, value) end - + value = convert_number_column_value(value) if preference_definitions[name].number? preferences_group(group)[name] = value - + value end - + # Whether any attributes have unsaved changes. - # + # # == Examples - # + # # user = User.find(:first) # user.preferences_changed? # => false # user.write_preference(:color, 'red') # user.preferences_changed? # => true # user.save # user.preferences_changed? # => false - # + # # # Groups # user.preferences_changed?(:car) # => false # user.write_preference(:color, 'red', :car) @@ -440,18 +460,18 @@ def write_preference(name, value, group = nil) def preferences_changed?(group = nil) !preferences_changed_group(group).empty? end - + # A list of the preferences that have unsaved changes. - # + # # == Examples - # + # # user = User.find(:first) # user.preferences_changed # => [] # user.write_preference(:color, 'red') # user.preferences_changed # => ["color"] # user.save # user.preferences_changed # => [] - # + # # # Groups # user.preferences_changed(:car) # => [] # user.write_preference(:color, 'red', :car) @@ -459,154 +479,154 @@ def preferences_changed?(group = nil) def preferences_changed(group = nil) preferences_changed_group(group).keys end - + # A map of the preferences that have changed in the current object. - # + # # == Examples - # + # # user = User.find(:first) # user.preferred(:color) # => nil # user.preference_changes # => {} - # + # # user.write_preference(:color, 'red') # user.preference_changes # => {"color" => [nil, "red"]} # user.save # user.preference_changes # => {} - # + # # # Groups # user.preferred(:color, :car) # => nil # user.preference_changes(:car) # => {} # user.write_preference(:color, 'red', :car) # user.preference_changes(:car) # => {"color" => [nil, "red"]} def preference_changes(group = nil) - preferences_changed(group).inject({}) do |changes, preference| + preferences_changed(group).each_with_object({}) do |preference, changes| changes[preference] = preference_change(preference, group) - changes end end - + # Reloads the pereferences of this object as well as its attributes def reload(*args) #:nodoc: result = super - + @preferences.clear if @preferences @preferences_changed.clear if @preferences_changed - + result end - + private - # Asserts that the given name is a valid preference in this model. If it - # is not, then an ArgumentError exception is raised. - def assert_valid_preference(name) - raise(ArgumentError, "Unknown preference: #{name}") unless preference_definitions.include?(name) - end - - # Gets the set of preferences identified by the given group - def preferences_group(group) - @preferences ||= {} - @preferences[group.is_a?(Symbol) ? group.to_s : group] ||= {} - end - - # Determines whether the given group of preferences has already been - # loaded from the database - def preferences_group_loaded?(group) - preference_definitions.length == preferences_group(group).length - end - - # Generates a clone of the current value stored for the preference with - # the given name / group - def clone_preference_value(name, group) - value = preferred(name, group) - value.duplicable? ? value.clone : value - rescue TypeError, NoMethodError - value - end - - # Keeps track of all preferences that have been changed so that they can - # be properly updated in the database. Maps group -> preference -> value. - def preferences_changed_group(group) - @preferences_changed ||= {} - @preferences_changed[group.is_a?(Symbol) ? group.to_s : group] ||= {} - end - - # Determines whether a preference changed in the given group - def preference_changed?(name, group) - preferences_changed_group(group).include?(name) - end - - # Builds an array of [original_value, new_value] for the given preference. - # If the perference did not change, this will return nil. - def preference_change(name, group) - [preferences_changed_group(group)[name], preferred(name, group)] if preference_changed?(name, group) - end - - # Gets the last saved value for the given preference - def preference_was(name, group) - preference_changed?(name, group) ? preferences_changed_group(group)[name] : preferred(name, group) - end - - # Forces the given preference to be saved regardless of whether the value - # is actually diferent - def preference_will_change!(name, group) - preferences_changed_group(group)[name] = clone_preference_value(name, group) - end - - # Reverts any unsaved changes to the given preference - def reset_preference!(name, group) - write_preference(name, preferences_changed_group(group)[name], group) if preference_changed?(name, group) - end - - # Determines whether the old value is different from the new value for the - # given preference. This will use the typecasted value to determine - # equality. - def preference_value_changed?(name, old, value) - definition = preference_definitions[name] - if definition.type == :integer && (old.nil? || old == 0) - # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. - # Hence we don't record it as a change if the value changes from nil to ''. - # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll - # be typecast back to 0 (''.to_i => 0) - value = nil if value.blank? - else - value = definition.type_cast(value) - end - - old != value + + # Asserts that the given name is a valid preference in this model. If it + # is not, then an ArgumentError exception is raised. + def assert_valid_preference(name) + raise(ArgumentError, "Unknown preference: #{name}") unless preference_definitions.include?(name) + end + + # Gets the set of preferences identified by the given group + def preferences_group(group) + @preferences ||= {} + @preferences[group.is_a?(Symbol) ? group.to_s : group] ||= {} + end + + # Determines whether the given group of preferences has already been + # loaded from the database + def preferences_group_loaded?(group) + preference_definitions.length == preferences_group(group).length + end + + # Generates a clone of the current value stored for the preference with + # the given name / group + def clone_preference_value(name, group) + value = preferred(name, group) + value.duplicable? ? value.clone : value + rescue TypeError, NoMethodError + value + end + + # Keeps track of all preferences that have been changed so that they can + # be properly updated in the database. Maps group -> preference -> value. + def preferences_changed_group(group) + @preferences_changed ||= {} + @preferences_changed[group.is_a?(Symbol) ? group.to_s : group] ||= {} + end + + # Determines whether a preference changed in the given group + def preference_changed?(name, group) + preferences_changed_group(group).include?(name) + end + + # Builds an array of [original_value, new_value] for the given preference. + # If the perference did not change, this will return nil. + def preference_change(name, group) + [preferences_changed_group(group)[name], preferred(name, group)] if preference_changed?(name, group) + end + + # Gets the last saved value for the given preference + def preference_was(name, group) + preference_changed?(name, group) ? preferences_changed_group(group)[name] : preferred(name, group) + end + + # Forces the given preference to be saved regardless of whether the value + # is actually diferent + def preference_will_change!(name, group) + preferences_changed_group(group)[name] = clone_preference_value(name, group) + end + + # Reverts any unsaved changes to the given preference + def reset_preference!(name, group) + write_preference(name, preferences_changed_group(group)[name], group) if preference_changed?(name, group) + end + + # Determines whether the old value is different from the new value for the + # given preference. This will use the typecasted value to determine + # equality. + def preference_value_changed?(name, old, value) + definition = preference_definitions[name] + if definition.type == :integer && (old.nil? || old == 0) + # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. + # Hence we don't record it as a change if the value changes from nil to ''. + # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll + # be typecast back to 0 (''.to_i => 0) + value = nil if value.blank? + else + value = definition.type_cast(value) end - - # Updates any preferences that have been changed/added since the record - # was last saved - def update_preferences - if @preferences_changed - @preferences_changed.each do |group, preferences| - group_id, group_type = Preference.split_group(group) - - preferences.keys.each do |name| - # Find an existing preference or build a new one - attributes = {:name => name, :group_id => group_id, :group_type => group_type} - preference = find_preferences(attributes).first || stored_preferences.build(attributes) - preference.value = preferred(name, group) - preference.save! - end + + old != value + end + + # Updates any preferences that have been changed/added since the record + # was last saved + def update_preferences + if @preferences_changed + @preferences_changed.each do |group, preferences| + group_id, group_type = Preference.split_group(group) + + preferences.keys.each do |name| + # Find an existing preference or build a new one + attributes = { name: name, group_id: group_id, group_type: group_type } + preference = find_preferences(attributes).first || stored_preferences.build(attributes) + preference.value = preferred(name, group) + preference.save! end - - @preferences_changed.clear end + + @preferences_changed.clear end - - # Finds all stored preferences with the given attributes. This will do a - # smart lookup by looking at the in-memory collection if it was eager- - # loaded. - def find_preferences(attributes) - if stored_preferences.loaded? - stored_preferences.select do |preference| - attributes.all? {|attribute, value| preference[attribute] == value} - end - else - stored_preferences.find(:all, :conditions => attributes) + end + + # Finds all stored preferences with the given attributes. This will do a + # smart lookup by looking at the in-memory collection if it was eager- + # loaded. + def find_preferences(attributes) + if stored_preferences.loaded? + stored_preferences.select do |preference| + attributes.all? { |attribute, value| preference[attribute] == value } end + else + stored_preferences.find(:all, conditions: attributes) end + end end end diff --git a/lib/preferences/engine.rb b/lib/preferences/engine.rb new file mode 100644 index 0000000..c1dcc53 --- /dev/null +++ b/lib/preferences/engine.rb @@ -0,0 +1,4 @@ +module Preferences + class Engine < Rails::Engine + end +end diff --git a/lib/preferences/preference_definition.rb b/lib/preferences/preference_definition.rb index da800d4..318e962 100644 --- a/lib/preferences/preference_definition.rb +++ b/lib/preferences/preference_definition.rb @@ -2,46 +2,47 @@ module Preferences # Represents the definition of a preference for a particular model class PreferenceDefinition # The data type for the content stored in this preference type - attr_reader :type - + attr_reader :type, :accessible + alias accessible? accessible + def initialize(name, *args) #:nodoc: options = args.extract_options! + @accessible = !!options.delete(:accessible) options.assert_valid_keys(:default, :group_defaults) - + @type = args.first ? args.first.to_sym : :boolean - + # Create a column that will be responsible for typecasting @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s) - - @group_defaults = (options[:group_defaults] || {}).inject({}) do |defaults, (group, default)| + + @group_defaults = (options[:group_defaults] || {}).each_with_object({}) do |(group, default), defaults| defaults[group.is_a?(Symbol) ? group.to_s : group] = type_cast(default) - defaults end end - + # The name of the preference def name @column.name end - + # The default value to use for the preference in case none have been # previously defined def default_value(group = nil) @group_defaults.include?(group) ? @group_defaults[group] : @column.default end - + # Determines whether column backing this preference stores numberic values def number? @column.number? end - + # Typecasts the value based on the type of preference that was defined. # This uses ActiveRecord's typecast functionality so the same rules for # typecasting a model's columns apply here. def type_cast(value) @type == :any ? value : @column.type_cast(value) end - + # Typecasts the value to true/false depending on the type of preference def query(value) if !(value = type_cast(value)) diff --git a/lib/preferences/version.rb b/lib/preferences/version.rb index 8400615..ef977cf 100644 --- a/lib/preferences/version.rb +++ b/lib/preferences/version.rb @@ -1,3 +1,3 @@ module Preferences - VERSION = '0.4.2' + VERSION = '1.0.0.pre1'.freeze end diff --git a/preferences.gemspec b/preferences.gemspec index 26b095f..ca47afa 100644 --- a/preferences.gemspec +++ b/preferences.gemspec @@ -2,19 +2,18 @@ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__) require 'preferences/version' Gem::Specification.new do |s| - s.name = "preferences" + s.name = 'preferences' s.version = Preferences::VERSION - s.authors = ["Aaron Pfeifer"] - s.email = "aaron@pluginaweek.org" - s.homepage = "http://www.pluginaweek.org" - s.description = "Adds support for easily creating custom preferences for ActiveRecord models" - s.summary = "Custom preferences for ActiveRecord models" - s.require_paths = ["lib"] + s.authors = ['Aaron Pfeifer', 'Jack Dempsey', 'Chad Boyd'] + s.email = 'aaron@pluginaweek.org' + s.homepage = 'http://www.pluginaweek.org' + s.description = 'Adds support for easily creating custom preferences for ActiveRecord models' + s.summary = 'Custom preferences for ActiveRecord models' + s.require_paths = ['lib', '.'] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- test/*`.split("\n") - s.rdoc_options = %w(--line-numbers --inline-source --title preferences --main README.rdoc) - s.extra_rdoc_files = %w(README.rdoc CHANGELOG.rdoc LICENSE) - - s.add_development_dependency("rake") - s.add_development_dependency("plugin_test_helper", ">= 0.3.2") + s.rdoc_options = %w[--line-numbers --inline-source --title preferences --main README.rdoc] + s.extra_rdoc_files = %w[README.rdoc CHANGELOG.rdoc LICENSE] + + s.add_development_dependency('rake') end diff --git a/test/app_root/app/models/user.rb b/test/app_root/app/models/user.rb index 6fcf9db..ea1e395 100644 --- a/test/app_root/app/models/user.rb +++ b/test/app_root/app/models/user.rb @@ -1,8 +1,8 @@ class User < ActiveRecord::Base -# preference :hot_salsa -# preference :dark_chocolate, :default => true -# preference :color, :string -# preference :car, :integer -# preference :language, :string, :default => 'English' -# preference :data, :any + # preference :hot_salsa + # preference :dark_chocolate, :default => true + # preference :color, :string + # preference :car, :integer + # preference :language, :string, :default => 'English' + # preference :data, :any end diff --git a/test/app_root/db/migrate/001_create_users.rb b/test/app_root/db/migrate/001_create_users.rb index 1f609ec..906dbb8 100644 --- a/test/app_root/db/migrate/001_create_users.rb +++ b/test/app_root/db/migrate/001_create_users.rb @@ -1,10 +1,10 @@ class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| - t.string :login, :null => false + t.string :login, null: false end end - + def self.down drop_table :users end diff --git a/test/app_root/db/migrate/002_create_cars.rb b/test/app_root/db/migrate/002_create_cars.rb index 8b8d23f..a735c6a 100644 --- a/test/app_root/db/migrate/002_create_cars.rb +++ b/test/app_root/db/migrate/002_create_cars.rb @@ -1,10 +1,10 @@ class CreateCars < ActiveRecord::Migration def self.up create_table :cars do |t| - t.string :name, :null => false + t.string :name, null: false end end - + def self.down drop_table :cars end diff --git a/test/app_root/db/migrate/003_create_employees.rb b/test/app_root/db/migrate/003_create_employees.rb index 5444362..dbb4a06 100644 --- a/test/app_root/db/migrate/003_create_employees.rb +++ b/test/app_root/db/migrate/003_create_employees.rb @@ -1,11 +1,11 @@ class CreateEmployees < ActiveRecord::Migration def self.up create_table :employees do |t| - t.string :name, :null => false + t.string :name, null: false t.string :type end end - + def self.down drop_table :employees end diff --git a/test/app_root/db/migrate/004_migrate_preferences_to_version_1.rb b/test/app_root/db/migrate/004_migrate_preferences_to_version_1.rb index 80be50a..4da09c9 100644 --- a/test/app_root/db/migrate/004_migrate_preferences_to_version_1.rb +++ b/test/app_root/db/migrate/004_migrate_preferences_to_version_1.rb @@ -4,7 +4,7 @@ def self.up migration.migrate(:up) end end - + def self.down ActiveRecord::Migrator.new(:down, "#{Rails.root}/../../generators/preferences/templates", 0).migrations.each do |migration| migration.migrate(:down) diff --git a/test/factory.rb b/test/factory.rb index 0bba77c..ae8a3a5 100644 --- a/test/factory.rb +++ b/test/factory.rb @@ -2,13 +2,13 @@ module Factory # Build actions for the model def self.build(model, &block) name = model.to_s.underscore - + define_method("#{name}_attributes", block) - define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)} - define_method("new_#{name}") {|*args| new_record(model, *args)} - define_method("create_#{name}") {|*args| create_record(model, *args)} + define_method("valid_#{name}_attributes") { |*args| valid_attributes_for(model, *args) } + define_method("new_#{name}") { |*args| new_record(model, *args) } + define_method("create_#{name}") { |*args| create_record(model, *args) } end - + # Get valid attributes for the model def valid_attributes_for(model, attributes = {}) name = model.to_s.underscore @@ -16,15 +16,15 @@ def valid_attributes_for(model, attributes = {}) attributes.stringify_keys! attributes end - + # Build an unsaved record def new_record(model, *args) attributes = valid_attributes_for(model, *args) record = model.new(attributes) - attributes.each {|attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr)} + attributes.each { |attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr) } record end - + # Build and save/reload a record def create_record(model, *args) record = new_record(model, *args) @@ -32,34 +32,34 @@ def create_record(model, *args) record.reload record end - + build Car do |attributes| attributes.reverse_merge!( - :name => 'Porsche' + name: 'Porsche' ) end - + build Employee do |attributes| attributes.reverse_merge!( - :name => 'John Smith' + name: 'John Smith' ) end - + build Manager do |attributes| valid_employee_attributes(attributes) end - + build Preference do |attributes| attributes[:owner] = create_user unless attributes.include?(:owner) attributes.reverse_merge!( - :name => 'notifications', - :value => false + name: 'notifications', + value: false ) end - + build User do |attributes| attributes.reverse_merge!( - :login => 'admin' + login: 'admin' ) end end diff --git a/test/functional/preferences_test.rb b/test/functional/preferences_test.rb index a006210..7e1bdd3 100644 --- a/test/functional/preferences_test.rb +++ b/test/functional/preferences_test.rb @@ -1,9 +1,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper') class ModelPreferenceTest < ActiveRecord::TestCase - def default_test - end - + def default_test; end + def teardown User.preference_definitions.clear end @@ -13,11 +12,11 @@ class ModelWithoutPreferencesTest < ActiveRecord::TestCase def test_should_not_create_preference_definitions assert !Car.respond_to?(:preference_definitions) end - + def test_should_not_create_stored_preferences_association assert !Car.new.respond_to?(:stored_preferences) end - + def test_should_not_create_preference_scopes assert !Car.respond_to?(:with_preferences) assert !Car.respond_to?(:without_preferences) @@ -29,16 +28,16 @@ def setup User.preference :notifications @user = new_user end - + def test_should_create_preference_definitions assert User.respond_to?(:preference_definitions) end - + def test_should_create_preference_scopes assert User.respond_to?(:with_preferences) assert User.respond_to?(:without_preferences) end - + def test_should_create_stored_preferences_associations assert @user.respond_to?(:stored_preferences) end @@ -49,83 +48,83 @@ def setup @definition = User.preference :notifications @user = new_user end - + def test_should_raise_exception_if_invalid_options_specified - assert_raise(ArgumentError) {User.preference :notifications, :invalid => true} - assert_raise(ArgumentError) {User.preference :notifications, :boolean, :invalid => true} + assert_raise(ArgumentError) { User.preference :notifications, invalid: true } + assert_raise(ArgumentError) { User.preference :notifications, :boolean, invalid: true } end - + def test_should_create_definition assert_not_nil @definition assert_equal 'notifications', @definition.name end - + def test_should_create_preferred_query_method assert @user.respond_to?(:preferred_notifications?) end - + def test_should_create_prefers_query_method assert @user.respond_to?(:prefers_notifications?) end - + def test_should_create_preferred_reader assert @user.respond_to?(:preferred_notifications) end - + def test_should_create_prefers_reader assert @user.respond_to?(:prefers_notifications) end - + def test_should_create_preferred_writer assert @user.respond_to?(:preferred_notifications=) end - + def test_should_create_prefers_writer assert @user.respond_to?(:prefers_notifications=) end - + def test_should_create_preferred_changed_query assert @user.respond_to?(:preferred_notifications_changed?) end - + def test_should_create_prefers_changed_query assert @user.respond_to?(:prefers_notifications_changed?) end - + def test_should_create_preferred_was assert @user.respond_to?(:preferred_notifications_was) end - + def test_should_create_prefers_was assert @user.respond_to?(:prefers_notifications_was) end - + def test_should_create_preferred_change assert @user.respond_to?(:preferred_notifications_change) end - + def test_should_create_prefers_change assert @user.respond_to?(:prefers_notifications_change) end - + def test_should_create_preferred_will_change assert @user.respond_to?(:preferred_notifications_will_change!) end - + def test_should_create_prefers_will_change assert @user.respond_to?(:prefers_notifications_will_change!) end - + def test_should_create_preferred_reset assert @user.respond_to?(:reset_preferred_notifications!) end - + def test_should_create_prefers_reset assert @user.respond_to?(:reset_prefers_notifications!) end - + def test_should_include_new_definitions_in_preference_definitions - assert_equal e = {'notifications' => @definition}, User.preference_definitions + assert_equal e = { 'notifications' => @definition }, User.preference_definitions end end @@ -134,39 +133,39 @@ def setup @definition = User.preference :notifications @user = new_user end - + def test_should_have_boolean_type assert_equal :boolean, @definition.type end - + def test_should_not_have_default_value assert_nil @definition.default_value end - + def test_should_only_have_default_preferences - assert_equal e = {'notifications' => nil}, @user.preferences + assert_equal e = { 'notifications' => nil }, @user.preferences end - + def test_should_not_query_preferences_changed assert_equal false, @user.preferences_changed? end - + def test_should_not_query_group_preferences_changed assert_equal false, @user.preferences_changed?(:chat) end - + def test_should_not_have_preferences_changed assert_equal [], @user.preferences_changed end - + def test_should_not_have_group_preferences_changed assert_equal [], @user.preferences_changed(:chat) end - + def test_should_not_have_preference_changes assert_equal e = {}, @user.preference_changes end - + def test_should_not_have_group_preference_changes assert_equal e = {}, @user.preference_changes(:chat) end @@ -177,57 +176,57 @@ def setup @definition = User.preference :vehicle_id, :integer @user = new_user end - + def test_should_have_boolean_type assert_equal :integer, @definition.type end - + def test_should_not_have_default_value assert_nil @definition.default_value end - + def test_should_only_have_default_preferences - assert_equal e = {'vehicle_id' => nil}, @user.preferences + assert_equal e = { 'vehicle_id' => nil }, @user.preferences end end class PreferencesWithCustomDefaultTest < ModelPreferenceTest def setup - @definition = User.preference :color, :string, :default => 'red' + @definition = User.preference :color, :string, default: 'red' @user = new_user end - + def test_should_have_boolean_type assert_equal :string, @definition.type end - + def test_should_have_default_value assert_equal 'red', @definition.default_value end - + def test_should_only_have_default_preferences - assert_equal e = {'color' => 'red'}, @user.preferences + assert_equal e = { 'color' => 'red' }, @user.preferences end end class PreferencesWithMultipleDefinitionsTest < ModelPreferenceTest def setup - User.preference :notifications, :default => true - User.preference :color, :string, :default => 'red' + User.preference :notifications, default: true + User.preference :color, :string, default: 'red' @user = new_user end - + def test_should_only_have_default_preferences - assert_equal e = {'notifications' => true, 'color' => 'red'}, @user.preferences + assert_equal e = { 'notifications' => true, 'color' => 'red' }, @user.preferences end end class PreferencesAfterBeingCreatedTest < ModelPreferenceTest def setup - User.preference :notifications, :default => true + User.preference :notifications, default: true @user = create_user end - + def test_should_not_have_any_stored_preferences assert @user.stored_preferences.empty? end @@ -235,56 +234,56 @@ def test_should_not_have_any_stored_preferences class PreferencesReaderTest < ModelPreferenceTest def setup - User.preference :notifications, :default => true + User.preference :notifications, default: true @user = create_user end - + def test_should_raise_exception_if_invalid_preference_read exception = assert_raise(ArgumentError) { @user.preferred(:invalid) } assert_equal 'Unknown preference: invalid', exception.message end - + def test_use_default_value_if_not_stored assert_equal true, @user.preferred(:notifications) end - + def test_should_use_group_default_value_if_not_stored - User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'} + User.preference :language, :string, default: 'English', group_defaults: { chat: 'Latin' } assert_equal 'English', @user.preferred(:language) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :name => 'notifications', :value => false) + create_preference(owner: @user, name: 'notifications', value: false) assert_equal false, @user.preferred(:notifications) end - + def test_should_type_cast_based_on_preference_definition @user.write_preference(:notifications, 'false') assert_equal false, @user.preferred(:notifications) end - + def test_should_cache_stored_values - create_preference(:owner => @user, :name => 'notifications', :value => false) + create_preference(owner: @user, name: 'notifications', value: false) assert_queries(1) { @user.preferred(:notifications) } assert_queries(0) { @user.preferred(:notifications) } end - + def test_should_not_query_if_preferences_already_loaded @user.preferences assert_queries(0) { @user.preferred(:notifications) } end - + def test_should_use_value_from_preferences_lookup - create_preference(:owner => @user, :name => 'notifications', :value => false) + create_preference(owner: @user, name: 'notifications', value: false) @user.preferences - + assert_queries(0) { assert_equal false, @user.preferred(:notifications) } end - + def test_should_be_able_to_use_prefers_reader assert_equal true, @user.prefers_notifications end - + def test_should_be_able_to_use_preferred_reader assert_equal true, @user.preferred_notifications end @@ -292,46 +291,46 @@ def test_should_be_able_to_use_preferred_reader class PreferencesGroupReaderTest < ModelPreferenceTest def setup - User.preference :notifications, :default => true + User.preference :notifications, default: true @user = create_user end - + def test_should_use_default_value_if_not_stored assert_equal true, @user.preferred(:notifications, :chat) end - + def test_should_use_group_default_value_if_not_stored - User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'} + User.preference :language, :string, default: 'English', group_defaults: { chat: 'Latin' } assert_equal 'Latin', @user.preferred(:language, :chat) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) assert_equal false, @user.preferred(:notifications, :chat) end - + def test_should_cache_stored_values - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) assert_queries(1) { @user.preferred(:notifications, :chat) } assert_queries(0) { @user.preferred(:notifications, :chat) } end - + def test_should_not_query_if_preferences_already_loaded @user.preferences(:chat) assert_queries(0) { @user.preferred(:notifications, :chat) } end - + def test_should_use_value_from_preferences_lookup - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) @user.preferences(:chat) - + assert_queries(0) { assert_equal false, @user.preferred(:notifications, :chat) } end - + def test_should_be_able_to_use_prefers_reader assert_equal true, @user.prefers_notifications(:chat) end - + def test_should_be_able_to_use_preferred_reader assert_equal true, @user.preferred_notifications(:chat) end @@ -340,31 +339,31 @@ def test_should_be_able_to_use_preferred_reader class PreferencesARGroupReaderTest < ModelPreferenceTest def setup @car = create_car - - User.preference :notifications, :default => true + + User.preference :notifications, default: true @user = create_user end - + def test_use_default_value_if_not_stored assert_equal true, @user.preferred(:notifications, @car) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'Car', group_id: @car.id, name: 'notifications', value: false) assert_equal false, @user.preferred(:notifications, @car) end - + def test_should_use_value_from_preferences_lookup - create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'Car', group_id: @car.id, name: 'notifications', value: false) @user.preferences(@car) - + assert_queries(0) { assert_equal false, @user.preferred(:notifications, @car) } end - + def test_should_be_able_to_use_prefers_reader assert_equal true, @user.prefers_notifications(@car) end - + def test_should_be_able_to_use_preferred_reader assert_equal true, @user.preferred_notifications(@car) end @@ -375,36 +374,36 @@ def setup User.preference :language, :string @user = create_user end - + def test_should_raise_exception_if_invalid_preference_queried exception = assert_raise(ArgumentError) { @user.preferred?(:invalid) } assert_equal 'Unknown preference: invalid', exception.message end - + def test_should_be_true_if_present @user.preferred_language = 'English' assert_equal true, @user.preferred?(:language) end - + def test_should_be_false_if_not_present assert_equal false, @user.preferred?(:language) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :name => 'language', :value => 'English') + create_preference(owner: @user, name: 'language', value: 'English') assert_equal true, @user.preferred?(:language) end - + def test_should_cache_stored_values - create_preference(:owner => @user, :name => 'language', :value => 'English') + create_preference(owner: @user, name: 'language', value: 'English') assert_queries(1) { @user.preferred?(:language) } assert_queries(0) { @user.preferred?(:language) } end - + def test_should_be_able_to_use_prefers_reader assert_equal false, @user.prefers_language? end - + def test_should_be_able_to_use_preferred_reader assert_equal false, @user.preferred_language? end @@ -415,31 +414,31 @@ def setup User.preference :language, :string @user = create_user end - + def test_should_be_true_if_present @user.preferred_language = 'English', :chat assert_equal true, @user.preferred?(:language, :chat) end - + def test_should_be_false_if_not_present assert_equal false, @user.preferred?(:language, :chat) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :group_type => 'chat', :name => 'language', :value => 'English') + create_preference(owner: @user, group_type: 'chat', name: 'language', value: 'English') assert_equal true, @user.preferred?(:language, :chat) end - + def test_should_cache_stored_values - create_preference(:owner => @user, :group_type => 'chat', :name => 'language', :value => 'English') + create_preference(owner: @user, group_type: 'chat', name: 'language', value: 'English') assert_queries(1) { @user.preferred?(:language, :chat) } assert_queries(0) { @user.preferred?(:language, :chat) } end - + def test_should_be_able_to_use_prefers_reader assert_equal false, @user.prefers_language?(:chat) end - + def test_should_be_able_to_use_preferred_reader assert_equal false, @user.preferred_language?(:chat) end @@ -448,29 +447,29 @@ def test_should_be_able_to_use_preferred_reader class PreferencesARGroupQueryTest < ModelPreferenceTest def setup @car = create_car - + User.preference :language, :string @user = create_user end - + def test_should_be_true_if_present @user.preferred_language = 'English', @car assert_equal true, @user.preferred?(:language, @car) end - + def test_should_be_false_if_not_present assert_equal false, @user.preferred?(:language, @car) end - + def test_should_use_stored_value_if_stored - create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'language', :value => 'English') + create_preference(owner: @user, group_type: 'Car', group_id: @car.id, name: 'language', value: 'English') assert_equal true, @user.preferred?(:language, @car) end - + def test_should_be_able_to_use_prefers_reader assert_equal false, @user.prefers_language?(@car) end - + def test_should_be_able_to_use_preferred_reader assert_equal false, @user.preferred_language?(@car) end @@ -478,158 +477,158 @@ def test_should_be_able_to_use_preferred_reader class PreferencesWriterTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - @user = create_user(:login => 'admin') + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user(login: 'admin') end - + def test_should_raise_exception_if_invalid_preference_written exception = assert_raise(ArgumentError) { @user.write_preference(:invalid, true) } assert_equal 'Unknown preference: invalid', exception.message end - + def test_should_have_same_value_if_not_changed @user.write_preference(:notifications, true) assert_equal true, @user.preferred(:notifications) end - + def test_should_use_new_value_if_changed @user.write_preference(:notifications, false) assert_equal false, @user.preferred(:notifications) end - + def test_should_not_save_record_after_changing_preference @user.login = 'test' @user.write_preference(:notifications, false) - + assert_equal 'admin', User.find(@user.id).login end - + def test_should_not_create_stored_preferences_immediately @user.write_preference(:notifications, false) assert @user.stored_preferences.empty? end - + def test_should_not_create_stored_preference_if_value_not_changed @user.write_preference(:notifications, true) @user.save! - + assert_equal 0, @user.stored_preferences.count end - + def test_should_not_create_stored_integer_preference_if_typecast_not_changed User.preference :age, :integer - + @user.write_preference(:age, '') @user.save! - + assert_equal 0, @user.stored_preferences.count end - + def test_should_create_stored_integer_preference_if_typecast_changed - User.preference :age, :integer, :default => 0 - + User.preference :age, :integer, default: 0 + @user.write_preference(:age, '') @user.save! - + assert_nil @user.preferred(:age) assert_equal 1, @user.stored_preferences.count end - + def test_should_create_stored_preference_if_value_changed @user.write_preference(:notifications, false) @user.save! - + assert_equal 1, @user.stored_preferences.count end - + def test_should_overwrite_existing_stored_preference_if_value_changed - preference = create_preference(:owner => @user, :name => 'notifications', :value => true) - + preference = create_preference(owner: @user, name: 'notifications', value: true) + @user.write_preference(:notifications, false) @user.save! - + preference.reload assert_equal false, preference.value end - + def test_should_not_remove_preference_if_set_to_default - create_preference(:owner => @user, :name => 'notifications', :value => false) - + create_preference(owner: @user, name: 'notifications', value: false) + @user.write_preference(:notifications, true) @user.save! @user.reload - + assert_equal 1, @user.stored_preferences.size preference = @user.stored_preferences.first assert_equal true, preference.value end - + def test_should_not_remove_preference_if_set_to_nil - create_preference(:owner => @user, :name => 'notifications', :value => false) - + create_preference(owner: @user, name: 'notifications', value: false) + @user.write_preference(:notifications, nil) @user.save! @user.reload - + assert_equal 1, @user.stored_preferences.size preference = @user.stored_preferences.first assert_nil preference.value end - + def test_should_not_query_for_old_value_if_preferences_loaded @user.preferences - + assert_queries(0) { @user.write_preference(:notifications, false) } end end class PreferencesGroupWriterTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - @user = create_user(:login => 'admin') + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user(login: 'admin') end - + def test_should_have_same_value_if_not_changed @user.write_preference(:notifications, true, :chat) assert_equal true, @user.preferred(:notifications, :chat) end - + def test_should_use_new_value_if_changed @user.write_preference(:notifications, false, :chat) assert_equal false, @user.preferred(:notifications, :chat) end - + def test_should_not_create_stored_preference_if_value_not_changed @user.write_preference(:notifications, true, :chat) @user.save! - + assert_equal 0, @user.stored_preferences.count end - + def test_should_create_stored_preference_if_value_changed @user.write_preference(:notifications, false, :chat) @user.save! - + assert_equal 1, @user.stored_preferences.count end - + def test_should_set_group_attributes_on_stored_preferences @user.write_preference(:notifications, false, :chat) @user.save! - + preference = @user.stored_preferences.first assert_equal 'chat', preference.group_type assert_nil preference.group_id end - + def test_should_overwrite_existing_stored_preference_if_value_changed - preference = create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => true) - + preference = create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: true) + @user.write_preference(:notifications, false, :chat) @user.save! - + preference.reload assert_equal false, preference.value end @@ -638,40 +637,40 @@ def test_should_overwrite_existing_stored_preference_if_value_changed class PreferencesARGroupWriterTest < ModelPreferenceTest def setup @car = create_car - - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - @user = create_user(:login => 'admin') + + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user(login: 'admin') end - + def test_should_have_same_value_if_not_changed @user.write_preference(:notifications, true, @car) assert_equal true, @user.preferred(:notifications, @car) end - + def test_should_use_new_value_if_changed @user.write_preference(:notifications, false, @car) assert_equal false, @user.preferred(:notifications, @car) end - + def test_should_not_create_stored_preference_if_value_not_changed @user.write_preference(:notifications, true, @car) @user.save! - + assert_equal 0, @user.stored_preferences.count end - + def test_should_create_stored_preference_if_value_changed @user.write_preference(:notifications, false, @car) @user.save! - + assert_equal 1, @user.stored_preferences.count end - + def test_should_set_group_attributes_on_stored_preferences @user.write_preference(:notifications, false, @car) @user.save! - + preference = @user.stored_preferences.first assert_equal 'Car', preference.group_type assert_equal @car.id, preference.group_id @@ -680,147 +679,147 @@ def test_should_set_group_attributes_on_stored_preferences class PreferencesAfterChangingPreferenceTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' @user = create_user - + @user.write_preference(:notifications, false) end - + def test_should_query_preferences_changed assert_equal true, @user.preferences_changed? end - + def test_should_query_preference_changed assert_equal true, @user.prefers_notifications_changed? end - + def test_should_not_query_preferences_changed_for_group assert_equal false, @user.preferences_changed?(:chat) end - + def test_should_not_query_preference_changed_for_group assert_equal false, @user.prefers_notifications_changed?(:chat) end - + def test_should_have_preferences_changed assert_equal ['notifications'], @user.preferences_changed end - + def test_should_not_build_same_preferences_changed_result assert_not_same @user.preferences_changed, @user.preferences_changed end - + def test_should_not_have_preferences_changed_for_group assert_equal [], @user.preferences_changed(:chat) end - + def test_should_track_multiple_preferences_changed @user.write_preference(:language, 'Latin') - assert_equal ['language', 'notifications'], @user.preferences_changed.sort + assert_equal %w[language notifications], @user.preferences_changed.sort end - + def test_should_have_preference_changes - assert_equal e = {'notifications' => [true, false]}, @user.preference_changes + assert_equal e = { 'notifications' => [true, false] }, @user.preference_changes end - + def test_should_not_build_same_preference_changes_result assert_not_same @user.preference_changes, @user.preference_changes end - + def test_should_have_preference_change assert_equal [true, false], @user.prefers_notifications_change end - + def test_should_have_preference_was assert_equal true, @user.prefers_notifications_was end - + def test_should_not_have_preference_changes_for_group assert_equal e = {}, @user.preference_changes(:chat) end - + def test_should_not_have_preference_change_for_group assert_nil @user.prefers_notifications_change(:chat) end - + def test_should_have_preference_was_for_group assert_equal true, @user.prefers_notifications_was(:chat) end - + def test_should_use_latest_value_for_preference_changes @user.write_preference(:notifications, nil) - assert_equal e = {'notifications' => [true, nil]}, @user.preference_changes + assert_equal e = { 'notifications' => [true, nil] }, @user.preference_changes end - + def test_should_use_cloned_old_value_for_preference_changes old_value = @user.preferred(:language) @user.write_preference(:language, 'Latin') - + tracked_old_value = @user.preference_changes['language'][0] assert_equal old_value, tracked_old_value assert_not_same old_value, tracked_old_value end - + def test_should_track_multiple_preference_changes @user.write_preference(:language, 'Latin') - assert_equal e = {'notifications' => [true, false], 'language' => ['English', 'Latin']}, @user.preference_changes + assert_equal e = { 'notifications' => [true, false], 'language' => %w[English Latin] }, @user.preference_changes end end class PreferencesAfterChangingGroupPreferenceTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' @user = create_user - + @user.write_preference(:notifications, false, :chat) end - + def test_should_not_query_preferences_changed assert_equal false, @user.preferences_changed? end - + def test_not_should_query_preference_changed assert_equal false, @user.prefers_notifications_changed? end - + def test_should_query_preferences_changed_for_group assert_equal true, @user.preferences_changed?(:chat) end - + def test_should_query_preference_changed_for_group assert_equal true, @user.prefers_notifications_changed?(:chat) end - + def test_should_have_preferences_changed assert_equal [], @user.preferences_changed end - + def test_should_not_have_preferences_changed_for_group assert_equal ['notifications'], @user.preferences_changed(:chat) end - + def test_should_have_preference_changes assert_equal e = {}, @user.preference_changes end - + def test_should_not_have_preference_change assert_nil @user.prefers_notifications_change end - + def test_should_have_preference_was assert_equal true, @user.prefers_notifications_was end - + def test_should_not_have_preference_changes_for_group - assert_equal e = {'notifications' => [true, false]}, @user.preference_changes(:chat) + assert_equal e = { 'notifications' => [true, false] }, @user.preference_changes(:chat) end - + def test_should_have_preference_change_for_group assert_equal [true, false], @user.prefers_notifications_change(:chat) end - + def test_should_have_preference_was_for_group assert_equal true, @user.prefers_notifications_was(:chat) end @@ -828,21 +827,21 @@ def test_should_have_preference_was_for_group class PreferencesAfterRevertPreferenceChangeTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.write_preference(:notifications, false) @user.write_preference(:notifications, true) end - + def test_should_not_query_preferences_changed assert_equal false, @user.preferences_changed? end - + def test_should_not_have_preferences_changed assert_equal [], @user.preferences_changed end - + def test_should_not_have_preference_changes assert_equal e = {}, @user.preference_changes end @@ -850,16 +849,16 @@ def test_should_not_have_preference_changes class PreferencesAfterForcingChangeTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.prefers_notifications_will_change! @user.save end - + def test_should_store_preference assert_equal 1, @user.stored_preferences.count - + preference = @user.stored_preferences.first assert_equal nil, preference.group_type assert_equal nil, preference.group_id @@ -869,27 +868,27 @@ def test_should_store_preference class PreferencesAfterForcingChangeForGroupTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user @user.prefers_notifications_will_change!(:chat) @user.save end - + def test_should_store_preference assert_equal 1, @user.stored_preferences.count - + preference = @user.stored_preferences.first assert_equal 'chat', preference.group_type assert_equal nil, preference.group_id assert_equal true, preference.value end - + def test_should_use_cloned_value_for_tracking_old_value old_value = @user.preferred(:language) @user.preferred_language_will_change! - + tracked_old_value = @user.preferred_language_was assert_equal old_value, tracked_old_value assert_not_same old_value, tracked_old_value @@ -898,18 +897,18 @@ def test_should_use_cloned_value_for_tracking_old_value class PreferencesAfterResettingPreferenceTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.write_preference(:notifications, false) @user.write_preference(:notifications, false, :chat) @user.reset_prefers_notifications! end - + def test_should_revert_to_original_value assert_equal true, @user.preferred(:notifications) end - + def test_should_not_reset_groups assert_equal true, @user.preferred(:notifications, :chat) end @@ -917,18 +916,18 @@ def test_should_not_reset_groups class PreferencesAfterResettingPreferenceTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.write_preference(:notifications, false) @user.write_preference(:notifications, false, :chat) @user.reset_prefers_notifications!(:chat) end - + def test_should_revert_to_original_value assert_equal true, @user.preferred(:notifications, :chat) end - + def test_should_not_reset_default_group assert_equal false, @user.preferred(:notifications) end @@ -936,61 +935,61 @@ def test_should_not_reset_default_group class PreferencesLookupTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'} - + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English', group_defaults: { chat: 'Latin' } + @user = create_user end - + def test_should_only_have_defaults_if_nothing_customized - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences end - + def test_should_merge_defaults_with_unsaved_changes @user.write_preference(:notifications, false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences end - + def test_should_merge_defaults_with_saved_changes - create_preference(:owner => @user, :name => 'notifications', :value => false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences + create_preference(owner: @user, name: 'notifications', value: false) + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences end - + def test_should_merge_stored_preferences_with_unsaved_changes - create_preference(:owner => @user, :name => 'notifications', :value => false) + create_preference(owner: @user, name: 'notifications', value: false) @user.write_preference(:language, 'Latin') - assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences + assert_equal e = { 'notifications' => false, 'language' => 'Latin' }, @user.preferences end - + def test_should_use_unsaved_changes_over_stored_preferences - create_preference(:owner => @user, :name => 'notifications', :value => true) + create_preference(owner: @user, name: 'notifications', value: true) @user.write_preference(:notifications, false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences end - + def test_should_typecast_unsaved_changes @user.write_preference(:notifications, 'true') - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences end - + def test_should_cache_results assert_queries(1) { @user.preferences } assert_queries(0) { @user.preferences } end - + def test_should_not_query_if_stored_preferences_eager_loaded - create_preference(:owner => @user, :name => 'notifications', :value => false) - user = User.find(@user.id, :include => :stored_preferences) - + create_preference(owner: @user, name: 'notifications', value: false) + user = User.find(@user.id, include: :stored_preferences) + assert_queries(0) do - assert_equal e = {'notifications' => false, 'language' => 'English'}, user.preferences + assert_equal e = { 'notifications' => false, 'language' => 'English' }, user.preferences end end - + def test_should_not_generate_same_object_twice assert_not_same @user.preferences, @user.preferences end - + def test_should_use_preferences_for_prefs assert_equal @user.preferences, @user.prefs end @@ -998,49 +997,49 @@ def test_should_use_preferences_for_prefs class PreferencesGroupLookupTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English', :group_defaults => {:chat => 'Latin'} - + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English', group_defaults: { chat: 'Latin' } + @user = create_user end - + def test_should_only_have_defaults_if_nothing_customized - assert_equal e = {'notifications' => true, 'language' => 'Latin'}, @user.preferences(:chat) + assert_equal e = { 'notifications' => true, 'language' => 'Latin' }, @user.preferences(:chat) end - + def test_should_merge_defaults_with_unsaved_changes @user.write_preference(:notifications, false, :chat) - assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat) + assert_equal e = { 'notifications' => false, 'language' => 'Latin' }, @user.preferences(:chat) end - + def test_should_merge_defaults_with_saved_changes - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) - assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) + assert_equal e = { 'notifications' => false, 'language' => 'Latin' }, @user.preferences(:chat) end - + def test_should_merge_stored_preferences_with_unsaved_changes - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) @user.write_preference(:language, 'Spanish', :chat) - assert_equal e = {'notifications' => false, 'language' => 'Spanish'}, @user.preferences(:chat) + assert_equal e = { 'notifications' => false, 'language' => 'Spanish' }, @user.preferences(:chat) end - + def test_should_typecast_unsaved_changes @user.write_preference(:notifications, 'true', :chat) - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences end - + def test_should_cache_results assert_queries(1) { @user.preferences(:chat) } assert_queries(0) { @user.preferences(:chat) } end - + def test_should_not_query_if_all_preferences_individually_loaded @user.preferred(:notifications, :chat) @user.preferred(:language, :chat) - + assert_queries(0) { @user.preferences(:chat) } end - + def test_should_not_generate_same_object_twice assert_not_same @user.preferences(:chat), @user.preferences(:chat) end @@ -1049,113 +1048,113 @@ def test_should_not_generate_same_object_twice class PreferencesARGroupLookupTest < ModelPreferenceTest def setup @car = create_car - - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - + + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user end - + def test_should_only_have_defaults_if_nothing_customized - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(@car) + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences(@car) end - + def test_should_merge_defaults_with_unsaved_changes @user.write_preference(:notifications, false, @car) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(@car) + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences(@car) end - + def test_should_merge_defaults_with_saved_changes - create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(@car) + create_preference(owner: @user, group_type: 'Car', group_id: @car.id, name: 'notifications', value: false) + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences(@car) end - + def test_should_merge_stored_preferences_with_unsaved_changes - create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'Car', group_id: @car.id, name: 'notifications', value: false) @user.write_preference(:language, 'Latin', @car) - assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(@car) + assert_equal e = { 'notifications' => false, 'language' => 'Latin' }, @user.preferences(@car) end end class PreferencesNilGroupLookupTest < ModelPreferenceTest def setup @car = create_car - - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - + + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user end - + def test_should_only_have_defaults_if_nothing_customized - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(nil) + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences(nil) end - + def test_should_merge_defaults_with_unsaved_changes @user.write_preference(:notifications, false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(nil) + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences(nil) end - + def test_should_merge_defaults_with_saved_changes - create_preference(:owner => @user, :name => 'notifications', :value => false) - assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(nil) + create_preference(owner: @user, name: 'notifications', value: false) + assert_equal e = { 'notifications' => false, 'language' => 'English' }, @user.preferences(nil) end - + def test_should_merge_stored_preferences_with_unsaved_changes - create_preference(:owner => @user, :name => 'notifications', :value => false) + create_preference(owner: @user, name: 'notifications', value: false) @user.write_preference(:language, 'Latin') - assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(nil) + assert_equal e = { 'notifications' => false, 'language' => 'Latin' }, @user.preferences(nil) end end class PreferencesLookupWithGroupsTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - User.preference :language, :string, :default => 'English' - + User.preference :notifications, :boolean, default: true + User.preference :language, :string, default: 'English' + @user = create_user - create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false) + create_preference(owner: @user, group_type: 'chat', name: 'notifications', value: false) end - + def test_not_include_group_preferences_by_default - assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences + assert_equal e = { 'notifications' => true, 'language' => 'English' }, @user.preferences end end class PreferencesAfterBeingReloadedTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.write_preference(:notifications, false) @user.reload end - + def test_should_reset_unsaved_preferences assert_equal true, @user.preferred(:notifications) end - + def test_should_not_save_reset_preferences @user.save! assert @user.stored_preferences.empty? end - + def test_should_reset_preferences - assert_equal e = {'notifications' => true}, @user.preferences + assert_equal e = { 'notifications' => true }, @user.preferences end - + def test_should_clear_query_cache_for_preferences assert_queries(1) { @user.preferences } end - + def test_should_reset_preferences_changed_query assert_equal false, @user.preferences_changed? end - + def test_should_reset_preferences_changed assert_equal [], @user.preferences_changed end - + def test_should_reset_preference_changes assert_equal e = {}, @user.preference_changes end @@ -1163,33 +1162,33 @@ def test_should_reset_preference_changes class PreferencesForGroupAfterBeingReloadedTest < ModelPreferenceTest def setup - User.preference :notifications, :boolean, :default => true - + User.preference :notifications, :boolean, default: true + @user = create_user @user.write_preference(:notifications, false, :chat) @user.reload end - + def test_should_reset_unsaved_preferences assert_equal true, @user.preferred(:notifications, :chat) end - + def test_should_reset_preferences - assert_equal e = {'notifications' => true}, @user.preferences(:chat) + assert_equal e = { 'notifications' => true }, @user.preferences(:chat) end - + def test_should_clear_query_cache_for_preferences assert_queries(1) { @user.preferences(:chat) } end - + def test_should_reset_preferences_changed_query assert_equal false, @user.preferences_changed?(:chat) end - + def test_should_reset_preferences_changed assert_equal [], @user.preferences_changed(:chat) end - + def test_should_reset_preference_changes assert_equal e = {}, @user.preference_changes(:chat) end @@ -1198,167 +1197,165 @@ def test_should_reset_preference_changes class PreferencesWithScopeTest < ModelPreferenceTest def setup User.preference :notifications - User.preference :language, :string, :default => 'English' - User.preference :color, :string, :default => 'red' - + User.preference :language, :string, default: 'English' + User.preference :color, :string, default: 'red' + @user = create_user - @customized_user = create_user(:login => 'customized', - :prefers_notifications => false, - :preferred_language => 'Latin' - ) + @customized_user = create_user(login: 'customized', + prefers_notifications: false, + preferred_language: 'Latin') @customized_user.prefers_notifications = false, :chat @customized_user.preferred_language = 'Latin', :chat @customized_user.save! end - + def test_should_not_find_if_no_preference_matched - assert_equal [], User.with_preferences(:language => 'Italian') + assert_equal [], User.with_preferences(language: 'Italian') end - + def test_should_find_with_null_preference - assert_equal [@user], User.with_preferences(:notifications => nil) + assert_equal [@user], User.with_preferences(notifications: nil) end - + def test_should_find_with_default_preference - assert_equal [@user], User.with_preferences(:language => 'English') + assert_equal [@user], User.with_preferences(language: 'English') end - + def test_should_find_with_multiple_default_preferences - assert_equal [@user], User.with_preferences(:notifications => nil, :language => 'English') + assert_equal [@user], User.with_preferences(notifications: nil, language: 'English') end - + def test_should_find_with_custom_preference - assert_equal [@customized_user], User.with_preferences(:language => 'Latin') + assert_equal [@customized_user], User.with_preferences(language: 'Latin') end - + def test_should_find_with_multiple_custom_preferences - assert_equal [@customized_user], User.with_preferences(:notifications => false, :language => 'Latin') + assert_equal [@customized_user], User.with_preferences(notifications: false, language: 'Latin') end - + def test_should_find_with_mixed_default_and_custom_preferences - assert_equal [@customized_user], User.with_preferences(:color => 'red', :language => 'Latin') + assert_equal [@customized_user], User.with_preferences(color: 'red', language: 'Latin') end - + def test_should_find_with_default_group_preference - assert_equal [@user], User.with_preferences(:chat => {:language => 'English'}) + assert_equal [@user], User.with_preferences(chat: { language: 'English' }) end - + def test_should_find_with_customized_default_group_preference - User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'} + User.preference :country, :string, default: 'US', group_defaults: { chat: 'UK' } @customized_user.preferred_country = 'US', :chat @customized_user.save! - - assert_equal [@user], User.with_preferences(:chat => {:country => 'UK'}) + + assert_equal [@user], User.with_preferences(chat: { country: 'UK' }) end - + def test_should_find_with_multiple_default_group_preferences - assert_equal [@user], User.with_preferences(:chat => {:notifications => nil, :language => 'English'}) + assert_equal [@user], User.with_preferences(chat: { notifications: nil, language: 'English' }) end - + def test_should_find_with_custom_group_preference - assert_equal [@customized_user], User.with_preferences(:chat => {:language => 'Latin'}) + assert_equal [@customized_user], User.with_preferences(chat: { language: 'Latin' }) end - + def test_should_find_with_multiple_custom_group_preferences - assert_equal [@customized_user], User.with_preferences(:chat => {:notifications => false, :language => 'Latin'}) + assert_equal [@customized_user], User.with_preferences(chat: { notifications: false, language: 'Latin' }) end - + def test_should_find_with_mixed_default_and_custom_group_preferences - assert_equal [@customized_user], User.with_preferences(:chat => {:color => 'red', :language => 'Latin'}) + assert_equal [@customized_user], User.with_preferences(chat: { color: 'red', language: 'Latin' }) end - + def test_should_find_with_mixed_basic_and_group_preferences @customized_user.preferred_language = 'English' @customized_user.save! - - assert_equal [@customized_user], User.with_preferences(:language => 'English', :chat => {:language => 'Latin'}) + + assert_equal [@customized_user], User.with_preferences(language: 'English', chat: { language: 'Latin' }) end - + def test_should_allow_chaining - assert_equal [@user], User.with_preferences(:language => 'English').with_preferences(:color => 'red') + assert_equal [@user], User.with_preferences(language: 'English').with_preferences(color: 'red') end end class PreferencesWithoutScopeTest < ModelPreferenceTest def setup User.preference :notifications - User.preference :language, :string, :default => 'English' - User.preference :color, :string, :default => 'red' - + User.preference :language, :string, default: 'English' + User.preference :color, :string, default: 'red' + @user = create_user - @customized_user = create_user(:login => 'customized', - :prefers_notifications => false, - :preferred_language => 'Latin' - ) + @customized_user = create_user(login: 'customized', + prefers_notifications: false, + preferred_language: 'Latin') @customized_user.prefers_notifications = false, :chat @customized_user.preferred_language = 'Latin', :chat @customized_user.save! end - + def test_should_not_find_if_no_preference_matched - assert_equal [], User.without_preferences(:color => 'red') + assert_equal [], User.without_preferences(color: 'red') end - + def test_should_find_with_null_preference - assert_equal [@user], User.without_preferences(:notifications => false) + assert_equal [@user], User.without_preferences(notifications: false) end - + def test_should_find_with_default_preference - assert_equal [@user], User.without_preferences(:language => 'Latin') + assert_equal [@user], User.without_preferences(language: 'Latin') end - + def test_should_find_with_multiple_default_preferences - assert_equal [@user], User.without_preferences(:language => 'Latin', :notifications => false) + assert_equal [@user], User.without_preferences(language: 'Latin', notifications: false) end - + def test_should_find_with_custom_preference - assert_equal [@customized_user], User.without_preferences(:language => 'English') + assert_equal [@customized_user], User.without_preferences(language: 'English') end - + def test_should_find_with_multiple_custom_preferences - assert_equal [@customized_user], User.without_preferences(:language => 'English', :notifications => nil) + assert_equal [@customized_user], User.without_preferences(language: 'English', notifications: nil) end - + def test_should_find_with_mixed_default_and_custom_preferences - assert_equal [@customized_user], User.without_preferences(:language => 'English', :color => 'blue') + assert_equal [@customized_user], User.without_preferences(language: 'English', color: 'blue') end - + def test_should_find_with_default_group_preference - assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin'}) + assert_equal [@user], User.without_preferences(chat: { language: 'Latin' }) end - + def test_should_find_with_customized_default_group_preference - User.preference :country, :string, :default => 'US', :group_defaults => {:chat => 'UK'} + User.preference :country, :string, default: 'US', group_defaults: { chat: 'UK' } @customized_user.preferred_country = 'US', :chat @customized_user.save! - - assert_equal [@user], User.without_preferences(:chat => {:country => 'US'}) + + assert_equal [@user], User.without_preferences(chat: { country: 'US' }) end - + def test_should_find_with_multiple_default_group_preferences - assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin', :notifications => false}) + assert_equal [@user], User.without_preferences(chat: { language: 'Latin', notifications: false }) end - + def test_should_find_with_custom_group_preference - assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English'}) + assert_equal [@customized_user], User.without_preferences(chat: { language: 'English' }) end - + def test_should_find_with_multiple_custom_group_preferences - assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English', :notifications => nil}) + assert_equal [@customized_user], User.without_preferences(chat: { language: 'English', notifications: nil }) end - + def test_should_find_with_mixed_default_and_custom_group_preferences - assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English', :color => 'blue'}) + assert_equal [@customized_user], User.without_preferences(chat: { language: 'English', color: 'blue' }) end - + def test_should_find_with_mixed_basic_and_group_preferences @customized_user.preferred_language = 'English' @customized_user.save! - - assert_equal [@customized_user], User.without_preferences(:language => 'Latin', :chat => {:language => 'English'}) + + assert_equal [@customized_user], User.without_preferences(language: 'Latin', chat: { language: 'English' }) end - + def test_should_allow_chaining - assert_equal [@user], User.without_preferences(:language => 'Latin').without_preferences(:color => 'blue') + assert_equal [@user], User.without_preferences(language: 'Latin').without_preferences(color: 'blue') end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 68f5281..e550ab5 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,5 @@ # Load the plugin testing framework -$:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib") +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib") require 'rubygems' require 'plugin_test_helper' @@ -14,13 +14,13 @@ # Add query counter ActiveRecord::Base.connection.class.class_eval do - IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/] - + IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/].freeze + def execute_with_query_record(sql, name = nil, &block) $queries_executed ||= [] $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r } execute_without_query_record(sql, name, &block) end - + alias_method_chain :execute, :query_record end diff --git a/test/unit/preference_definition_test.rb b/test/unit/preference_definition_test.rb index a1d554b..fa1f658 100644 --- a/test/unit/preference_definition_test.rb +++ b/test/unit/preference_definition_test.rb @@ -4,19 +4,19 @@ class PreferenceDefinitionByDefaultTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications) end - + def test_should_have_a_name assert_equal 'notifications', @definition.name end - + def test_should_not_have_a_default_value assert_nil @definition.default_value end - + def test_should_have_a_type assert_equal :boolean, @definition.type end - + def test_should_type_cast_values_as_booleans assert_equal nil, @definition.type_cast(nil) assert_equal true, @definition.type_cast(true) @@ -28,15 +28,15 @@ def test_should_type_cast_values_as_booleans class PreferenceDefinitionTest < ActiveSupport::TestCase def test_should_raise_exception_if_invalid_option_specified - assert_raise(ArgumentError) {Preferences::PreferenceDefinition.new(:notifications, :invalid => true)} + assert_raise(ArgumentError) { Preferences::PreferenceDefinition.new(:notifications, invalid: true) } end end class PreferenceDefinitionWithDefaultValueTest < ActiveSupport::TestCase def setup - @definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, :default => 1) + @definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, default: 1) end - + def test_should_type_cast_default_values assert_equal true, @definition.default_value end @@ -44,17 +44,17 @@ def test_should_type_cast_default_values class PreferenceDefinitionWithGroupDefaultsTest < ActiveSupport::TestCase def setup - @definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, :default => 1, :group_defaults => {:chat => 0}) + @definition = Preferences::PreferenceDefinition.new(:notifications, :boolean, default: 1, group_defaults: { chat: 0 }) end - + def test_should_use_default_for_default_group assert_equal true, @definition.default_value end - + def test_should_use_default_for_unknown_group assert_equal true, @definition.default_value('email') end - + def test_should_use_group_default_for_known_group assert_equal false, @definition.default_value('chat') end @@ -64,7 +64,7 @@ class PreferenceDefinitionWithStringifiedTypeTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications, 'any') end - + def test_should_symbolize_type assert_equal :any, @definition.type end @@ -74,15 +74,15 @@ class PreferenceDefinitionWithAnyTypeTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications, :any) end - + def test_use_custom_type assert_equal :any, @definition.type end - + def test_should_not_be_number assert !@definition.number? end - + def test_should_not_type_cast assert_equal nil, @definition.type_cast(nil) assert_equal 0, @definition.type_cast(0) @@ -91,24 +91,24 @@ def test_should_not_type_cast assert_equal true, @definition.type_cast(true) assert_equal '', @definition.type_cast('') end - + def test_should_query_false_if_value_is_nil assert_equal false, @definition.query(nil) end - + def test_should_query_true_if_value_is_zero assert_equal true, @definition.query(0) end - + def test_should_query_true_if_value_is_not_zero assert_equal true, @definition.query(1) assert_equal true, @definition.query(-1) end - + def test_should_query_false_if_value_is_blank assert_equal false, @definition.query('') end - + def test_should_query_true_if_value_is_not_blank assert_equal true, @definition.query('hello') end @@ -118,47 +118,47 @@ class PreferenceDefinitionWithBooleanTypeTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications) end - + def test_should_not_be_number assert !@definition.number? end - + def test_should_not_type_cast_if_value_is_nil assert_equal nil, @definition.type_cast(nil) end - + def test_should_type_cast_to_false_if_value_is_zero assert_equal false, @definition.type_cast(0) end - + def test_should_type_cast_to_true_if_value_is_not_zero assert_equal true, @definition.type_cast(1) end - + def test_should_type_cast_to_true_if_value_is_true_string assert_equal true, @definition.type_cast('true') end - + def test_should_type_cast_to_nil_if_value_is_not_true_string assert_nil @definition.type_cast('') end - + def test_should_query_false_if_value_is_nil assert_equal false, @definition.query(nil) end - + def test_should_query_true_if_value_is_one assert_equal true, @definition.query(1) end - + def test_should_query_false_if_value_not_one assert_equal false, @definition.query(0) end - + def test_should_query_true_if_value_is_true_string assert_equal true, @definition.query('true') end - + def test_should_query_false_if_value_is_not_true_string assert_equal false, @definition.query('') end @@ -168,31 +168,31 @@ class PreferenceDefinitionWithNumericTypeTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications, :integer) end - + def test_should_be_number assert @definition.number? end - + def test_should_type_cast_true_to_integer assert_equal 1, @definition.type_cast(true) end - + def test_should_type_cast_false_to_integer assert_equal 0, @definition.type_cast(false) end - + def test_should_type_cast_string_to_integer assert_equal 0, @definition.type_cast('hello') end - + def test_should_query_false_if_value_is_nil assert_equal false, @definition.query(nil) end - + def test_should_query_true_if_value_is_one assert_equal true, @definition.query(1) end - + def test_should_query_false_if_value_is_zero assert_equal false, @definition.query(0) end @@ -202,35 +202,35 @@ class PreferenceDefinitionWithStringTypeTest < ActiveSupport::TestCase def setup @definition = Preferences::PreferenceDefinition.new(:notifications, :string) end - + def test_should_not_be_number assert !@definition.number? end - + def test_should_type_cast_integers_to_strings assert_equal '1', @definition.type_cast('1') end - + def test_should_not_type_cast_booleans assert_equal true, @definition.type_cast(true) end - + def test_should_query_false_if_value_is_nil assert_equal false, @definition.query(nil) end - + def test_should_query_true_if_value_is_one assert_equal true, @definition.query(1) end - + def test_should_query_true_if_value_is_zero assert_equal true, @definition.query(0) end - + def test_should_query_false_if_value_is_blank assert_equal false, @definition.query('') end - + def test_should_query_true_if_value_is_not_blank assert_equal true, @definition.query('hello') end diff --git a/test/unit/preference_test.rb b/test/unit/preference_test.rb index fd65950..36ce9e0 100644 --- a/test/unit/preference_test.rb +++ b/test/unit/preference_test.rb @@ -4,31 +4,31 @@ class PreferenceByDefaultTest < ActiveSupport::TestCase def setup @preference = Preference.new end - + def test_should_not_have_a_name assert @preference.name.blank? end - + def test_should_not_have_an_owner assert_nil @preference.owner_id end - + def test_should_not_have_an_owner_type assert @preference.owner_type.blank? end - + def test_should_not_have_a_group_association assert_nil @preference.group_id end - + def test_should_not_have_a_group_type assert @preference.group_type.nil? end - + def test_should_not_have_a_value assert @preference.value.blank? end - + def test_should_not_have_a_definition assert_nil @preference.definition end @@ -39,59 +39,59 @@ def test_should_be_valid_with_a_set_of_valid_attributes preference = new_preference assert preference.valid? end - + def test_should_require_a_name - preference = new_preference(:name => nil) + preference = new_preference(name: nil) assert !preference.valid? assert preference.errors.invalid?(:name) end - + def test_should_require_an_owner_id - preference = new_preference(:owner => nil) + preference = new_preference(owner: nil) assert !preference.valid? assert preference.errors.invalid?(:owner_id) end - + def test_should_require_an_owner_type - preference = new_preference(:owner => nil) + preference = new_preference(owner: nil) assert !preference.valid? assert preference.errors.invalid?(:owner_type) end - + def test_should_not_require_a_group_id - preference = new_preference(:group => nil) + preference = new_preference(group: nil) assert preference.valid? end - + def test_should_not_require_a_group_id_if_type_specified - preference = new_preference(:group => nil) + preference = new_preference(group: nil) preference.group_type = 'Car' assert preference.valid? end - + def test_should_not_require_a_group_type - preference = new_preference(:group => nil) + preference = new_preference(group: nil) assert preference.valid? end - + def test_should_require_a_group_type_if_id_specified - preference = new_preference(:group => nil) + preference = new_preference(group: nil) preference.group_id = 1 assert !preference.valid? assert preference.errors.invalid?(:group_type) end - + def test_should_protect_attributes_from_mass_assignment preference = Preference.new( - :id => 1, - :name => 'notifications', - :value => '123', - :owner_id => 1, - :owner_type => 'User', - :group_id => 1, - :group_type => 'Car' + id: 1, + name: 'notifications', + value: '123', + owner_id: 1, + owner_type: 'User', + group_id: 1, + group_type: 'Car' ) - + assert_nil preference.id assert_equal 'notifications', preference.name assert_equal '123', preference.value @@ -108,24 +108,24 @@ def test_should_be_able_to_split_nil_groups assert_nil group_id assert_nil group_type end - + def test_should_be_able_to_split_non_active_record_groups group_id, group_type = Preference.split_group('car') assert_nil group_id assert_equal 'car', group_type - + group_id, group_type = Preference.split_group(:car) assert_nil group_id assert_equal 'car', group_type - + group_id, group_type = Preference.split_group(10) assert_nil group_id assert_equal 10, group_type end - + def test_should_be_able_to_split_active_record_groups car = create_car - + group_id, group_type = Preference.split_group(car) assert_equal 1, group_id assert_equal 'Car', group_type @@ -135,26 +135,26 @@ def test_should_be_able_to_split_active_record_groups class PreferenceAfterBeingCreatedTest < ActiveSupport::TestCase def setup User.preference :notifications, :boolean - - @preference = create_preference(:name => 'notifications') + + @preference = create_preference(name: 'notifications') end - + def test_should_have_an_owner assert_not_nil @preference.owner end - + def test_should_have_a_definition assert_not_nil @preference.definition end - + def test_should_have_a_value assert_not_nil @preference.value end - + def test_should_not_have_a_group_association assert_nil @preference.group end - + def teardown User.preference_definitions.delete('notifications') end @@ -162,9 +162,9 @@ def teardown class PreferenceWithBasicGroupTest < ActiveSupport::TestCase def setup - @preference = create_preference(:group_type => 'car') + @preference = create_preference(group_type: 'car') end - + def test_should_have_a_group_association assert_equal 'car', @preference.group end @@ -173,9 +173,9 @@ def test_should_have_a_group_association class PreferenceWithActiveRecordGroupTest < ActiveSupport::TestCase def setup @car = create_car - @preference = create_preference(:group => @car) + @preference = create_preference(group: @car) end - + def test_should_have_a_group_association assert_equal @car, @preference.group end @@ -185,28 +185,28 @@ class PreferenceWithBooleanTypeTest < ActiveSupport::TestCase def setup User.preference :notifications, :boolean end - + def test_should_type_cast_nil_values - preference = new_preference(:name => 'notifications', :value => nil) + preference = new_preference(name: 'notifications', value: nil) assert_nil preference.value end - + def test_should_type_cast_numeric_values - preference = new_preference(:name => 'notifications', :value => 0) + preference = new_preference(name: 'notifications', value: 0) assert_equal false, preference.value - + preference.value = 1 assert_equal true, preference.value end - + def test_should_type_cast_boolean_values - preference = new_preference(:name => 'notifications', :value => false) + preference = new_preference(name: 'notifications', value: false) assert_equal false, preference.value - + preference.value = true assert_equal true, preference.value end - + def teardown User.preference_definitions.delete('notifications') end @@ -215,21 +215,21 @@ def teardown class PreferenceWithSTIOwnerTest < ActiveSupport::TestCase def setup @manager = create_manager - @preference = create_preference(:owner => @manager, :name => 'health_insurance', :value => true) + @preference = create_preference(owner: @manager, name: 'health_insurance', value: true) end - + def test_should_have_an_owner assert_equal @manager, @preference.owner end - + def test_should_have_an_owner_type assert_equal 'Employee', @preference.owner_type end - + def test_should_have_a_definition assert_not_nil @preference.definition end - + def test_should_have_a_value assert_equal true, @preference.value end