enumerize-1.1.1/ 0000755 0000041 0000041 00000000000 12677055751 013564 5 ustar www-data www-data enumerize-1.1.1/Rakefile 0000644 0000041 0000041 00000000410 12677055751 015224 0 ustar www-data www-data #!/usr/bin/env rake
require "bundler/gem_tasks"
require 'rake/testtask'
require 'rspec/core/rake_task'
Rake::TestTask.new do |t|
t.libs << 'test'
t.pattern = 'test/*_test.rb'
t.verbose = true
end
RSpec::Core::RakeTask.new
task :default => [:test, :spec]
enumerize-1.1.1/Gemfile 0000644 0000041 0000041 00000000175 12677055751 015062 0 ustar www-data www-data eval_gemfile('Gemfile.global')
gem 'minitest', '~> 5.8'
gem 'rails', '4.2.4', :require => false
gem 'mongoid', '~> 5.0'
enumerize-1.1.1/enumerize.gemspec 0000644 0000041 0000041 00000001567 12677055751 017145 0 ustar www-data www-data # -*- encoding: utf-8 -*-
require File.expand_path('../lib/enumerize/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Sergey Nartimov"]
gem.email = "team@brainspec.com"
gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
gem.homepage = "https://github.com/brainspec/enumerize"
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.name = "enumerize"
gem.require_paths = ["lib"]
gem.version = Enumerize::VERSION
gem.required_ruby_version = '>= 1.9.3'
gem.add_dependency('activesupport', '>= 3.2')
end
enumerize-1.1.1/.rspec 0000644 0000041 0000041 00000000036 12677055751 014700 0 ustar www-data www-data --color
--require spec_helper
enumerize-1.1.1/MIT-LICENSE 0000644 0000041 0000041 00000002052 12677055751 015217 0 ustar www-data www-data Copyright (c) 2012 Brainspec
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
enumerize-1.1.1/Gemfile.global 0000644 0000041 0000041 00000000554 12677055751 016322 0 ustar www-data www-data source 'https://rubygems.org'
gemspec
gem 'rake'
gem 'rspec', :require => false
gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
gem 'sequel'
platforms :rbx do
gem 'rubysl', '~> 2.0'
gem 'psych'
gem 'rubinius-developer_tools'
gem 'rubysl-test-unit'
end
gem 'simple_form'
gem 'formtastic'
enumerize-1.1.1/spec/ 0000755 0000041 0000041 00000000000 12677055751 014516 5 ustar www-data www-data enumerize-1.1.1/spec/spec_helper.rb 0000644 0000041 0000041 00000001271 12677055751 017335 0 ustar www-data www-data require 'rails'
require 'enumerize'
require 'rspec/matchers/fail_matchers'
RSpec.configure do |config|
config.disable_monkey_patching!
config.order = :random
Kernel.srand config.seed
config.filter_run focus: true
config.run_all_when_everything_filtered = true
config.expect_with :rspec do |expectations|
expectations.syntax = :expect
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.syntax = :expect
mocks.verify_partial_doubles = true
end
if config.files_to_run.one?
config.default_formatter = 'doc'
end
config.warnings = true
config.include RSpec::Matchers::FailMatchers
end
enumerize-1.1.1/spec/enumerize/ 0000755 0000041 0000041 00000000000 12677055751 016521 5 ustar www-data www-data enumerize-1.1.1/spec/enumerize/integrations/ 0000755 0000041 0000041 00000000000 12677055751 021227 5 ustar www-data www-data enumerize-1.1.1/spec/enumerize/integrations/rspec/ 0000755 0000041 0000041 00000000000 12677055751 022343 5 ustar www-data www-data enumerize-1.1.1/spec/enumerize/integrations/rspec/matcher_spec.rb 0000644 0000041 0000041 00000017402 12677055751 025331 0 ustar www-data www-data require 'active_record'
silence_warnings do
ActiveRecord::Migration.verbose = false
ActiveRecord::Base.logger = Logger.new(nil)
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
end
ActiveRecord::Base.connection.instance_eval do
create_table :users do |t|
t.string :sex
t.string :role
t.string :account_type
end
end
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, :in => [:male, :female], scope: true
enumerize :role, :in => [:user, :admin], scope: :having_role
enumerize :account_type, :in => [:basic, :premium]
end
RSpec.describe Enumerize::Integrations::RSpec::Matcher do
let(:model) do
Class.new do
extend Enumerize
def self.name
'Model'
end
end
end
subject do
model.new
end
describe 'without qualifier' do
it 'accepts when has defined a enumerize' do
model.enumerize(:sex, :in => [:male, :female])
expect(subject).to enumerize(:sex)
end
it 'rejects when has not defined a enumerize' do
message = 'Expected Model to define enumerize :sex'
expect do
expect(subject).to enumerize(:sex)
end.to fail_with(message)
end
end
describe '#in' do
context 'defined as array' do
before do
model.enumerize(:sex, :in => [:male, :female])
end
it 'accepts the right params as an array' do
expect(subject).to enumerize(:sex).in([:male, :female])
end
it 'accepts the right params as regular params' do
expect(subject).to enumerize(:sex).in(:male, :female)
end
it 'accepts the the right params in a different order' do
expect(subject).to enumerize(:sex).in(:female, :male)
end
it 'rejects wrong params' do
message = 'Expected Model to define enumerize :sex in: "boy", "girl"'
expect do
expect(subject).to enumerize(:sex).in(:boy, :girl)
end.to fail_with(message)
end
it 'has the right message when negated' do
message = 'Did not expect Model to define enumerize :sex in: "female", "male"'
expect do
expect(subject).to_not enumerize(:sex).in(:male, :female)
end.to fail_with(message)
end
end
context 'defined as hash' do
before do
model.enumerize(:sex, :in => { male: 0, female: 1 })
end
it 'accepts the right params as an array' do
expect(subject).to enumerize(:sex).in(:male, :female)
end
it 'accepts the right params as a hash' do
expect(subject).to enumerize(:sex).in(male: 0, female: 1)
end
it 'accepts the right params as a hash in a different order' do
expect(subject).to enumerize(:sex).in(female: 1, male: 0)
end
it 'rejects wrong keys' do
message = 'Expected Model to define enumerize :sex in: "{:boy=>0, :girl=>1}"'
expect do
expect(subject).to enumerize(:sex).in(boy: 0, girl: 1)
end.to fail_with(message)
end
it 'rejects wrong values' do
message = 'Expected Model to define enumerize :sex in: "{:male=>2, :female=>3}"'
expect do
expect(subject).to enumerize(:sex).in(male: 2, female: 3)
end.to fail_with(message)
end
end
it 'has the right description' do
matcher = enumerize(:sex).in(:male, :female)
expect(matcher.description).to eq('define enumerize :sex in: "female", "male"')
end
end
describe '#with_default' do
before do
model.enumerize(:sex, :in => [:male, :female], default: :female)
end
it 'accepts the right default value' do
expect(subject).to enumerize(:sex).in(:male, :female).with_default(:female)
end
it 'rejects the wrong default value' do
message = 'Expected Model to define enumerize :sex in: "female", "male" with "male" as default value'
expect do
expect(subject).to enumerize(:sex).in(:male, :female).with_default(:male)
end.to fail_with(message)
end
it 'rejects if the `in` is wrong with a correct default value' do
message = 'Expected Model to define enumerize :sex in: "boy", "girl" with "female" as default value'
expect do
expect(subject).to enumerize(:sex).in(:boy, :girl).with_default(:female)
end.to fail_with(message)
end
it 'has the right description' do
matcher = enumerize(:sex).in(:male, :female).with_default(:female)
message = 'define enumerize :sex in: "female", "male" with "female" as default value'
expect(matcher.description).to eq(message)
end
end
describe '#with_i18n_scope' do
context 'defined as string' do
before do
model.enumerize(:sex, :in => [:male, :female], i18n_scope: 'sex')
end
it 'accepts the right i18n_scope' do
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope('sex')
end
it 'rejects the wrong i18n_scope' do
message = 'Expected Model to define enumerize :sex in: "female", "male" i18n_scope: "gender"'
expect do
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope('gender')
end.to fail_with(message)
end
end
context 'defined as array' do
before do
model.enumerize(:sex, :in => [:male, :female], i18n_scope: ['sex', 'more.sex'])
end
it 'accepts the wrong i18n_scope' do
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope(['sex', 'more.sex'])
end
it 'rejects the wrong i18n_scope' do
message = 'Expected Model to define enumerize :sex in: "female", "male" i18n_scope: ["sex"]'
expect do
expect(subject).to enumerize(:sex).in(:male, :female).with_i18n_scope(['sex'])
end.to fail_with(message)
end
end
end
describe '#with_predicates' do
it 'accepts when predicates is defined as a boolean' do
model.enumerize(:sex, :in => [:male, :female], predicates: true)
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
end
it 'accepts when predicates is defined as a hash' do
model.enumerize(:sex, :in => [:male, :female], predicates: { prefix: true })
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(prefix: true)
end
it 'rejects when predicates is not defined' do
model.enumerize(:sex, :in => [:male, :female])
message = 'Expected Model to define enumerize :sex in: "female", "male" predicates: true'
expect do
expect(subject).to enumerize(:sex).in(:male, :female).with_predicates(true)
end.to fail_with(message)
end
end
describe '#with_multiple' do
it 'accepts when has defined the multiple' do
model.enumerize(:sex, :in => [:male, :female], multiple: true)
expect(subject).to enumerize(:sex).in(:male, :female).with_multiple(true)
end
it 'rejects when has not defined the multiple' do
model.enumerize(:sex, :in => [:male, :female])
message = 'Expected Model to define enumerize :sex in: "female", "male" multiple: true'
expect do
expect(subject).to enumerize(:sex).in(:male, :female).with_multiple(true)
end.to fail_with(message)
end
end
describe '#with_scope' do
subject do
User.new
end
it 'accepts when scope is defined as a boolean' do
expect(subject).to enumerize(:sex).in(:male, :female).with_scope(true)
end
it 'accepts when scope is defined as a hash' do
expect(subject).to enumerize(:role).in(:user, :admin).with_scope(scope: :having_role)
end
it 'rejects when scope is not defined' do
message = 'Expected User to define enumerize :account_type in: "basic", "premium" scope: true'
expect do
expect(subject).to enumerize(:account_type).in(:basic, :premium).with_scope(true)
end.to fail_with(message)
end
end
end
enumerize-1.1.1/.travis.yml 0000644 0000041 0000041 00000000620 12677055751 015673 0 ustar www-data www-data language: ruby
services:
- mongodb
before_install:
- gem install bundler
gemfile:
- Gemfile
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- jruby-19mode
matrix:
include:
- rvm: 2.2
gemfile: Gemfile.rails40
- rvm: 2.2
gemfile: Gemfile.mongo_mapper
notifications:
email:
recipients:
- lest@brainspec.com
- nashby@brainspec.com
- dreamfall@brainspec.com
enumerize-1.1.1/lib/ 0000755 0000041 0000041 00000000000 12677055751 014332 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize.rb 0000644 0000041 0000041 00000004176 12677055751 016672 0 ustar www-data www-data require 'active_support/concern'
require 'enumerize/version'
module Enumerize
autoload :Attribute, 'enumerize/attribute'
autoload :AttributeMap, 'enumerize/attribute_map'
autoload :Value, 'enumerize/value'
autoload :Set, 'enumerize/set'
autoload :Base, 'enumerize/base'
autoload :Module, 'enumerize/module'
autoload :Predicates, 'enumerize/predicates'
autoload :Predicatable, 'enumerize/predicatable'
autoload :ModuleAttributes, 'enumerize/module_attributes'
autoload :ActiveRecordSupport, 'enumerize/activerecord'
autoload :SequelSupport, 'enumerize/sequel'
autoload :MongoidSupport, 'enumerize/mongoid'
module Scope
autoload :ActiveRecord, 'enumerize/scope/activerecord'
autoload :Sequel, 'enumerize/scope/sequel'
autoload :Mongoid, 'enumerize/scope/mongoid'
end
def self.included(base)
ActiveSupport::Deprecation.warn '`include Enumerize` was deprecated. Please use `extend Enumerize`.', caller
extended(base)
end
def self.extended(base)
base.send :include, Enumerize::Base
base.extend Enumerize::Predicates
if defined?(::ActiveRecord::Base)
base.extend Enumerize::ActiveRecordSupport
base.extend Enumerize::Scope::ActiveRecord
end
if defined?(::Mongoid::Document)
base.extend Enumerize::MongoidSupport
base.extend Enumerize::Scope::Mongoid
end
if defined?(::Sequel::Model)
base.extend Enumerize::SequelSupport
base.extend Enumerize::Scope::Sequel
end
if defined?(::RailsAdmin)
require 'enumerize/integrations/rails_admin'
base.extend Enumerize::Integrations::RailsAdmin
end
if ::Module === base
base.extend Enumerize::Base::ClassMethods
base.extend Enumerize::ModuleAttributes
end
super
end
begin
require 'simple_form'
require 'enumerize/hooks/simple_form'
require 'enumerize/form_helper'
rescue LoadError
end
begin
require 'formtastic'
require 'enumerize/hooks/formtastic'
rescue LoadError
end
begin
require 'rspec/matchers'
rescue LoadError
else
require 'enumerize/integrations/rspec'
end
end
enumerize-1.1.1/lib/enumerize/ 0000755 0000041 0000041 00000000000 12677055751 016335 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize/predicatable.rb 0000644 0000041 0000041 00000000707 12677055751 021305 0 ustar www-data www-data module Enumerize
module Predicatable
def respond_to_missing?(method, include_private=false)
predicate_method?(method) || super
end
private
def method_missing(method, *args, &block)
if predicate_method?(method)
predicate_call(method[0..-2], *args, &block)
else
super
end
end
def predicate_method?(method)
method[-1] == '?' && @attr.values.include?(method[0..-2])
end
end
end
enumerize-1.1.1/lib/enumerize/integrations/ 0000755 0000041 0000041 00000000000 12677055751 021043 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize/integrations/rails_admin.rb 0000644 0000041 0000041 00000000544 12677055751 023655 0 ustar www-data www-data module Enumerize
module Integrations
module RailsAdmin
def enumerize(name, options={})
super
_enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}_enum
self.class.enumerized_attributes[:#{name}].values.map{|v| [v.text, v.value]}
end
RUBY
end
end
end
end
enumerize-1.1.1/lib/enumerize/integrations/rspec/ 0000755 0000041 0000041 00000000000 12677055751 022157 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize/integrations/rspec/matcher.rb 0000644 0000041 0000041 00000011024 12677055751 024125 0 ustar www-data www-data module Enumerize
module Integrations
module RSpec
class Matcher
def initialize(expected_attr)
self.expected_attr = expected_attr
end
def in(*expected_values)
self.expected_values = expected_values.flatten
self
end
def with_default(expected_default)
self.expected_default = expected_default.to_s
self
end
def with_i18n_scope(expected_i18n_scope)
self.expected_i18n_scope = expected_i18n_scope
self
end
def with_predicates(expected_predicates)
self.expected_predicates = expected_predicates
self
end
def with_multiple(expected_multiple)
self.expected_multiple = expected_multiple
self
end
def with_scope(expected_scope)
self.expected_scope = expected_scope
self
end
def failure_message
"Expected #{expectation}"
end
def failure_message_when_negated
"Did not expect #{expectation}"
end
def description
description = "define enumerize :#{expected_attr}"
description += " in: #{quote_values(expected_values)}" if expected_values
description += " with #{expected_default.inspect} as default value" if expected_default
description += " i18n_scope: #{expected_i18n_scope.inspect}" if expected_i18n_scope
description += " predicates: #{expected_predicates.inspect}" if expected_predicates
description += " multiple: #{expected_multiple.inspect}" if expected_multiple
description += " scope: #{expected_scope.inspect}" if expected_scope
description
end
def matches?(subject)
self.subject = subject
matches = true
matches &= matches_attribute?
matches &= matches_values? if expected_values
matches &= matches_default_value? if expected_default
matches &= matches_i18n_scope? if expected_i18n_scope
matches &= matches_predicates? if expected_predicates
matches &= matches_multiple? if expected_multiple
matches &= matches_scope? if expected_scope
matches
end
private
attr_accessor :expected_attr, :expected_values, :subject, :expected_default,
:expected_i18n_scope, :expected_predicates, :expected_multiple,
:expected_scope
def expectation
"#{subject.class.name} to #{description}"
end
def matches_attribute?
attributes.present?
end
def matches_values?
matches_array_values? || matches_hash_values?
end
def matches_array_values?
sorted_values == enumerized_values
end
def matches_hash_values?
return unless expected_values.first.is_a?(Hash)
expected_values.first.all? { |k, v| enumerized_value_hash[k.to_s] == v; }
end
def matches_default_value?
expected_default == enumerized_default
end
def matches_i18n_scope?
attributes.i18n_scope == expected_i18n_scope
end
def matches_predicates?
if expected_predicates.is_a?(TrueClass)
subject.respond_to?("#{sorted_values.first}?")
else
subject.respond_to?("#{expected_attr}_#{attributes.values.first}?")
end
end
def matches_multiple?
subject.instance_variable_defined?("@_#{expected_attr}_enumerized_set")
end
def matches_scope?
if expected_scope.is_a?(TrueClass)
subject_class.respond_to?("with_#{expected_attr}")
else
subject_class.respond_to?(expected_scope[:scope])
end
end
def sorted_values
@sorted_values ||=expected_values.map(&:to_s).sort
end
def enumerized_values
@enumerized_values ||= attributes.values.sort
end
def enumerized_default
@enumerized_default ||= attributes.default_value
end
def enumerized_value_hash
@enumerized_value_hash ||= attributes.instance_variable_get('@value_hash')
end
def attributes
subject_class.enumerized_attributes.attributes[expected_attr.to_s]
end
def subject_class
@subject_class ||= subject.class
end
def quote_values(values)
sorted_values.map(&:inspect).join(', ')
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/integrations/rspec.rb 0000644 0000041 0000041 00000000457 12677055751 022512 0 ustar www-data www-data require 'enumerize/integrations/rspec/matcher'
module Enumerize
module Integrations
module RSpec
def enumerize(attr)
::Enumerize::Integrations::RSpec::Matcher.new(attr)
end
end
end
end
module RSpec
module Matchers
include Enumerize::Integrations::RSpec
end
end
enumerize-1.1.1/lib/enumerize/predicates.rb 0000644 0000041 0000041 00000003145 12677055751 021010 0 ustar www-data www-data require 'active_support/core_ext/module/delegation'
module Enumerize
# Predicate methods.
#
# Basic usage:
#
# class User
# extend Enumerize
# enumerize :sex, in: %w(male female), predicates: true
# end
#
# user = User.new
#
# user.male? # => false
# user.female? # => false
#
# user.sex = 'male'
#
# user.male? # => true
# user.female? # => false
#
# Using prefix:
#
# class User
# extend Enumerize
# enumerize :sex, in: %w(male female), predicates: { prefix: true }
# end
#
# user = User.new
# user.sex = 'female'
# user.sex_female? # => true
#
# Use only and except options to specify what values create
# predicate methods for.
module Predicates
def enumerize(name, options={})
super
if options[:predicates]
Builder.new(enumerized_attributes[name], options[:predicates]).build(_enumerize_module)
end
end
class Builder
def initialize(attr, options)
@attr = attr
@options = options.is_a?(Hash) ? options : {}
end
def values
values = @attr.values
if @options[:only]
values &= Array(@options[:only]).map(&:to_s)
end
if @options[:except]
values -= Array(@options[:except]).map(&:to_s)
end
values
end
def names
values.map { |v| "#{v.tr('-', '_')}?" }
end
def build(klass)
klass.delegate(*names, to: @attr.name, prefix: @options[:prefix], allow_nil: true)
end
end
end
end
enumerize-1.1.1/lib/enumerize/set.rb 0000644 0000041 0000041 00000002637 12677055751 017465 0 ustar www-data www-data require 'active_support/core_ext/module/delegation'
module Enumerize
class Set
include Enumerable
include Predicatable
attr_reader :values
def initialize(obj, attr, values)
@obj = obj
@attr = attr
@values = []
if values.respond_to?(:each)
values.each do |input|
value = @attr.find_value(input)
if value && !@values.include?(value)
@values << value
end
end
end
end
def <<(value)
@values << value
mutate!
end
alias_method :push, :<<
delegate :each, :empty?, :size, to: :values
def to_ary
@values.to_a
end
def texts
@values.map(&:text)
end
delegate :join, to: :to_ary
def ==(other)
return false unless other.respond_to?(:each)
other.size == size && other.all? { |v| @values.include?(@attr.find_value(v)) }
end
alias_method :eql?, :==
def include?(value)
@values.include?(@attr.find_value(value))
end
def delete(value)
@values.delete(@attr.find_value(value))
mutate!
end
def inspect
"#"
end
def encode_with(coder)
coder.represent_object(Array, @values)
end
private
def predicate_call(value)
include?(value)
end
def mutate!
@values = @obj.public_send("#{@attr.name}=", @values).values
end
end
end
enumerize-1.1.1/lib/enumerize/sequel.rb 0000644 0000041 0000041 00000003500 12677055751 020156 0 ustar www-data www-data module Enumerize
module SequelSupport
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if defined?(::Sequel::Model) && self < ::Sequel::Model
include InstanceMethods
require 'enumerize/hooks/sequel_dataset'
end
end
end
private
module InstanceMethods
def validate
super
self.class.enumerized_attributes.each do |attr|
value = read_attribute_for_validation(attr.name)
next if value.blank?
if attr.kind_of? Multiple
errors.add attr.name, "is invalid" unless value.respond_to?(:all?) && value.all? { |v| v.blank? || attr.find_value(v) }
else
errors.add attr.name, "is not included in the list" unless attr.find_value(value)
end
end
end
def _set_default_value_for_enumerized_attributes
_enumerized_values_for_validation.delete_if do |k, v|
v.nil?
end
if defined?(Sequel::Plugins::Serialization::InstanceMethods)
modules = self.class.ancestors
plugin_idx = modules.index(Sequel::Plugins::Serialization::InstanceMethods)
if plugin_idx && plugin_idx < modules.index(Enumerize::SequelSupport::InstanceMethods)
abort "ERROR: You need to enable the Sequel serialization plugin before calling any enumerize methods on a model."
end
plugin_idx = modules.index(Sequel::Plugins::ValidationHelpers::InstanceMethods)
if plugin_idx && plugin_idx < modules.index(Enumerize::SequelSupport::InstanceMethods)
abort "ERROR: You need to enable the Sequel validation_helpers plugin before calling any enumerize methods on a model."
end
end
super
end
end
end
end
enumerize-1.1.1/lib/enumerize/value.rb 0000644 0000041 0000041 00000001740 12677055751 020000 0 ustar www-data www-data require 'i18n'
module Enumerize
class Value < String
include Predicatable
attr_reader :value
def initialize(attr, name, value=nil)
@attr = attr
@value = value.nil? ? name.to_s : value
super(name.to_s)
end
def text
I18n.t(i18n_keys[0], :default => i18n_keys[1..-1])
end
def ==(other)
super(other.to_s) || value == other
end
def encode_with(coder)
coder.represent_object(self.class.superclass, @value)
end
private
def predicate_call(value)
value == self
end
def i18n_keys
@i18n_keys ||= begin
i18n_keys = i18n_scopes
i18n_keys << [:"enumerize.defaults.#{@attr.name}.#{self}"]
i18n_keys << [:"enumerize.#{@attr.name}.#{self}"]
i18n_keys << self.underscore.humanize # humanize value if there are no translations
i18n_keys.flatten
end
end
def i18n_scopes
@attr.i18n_scopes.map { |s| :"#{s}.#{self}" }
end
end
end
enumerize-1.1.1/lib/enumerize/module.rb 0000644 0000041 0000041 00000001061 12677055751 020145 0 ustar www-data www-data module Enumerize
class Module < ::Module
attr_reader :_class_methods
def initialize
super
@_class_methods = ::Module.new
@_dependents = []
@_dependent_evals = []
end
def included(klass)
klass.extend _class_methods
@_dependent_evals.each do |block|
klass.instance_eval(&block)
end
@_dependents << klass
end
def dependent_eval(&block)
@_dependents.each do |klass|
klass.instance_eval(&block)
end
@_dependent_evals << block
end
end
end
enumerize-1.1.1/lib/enumerize/hooks/ 0000755 0000041 0000041 00000000000 12677055751 017460 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize/hooks/sequel_dataset.rb 0000644 0000041 0000041 00000000706 12677055751 023013 0 ustar www-data www-data module Enumerize
module Hooks
module SequelDataset
def self.included(klass)
klass.alias_method_chain :literal_append, :enumerize
end
def literal_append_with_enumerize(sql, v)
if v.is_a?(Enumerize::Value)
literal_append(sql, v.value)
else
literal_append_without_enumerize(sql, v)
end
end
end
end
end
::Sequel::Dataset.send :include, Enumerize::Hooks::SequelDataset
enumerize-1.1.1/lib/enumerize/hooks/simple_form.rb 0000644 0000041 0000041 00000002417 12677055751 022325 0 ustar www-data www-data require 'active_support/concern'
module Enumerize
module Hooks
module SimpleFormBuilderExtension
extend ActiveSupport::Concern
included do
alias_method_chain :input, :enumerize
alias_method_chain :input_field, :enumerize
end
def input_with_enumerize(attribute_name, options={}, &block)
add_input_options_for_enumerized_attribute(attribute_name, options)
input_without_enumerize(attribute_name, options, &block)
end
def input_field_with_enumerize(attribute_name, options={})
add_input_options_for_enumerized_attribute(attribute_name, options)
input_field_without_enumerize(attribute_name, options)
end
private
def add_input_options_for_enumerized_attribute(attribute_name, options)
klass = object.class
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
options[:collection] ||= attr.options
if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
end
end
end
end
end
end
::SimpleForm::FormBuilder.send :include, Enumerize::Hooks::SimpleFormBuilderExtension
enumerize-1.1.1/lib/enumerize/hooks/formtastic.rb 0000644 0000041 0000041 00000001461 12677055751 022162 0 ustar www-data www-data require 'active_support/concern'
module Enumerize
module Hooks
module FormtasticFormBuilderExtension
extend ActiveSupport::Concern
included do
alias_method_chain :input, :enumerize
end
def input_with_enumerize(method, options={})
klass = object.class
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
options[:collection] ||= attr.options
if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
end
end
input_without_enumerize(method, options)
end
end
end
end
::Formtastic::FormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
enumerize-1.1.1/lib/enumerize/hooks/uniqueness.rb 0000644 0000041 0000041 00000001210 12677055751 022176 0 ustar www-data www-data require 'active_support/concern'
module Enumerize
module Hooks
module UniquenessValidator
extend ActiveSupport::Concern
included do
alias_method_chain :validate_each, :enumerize
end
def validate_each_with_enumerize(record, name, value)
if record.class.respond_to?(:enumerized_attributes) && (attr = record.class.enumerized_attributes[name])
value = attr.find_value(value).try(:value)
end
validate_each_without_enumerize(record, name, value)
end
end
end
end
::ActiveRecord::Validations::UniquenessValidator.send :include, Enumerize::Hooks::UniquenessValidator
enumerize-1.1.1/lib/enumerize/version.rb 0000644 0000041 0000041 00000000051 12677055751 020343 0 ustar www-data www-data module Enumerize
VERSION = "1.1.1"
end
enumerize-1.1.1/lib/enumerize/scope/ 0000755 0000041 0000041 00000000000 12677055751 017446 5 ustar www-data www-data enumerize-1.1.1/lib/enumerize/scope/sequel.rb 0000644 0000041 0000041 00000002135 12677055751 021272 0 ustar www-data www-data module Enumerize
module Scope
module Sequel
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if defined?(::Sequel::Model) && self < ::Sequel::Model
if options[:scope]
_define_sequel_scope_methods!(name, options)
end
require 'enumerize/hooks/sequel_dataset'
end
end
end
private
def _define_sequel_scope_methods!(name, options)
klass = self
scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
def_dataset_method scope_name do |*values|
values = values.map { |value| klass.enumerized_attributes[name].find_value(value).value }
values = values.first if values.size == 1
where(name => values)
end
if options[:scope] == true
def_dataset_method "without_#{name}" do |*values|
values = values.map { |value| klass.enumerized_attributes[name].find_value(value).value }
exclude(name => values)
end
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/scope/mongoid.rb 0000644 0000041 0000041 00000001654 12677055751 021435 0 ustar www-data www-data module Enumerize
module Scope
module Mongoid
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if self < ::Mongoid::Document
if options[:scope]
_define_mongoid_scope_methods!(name, options)
end
end
end
end
private
def _define_mongoid_scope_methods!(name, options)
scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
define_singleton_method scope_name do |*values|
values = enumerized_attributes[name].find_values(*values).map(&:value)
self.in(name => values)
end
if options[:scope] == true
define_singleton_method "without_#{name}" do |*values|
values = enumerized_attributes[name].find_values(*values).map(&:value)
not_in(name => values)
end
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/scope/activerecord.rb 0000644 0000041 0000041 00000001777 12677055751 022461 0 ustar www-data www-data module Enumerize
module Scope
module ActiveRecord
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if self < ::ActiveRecord::Base
if options[:scope]
_define_activerecord_scope_methods!(name, options)
end
end
end
end
private
def _define_activerecord_scope_methods!(name, options)
scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
define_singleton_method scope_name do |*values|
values = enumerized_attributes[name].find_values(*values).map(&:value)
values = values.first if values.size == 1
where(name => values)
end
if options[:scope] == true
define_singleton_method "without_#{name}" do |*values|
values = enumerized_attributes[name].find_values(*values).map(&:value)
where(arel_table[name].not_in(values))
end
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/module_attributes.rb 0000644 0000041 0000041 00000000355 12677055751 022420 0 ustar www-data www-data module Enumerize
module ModuleAttributes
def included(base)
base.extend Enumerize
base.send :include, _enumerize_module
enumerized_attributes.add_dependant base.enumerized_attributes
super
end
end
end
enumerize-1.1.1/lib/enumerize/mongoid.rb 0000644 0000041 0000041 00000000433 12677055751 020316 0 ustar www-data www-data module Enumerize
module MongoidSupport
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if self < ::Mongoid::Document
after_initialize :_set_default_value_for_enumerized_attributes
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/base.rb 0000644 0000041 0000041 00000006054 12677055751 017601 0 ustar www-data www-data module Enumerize
module Base
def self.included(base)
base.extend ClassMethods
if base.respond_to?(:validate)
base.validate :_validate_enumerized_attributes
end
class << base
if (method_defined?(:inherited) || private_method_defined?(:inherited)) && !private_method_defined?(:inherited_without_enumerized)
alias_method :inherited_without_enumerized, :inherited
private :inherited_without_enumerized
end
alias_method :inherited, :inherited_with_enumerized
end
end
module ClassMethods
def enumerize(name, options={})
attr = Attribute.new(self, name, options)
enumerized_attributes << attr
unless methods.include?(attr.name)
_enumerize_module._class_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{attr.name}
enumerized_attributes[:#{attr.name}]
end
RUBY
end
attr.define_methods!(_enumerize_module)
end
def enumerized_attributes
@enumerized_attributes ||= AttributeMap.new
end
def inherited_with_enumerized(subclass)
enumerized_attributes.add_dependant subclass.enumerized_attributes
if respond_to?(:inherited_without_enumerized, true)
inherited_without_enumerized subclass
end
end
private
def _enumerize_module
@_enumerize_module ||= begin
mod = Module.new
include mod
mod
end
end
end
def initialize(*)
super
_set_default_value_for_enumerized_attributes
end
def read_attribute_for_validation(key)
key = key.to_s
if _enumerized_values_for_validation.has_key?(key)
_enumerized_values_for_validation[key]
elsif defined?(super)
super
else
send(key)
end
end
private
def _enumerized_values_for_validation
@_enumerized_values_for_validation ||= {}
end
def _validate_enumerized_attributes
self.class.enumerized_attributes.each do |attr|
value = read_attribute_for_validation(attr.name)
next if value.blank?
if attr.kind_of? Multiple
errors.add attr.name unless value.respond_to?(:all?) && value.all? { |v| v.blank? || attr.find_value(v) }
else
errors.add attr.name, :inclusion unless attr.find_value(value)
end
end
end
def _set_default_value_for_enumerized_attributes
self.class.enumerized_attributes.each do |attr|
if respond_to?(attr.name)
attr_value = public_send(attr.name)
else
next
end
value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
value = attr.default_value
if value.respond_to?(:call)
value = value.arity == 0 ? value.call : value.call(self)
end
public_send("#{attr.name}=", value)
end
end
end
end
end
enumerize-1.1.1/lib/enumerize/activerecord.rb 0000644 0000041 0000041 00000002247 12677055751 021341 0 ustar www-data www-data module Enumerize
module ActiveRecordSupport
def enumerize(name, options={})
super
_enumerize_module.dependent_eval do
if self < ::ActiveRecord::Base
include InstanceMethods
# Since Rails use `allocate` method on models and initializes them with `init_with` method.
# This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
after_initialize :_set_default_value_for_enumerized_attributes
# https://github.com/brainspec/enumerize/issues/111
require 'enumerize/hooks/uniqueness'
end
end
end
module InstanceMethods
# https://github.com/brainspec/enumerize/issues/74
def write_attribute(attr_name, value)
if self.class.enumerized_attributes[attr_name]
_enumerized_values_for_validation[attr_name.to_s] = value
end
super
end
# Support multiple enumerized attributes
def becomes(klass)
became = super
klass.enumerized_attributes.each do |attr|
became.send("#{attr.name}=", send(attr.name))
end
became
end
end
end
end
enumerize-1.1.1/lib/enumerize/attribute_map.rb 0000644 0000041 0000041 00000001155 12677055751 021524 0 ustar www-data www-data module Enumerize
class AttributeMap
attr_reader :attributes
def initialize
@attributes = {}
@dependants = []
end
def [](name)
@attributes[name.to_s]
end
def <<(attr)
@attributes[attr.name.to_s] = attr
@dependants.each do |dependant|
dependant << attr
end
end
def each
@attributes.each_pair do |_name, attr|
yield attr
end
end
def empty?
@attributes.empty?
end
def add_dependant(dependant)
@dependants << dependant
each do |attr|
dependant << attr
end
end
end
end
enumerize-1.1.1/lib/enumerize/attribute.rb 0000644 0000041 0000041 00000012077 12677055751 020674 0 ustar www-data www-data module Enumerize
class Attribute
attr_reader :name, :values, :default_value, :i18n_scope
def initialize(klass, name, options={})
raise ArgumentError, ':in option is required' unless options[:in]
raise ArgumentError, ':scope option does not work with option :multiple' if options[:multiple] && options[:scope]
extend Multiple if options[:multiple]
@klass = klass
@name = name.to_sym
value_class = options.fetch(:value_class, Value)
@values = Array(options[:in]).map { |v| value_class.new(self, *v) }
@value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
@value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
if options[:i18n_scope]
raise ArgumentError, ':i18n_scope option accepts only String or Array of strings' unless Array(options[:i18n_scope]).all? { |s| s.is_a?(String) }
@i18n_scope = options[:i18n_scope]
end
if options[:default]
@default_value = find_default_value(options[:default])
raise ArgumentError, 'invalid default value' unless @default_value
end
end
def find_default_value(value)
if value.respond_to?(:call)
value
else
find_value(value)
end
end
def find_value(value)
@value_hash[value.to_s] unless value.nil?
end
def find_values(*values)
values.map { |value| find_value(value) }.compact
end
def i18n_scopes
@i18n_scopes ||= if i18n_scope
scopes = Array(i18n_scope)
elsif @klass.respond_to?(:model_name)
scopes = ["enumerize.#{@klass.model_name.i18n_key}.#{name}"]
else
[]
end
end
def options(options = {})
values = if options.empty?
@values
else
raise ArgumentError, 'Options cannot have both :only and :except' if options[:only] && options[:except]
only = Array(options[:only]).map(&:to_s)
except = Array(options[:except]).map(&:to_s)
@values.reject do |value|
if options[:only]
!only.include?(value)
elsif options[:except]
except.include?(value)
end
end
end
values.map { |v| [v.text, v.to_s] }
end
def respond_to_missing?(method, include_private=false)
@value_hash.include?(method.to_s) || super
end
def define_methods!(mod)
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}
if defined?(super)
self.class.enumerized_attributes[:#{name}].find_value(super)
elsif respond_to?(:read_attribute)
self.class.enumerized_attributes[:#{name}].find_value(read_attribute(:#{name}))
else
if defined?(@#{name})
self.class.enumerized_attributes[:#{name}].find_value(@#{name})
else
@#{name} = nil
end
end
end
def #{name}=(new_value)
allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
if defined?(super)
super allowed_value_or_nil
elsif respond_to?(:write_attribute, true)
write_attribute '#{name}', allowed_value_or_nil
else
@#{name} = allowed_value_or_nil
end
_enumerized_values_for_validation['#{name}'] = new_value.nil? ? nil : new_value.to_s
allowed_value_or_nil
end
def #{name}_text
self.#{name} && self.#{name}.text
end
def #{name}_value
self.#{name} && self.#{name}.value
end
RUBY
end
private
def method_missing(method)
if @value_hash.include?(method.to_s)
find_value(method)
else
super
end
end
end
module Multiple
def find_default_value(value)
if value.respond_to?(:call)
value
else
find_values(*value)
end
end
def define_methods!(mod)
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}
unless defined?(@_#{name}_enumerized_set)
if defined?(super)
self.#{name} = super
elsif respond_to?(:read_attribute)
self.#{name} = read_attribute(:#{name})
else
if defined?(@#{name})
self.#{name} = @#{name}
else
self.#{name} = []
end
end
end
@_#{name}_enumerized_set
end
def #{name}=(values)
@_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
raw_values = #{name}.values.map(&:value)
if defined?(super)
super raw_values
elsif respond_to?(:write_attribute, true)
write_attribute '#{name}', raw_values
else
@#{name} = raw_values
end
_enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.map(&:to_s) : values
#{name}
end
RUBY
end
end
end
enumerize-1.1.1/Gemfile.rails40 0000644 0000041 0000041 00000000163 12677055751 016334 0 ustar www-data www-data eval_gemfile('Gemfile.global')
gem 'minitest', '~> 4.1'
gem 'rails', '4.0.13', :require => false
gem 'mongoid'
enumerize-1.1.1/test/ 0000755 0000041 0000041 00000000000 12677055751 014543 5 ustar www-data www-data enumerize-1.1.1/test/mongo_mapper_test.rb 0000644 0000041 0000041 00000002676 12677055751 020625 0 ustar www-data www-data require 'test_helper'
begin
silence_warnings do
require 'mongo_mapper'
end
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = 'enumerize-test-suite-of-mongomapper'
describe Enumerize do
class MongoMapperUser
include MongoMapper::Document
extend Enumerize
key :sex
key :role
enumerize :sex, :in => %w[male female]
enumerize :role, :in => %w[admin user], :default => 'user'
end
before { $VERBOSE = nil }
after { $VERBOSE = true }
let(:model) { MongoMapperUser }
it 'sets nil if invalid value is passed' do
user = model.new
user.sex = :invalid
user.sex.must_equal nil
end
it 'saves value' do
model.delete_all
user = model.new
user.sex = :female
user.save!
user.sex.must_equal 'female'
end
it 'loads value' do
model.delete_all
model.create!(:sex => :male)
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
user = model.first
user.sex.must_equal 'male'
user.sex_text.must_equal 'Male'
end
end
it 'has default value' do
model.new.role.must_equal 'user'
end
it 'validates inclusion' do
user = model.new
user.role = 'wrong'
user.wont_be :valid?
end
it 'assigns value on loaded record' do
model.delete_all
model.create!(:sex => :male)
user = model.first
user.sex = :female
user.sex.must_equal 'female'
end
end
rescue LoadError
# Skip
end
enumerize-1.1.1/test/attribute_map_test.rb 0000644 0000041 0000041 00000002621 12677055751 020770 0 ustar www-data www-data require 'test_helper'
module Enumerize
class AttributeMapTest < MiniTest::Spec
subject { AttributeMap.new }
def make_attr(name)
Attribute.new(nil, name, :in => %[a b])
end
it 'empty when no attrs' do
subject.must_be_empty
end
it 'not empty when attr added' do
subject << make_attr(:a)
subject.wont_be_empty
end
it 'iterates over added attrs' do
attr_1 = make_attr(:a)
attr_2 = make_attr(:b)
subject << attr_1
subject << attr_2
count = 0
actual = []
subject.each do |element|
count += 1
actual << element
end
count.must_equal 2
actual.must_equal [attr_1, attr_2]
end
it 'reads attribute by name' do
attr = make_attr(:a)
subject << attr
subject[:a].must_equal attr
end
it 'reads attribute by name using string' do
attr = make_attr(:a)
subject << attr
subject['a'].must_equal attr
end
it 'updates dependants' do
attr = make_attr(:a)
dependant = MiniTest::Mock.new
dependant.expect(:<<, nil, [attr])
subject.add_dependant dependant
subject << attr
dependant.verify
end
it 'adds attrs to dependant' do
attr = make_attr(:a)
subject << attr
dependant = AttributeMap.new
subject.add_dependant dependant
dependant[:a].must_equal attr
end
end
end
enumerize-1.1.1/test/simple_form_test.rb 0000644 0000041 0000041 00000006205 12677055751 020446 0 ustar www-data www-data require 'test_helper'
require 'simple_form/version'
class SimpleFormSpec < MiniTest::Spec
include ViewTestHelper
include SimpleForm::ActionViewExtensions::FormHelper
class Thing < Struct.new(:name)
extend ActiveModel::Naming
include ActiveModel::Conversion
def persisted?
false
end
end
class User < Struct.new(:sex, :age)
extend ActiveModel::Naming
include ActiveModel::Conversion
extend Enumerize
enumerize :sex, :in => [:male, :female]
def persisted?
false
end
end
class Post < Struct.new(:category, :title)
extend ActiveModel::Naming
include ActiveModel::Conversion
extend Enumerize
enumerize :categories, :in => [:music, :games], :multiple => true
def persisted?
false
end
end
let(:user) { User.new }
let(:post) { Post.new }
it 'renders select with enumerized values using input_field' do
concat(simple_form_for(user) do |f|
f.input_field(:sex)
end)
assert_select 'select option[value=male]'
assert_select 'select option[value=female]'
end
it 'renders select with enumerized values' do
concat(simple_form_for(user) do |f|
f.input(:sex)
end)
assert_select 'select option[value=male]'
assert_select 'select option[value=female]'
end
it 'renders multiple select with enumerized values' do
concat(simple_form_for(post) do |f|
f.input(:categories)
end)
assert_select 'select[multiple=multiple]'
assert_select 'select option[value=music]'
assert_select 'select option[value=games]'
end
it 'renders multiple select with selected enumerized value' do
post.categories << :music
concat(simple_form_for(post) do |f|
f.input(:categories)
end)
assert_select 'select[multiple=multiple]'
assert_select 'select option[value=music][selected=selected]'
assert_select 'select option[value=games][selected=selected]', count: 0
end
it 'renders checkboxes with enumerized values' do
concat(simple_form_for(post) do |f|
f.input(:categories, as: :check_boxes)
end)
assert_select 'select[multiple=multiple]', count: 0
assert_select 'input[type=checkbox][value=music]'
assert_select 'input[type=checkbox][value=games]'
end
it 'renders checkboxes with selected enumerized value' do
post.categories << :music
concat(simple_form_for(post) do |f|
f.input(:categories, as: :check_boxes)
end)
assert_select 'input[type=checkbox][value=music][checked=checked]'
assert_select 'input[type=checkbox][value=games][checked=checked]', count: 0
end
it 'renders radio buttons with enumerated values' do
concat(simple_form_for(user) do |f|
f.input(:sex, :as => :radio_buttons)
end)
assert_select 'input[type=radio][value=male]'
assert_select 'input[type=radio][value=female]'
end
it 'does not affect not enumerized attributes' do
concat(simple_form_for(user) do |f|
f.input(:age)
end)
assert_select 'input.string'
end
it 'does not affect not enumerized classes' do
concat(simple_form_for(Thing.new) do |f|
f.input(:name)
end)
assert_select 'input.string'
end
end
enumerize-1.1.1/test/rails_admin_test.rb 0000644 0000041 0000041 00000001265 12677055751 020415 0 ustar www-data www-data require 'test_helper'
class RailsAdminSpec < MiniTest::Spec
let(:klass) do
Class.new do
extend Enumerize
end
end
let(:object) { klass.new }
it 'defines enum method' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
klass.enumerize(:foo, in: [:a, :b])
object.foo_enum.must_equal [['a text', 'a'], ['b text', 'b']]
end
end
it 'defines enum properly for custom values enumerations' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
klass.enumerize(:foo, in: {:a => 1, :b => 2})
object.foo_enum.must_equal [['a text', 1], ['b text', 2]]
end
end
end
enumerize-1.1.1/test/module_attributes_test.rb 0000644 0000041 0000041 00000002447 12677055751 021671 0 ustar www-data www-data require 'test_helper'
class ModuleAttributesSpec < MiniTest::Spec
it 'inherits attribute from the module' do
mod = Module.new do
extend Enumerize
enumerize :sex, :in => %w[male female], :default => 'male'
end
klass = Class.new
klass.send :include, mod
klass.enumerized_attributes[:sex].must_be_instance_of Enumerize::Attribute
klass.new.sex.must_equal 'male'
klass.sex.must_be_instance_of Enumerize::Attribute
end
it 'uses new attributes from the module' do
mod = Module.new do
extend Enumerize
end
klass = Class.new
klass.send :include, mod
mod.enumerize :sex, :in => %w[male female], :default => 'male'
klass.enumerized_attributes[:sex].must_be_instance_of Enumerize::Attribute
klass.new.sex.must_equal 'male'
klass.sex.must_be_instance_of Enumerize::Attribute
end
it 'validates attributes' do
mod = Module.new do
extend Enumerize
enumerize :sex, :in => %w[male female]
end
klass = Class.new do
include ActiveModel::Validations
include mod
def self.model_name
ActiveModel::Name.new(self, nil, 'name')
end
end
object = klass.new
object.sex = 'wrong'
object.wont_be :valid?
object.errors[:sex].must_include 'is not included in the list'
end
end
enumerize-1.1.1/test/formtastic_test.rb 0000644 0000041 0000041 00000006107 12677055751 020306 0 ustar www-data www-data require 'test_helper'
Formtastic::FormBuilder.action_class_finder = Formtastic::ActionClassFinder
Formtastic::FormBuilder.input_class_finder = Formtastic::InputClassFinder
class FormtasticSpec < MiniTest::Spec
include ViewTestHelper
include Formtastic::Helpers::FormHelper
class Thing < Struct.new(:name)
extend ActiveModel::Naming
include ActiveModel::Conversion
def persisted?
false
end
end
class User < Struct.new(:sex, :age)
extend ActiveModel::Naming
include ActiveModel::Conversion
extend Enumerize
enumerize :sex, :in => [:male, :female]
def persisted?
false
end
end
class Post < Struct.new(:category, :title)
extend ActiveModel::Naming
include ActiveModel::Conversion
extend Enumerize
enumerize :categories, :in => [:music, :games], :multiple => true
def persisted?
false
end
end
before { $VERBOSE = nil }
after { $VERBOSE = true }
let(:user) { User.new }
let(:post) { Post.new }
it 'renders select with enumerized values' do
concat(semantic_form_for(user) do |f|
f.input :sex
end)
assert_select 'select option[value=male]'
assert_select 'select option[value=female]'
end
it 'renders multiple select with enumerized values' do
concat(semantic_form_for(post) do |f|
f.input(:categories)
end)
assert_select 'select[multiple=multiple]'
assert_select 'select option[value=music]'
assert_select 'select option[value=games]'
end
it 'renders multiple select with selected enumerized value' do
post.categories << :music
concat(semantic_form_for(post) do |f|
f.input(:categories)
end)
assert_select 'select[multiple=multiple]'
assert_select 'select option[value=music][selected=selected]'
assert_select 'select option[value=games][selected=selected]', count: 0
end
it 'renders checkboxes with enumerized values' do
concat(semantic_form_for(post) do |f|
f.input(:categories, as: :check_boxes)
end)
assert_select 'select[multiple=multiple]', count: 0
assert_select 'input[type=checkbox][value=music]'
assert_select 'input[type=checkbox][value=games]'
end
it 'renders checkboxes with selected enumerized value' do
post.categories << :music
concat(semantic_form_for(post) do |f|
f.input(:categories, as: :check_boxes)
end)
assert_select 'input[type=checkbox][value=music][checked=checked]'
assert_select 'input[type=checkbox][value=games][checked=checked]', count: 0
end
it 'renders radio buttons with enumerized values' do
concat(semantic_form_for(user) do |f|
f.input :sex, :as => :radio
end)
assert_select 'input[type=radio][value=male]'
assert_select 'input[type=radio][value=female]'
end
it 'does not affect not enumerized attributes' do
concat(semantic_form_for(user) do |f|
f.input(:age)
end)
assert_select 'input[type=text]'
end
it 'does not affect not enumerized classes' do
concat(semantic_form_for(Thing.new) do |f|
f.input(:name)
end)
assert_select 'input[type=text]'
end
end
enumerize-1.1.1/test/predicates_test.rb 0000644 0000041 0000041 00000003237 12677055751 020257 0 ustar www-data www-data require 'test_helper'
describe Enumerize::Predicates do
let(:klass) do
Class.new do
extend Enumerize
end
end
let(:object) { klass.new }
it 'creates predicate methods' do
klass.enumerize(:foo, in: %w(a b), predicates: true)
object.must_respond_to :a?
object.must_respond_to :b?
end
it 'creates predicate methods when enumerized values have dash in it' do
klass.enumerize(:foo, in: %w(foo-bar bar-foo), predicates: true)
object.must_respond_to :foo_bar?
object.must_respond_to :bar_foo?
end
it 'creates predicate methods on multiple attribute' do
klass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
object.must_respond_to :a?
object.must_respond_to :b?
end
it 'checks values' do
klass.enumerize(:foo, in: %w(a b), predicates: true)
object.foo = 'a'
object.a?.must_equal true
object.b?.must_equal false
end
it 'checks values on multiple attribute' do
klass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
object.foo << :a
object.a?.must_equal true
object.b?.must_equal false
end
it 'prefixes methods' do
klass.enumerize(:foo, in: %w(a b), predicates: { prefix: 'bar' })
object.wont_respond_to :a?
object.wont_respond_to :b?
object.must_respond_to :bar_a?
object.must_respond_to :bar_b?
end
it 'accepts only option' do
klass.enumerize(:foo, in: %w(a b), predicates: { only: :a })
object.must_respond_to :a?
object.wont_respond_to :b?
end
it 'accepts except option' do
klass.enumerize(:foo, in: %w(a b), predicates: { except: :a })
object.wont_respond_to :a?
object.must_respond_to :b?
end
end
enumerize-1.1.1/test/sequel_test.rb 0000644 0000041 0000041 00000016752 12677055751 017440 0 ustar www-data www-data require 'test_helper'
require 'sequel'
require 'logger'
require 'jdbc/sqlite3' if RUBY_PLATFORM == 'java'
module SequelTest
silence_warnings do
DB = if RUBY_PLATFORM == 'java'
Sequel.connect('jdbc:sqlite::memory:')
else
Sequel.sqlite
end
DB.loggers << Logger.new(nil)
end
DB.create_table :users do
primary_key :id
String :sex
String :role
String :lambda_role
String :name
String :interests
String :status
String :account_type, default: "basic"
end
DB.create_table :documents do
primary_key :id
String :visibility
Time :created_at
Time :updated_at
end
class Document < Sequel::Model
extend Enumerize
enumerize :visibility, :in => [:public, :private, :protected], :scope => true, :default => :public
end
module RoleEnum
extend Enumerize
enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
end
class User < Sequel::Model
plugin :serialization, :json, :interests
plugin :dirty
plugin :defaults_setter
plugin :validation_helpers
extend Enumerize
include RoleEnum
enumerize :sex, :in => [:male, :female]
enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
enumerize :account_type, :in => [:basic, :premium]
end
class UniqStatusUser < User
def validate
super
validates_unique :status
validates_presence :sex
end
end
describe Enumerize::SequelSupport do
it 'sets nil if invalid value is passed' do
user = User.new
user.sex = :invalid
user.sex.must_equal nil
end
it 'saves value' do
User.filter.delete
user = User.new
user.sex = :female
user.save
user.sex.must_equal 'female'
end
it 'loads value' do
User.filter.delete
User.create(:sex => :male)
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
user = User.first
user.sex.must_equal 'male'
user.sex_text.must_equal 'Male'
end
end
it 'has default value' do
User.new.role.must_equal 'user'
User.new.values[:role].must_equal 'user'
end
it 'does not set default value for not selected attributes' do
User.filter.delete
User.create(:sex => :male)
assert_equal [:id], User.select(:id).first.values.keys
end
it 'has default value with lambda' do
User.new.lambda_role.must_equal 'admin'
User.new.values[:lambda_role].must_equal 'admin'
end
it 'uses after_initialize callback to set default value' do
User.filter.delete
User.create(sex: 'male', lambda_role: nil)
user = User.where(:sex => 'male').first
user.lambda_role.must_equal 'admin'
end
it 'uses default value from db column' do
User.new.account_type.must_equal 'basic'
end
it 'validates inclusion' do
user = User.new
user.role = 'wrong'
user.wont_be :valid?
user.errors[:role].must_include 'is not included in the list'
end
it 'validates inclusion on mass assignment' do
assert_raises Sequel::ValidationFailed do
User.create(role: 'wrong')
end
end
it "uses persisted value for validation if it hasn't been set" do
user = User.create :sex => :male
User[user.id].read_attribute_for_validation(:sex).must_equal 'male'
end
it 'is valid with empty string assigned' do
user = User.new
user.role = ''
user.must_be :valid?
end
it 'stores nil when empty string assigned' do
user = User.new
user.role = ''
user.values[:role].must_equal nil
end
it 'supports multiple attributes' do
user = User.new
user.interests ||= []
user.interests.must_be_empty
user.interests << "music"
user.interests.must_equal %w(music)
user.save
user = User[user.id]
user.interests.must_be_instance_of Enumerize::Set
user.interests.must_equal %w(music)
user.interests << "sports"
user.interests.must_equal %w(music sports)
user.interests = []
interests = user.interests
interests << "music"
interests.must_equal %w(music)
interests << "dancing"
interests.must_equal %w(music dancing)
end
it 'returns invalid multiple value for validation' do
user = User.new
user.interests << :music
user.interests << :invalid
values = user.read_attribute_for_validation(:interests)
values.must_equal %w(music invalid)
end
it 'validates multiple attributes' do
user = User.new
user.interests << :invalid
user.wont_be :valid?
user.interests = Object.new
user.wont_be :valid?
user.interests = ['music', '']
user.must_be :valid?
end
it 'stores custom values for multiple attributes' do
User.filter.delete
klass = Class.new(User)
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
user = klass.new
user.interests << :music
user.interests.must_equal %w(music)
user.save
user = klass[user.id]
user.interests.must_equal %w(music)
end
it 'adds scope' do
User.filter.delete
user_1 = User.create(status: :active, role: :admin)
user_2 = User.create(status: :blocked)
User.with_status(:active).to_a.must_equal [user_1]
User.with_status(:blocked).to_a.must_equal [user_2]
User.with_status(:active, :blocked).to_set.must_equal [user_1, user_2].to_set
User.without_status(:active).to_a.must_equal [user_2]
User.without_status(:active, :blocked).to_a.must_equal []
User.having_role(:admin).to_a.must_equal [user_1]
end
it 'allows either key or value as valid' do
user_1 = User.new(status: :active)
user_2 = User.new(status: 1)
user_3 = User.new(status: '1')
user_1.status.must_equal 'active'
user_2.status.must_equal 'active'
user_3.status.must_equal 'active'
user_1.must_be :valid?
user_2.must_be :valid?
user_3.must_be :valid?
end
it 'supports defining enumerized attributes on abstract class' do
Document.filter.delete
document = Document.new
document.visibility = :protected
document.visibility.must_equal 'protected'
end
it 'supports defining enumerized scopes on abstract class' do
Document.filter.delete
document_1 = Document.create(visibility: :public)
document_2 = Document.create(visibility: :private)
Document.with_visibility(:public).to_a.must_equal [document_1]
end
it 'validates uniqueness' do
user = User.create(status: :active, sex: "male")
user = UniqStatusUser.new
user.sex = "male"
user.status = :active
user.valid?.must_equal false
user.errors[:status].wont_be :empty?
end
it "doesn't update record" do
Document.filter.delete
expected = Time.new(2010, 10, 10)
document = Document.new
document.updated_at = expected
document.save
document = Document.last
document.save
assert_equal expected, document.updated_at
end
it 'changes from dirty should be serialized as scalar values' do
user = User.create(:status => :active)
user.status = :blocked
expected = { status: [1, 2] }.to_yaml
assert_equal expected, user.column_changes.to_yaml
end
end
end
enumerize-1.1.1/test/set_test.rb 0000644 0000041 0000041 00000006103 12677055751 016722 0 ustar www-data www-data require 'test_helper'
require 'yaml'
describe Enumerize::Set do
let(:klass) do
Class.new do
extend Enumerize
enumerize :foo, :in => %w(a b c), :multiple => true
end
end
let(:object) { klass.new }
def build_set(values)
@set = Enumerize::Set.new(object, klass.foo, values)
end
def set
@set
end
def assert_called(object, method)
called = false
object.singleton_class.class_eval do
define_method method do |*args, &block|
called = true
super(*args, &block)
end
end
yield
assert called, "Expected ##{method} to be called"
end
before do
build_set %w(a)
end
it 'equals to other set' do
set.must_equal Enumerize::Set.new(nil, klass.foo, %w(a))
end
it 'equals to array' do
set.must_equal %w(a)
end
it 'equals to array of symbols' do
set.must_equal [:a]
end
it 'has unique values' do
set << :a
set.must_equal %w(a)
end
it 'equals to array with different value order' do
set << :b
set.must_equal %w(b a)
end
it "isn't equal to a part of values" do
set << :b
set.wont_equal %w(a)
end
describe '#push' do
it 'appends values' do
set.push :b
set.must_include :b
end
it 'reassigns attribute' do
assert_called object, :foo= do
set.push :b
end
end
end
describe '#delete' do
it 'deletes value' do
set.delete :a
set.wont_include :a
end
it 'reassigns attribute' do
assert_called object, :foo= do
set.delete :a
end
end
end
describe '#inspect' do
it 'returns custom string' do
set << :b
set.inspect.must_equal '#'
end
end
describe '#to_ary' do
it 'returns array' do
set.to_ary.must_be_instance_of Array
end
end
describe '#texts' do
it 'returns array of text values' do
set.texts.must_equal ['A']
end
end
describe '#join' do
it 'joins values' do
set << :b
set.join(', ').must_equal 'a, b'
end
end
describe 'boolean methods comparison' do
it 'returns true if value equals method' do
set << :a
set.a?.must_equal true
end
it 'returns false if value does not equal method' do
set << :a
set.b?.must_equal false
end
it 'raises NoMethodError if there are no values like boolean method' do
proc {
set.some_method?
}.must_raise NoMethodError
end
it 'raises ArgumentError if arguments are passed' do
proc {
set.a?('<3')
}.must_raise ArgumentError
end
it 'responds to methods for existing values' do
set.must_respond_to :a?
set.must_respond_to :b?
set.must_respond_to :c?
end
it 'returns a method object' do
set.method(:a?).must_be_instance_of Method
end
it 'does not respond to a method for not existing value' do
set.wont_respond_to :some_method?
end
end
describe 'serialization' do
it 'is serialized to yaml as array' do
set << :a
assert_equal YAML.dump(%w(a)), YAML.dump(set)
end
end
end
enumerize-1.1.1/test/test_helper.rb 0000644 0000041 0000041 00000001631 12677055751 017407 0 ustar www-data www-data require 'minitest/autorun'
require 'minitest/spec'
require 'active_support/core_ext/kernel/reporting'
require 'active_model'
require 'rails'
begin
require 'mongoid'
rescue LoadError
end
module RailsAdmin
end
require 'simple_form'
SimpleForm.setup {}
require 'formtastic'
module EnumerizeTest
class Application < Rails::Application
config.active_support.deprecation = :stderr
config.active_support.test_order = :random
config.eager_load = false
config.secret_key_base = 'secret'
end
end
EnumerizeTest::Application.initialize!
$VERBOSE=true
require 'enumerize'
Dir["#{File.dirname(__FILE__)}/support/*.rb"].each do |file|
require file
end
module MiscHelpers
def store_translations(locale, translations, &block)
begin
I18n.backend.store_translations locale, translations
yield
ensure
I18n.reload!
end
end
end
class MiniTest::Spec
include MiscHelpers
end
enumerize-1.1.1/test/mongoid_test.rb 0000644 0000041 0000041 00000006160 12677055751 017566 0 ustar www-data www-data require 'test_helper'
begin
silence_warnings do
require 'mongoid'
end
Mongoid.configure do |config|
config.connect_to('enumerize-test-suite')
config.options = { use_utc: true, include_root_in_json: true }
end
describe Enumerize do
class MongoidUser
include Mongoid::Document
extend Enumerize
field :sex
field :role
enumerize :sex, :in => %w[male female], scope: true
enumerize :status, :in => %w[notice warning error], scope: true
enumerize :role, :in => %w[admin user], :default => 'user', scope: :having_role
enumerize :mult, :in => %w[one two three four], :multiple => true
end
before { $VERBOSE = nil }
after { $VERBOSE = true }
let(:model) { MongoidUser }
it 'sets nil if invalid value is passed' do
user = model.new
user.sex = :invalid
user.sex.must_equal nil
end
it 'saves value' do
model.delete_all
user = model.new
user.sex = :female
user.save!
user.sex.must_equal 'female'
end
it 'loads value' do
model.delete_all
model.create!(:sex => :male)
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
user = model.first
user.sex.must_equal 'male'
user.sex_text.must_equal 'Male'
end
end
it 'has default value' do
model.new.role.must_equal 'user'
end
it 'uses after_initialize callback to set default value' do
model.delete_all
model.create!(sex: 'male', role: nil)
user = model.where(sex: 'male').first
user.role.must_equal 'user'
end
it 'validates inclusion' do
user = model.new
user.role = 'wrong'
user.wont_be :valid?
end
it 'assigns value on loaded record' do
model.delete_all
model.create!(:sex => :male)
user = model.first
user.sex = :female
user.sex.must_equal 'female'
end
it 'loads multiple properly' do
model.delete_all
model.create!(:mult => ['one', 'two'])
user = model.first
user.mult.to_a.must_equal ['one', 'two']
end
it 'adds scope' do
model.delete_all
user_1 = model.create!(sex: :male, role: :admin)
user_2 = model.create!(sex: :female, role: :user)
model.with_sex(:male).to_a.must_equal [user_1]
model.with_sex(:female).to_a.must_equal [user_2]
model.with_sex(:male, :female).to_set.must_equal [user_1, user_2].to_set
model.without_sex(:male).to_a.must_equal [user_2]
model.without_sex(:female).to_a.must_equal [user_1]
model.without_sex(:male, :female).to_a.must_equal []
model.having_role(:admin).to_a.must_equal [user_1]
model.having_role(:user).to_a.must_equal [user_2]
end
it 'chains scopes' do
model.delete_all
user_1 = model.create!(status: :notice)
user_2 = model.create!(status: :warning)
user_3 = model.create!(status: :error)
model.with_status(:notice, :warning).with_status(:notice, :error).to_a.must_equal [user_1]
model.with_status(:notice, :warning).union.with_status(:notice, :error).to_a.must_equal [user_1, user_2, user_3]
end
it 'ignores not enumerized values that passed to the scope method' do
model.delete_all
model.with_sex(:foo).must_equal []
end
end
rescue LoadError
# Skip
end
enumerize-1.1.1/test/base_test.rb 0000644 0000041 0000041 00000012256 12677055751 017047 0 ustar www-data www-data require 'test_helper'
describe Enumerize::Base do
let(:klass) do
Class.new do
extend Enumerize
end
end
let(:subklass) do
Class.new(klass)
end
let(:object) { klass.new }
it 'returns nil when not set' do
klass.enumerize(:foo, :in => [:a, :b])
object.foo.must_equal nil
end
it 'returns value that was set' do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :a
object.foo.must_equal 'a'
end
it 'returns translation' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text'}}) do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :a
object.foo.text.must_equal 'a text'
object.foo_text.must_equal 'a text'
object.foo_text.must_equal 'a text'
end
end
it 'returns nil as translation when value is nil' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text'}}) do
klass.enumerize(:foo, :in => [:a, :b])
object.foo_text.must_equal nil
end
end
it 'scopes translation by i18 key' do
def klass.model_name
name = "ExampleClass"
def name.i18n_key
'example_class'
end
name
end
store_translations(:en, :enumerize => {:example_class => {:foo => {:a => 'a text scoped'}}}) do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :a
object.foo.text.must_equal 'a text scoped'
object.foo_text.must_equal 'a text scoped'
end
end
it 'returns humanized value if there are no translations' do
store_translations(:en, :enumerize => {}) do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :a
object.foo_text.must_equal 'A'
end
end
it 'stores value as string' do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :a
object.instance_variable_get(:@foo).must_be_instance_of String
end
it 'handles default value' do
klass.enumerize(:foo, :in => [:a, :b], :default => :b)
object.foo.must_equal 'b'
end
it 'handles default value with lambda' do
klass.enumerize(:foo, :in => [:a, :b], :default => lambda { :b })
object.foo.must_equal 'b'
end
it 'injects object instance into lamda default value' do
klass.enumerize(:foo, :in => [:a, :b], :default => lambda { |obj| :b if obj.is_a? klass })
object.foo.must_equal 'b'
end
it 'raises exception on invalid default value' do
proc {
klass.enumerize(:foo, :in => [:a, :b], :default => :c)
}.must_raise ArgumentError
end
it 'has enumerized attributes' do
klass.enumerized_attributes.must_be_empty
klass.enumerize(:foo, :in => %w[a b])
klass.enumerized_attributes[:foo].must_be_instance_of Enumerize::Attribute
end
it "doesn't override existing method" do
method = klass.method(:name)
klass.enumerize(:name, :in => %w[a b], :default => 'a')
klass.method(:name).must_equal method
end
it "inherits enumerized attributes from a parent class" do
klass.enumerize(:foo, :in => %w[a b])
subklass.enumerized_attributes[:foo].must_be_instance_of Enumerize::Attribute
end
it "inherits enumerized attributes from a grandparent class" do
klass.enumerize(:foo, :in => %w[a b])
Class.new(subklass).enumerized_attributes[:foo].must_be_instance_of Enumerize::Attribute
end
it "doesn't add enumerized attributes to parent class" do
klass.enumerize(:foo, :in => %w[a b])
subklass.enumerize(:bar, :in => %w[c d])
klass.enumerized_attributes[:bar].must_equal nil
end
it 'adds new parent class attributes to subclass' do
subklass = Class.new(klass)
klass.enumerize :foo, :in => %w[a b]
subklass.enumerized_attributes[:foo].must_be_instance_of Enumerize::Attribute
end
it 'stores nil value' do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = nil
object.instance_variable_get(:@foo).must_equal nil
end
it 'casts value to string for validation' do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = :c
object.read_attribute_for_validation(:foo).must_equal 'c'
end
it "doesn't cast nil to string for validation" do
klass.enumerize(:foo, :in => [:a, :b])
object.foo = nil
object.read_attribute_for_validation(:foo).must_equal nil
end
it 'calls super in the accessor method' do
accessors = Module.new do
def attributes
@attributes ||= {}
end
def foo
attributes[:foo]
end
def foo=(v)
attributes[:foo] = v
end
end
klass = Class.new do
include accessors
extend Enumerize
enumerize :foo, :in => %w[test]
end
object = klass.new
object.foo.must_be_nil
object.attributes.must_equal({:foo => nil})
object.foo = 'test'
object.foo.must_equal 'test'
object.attributes.must_equal(:foo => 'test')
end
it 'stores hash values' do
klass.enumerize(:foo, :in => {:a => 1, :b => 2})
object.foo = :a
object.instance_variable_get(:@foo).must_equal 1
object.foo.must_equal 'a'
object.foo = :b
object.instance_variable_get(:@foo).must_equal 2
object.foo.must_equal 'b'
end
it 'returns custom value' do
klass.enumerize(:foo, :in => {:a => 1, :b => 2})
object.foo = :a
object.foo_value.must_equal 1
object.foo = :b
object.foo_value.must_equal 2
end
end
enumerize-1.1.1/test/activerecord_test.rb 0000644 0000041 0000041 00000021452 12677055751 020605 0 ustar www-data www-data require 'test_helper'
require 'active_record'
require 'logger'
silence_warnings do
ActiveRecord::Migration.verbose = false
ActiveRecord::Base.logger = Logger.new(nil)
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
end
ActiveRecord::Base.connection.instance_eval do
create_table :users do |t|
t.string :sex
t.string :role
t.string :lambda_role
t.string :name
t.string :interests
t.integer :status
t.string :account_type, :default => :basic
end
create_table :documents do |t|
t.string :visibility
t.timestamps null: true
end
end
class BaseEntity < ActiveRecord::Base
self.abstract_class = true
extend Enumerize
enumerize :visibility, :in => [:public, :private, :protected], :scope => true, :default => :public
end
class Document < BaseEntity
end
module RoleEnum
extend Enumerize
enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
end
class User < ActiveRecord::Base
extend Enumerize
include RoleEnum
enumerize :sex, :in => [:male, :female]
serialize :interests, Array
enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
enumerize :status, :in => { active: 1, blocked: 2 }, scope: true
enumerize :account_type, :in => [:basic, :premium]
end
class UniqStatusUser < User
validates :status, uniqueness: true
validates :sex, presence: true
end
describe Enumerize::ActiveRecordSupport do
it 'sets nil if invalid value is passed' do
user = User.new
user.sex = :invalid
user.sex.must_equal nil
end
it 'saves value' do
User.delete_all
user = User.new
user.sex = :female
user.save!
user.sex.must_equal 'female'
end
it 'loads value' do
User.delete_all
User.create!(:sex => :male)
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
user = User.first
user.sex.must_equal 'male'
user.sex_text.must_equal 'Male'
end
end
it 'has default value' do
User.new.role.must_equal 'user'
User.new.attributes['role'].must_equal 'user'
end
it 'does not set default value for not selected attributes' do
User.delete_all
User.create!(:sex => :male)
assert_equal ['id'], User.select(:id).first.attributes.keys
end
it 'has default value with lambda' do
User.new.lambda_role.must_equal 'admin'
User.new.attributes['lambda_role'].must_equal 'admin'
end
it 'uses after_initialize callback to set default value' do
User.delete_all
User.create!(sex: 'male', lambda_role: nil)
user = User.where(:sex => 'male').first
user.lambda_role.must_equal 'admin'
end
it 'uses default value from db column' do
User.new.account_type.must_equal 'basic'
end
it 'has default value with default scope' do
UserWithDefaultScope = Class.new(User) do
default_scope -> { having_role(:user) }
end
UserWithDefaultScope.new.role.must_equal 'user'
UserWithDefaultScope.new.attributes['role'].must_equal 'user'
end
it 'validates inclusion' do
user = User.new
user.role = 'wrong'
user.wont_be :valid?
user.errors[:role].must_include 'is not included in the list'
end
it 'validates inclusion when using write_attribute with string attribute' do
user = User.new
user.send(:write_attribute, 'role', 'wrong')
user.read_attribute_for_validation(:role).must_equal 'wrong'
user.wont_be :valid?
user.errors[:role].must_include 'is not included in the list'
end
it 'validates inclusion when using write_attribute with symbol attribute' do
user = User.new
user.send(:write_attribute, :role, 'wrong')
user.read_attribute_for_validation(:role).must_equal 'wrong'
user.wont_be :valid?
user.errors[:role].must_include 'is not included in the list'
end
it 'validates inclusion on mass assignment' do
assert_raises ActiveRecord::RecordInvalid do
User.create!(role: 'wrong')
end
end
it "uses persisted value for validation if it hasn't been set" do
user = User.create! :sex => :male
User.find(user.id).read_attribute_for_validation(:sex).must_equal 'male'
end
it 'is valid with empty string assigned' do
user = User.new
user.role = ''
user.must_be :valid?
end
it 'stores nil when empty string assigned' do
user = User.new
user.role = ''
user.read_attribute(:role).must_equal nil
end
it 'supports multiple attributes' do
user = User.new
user.interests.must_be_empty
user.interests << :music
user.interests.must_equal %w(music)
user.save!
user = User.find(user.id)
user.interests.must_be_instance_of Enumerize::Set
user.interests.must_equal %w(music)
user.interests << :sports
user.interests.must_equal %w(music sports)
user.interests = []
interests = user.interests
interests << :music
interests.must_equal %w(music)
interests << :dancing
interests.must_equal %w(music dancing)
end
it 'stores multiple value passed passed to new' do
user = User.new(interests: [:music, :dancing])
user.save!
user.interests.must_equal %w(music dancing)
User.find(user.id).interests.must_equal %w(music dancing)
end
it 'returns invalid multiple value for validation' do
user = User.new
user.interests << :music
user.interests << :invalid
values = user.read_attribute_for_validation(:interests)
values.must_equal %w(music invalid)
end
it 'validates multiple attributes' do
user = User.new
user.interests << :invalid
user.wont_be :valid?
user.interests = Object.new
user.wont_be :valid?
user.interests = ['music', '']
user.must_be :valid?
end
it 'stores custom values for multiple attributes' do
User.delete_all
klass = Class.new(User)
klass.enumerize :interests, in: { music: 0, sports: 1, dancing: 2, programming: 3}, multiple: true
user = klass.new
user.interests << :music
user.read_attribute(:interests).must_equal [0]
user.interests.must_equal %w(music)
user.save
user = klass.find(user.id)
user.interests.must_equal %w(music)
end
it 'adds scope' do
User.delete_all
user_1 = User.create!(status: :active, role: :admin)
user_2 = User.create!(status: :blocked)
User.with_status(:active).must_equal [user_1]
User.with_status(:blocked).must_equal [user_2]
User.with_status(:active, :blocked).to_set.must_equal [user_1, user_2].to_set
User.without_status(:active).must_equal [user_2]
User.without_status(:active, :blocked).must_equal []
User.having_role(:admin).must_equal [user_1]
end
it 'ignores not enumerized values that passed to the scope method' do
User.delete_all
User.with_status(:foo).must_equal []
end
it 'allows either key or value as valid' do
user_1 = User.new(status: :active)
user_2 = User.new(status: 1)
user_3 = User.new(status: '1')
user_1.status.must_equal 'active'
user_2.status.must_equal 'active'
user_3.status.must_equal 'active'
user_1.must_be :valid?
user_2.must_be :valid?
user_3.must_be :valid?
end
it 'supports defining enumerized attributes on abstract class' do
Document.delete_all
document = Document.new
document.visibility = :protected
document.visibility.must_equal 'protected'
end
it 'supports defining enumerized scopes on abstract class' do
Document.delete_all
document_1 = Document.create!(visibility: :public)
document_2 = Document.create!(visibility: :private)
Document.with_visibility(:public).must_equal [document_1]
end
it 'validates uniqueness' do
user = User.new
user.status = :active
user.save!
user = UniqStatusUser.new
user.status = :active
user.valid?
user.errors[:status].wont_be :empty?
end
it 'is valid after #becomes' do
User.delete_all
user = User.new
user.sex = :male
user.save!
uniq_user = User.find(user.id).becomes(UniqStatusUser)
uniq_user.valid?
uniq_user.errors.must_be_empty
end
it 'supports multiple attributes in #becomes' do
User.delete_all
uniq_user = UniqStatusUser.new
uniq_user.interests = [:sports, :dancing]
uniq_user.sex = :male
uniq_user.save!
user = uniq_user.becomes(User)
user.sex.must_equal uniq_user.sex
user.interests.must_equal uniq_user.interests
end
it "doesn't update record" do
Document.delete_all
expected = Time.utc(2010, 10, 10)
document = Document.new
document.updated_at = expected
document.save!
document = Document.last
document.save!
assert_equal expected, document.updated_at
end
it 'changes from dirty should be serialized as scalar values' do
user = User.create(:status => :active)
user.status = :blocked
assert_equal [1, 2], YAML.load(user.changes.to_yaml)[:status]
end
end
enumerize-1.1.1/test/value_test.rb 0000644 0000041 0000041 00000007750 12677055751 017254 0 ustar www-data www-data require 'test_helper'
require 'yaml'
describe Enumerize::Value do
class Attr < Struct.new(:values)
end
let(:attr) { Attr.new([]) }
let(:val) { Enumerize::Value.new(attr, 'test_value', 1) }
it 'is a string' do
val.must_be_kind_of String
end
describe 'equality' do
it 'is compared to string' do
val.must_be :==, 'test_value'
val.wont_be :==, 'not_value'
end
it 'is compared to symbol' do
val.must_be :==, :test_value
val.wont_be :==, :not_value
end
it 'is compared to integer' do
val.must_be :==, 1
val.wont_be :==, 2
end
end
describe 'translation' do
let(:attr) { Struct.new(:values, :name, :i18n_scopes).new([], "attribute_name", []) }
it 'uses common translation' do
store_translations(:en, :enumerize => {:attribute_name => {:test_value => "Common translation"}}) do
val.text.must_be :==, "Common translation"
end
end
it 'uses default translation from the "default" section if its present' do
store_translations(:en, :enumerize => {:defaults => {:attribute_name => {:test_value => "Common translation"}}}) do
val.text.must_be :==, "Common translation"
end
end
it 'uses model specific translation' do
attr.i18n_scopes = ["enumerize.model_name.attribute_name"]
store_translations(:en, :enumerize => {:model_name => {:attribute_name => {:test_value => "Model Specific translation"}}}) do
val.text.must_be :==, "Model Specific translation"
end
end
it 'uses model specific translation rather than common translation' do
attr.i18n_scopes = ["enumerize.model_name.attribute_name"]
store_translations(:en, :enumerize => {:attribute_name => {:test_value => "Common translation"}, :model_name => {:attribute_name => {:test_value => "Model Specific translation"}}}) do
val.text.must_be :==, "Model Specific translation"
end
end
it 'uses simply humanized value when translation is undefined' do
store_translations(:en, :enumerize => {}) do
val.text.must_be :==, "Test value"
end
end
it 'uses specified in options translation scope' do
attr.i18n_scopes = ["other.scope"]
store_translations(:en, :other => {:scope => {:test_value => "Scope specific translation"}}) do
val.text.must_be :==, "Scope specific translation"
end
end
it 'uses first found translation scope from options' do
attr.i18n_scopes = ["nonexistent.scope", "other.scope"]
store_translations(:en, :other => {:scope => {:test_value => "Scope specific translation"}}) do
val.text.must_be :==, "Scope specific translation"
end
end
end
describe 'boolean methods comparison' do
before do
attr.values = [val, Enumerize::Value.new(attr, 'other_value')]
end
it 'returns true if value equals method' do
val.test_value?.must_equal true
end
it 'returns false if value does not equal method' do
val.other_value?.must_equal false
end
it 'raises NoMethodError if there are no values like boolean method' do
proc {
val.some_method?
}.must_raise NoMethodError
end
it 'raises ArgumentError if arguments are passed' do
proc {
val.other_value?('<3')
}.must_raise ArgumentError
end
it 'responds to methods for existing values' do
val.must_respond_to :test_value?
val.must_respond_to :other_value?
end
it 'returns a method object' do
val.method(:test_value?).must_be_instance_of Method
end
it "doesn't respond to a method for not existing value" do
val.wont_respond_to :some_method?
end
end
describe 'serialization' do
let(:val) { Enumerize::Value.new(attr, 'test_value') }
it 'should be serialized to yaml as string value' do
assert_equal YAML.dump('test_value'), YAML.dump(val)
end
it 'serializes with Marshal' do
dump_value = Marshal.dump(val)
Marshal.load(dump_value).must_equal 'test_value'
end
end
end
enumerize-1.1.1/test/multiple_test.rb 0000644 0000041 0000041 00000002627 12677055751 017771 0 ustar www-data www-data require 'test_helper'
describe Enumerize::Base do
let(:klass) do
Class.new do
extend Enumerize
end
end
let(:subklass) do
Class.new(klass)
end
let(:object) { klass.new }
it 'returns [] when not set' do
klass.enumerize :foos, in: %w(a b), multiple: true
object.foos.must_equal []
end
it 'returns setted array' do
klass.enumerize :foos, in: %w(a b c), multiple: true
object.foos = %w(a c)
object.foos.must_equal %w(a c)
end
it 'sets default value as single value' do
klass.enumerize :foos, in: %w(a b c), default: 'b', multiple: true
object.foos.must_equal %w(b)
end
it 'sets default value as array of one element' do
klass.enumerize :foos, in: %w(a b c), default: %w(b), multiple: true
object.foos.must_equal %w(b)
end
it 'sets default value as array of several elements' do
klass.enumerize :foos, in: %w(a b c), default: %w(b c), multiple: true
object.foos.must_equal %w(b c)
end
it "doesn't define _text method" do
klass.enumerize :foos, in: %w(a b c), multiple: true
object.wont_respond_to :foos_text
end
it "doesn't define _value method" do
klass.enumerize :foos, in: %w(a b c), multiple: true
object.wont_respond_to :foos_value
end
it "cannot define multiple with scope" do
assert_raises ArgumentError do
klass.enumerize :foos, in: %w(a b c), multiple: true, scope: true
end
end
end
enumerize-1.1.1/test/support/ 0000755 0000041 0000041 00000000000 12677055751 016257 5 ustar www-data www-data enumerize-1.1.1/test/support/view_test_helper.rb 0000644 0000041 0000041 00000001266 12677055751 022161 0 ustar www-data www-data require 'active_support/concern'
require 'active_support/testing/setup_and_teardown'
if defined?(ActionView::RoutingUrlFor)
ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
end
module ViewTestHelper
extend ActiveSupport::Concern
include ActiveSupport::Testing::SetupAndTeardown
include ActionView::TestCase::Behavior
included do
setup :set_controller
end
def set_controller
@controller = MockController.new
end
def method_missing(method, *args)
super unless method.to_s =~ /_path$/
end
def respond_to?(method, include_private=false)
method.to_s =~ /_path$/ || super
end
def protect_against_forgery?
false
end
end
enumerize-1.1.1/test/support/mock_controller.rb 0000644 0000041 0000041 00000000470 12677055751 022001 0 ustar www-data www-data class MockController
attr_writer :action_name
def _routes
self
end
def action_name
defined?(@action_name) ? @action_name : "edit"
end
def url_for(*args)
"http://example.com"
end
def url_helpers
self
end
def url_options
{}
end
def hash_for_users_path(*); end
end
enumerize-1.1.1/test/attribute_test.rb 0000644 0000041 0000041 00000007436 12677055751 020144 0 ustar www-data www-data require 'test_helper'
describe Enumerize::Attribute do
def attr
@attr ||= nil
end
def build_attr(*args, &block)
@attr = Enumerize::Attribute.new(*args, &block)
end
it 'returns values' do
build_attr nil, :foo, :in => [:a, :b]
attr.values.must_equal %w[a b]
end
it 'converts name to symbol' do
build_attr nil, 'foo', :in => %w[a b]
attr.name.must_equal :foo
end
it 'uses custom value class' do
value_class = Class.new(Enumerize::Value)
build_attr nil, 'foo', :in => %w[a b], :value_class => value_class
attr.values.first.must_be_instance_of value_class
end
describe 'i18n scopes' do
it 'returns scopes from options' do
build_attr nil, 'foo', :in => %w[a b], :i18n_scope => %w[bar buzz]
attr.i18n_scopes.must_equal %w[bar buzz]
end
it 'accepts only string scopes' do
proc { build_attr nil, 'foo', :in => %w[a b], :i18n_scope => [%w[bar buzz], "bar.buzz"] }.must_raise ArgumentError
end
end
describe 'options for select' do
it 'returns all options for select' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
build_attr nil, :foo, :in => %w[a b]
attr.options.must_equal [['a text', 'a'], ['b text', 'b']]
end
end
it 'returns requested options for select via :only' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
build_attr nil, :foo, :in => %w[a b]
attr.options(:only => :a).must_equal [['a text', 'a']]
attr.options(:only => [:b]).must_equal [['b text', 'b']]
attr.options(:only => []).must_equal []
end
end
it 'returns requested options for select via :except' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
build_attr nil, :foo, :in => %w[a b]
attr.options(:except => :a).must_equal [['b text', 'b']]
attr.options(:except => :b).must_equal [['a text', 'a']]
attr.options(:except => []).must_equal [['a text', 'a'], ['b text', 'b']]
end
end
it 'does not work with both :only and :except' do
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
build_attr nil, :foo, :in => %w[a b]
proc { attr.options(:except => [], :only => []) }.must_raise ArgumentError
end
end
end
describe 'values hash' do
before do
build_attr nil, :foo, :in => {:a => 1, :b => 2}
end
it 'returns hash keys as values' do
attr.values.must_equal %w[a b]
end
it 'finds values by hash values' do
attr.find_value(1).must_equal 'a'
attr.find_value(2).must_equal 'b'
end
end
it 'sets up shortcut methods for each value' do
build_attr nil, :foo, :in => {:a => 1, :b => 2}
attr.must_respond_to :a
attr.must_respond_to :b
attr.a.value.must_equal 1
attr.b.value.must_equal 2
attr.a.text.must_equal 'A'
attr.b.text.must_equal 'B'
end
describe 'values hash with zero' do
before do
build_attr nil, :foo, :in => {:a => 1, :b => 2, :c => 0}
end
it 'returns hash keys as values' do
attr.values.must_equal %w[a b c]
end
it 'finds values by hash values' do
attr.find_value(1).must_equal 'a'
attr.find_value(2).must_equal 'b'
attr.find_value(0).must_equal 'c'
end
it 'finds all values by hash values' do
attr.find_values(1, 2, 0).must_equal ['a', 'b', 'c']
end
end
describe 'boolean values hash' do
before do
build_attr nil, :foo, :in => {:a => true, :b => false}
end
it 'returns hash keys as values' do
attr.values.must_equal %w[a b]
end
it 'finds values by hash values' do
attr.find_value(true).must_equal 'a'
attr.find_value(false).must_equal 'b'
end
end
end
enumerize-1.1.1/.gitignore 0000644 0000041 0000041 00000000352 12677055751 015554 0 ustar www-data www-data *.gem
*.rbc
.bundle
.config
.ruby-version
.yardoc
.idea/
enumerize.iml
Gemfile*.lock
gemfiles/Gemfile-*.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
log/*
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
vendor/bundle
enumerize-1.1.1/Gemfile.mongo_mapper 0000644 0000041 0000041 00000000167 12677055751 017545 0 ustar www-data www-data eval_gemfile('Gemfile.global')
gem 'minitest', '~> 5.8'
gem 'rails', '4.2.4', :require => false
gem 'mongo_mapper'
enumerize-1.1.1/CHANGELOG.md 0000644 0000041 0000041 00000021712 12677055751 015400 0 ustar www-data www-data ## master
### enhancements
### bug fix
## 1.1.1 (January 25, 2016)
### bug fix
* Fix exception when using predicate methods and enumerized values have dash in it. (by [@nashby](https://github.com/nashby))
## 1.1.0 (November 15, 2015)
### enhancements
* Add Sequel support. (by [@mrbrdo](https://github.com/mrbrdo))
* Add qualifiers to RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
* Support hash in the RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
### bug fix
## 1.0.0 (August 2, 2015)
### enhancements
* Add `texts` method for getting an array of text values of the enumerized field with multiple type. (by [@huynhquancam](https://github.com/huynhquancam))
* Drop Rails 3.2 support. (by [@nashby](https://github.com/nashby))
### bug fix
* Fix conflicts when Active Record and Mongoid are used at the same time. (by [@matsu911](https://github.com/matsu911))
## 0.11.0 (March 29, 2015) ##
### enhancements
* Add ability to set default value for enumerized field with multiple type. (by [@nashby](https://github.com/nashby))
* Support Rails 4.2. (by [@lest](https://github.com/lest))
### bug fix
* Use Mongoid's `:in` method for generated scopes, fix chained scopes. (by [@nashby](https://github.com/nashby))
* Use `after_initialize` callback to set default value in Mongoid documents. (by [@nashby](https://github.com/nashby))
## 0.10.1 (March 4, 2015) ##
### bug fix
* Use method_missing instead of defining singleton class methods to allow Marshal serialization (by [@lest](https://github.com/lest))
## 0.10.0 (February 17, 2015) ##
### enhancements
* Add scopes support to mongoid documents (by [@nashby](https://github.com/nashby))
* Use underscore.humanize in #text to make use of Inflector acronyms (by [@mintuhouse](https://github.com/mintuhouse))
* Raise an exception when :scope option is used together with :multiple option (by [@maurogeorge](https://github.com/maurogeorge))
* Use alias_method_chain instead of overriding Class#inherited (by [@yuroyoro](https://github.com/yuroyoro))
* Shortcut methods to retrieve enumerize values (by [@CyborgMaster](https://github.com/CyborgMaster))
* Extend equality operator to support comparing with symbols and custom values (e.g. integers) (by [@CyborgMaster](https://github.com/CyborgMaster))
## 0.9.0 (December 11, 2014) ##
### enhancements
* Add :value_class option (by [@lest](https://github.com/lest))
* Use 'defaults' scope in the localization file for the attributes that used across several models. This will help to avoid conflicting keys with model names and attribute names. Example:
```yml
en:
enumerize:
defaults:
sex:
male: Male
female: Female
```
You still can use the old solution without "default" scope:
```yml
en:
enumerize:
sex:
male: Male
female: Female
```
(by [@nashby](https://github.com/nashby))
### bug fix
* Store values for validation using string keys (by [@nagyt234](https://github.com/nagyt234))
* Store custom values for multiple attributes (by [@lest](https://github.com/lest))
* Support validations after using AR#becomes (by [@lest](https://github.com/lest))
* Do not try to set attribute for not selected attributes (by [@dany1468](https://github.com/dany1468))
## 0.8.0 (March 4, 2014) ##
### enhancements
* Integration with SimpleForm's `input_field` (by [@nashby](https://github.com/nashby))
* Support multiple attributes in Active Record #becomes method (by [@lest](https://github.com/lest))
* Add ability to specify localization scope with `i18n_scope` option (by [@dreamfall](https://github.com/dreamfall))
### bug fix
* Fix Rails Admin integration when custom values are used (by [@brenes](https://github.com/brenes))
* Fix RSpec integration using enumerize with Spring (by [@winston](https://github.com/winston))
* Return proper RSpec failure message for enumerized attribute with default value (by [@nashby](https://github.com/nashby))
* Return proper RSpec description for enumerized attribute without default value (by [@andreygerasimchuk](https://github.com/andreygerasimchuk))
* Do not try to set default value for not selected attributes (by [@nashby](https://github.com/nashby))
* Fix uniqueness validation with Active Record (by [@lest](https://github.com/lest))
* Fix loading of attributes with multiple: true in mongoid (by [glebtv](https://github.com/glebtv))
* Serialize value as scalar type (by [@ka8725](https://github.com/ka8725))
## 0.7.0 (August 21, 2013) ##
### enhancements
* Give priority to model specific translation definition. See example [here](https://github.com/brainspec/enumerize/pull/96) (by [@labocho](https://github.com/labocho))
* Allow lambda in default value (by [@adie](https://github.com/adie))
* Add predicate methods to the multiple attributes (by [@nashby](https://github.com/nashby))
* Add RSpec matcher (by [@nashby](https://github.com/nashby))
* Add `*_value` method that returns actual value of the enumerized attribute (useful for attributes with custom values)
(by [@tkyowa](https://github.com/tkyowa))
### bug fix
* Make validation work when `write_attribute` is using for setting enumerized values (by [@nashby](https://github.com/nashby))
* Validates enumerized values when enumeration is included via module
(by [@nashby](https://github.com/nashby)) and (by [@lest](https://github.com/lest))
## 0.6.1 (May 20, 2013) ##
### bug fix
* Don't raise error when enumerized attribute is already defined. (by [@lest](https://github.com/lest))
## 0.6.0 (May 16, 2013) ##
### enhancements
* Use inclusion error message for invalid values (by [@lest](https://github.com/lest))
* Add `:only` and `except` options to the `Attribute#options` method. (by [@thehappycoder](https://github.com/thehappycoder) and [@randoum](https://github.com/randoum))
* ActiveRecord scopes. (by [@lest](https://github.com/lest), [@banyan](https://github.com/banyan) and [@nashby](https://github.com/nashby))
* Support for RailsAdmin (by [@drewda](https://github.com/drewda))
### bug fix
* Return correct default value for enumerized attribute using `default_scope` with generated scope [@nashby](https://github.com/nashby)
* Allow either key or value as valid (by [aghull](https://github.com/aghull) and [@lest](https://github.com/lest))
* Use default enum value from db column (by [@lest](https://github.com/lest))
## 0.5.1 (December 10, 2012) ##
### bug fix
* Always return Enumerize::Set for multiple attributes (by [@nashby](https://github.com/nashby))
## 0.5.0 (October 31, 2012) ##
The previous method of adding enumerize to a class was deprecated. Please use
`extend Enumerize` instead of `include Enumerize`.
### enhancements
* SimpleForm support for multiple attributes. (by [@nashby](https://github.com/nashby))
* Formtastic support for multiple attributes. (by [@nashby](https://github.com/nashby))
* Array-like multiple attributes. (by [@lest](https://github.com/lest))
## 0.4.0 (September 6, 2012) ##
Legacy support was dropped. The following versions are supported:
* Ruby 1.9.3+ (including JRuby and Rubinius)
* Rails 3.2+
* Formtastic 2.2+
* SimpleForm 2+
* Mongoid 3+
### enhancements
* Ability to define predicate methods on enumerized object. (by [@lest](https://github.com/lest))
## 0.3.0 (July 9, 2012) ##
### enhancements
* Accept a values hash to store an attribute using custom values (e.g. integers) (by [@lest](https://github.com/lest))
## 0.2.2 (May 22, 2012) ##
### bug fix
* Correctly assign default value to handle mass assignment in Active Record (by [@lest](https://github.com/lest))
## 0.2.1 (May 21, 2012) ##
### bug fix
* Call super in attribute accessors if available (by [@lest](https://github.com/lest))
## 0.2.0 (March 29, 2012) ##
### enhancements
* Ability to enumerize attributes in a module and then include it into classes (by [@lest](https://github.com/lest))
* Add error to a model when attribute value is not included in allowed list (by [@lest](https://github.com/lest))
### bug fix
* Inheriting enumerized attributes (by [@cgunther](https://github.com/cgunther) and [@nashby](https://github.com/nashby))
* Don't cast nil to string (by [@jimryan](https://github.com/jimryan))
## 0.1.1 (March 6, 2012) ##
### bug fix
* I18n regression: Multiple calls to value #text return different results (by [@cgunther](https://github.com/cgunther) and [@lest](https://github.com/lest))
## 0.1.0 (March 5, 2012) ##
### enhancements
* Return humanized value if there are no translations (by [@nashby](https://github.com/nashby))
* Integration with SimpleForm (by [@nashby](https://github.com/nashby))
* Integration with Formtastic (by [@lest](https://github.com/lest))
## 0.0.4 (February 8, 2012) ##
### bug fix
* Make attribute accessors to work with ActiveRecord 3.1.x (by [@lest](https://github.com/lest))
## 0.0.3 (February 8, 2012) ##
### enhancements
* Mongoid support (by [@lest](https://github.com/lest))
* Boolean methods (by [@Dreamfa11](https://github.com/Dreamfa11))
enumerize-1.1.1/README.md 0000644 0000041 0000041 00000022422 12677055751 015045 0 ustar www-data www-data # Enumerize [](http://travis-ci.org/brainspec/enumerize) [](https://gemnasium.com/brainspec/enumerize)
Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper/Sequel support
## Installation
Add this line to your application's Gemfile:
gem 'enumerize'
And then execute:
$ bundle
Or install it yourself as:
$ gem install enumerize
## Usage
Basic:
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
```
Note that enumerized values are just identificators so if you want to use multi-word, etc. values you should use `I18n` feature.
ActiveRecord:
```ruby
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :sex
t.string :role
t.timestamps
end
end
end
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, in: [:male, :female], default: lambda { |user| SexIdentifier.sex_for_name(user.name).to_sym }
enumerize :role, in: [:user, :admin], default: :user
end
```
Mongoid:
```ruby
class User
include Mongoid::Document
extend Enumerize
field :role
enumerize :role, in: [:user, :admin], default: :user
end
```
MongoMapper:
```ruby
class User
include MongoMapper::Document
extend Enumerize
key :role
enumerize :role, in: [:user, :admin], default: :user
end
```
I18n:
```ruby
en:
enumerize:
user:
sex:
male: "Male"
female: "Female"
```
or if you use `sex` attribute across several models you can use `defaults` scope:
```ruby
en:
enumerize:
defaults:
sex:
male: "Male"
female: "Female"
```
You can also pass `i18n_scope` option to specify scope (or array of scopes) storing the translations.
```ruby
class Person
extend Enumerize
extend ActiveModel::Naming
enumerize :sex, in: %w[male female], i18n_scope: "sex"
enumerize :color, in: %w[black white], i18n_scope: ["various.colors", "colors"]
end
# localization file
en:
sex:
male: "Male"
female: "Female"
various:
colors:
black: "Black"
colors:
white: "White"
```
Note that if you want to use I18n feature with plain Ruby object don't forget to extend it with `ActiveModel::Naming`:
```ruby
class User
extend Enumerize
extend ActiveModel::Naming
end
```
get attribute value:
```ruby
@user.sex_text # or @user.sex.text
```
get all values for enumerized attribute:
```ruby
User.sex.values # or User.enumerized_attributes[:sex].values
```
use it with forms (it supports `:only` and `:except` options):
```erb
<%= form_for @user do |f| %>
<%= f.select :sex, User.sex.options %>
<% end %>
```
Boolean methods:
```ruby
user.sex = :male
user.sex.male? #=> true
user.sex.female? #=> false
```
Predicate methods:
```ruby
class User
extend Enumerize
enumerize :sex, in: %w(male female), predicates: true
end
user = User.new
user.male? # => false
user.female? # => false
user.sex = 'male'
user.male? # => true
user.female? # => false
```
Using prefix:
```ruby
class User
extend Enumerize
enumerize :sex, in: %w(male female), predicates: { prefix: true }
end
user = User.new
user.sex = 'female'
user.sex_female? # => true
```
Use `:only` and `:except` options to specify what values create predicate methods for.
To make some attributes shared across different classes it's possible to define them in a separate module and then include it into classes:
```ruby
module PersonEnumerations
extend Enumerize
enumerize :sex, in: %w[male female]
end
class Person
include PersonEnumerations
end
class User
include PersonEnumerations
end
```
It's also possible to store enumerized attribute value using custom values (e.g. integers). You can pass a hash as `:in` option to achieve this:
```ruby
class User < ActiveRecord::Base
extend Enumerize
enumerize :role, in: {:user => 1, :admin => 2}
end
user = User.new
user.role = :user
user.role #=> 'user'
user.role_value #=> 1
User.role.find_value(:user).value #=> 1
User.role.find_value(:admin).value #=> 2
```
ActiveRecord scopes:
```ruby
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, :in => [:male, :female], scope: true
enumerize :status, :in => { active: 1, blocked: 2 }, scope: :having_status
end
User.with_sex(:female)
# SELECT "users".* FROM "users" WHERE "users"."sex" IN ('female')
User.without_sex(:male)
# SELECT "users".* FROM "users" WHERE "users"."sex" NOT IN ('male')
User.having_status(:blocked).with_sex(:male, :female)
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
```
:warning: It is not possible to define a scope when using the `:multiple` option. :warning:
Array-like attributes with plain ruby objects:
```ruby
class User
extend Enumerize
enumerize :interests, in: [:music, :sports], multiple: true
end
user = User.new
user.interests << :music
user.interests << :sports
```
and with ActiveRecord:
```ruby
class User < ActiveRecord::Base
extend Enumerize
serialize :interests, Array
enumerize :interests, in: [:music, :sports], multiple: true
end
```
get an array of all text values:
```ruby
@user.interests.texts # shortcut for @user.interests.map(&:text)
```
### SimpleForm
If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
```erb
<%= simple_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
```
and if you want it as radio buttons:
```erb
<%= simple_form_for @user do |f| %>
<%= f.input :sex, :as => :radio_buttons %>
<% end %>
```
### Formtastic
If you are using Formtastic gem you also don't need to specify input type (`:select` by default) and collection:
```erb
<%= semantic_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
```
and if you want it as radio buttons:
```erb
<%= semantic_form_for @user do |f| %>
<%= f.input :sex, :as => :radio %>
<% end %>
```
### RSpec
Also you can use builtin RSpec matcher:
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
describe User do
it { should enumerize(:sex) }
# or with RSpec 3 expect syntax
it { is_expected.to enumerize(:sex) }
end
```
#### Qualifiers
##### in
Use `in` to test usage of the `:in` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female]
end
describe User do
it { should enumerize(:sex).in(:male, :female) }
end
```
You can test enumerized attribute value using custom values with the `in`
qualifier.
```ruby
class User
extend Enumerize
enumerize :sex, in: { male: 0, female: 1 }
end
describe User do
it { should enumerize(:sex).in(male: 0, female: 1) }
end
```
##### with_default
Use `with_default` to test usage of the `:default` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], default: :female
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_default(:female) }
end
```
##### with_i18n_scope
Use `with_i18n_scope` to test usage of the `:i18n_scope` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], i18n_scope: 'sex'
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_i18n_scope('sex') }
end
```
##### with_predicates
Use `with_predicates` to test usage of the `:predicates` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], predicates: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_predicates(true) }
end
```
You can text prefixed predicates with the `with_predicates` qualifiers.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], predicates: { prefix: true }
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_predicates(prefix: true) }
end
```
##### with_scope
Use `with_scope` to test usage of the `:scope` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], scope: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_scope(true) }
end
```
You can text custom scope with the `with_scope` qualifiers.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], scope: :having_sex
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_scope(scope: :having_sex) }
end
```
##### with_multiple
Use `with_multiple` to test usage of the `:multiple` option.
```ruby
class User
extend Enumerize
enumerize :sex, in: [:male, :female], multiple: true
end
describe User do
it { should enumerize(:sex).in(:male, :female).with_multiple(true) }
end
```
### Minitest with Shoulda
You can use the RSpec matcher with shoulda in your tests by adding two lines in your `test_helper.rb` inside `class ActiveSupport::TestCase` definition:
```ruby
class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending!
require 'enumerize/integrations/rspec'
extend Enumerize::Integrations::RSpec
...
end
```
### Other Integrations
Enumerize integrates with the following automatically:
* [RailsAdmin](https://github.com/sferik/rails_admin/)
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request