Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Baker committed Mar 15, 2011
0 parents commit 0fbacc1
Show file tree
Hide file tree
Showing 13 changed files with 360 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .document
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lib/**/*.rb
bin/*
-
features/**/*.feature
LICENSE.txt
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
coverage
rdoc
doc
.yardoc
.bundle
pkg
Gemfile.lock
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format documentation
13 changes: 13 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
source :rubygems

gem "activesupport", ">= 3.0.0"
gem "activemodel", ">= 3.0.0"
gem "i18n"

group :development, :test do
gem "activerecord", ">= 3.0.0"
gem "bundler"
gem "jeweler"
gem "rspec", ">= 2.5.0"
gem "watchr"
end
20 changes: 20 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2011 Chris Baker

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.
19 changes: 19 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
= attr_enumerator

Description goes here.

== Contributing to attr_enumerator

* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
* Fork the project
* Start a feature/bugfix branch
* Commit and push until you are happy with your contribution
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

== Copyright

Copyright (c) 2011 Chris Baker. See LICENSE.txt for
further details.

46 changes: 46 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'rubygems'
require 'bundler'
begin
Bundler.setup(:default, :development)
rescue Bundler::BundlerError => e
$stderr.puts e.message
$stderr.puts "Run `bundle install` to install missing gems"
exit e.status_code
end
require 'rake'

require 'jeweler'
Jeweler::Tasks.new do |gem|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
gem.name = "attr_enumerator"
gem.homepage = "http://github.com/chrisb87/attr_enumerator"
gem.license = "MIT"
gem.summary = %Q{Enumerated attributes for ActiveModel}
gem.description = %Q{Enumerated attributes for ActiveModel}
gem.email = "[email protected]"
gem.authors = ["Chris Baker"]
end
Jeweler::RubygemsDotOrgTasks.new

require 'rspec/core'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec) do |spec|
spec.pattern = FileList['spec/**/*_spec.rb']
end

RSpec::Core::RakeTask.new(:rcov) do |spec|
spec.pattern = 'spec/**/*_spec.rb'
spec.rcov = true
end

task :default => :spec

require 'rake/rdoctask'
Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""

rdoc.rdoc_dir = 'rdoc'
rdoc.title = "attr_enumerator #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
end
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
77 changes: 77 additions & 0 deletions attr_enumerator.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Generated by jeweler
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-

Gem::Specification.new do |s|
s.name = %q{attr_enumerator}
s.version = "0.1.0"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Chris Baker"]
s.date = %q{2011-03-15}
s.description = %q{Enumerated attributes for ActiveModel}
s.email = %q{[email protected]}
s.extra_rdoc_files = [
"LICENSE.txt",
"README.rdoc"
]
s.files = [
".document",
".rspec",
"Gemfile",
"LICENSE.txt",
"README.rdoc",
"Rakefile",
"VERSION",
"attr_enumerator.gemspec",
"lib/attr_enumerator.rb",
"spec/attr_enumerator_spec.rb",
"spec/spec_helper.rb",
"watchr.rb"
]
s.homepage = %q{http://github.com/chrisb87/attr_enumerator}
s.licenses = ["MIT"]
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.7}
s.summary = %q{Enumerated attributes for ActiveModel}
s.test_files = [
"spec/attr_enumerator_spec.rb",
"spec/spec_helper.rb"
]

if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0"])
s.add_runtime_dependency(%q<i18n>, [">= 0"])
s.add_development_dependency(%q<activerecord>, [">= 3.0.0"])
s.add_development_dependency(%q<bundler>, [">= 0"])
s.add_development_dependency(%q<jeweler>, [">= 0"])
s.add_development_dependency(%q<rspec>, [">= 2.5.0"])
s.add_development_dependency(%q<watchr>, [">= 0"])
else
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
s.add_dependency(%q<i18n>, [">= 0"])
s.add_dependency(%q<activerecord>, [">= 3.0.0"])
s.add_dependency(%q<bundler>, [">= 0"])
s.add_dependency(%q<jeweler>, [">= 0"])
s.add_dependency(%q<rspec>, [">= 2.5.0"])
s.add_dependency(%q<watchr>, [">= 0"])
end
else
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
s.add_dependency(%q<i18n>, [">= 0"])
s.add_dependency(%q<activerecord>, [">= 3.0.0"])
s.add_dependency(%q<bundler>, [">= 0"])
s.add_dependency(%q<jeweler>, [">= 0"])
s.add_dependency(%q<rspec>, [">= 2.5.0"])
s.add_dependency(%q<watchr>, [">= 0"])
end
end

34 changes: 34 additions & 0 deletions lib/attr_enumerator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'active_model'
require 'active_support'

module AttrEnumerator
extend ActiveSupport::Concern

DEFAULT_OPTIONS = {
:constant => true,
:prefix => '',
:message => :invalid
}

module ClassMethods
def attr_enumerator(field, enumerators, opts={})
options = opts.reverse_merge(DEFAULT_OPTIONS)

unless !(constant = options.delete(:constant))
constant = field.to_s.pluralize.upcase if constant == true
const_set(constant.to_s, enumerators).freeze unless const_defined?(constant)
end

prefix = options.delete(:prefix)
enumerators.each do |enumerator|
define_method(prefix + enumerator.underscore.parameterize('_') + '?') do
self.send(field) == enumerator
end
end

validates_inclusion_of field, options.merge({ :in => enumerators })
end
end
end

ActiveRecord::Base.class_eval { include AttrEnumerator } if defined? ActiveRecord
110 changes: 110 additions & 0 deletions spec/attr_enumerator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
require 'ostruct'

describe "AttrEnumerator" do
before(:each) do
class TestModel < OpenStruct
include ActiveModel::Validations
include AttrEnumerator
end
end

after(:each) do
Object.send(:remove_const, :TestModel)
end

def instance(fields={})
@instance ||= TestModel.new(fields)
end

describe "enum constant" do
it "should create a constant with possible values" do
TestModel.attr_enumerator :color, ['red', 'blue']
TestModel::COLORS.should == ['red', 'blue']
end

it "should allow for a custom constant name" do
TestModel.attr_enumerator :color, ['red', 'blue'], :constant => :POSSIBLE_COLORS
TestModel::POSSIBLE_COLORS.should == ['red', 'blue']
end

it "should allow for not generating the constant" do
TestModel.attr_enumerator :color, ['red', 'blue'], :constant => false
TestModel.constants.should_not include('COLORS')
end

it "should define the standard constant when using option :constant => true" do
TestModel.attr_enumerator :color, ['red', 'blue'], :constant => true
TestModel::COLORS.should == ['red', 'blue']
end
end

describe "convinience methods" do
it "should create convinience methods for each enum type" do
TestModel.attr_enumerator :color, ['red', 'blue']
instance.color = 'red'

instance.should respond_to :red?
instance.red?.should be_true

instance.should respond_to :blue?
instance.blue?.should be_false
end

it "should allow for prefixing the convinience methods" do
TestModel.attr_enumerator :color, ['red', 'blue'], :prefix => 'colored_'
instance.color = 'red'

instance.should respond_to :colored_red?
instance.colored_red?.should be_true

instance.should respond_to :colored_blue?
instance.colored_blue?.should be_false
end

it "should handle strangely formated choices" do
TestModel.attr_enumerator :choices, \
['choice one', 'choice-two', 'CHOICE THREE', 'ChoiceFour', 'choice%five', 'choice☺six', 'choice_seven.']

instance.should respond_to :choice_one?
instance.should respond_to :choice_two?
instance.should respond_to :choice_three?
instance.should respond_to :choice_four?
instance.should respond_to :choice_five?
instance.should respond_to :choice_six?
instance.should respond_to :choice_seven?
end
end

describe "validation" do
it "should have a default message" do
TestModel.attr_enumerator :color, ['red', 'blue']
instance.should_not be_valid
instance.errors.should == {:color => ['is invalid']}
end

it "should allow for a custom message" do
TestModel.attr_enumerator :color, ['red', 'blue'], :message => 'custom message'
instance.should_not be_valid
instance.errors.should == {:color => ['custom message']}
end

it "should handle allow_blank" do
TestModel.attr_enumerator :color, ['red', 'blue'], :allow_blank => true
instance.color = ''
instance.should be_valid
end

it "should handle allow_nil" do
TestModel.attr_enumerator :color, ['red', 'blue'], :allow_nil => true
instance.color = nil
instance.should be_valid
end
end

describe "ActiveRecord" do
it "should respond to attr_enumerator" do
ActiveRecord::Base.should respond_to :attr_enumerator
end
end
end
13 changes: 13 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rspec'
require 'active_record'
require 'attr_enumerator'

# Requires supporting files with custom matchers and macros, etc,
# in ./support/ and its subdirectories.
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

RSpec.configure do |config|

end
13 changes: 13 additions & 0 deletions watchr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
def run(cmd)
full_command = "bundle exec rspec #{cmd}"
puts(full_command)
system(full_command)
end

def run_all
run("spec")
end

watch( '^lib/(.*)\.rb' ) { |m| run("spec/%s_spec.rb" % m[1]) }
watch( '^spec/spec_helper\.rb' ) { run_all }
watch( '^spec.*/.*_spec\.rb' ) { |m| run(m[0]) }

0 comments on commit 0fbacc1

Please sign in to comment.