Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merged xing/flag_shih_tzu@master

  • Loading branch information...
commit f6da0887e927804f517b1a0caab641c3a22fc50b 2 parents d05cbd2 + b7c5839
@pboling authored
View
2  .gitignore
@@ -7,4 +7,6 @@ coverage
*.gem
.bundle
Gemfile.lock
+gemfiles/*.lock
pkg/*
+rdoc/*
View
9 .travis.yml
@@ -0,0 +1,9 @@
+rvm:
+ - 1.8.7
+ - 1.9.2
+ - 1.9.3
+gemfile:
+ - gemfiles/Gemfile.activerecord-2.3.x
+ - gemfiles/Gemfile.activerecord-3.0.x
+ - gemfiles/Gemfile.activerecord-3.1.x
+ - gemfiles/Gemfile.activerecord-3.2.x
View
1  Gemfile
@@ -1,5 +1,4 @@
source "http://rubygems.org"
-gem 'activesupport', '>3.0.0'
# Specify your gem's dependencies in flag_shih_tzu.gemspec
gemspec
View
226 README.rdoc
@@ -1,56 +1,67 @@
=FlagShihTzu
-A rails plugin to store a collection of boolean attributes in a single
-ActiveRecord column as a bit field.
+Bit fields for ActiveRecord
+
+An extension for {ActiveRecord}[https://rubygems.org/gems/activerecord]
+to store a collection of boolean attributes in a single integer column
+as a bit field.
http://github.com/xing/flag_shih_tzu
-This plugin lets you use a single integer column in an ActiveRecord model
+This gem lets you use a single integer column in an ActiveRecord model
to store a collection of boolean attributes (flags). Each flag can be used
almost in the same way you would use any boolean attribute on an
ActiveRecord object.
The benefits:
* No migrations needed for new boolean attributes. This helps a lot
- if you have very large db-tables where you want to avoid ALTER TABLE whenever
- possible.
+ if you have very large db-tables, on which you want to avoid ALTER TABLE
+ whenever possible.
* Only the one integer column needs to be indexed.
Using FlagShihTzu, you can add new boolean attributes whenever you want,
without needing any migration. Just add a new flag to the +has_flags+ call.
-And just in case you are wondering what "Shih Tzu" means:
+And just in case you are wondering what a "Shih Tzu" is:
http://en.wikipedia.org/wiki/Shih_Tzu
+==Build status
+
+{<img src="https://secure.travis-ci.org/xing/flag_shih_tzu.png" />}[http://travis-ci.org/xing/flag_shih_tzu]
+
+
==Prerequisites
-FlagShihTzu assumes that your ActiveRecord model already has an integer field
-to store the flags, which should be defined to not allow NULL values and
-should have a default value of 0 (which means all flags are initially set to
-false).
+The gem is actively being tested with:
-The plugin has been tested with Rails versions from 2.1 to 3.0 and MySQL,
-PostgreSQL and SQLite3 databases. It has been tested with ruby 1.9.2 (with
-Rails 3 only).
+* ActiveRecord versions 2.3.x, 3.0.x, 3.1.x, 3.2.x
+* MySQL, PostgreSQL and SQLite3 databases
+* Ruby 1.8.7, 1.9.2 and 1.9.3
==Installation
-===As plugin (Rails 2.x, Rails 3)
+===Rails 2.x
+
+In environment.rb:
+
+ config.gem 'flag_shih_tzu'
+
+Then:
- cd path/to/your/rails-project
- ./script/plugin install git://github.com/xing/flag_shih_tzu.git
+ $ rake gems:install # use sudo if necessary
-===As gem (Rails 3)
+===Rails 3
-Add following line to your Gemfile:
+In Gemfile:
- gem 'flag_shih_tzu', '= 0.1.0.pre'
+ gem 'flag_shih_tzu'
-Make sure to install gem with bundler:
+Then:
+
+ $ bundle install
- bundle install
==Usage
@@ -62,15 +73,54 @@ Make sure to install gem with bundler:
has_flags 1 => :warpdrive,
2 => :shields,
3 => :electrolytes
+
end
-+has_flags+ takes a hash. The keys must be positive integers and represent
-the position of the bit being used to enable or disable the flag.
++has_flags+ takes a hash. The keys must be positive integers and represent
+the position of the bit being used to enable or disable the flag.
<b>The keys must not be changed once in use, or you will get wrong results.</b>
That is why the plugin forces you to set them explicitly.
The values are symbols for the flags being created.
+===How it stores the values
+
+As said, FlagShihTzu uses a single integer column to store the values for all
+the defined flags as a bit field.
+
+The bit position of a flag corresponds to the given key.
+
+This way, we can use bit operators on the stored integer value to set, unset
+and check individual flags.
+
+ +---+---+---+ +---+---+---+
+ | | | | | | | |
+ Bit position | 3 | 2 | 1 | | 3 | 2 | 1 |
+ (flag key) | | | | | | | |
+ +---+---+---+ +---+---+---+
+ | | | | | | | |
+ Bit value | 4 | 2 | 1 | | 4 | 2 | 1 |
+ | | | | | | | |
+ +---+---+---+ +---+---+---+
+ | e | s | w | | e | s | w |
+ | l | h | a | | l | h | a |
+ | e | i | r | | e | i | r |
+ | c | e | p | | c | e | p |
+ | t | l | d | | t | l | d |
+ | r | d | r | | r | d | r |
+ | o | s | i | | o | s | i |
+ | l | | v | | l | | v |
+ | y | | e | | y | | e |
+ | t | | | | t | | |
+ | e | | | | e | | |
+ | s | | | | s | | |
+ +---+---+---+ +---+---+---+
+ | 1 | 1 | 0 | = 4 + 2 = 6 | 1 | 0 | 1 | = 4 + 1 = 5
+ +---+---+---+ +---+---+---+
+
+Read more about bit fields here: http://en.wikipedia.org/wiki/Bit_field
+
+
===Using a custom column name
The default column name to store the flags is 'flags', but you can provide a
@@ -82,7 +132,7 @@ different columns for separate flags:
3 => :electrolytes,
:column => 'features'
- has_flags 1 => :spock,
+ has_flags 1 => :spock,
2 => :scott,
3 => :kirk,
:column => 'crew'
@@ -96,13 +146,24 @@ on Spaceship:
Spaceship#warpdrive
Spaceship#warpdrive?
Spaceship#warpdrive=
+ Spaceship#warpdrive_changed?
+
Spaceship#shields
Spaceship#shields?
Spaceship#shields=
+ Spaceship#shields_changed?
+
Spaceship#electrolytes
Spaceship#electrolytes?
Spaceship#electrolytes=
+ Spaceship#electrolytes_changed?
+
+===Generated class methods
+Calling +has_flags+ as shown above creates the following class methods
+on Spaceship:
+
+ Spaceship.flag_columns # [:features, :crew]
===Generated named scopes
@@ -141,44 +202,6 @@ the scopes. The option on has_flags is still named <tt>:named_scopes</tt> howeve
...
-===How it stores the values
-
-As said, FlagShihTzu uses a single integer column to store the values for all
-the defined flags as a bit field.
-
-The bit position of a flag corresponds to the given key.
-
-This way, we can use bit operators on the stored integer value to set, unset
-and check individual flags.
-
- +---+---+---+ +---+---+---+
- | | | | | | | |
- Bit position | 3 | 2 | 1 | | 3 | 2 | 1 |
- (flag key) | | | | | | | |
- +---+---+---+ +---+---+---+
- | | | | | | | |
- Bit value | 4 | 2 | 1 | | 4 | 2 | 1 |
- | | | | | | | |
- +---+---+---+ +---+---+---+
- | e | s | w | | e | s | w |
- | l | h | a | | l | h | a |
- | e | i | r | | e | i | r |
- | c | e | p | | c | e | p |
- | t | l | d | | t | l | d |
- | r | d | r | | r | d | r |
- | o | s | i | | o | s | i |
- | l | | v | | l | | v |
- | y | | e | | y | | e |
- | t | | | | t | | |
- | e | | | | e | | |
- | s | | | | s | | |
- +---+---+---+ +---+---+---+
- | 1 | 1 | 0 | = 4 + 2 = 6 | 1 | 0 | 1 | = 4 + 1 = 5
- +---+---+---+ +---+---+---+
-
-Read more about bit fields here: http://en.wikipedia.org/wiki/Bit_field
-
-
===Support for manually building conditions
The following class methods may support you when manually building
@@ -190,8 +213,8 @@ ActiveRecord conditions:
Spaceship.not_shields_condition # "(spaceships.flags not in (2,3,6,7))"
Spaceship.electrolytes_condition # "(spaceships.flags in (4,5,6,7))"
Spaceship.not_electrolytes_condition # "(spaceships.flags not in (4,5,6,7))"
-
-These methods also accept a :table_alias option that can be used when
+
+These methods also accept a :table_alias option that can be used when
generating SQL that references the same table more than once:
Spaceship.shields_condition(:table_alias => 'evil_spaceships') # "(evil_spaceships.flags in (2,3,6,7))"
@@ -209,74 +232,75 @@ For MySQL, depending on your MySQL settings, this can even hit the
In this case, consider changing the flag query mode to <tt>:bit_operator</tt>
instead of <tt>:in_list</tt>, like so:
- has_flags 1 => :warpdrive,
- 2 => :shields,
+ has_flags 1 => :warpdrive,
+ 2 => :shields,
:flag_query_mode => :bit_operator
This will modify the generated condition and named_scope methods to use bit
operators in the SQL instead of an IN() list:
- Spaceship.warpdrive_condition # "(spaceships.flags & 1 = 1)",
- Spaceship.not_warpdrive_condition # "(spaceships.flags & 1 = 0)",
- Spaceship.shields_condition # "(spaceships.flags & 2 = 2)",
- Spaceship.not_shields_condition # "(spaceships.flags & 2 = 0)",
+ Spaceship.warpdrive_condition # "(spaceships.flags & 1 = 1)",
+ Spaceship.not_warpdrive_condition # "(spaceships.flags & 1 = 0)",
+ Spaceship.shields_condition # "(spaceships.flags & 2 = 2)",
+ Spaceship.not_shields_condition # "(spaceships.flags & 2 = 0)",
- Spaceship.warpdrive # :conditions => "(spaceships.flags & 1 = 1)"
- Spaceship.not_warpdrive # :conditions => "(spaceships.flags & 1 = 0)"
- Spaceship.shields # :conditions => "(spaceships.flags & 2 = 2)"
- Spaceship.not_shields # :conditions => "(spaceships.flags & 2 = 0)"
+ Spaceship.warpdrive # :conditions => "(spaceships.flags & 1 = 1)"
+ Spaceship.not_warpdrive # :conditions => "(spaceships.flags & 1 = 0)"
+ Spaceship.shields # :conditions => "(spaceships.flags & 2 = 2)"
+ Spaceship.not_shields # :conditions => "(spaceships.flags & 2 = 0)"
The drawback is that due to the bit operator, this query can not use an index
on the flags column.
-==Running the plugin tests
+==Running the gem tests
+
+First, make sure all required gems are installed:
+
+ $ bundle install
-1. (Rails 3 only) Add <tt>mysql2</tt>, <tt>pg</tt> and <tt>sqlite3</tt> gems to your Gemfile.
-1. Install flag_shih_tzu as plugin inside working Rails application.
-1. Modify <tt>test/database.yml</tt> to fit your test environment.
-2. If needed, create the test database you configured in <tt>test/database.yml</tt>.
+The default rake test task will run the tests against the currently locked
+ActiveRecord version (see +Gemfile.lock+):
-Then you can run
+ $ bundle exec rake test
- DB=mysql|postgres|sqlite3 rake test:plugins PLUGIN=flag_shih_tzu
+If you want to run the tests against all supported ActiveRecord versions:
-from your Rails project root or
+ $ bundle exec rake test:all
- DB=mysql|postgres|sqlite3 rake
+This will internally use bundler to load specific ActiveRecord versions
+before executing the tests (see +gemfiles/+), e.g.:
-from <tt>vendor/plugins/flag_shih_tzu</tt>.
+ $ BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-3.1.x' bundle exec rake test
+
+
+All tests will use an in-memory sqlite database by default.
+If you want to use a different database, see <tt>test/database.yml</tt>,
+install the required adapter gem and use the DB environment variable to
+specify which config from <tt>test/database.yml</tt> to use, e.g.:
+
+ $ DB=mysql bundle exec rake
==Authors
{Patryk Peszko}[http://github.com/ppeszko],
{Sebastian Roebke}[http://github.com/boosty],
-{David Anderson}[http://github.com/alpinegizmo]
-and {Tim Payton}[http://github.com/dizzy42]
+{David Anderson}[http://github.com/alpinegizmo],
+{Tim Payton}[http://github.com/dizzy42]
+and a helpful group of
+{contributors}[https://github.com/xing/flag_shih_tzu/contributors].
+Thanks!
Please find out more about our work in our
-{tech blog}[http://blog.xing.com/category/english/tech-blog].
-
-
-==Contributors
-
-{TobiTobes}[http://github.com/rngtng],
-{Martin Stannard}[http://github.com/martinstannard],
-{Ladislav Martincik}[http://github.com/lacomartincik],
-{Peter Boling}[http://github.com/pboling],
-{Daniel Jagszent}[http://github.com/d--j],
-{Thorsten Boettger}[http://github.com/alto],
-{Darren Torpey}[http://github.com/darrentorpey],
-{Joost Baaij}[http://github.com/tilsammans] and
-{Musy Bite}[http://github.com/musybite]
+{Devblog}[http://devblog.xing.com/].
==License
The MIT License
-Copyright (c) 2009 {XING AG}[http://www.xing.com/]
+Copyright (c) 2011 {XING AG}[http://www.xing.com/]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
View
12 Rakefile
@@ -16,15 +16,23 @@ Rake::TestTask.new(:test) do |t|
end
desc 'Generate documentation for the flag_shih_tzu plugin.'
-RDoc::Task.new do |rdoc|
+RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'FlagShihTzu'
- rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
namespace :test do
+ desc 'Test against all supported ActiveRecord versions'
+ task :all do
+ %w(2.3.x 3.0.x 3.1.x 3.2.x).each do |version|
+ sh "BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-#{version}' bundle"
+ sh "BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-#{version}' bundle exec rake test"
+ end
+ end
+
desc 'Measures test coverage'
task :coverage do
rm_f "coverage"
View
13 flag_shih_tzu.gemspec
@@ -8,9 +8,10 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.authors = ["Patryk Peszko", "Sebastian Roebke", "David Anderson", "Tim Payton"]
s.homepage = "https://github.com/xing/flag_shih_tzu"
- s.summary = %q{A rails plugin to store a collection of boolean attributes in a single ActiveRecord column as a bit field}
+ s.summary = %q{Bit fields for ActiveRecord}
s.description = <<-EODOC
-This plugin lets you use a single integer column in an ActiveRecord model
+Bit fields for ActiveRecord:
+This gem lets you use a single integer column in an ActiveRecord model
to store a collection of boolean attributes (flags). Each flag can be used
almost in the same way you would use any boolean attribute on an
ActiveRecord object.
@@ -20,4 +21,12 @@ ActiveRecord object.
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
+
+ s.add_dependency "activerecord", ">= 2.3.0"
+
+ s.add_development_dependency "bundler"
+ s.add_development_dependency "rdoc", ">= 2.4.2"
+ s.add_development_dependency "rake"
+ #s.add_development_dependency "rcov"
+ s.add_development_dependency "sqlite3"
end
View
5 gemfiles/Gemfile.activerecord-2.3.x
@@ -0,0 +1,5 @@
+source "http://rubygems.org"
+
+gemspec :path => '..'
+
+gem "activerecord", "~>2.3.0"
View
5 gemfiles/Gemfile.activerecord-3.0.x
@@ -0,0 +1,5 @@
+source "http://rubygems.org"
+
+gemspec :path => '..'
+
+gem "activerecord", "~>3.0.0"
View
5 gemfiles/Gemfile.activerecord-3.1.x
@@ -0,0 +1,5 @@
+source "http://rubygems.org"
+
+gemspec :path => '..'
+
+gem "activerecord", "~>3.1.0"
View
5 gemfiles/Gemfile.activerecord-3.2.x
@@ -0,0 +1,5 @@
+source "http://rubygems.org"
+
+gemspec :path => '..'
+
+gem "activerecord", "~>3.2.0rc1"
View
90 lib/flag_shih_tzu.rb
@@ -1,17 +1,24 @@
-require 'active_support/core_ext/class/inheritable_attributes'
+require "rubygems"
+require "active_record"
+require "active_support/all"
module FlagShihTzu
- TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'] # taken from ActiveRecord::ConnectionAdapters::Column
+ # taken from ActiveRecord::ConnectionAdapters::Column
+ TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
+
DEFAULT_COLUMN_NAME = 'flags'
def self.included(base)
base.extend(ClassMethods)
+ base.class_attribute :flag_options
+ base.class_attribute :flag_mapping
+ base.class_attribute :flag_columns
end
class IncorrectFlagColumnException < Exception; end
- class DuplicateFlagColumnException < Exception; end
class NoSuchFlagQueryModeException < Exception; end
class NoSuchFlagException < Exception; end
+ class DuplicateFlagColumnException < Exception; end
module ClassMethods
def has_flags(*args)
@@ -19,48 +26,39 @@ def has_flags(*args)
opts = {
:named_scopes => true,
:column => DEFAULT_COLUMN_NAME,
- :flag_query_mode => :in_list
+ :flag_query_mode => :in_list,
+ :strict => false
}.update(opts)
colmn = opts[:column].to_s
return unless check_flag_column(colmn)
# options are stored in a class level hash and apply per-column
- # the mappings are stored in this class level hash and apply per-column
- class_eval <<-EVAL
- unless defined?(HAS_FLAGS_INITIALIZED)
- (class_attribute :flag_columns, :instance_writer => false)
- (class_attribute :flag_options, :instance_writer => false)
- (class_attribute :flag_mapping, :instance_writer => false)
- end
-
- self.flag_columns ||= []
- self.flag_columns += ['#{colmn}']
-
- self.flag_options = {} if self.flag_options.nil?
- self.flag_options['#{colmn}'] = opts
+ self.flag_options ||= {}
+ self.flag_options[colmn] = opts
- # if has_flags is used more than once in a single class, then flag_mapping will already have data in it in successive declarations
- self.flag_mapping = {} if self.flag_mapping.nil?
- #If we already have an instance of the same column in the flag_mapping, then there is a double definition on a column
- raise DuplicateFlagColumnException unless self.flag_mapping['#{colmn}'].nil?
- # initialize flag_mapping for this column
- self.flag_mapping['#{colmn}'] ||= {}
+ # the mappings are stored in this class level hash and apply per-column
+ self.flag_mapping ||= {}
+ #If we already have an instance of the same column in the flag_mapping, then there is a double definition on a column
+ raise DuplicateFlagColumnException if opts[:strict] && !self.flag_mapping[colmn].nil?
+ self.flag_mapping[colmn] ||= {}
+ # keep track of which flag columns are defined on this class
+ class_eval <<-EVAL
+ cattr_accessor :flag_columns
+ @@flag_columns ||= []
+ @@flag_columns << "#{colmn}"
EVAL
flag_hash.each do |flag_key, flag_name|
raise ArgumentError, "has_flags: flag keys should be positive integers, and #{flag_key} is not" unless is_valid_flag_key(flag_key)
raise ArgumentError, "has_flags: flag names should be symbols, and #{flag_name} is not" unless is_valid_flag_name(flag_name)
- next if flag_mapping[colmn][flag_name] & (1 << (flag_key - 1)) # next if already methods defined by flag_shih_tzu
+ next if flag_mapping[colmn][flag_name] & (1 << (flag_key - 1)) # next if already methods defined by flagshitzu
raise ArgumentError, "has_flags: flag name #{flag_name} already defined, please choose different name" if method_defined?(flag_name)
flag_mapping[colmn][flag_name] = 1 << (flag_key - 1)
- # HAS_FLAGS_INITIALIZED: We don't want to initialize has_flags twice for the same class:
class_eval <<-EVAL
- HAS_FLAGS_INITIALIZED = true unless defined?(HAS_FLAGS_INITIALIZED)
-
def #{flag_name}
flag_enabled?(:#{flag_name}, '#{colmn}')
end
@@ -73,6 +71,15 @@ def #{flag_name}=(value)
FlagShihTzu::TRUE_VALUES.include?(value) ? enable_flag(:#{flag_name}, '#{colmn}') : disable_flag(:#{flag_name}, '#{colmn}')
end
+ def #{flag_name}_changed?
+ if colmn_changes = changes['#{colmn}']
+ flag_bit = self.class.flag_mapping['#{colmn}'][:#{flag_name}]
+ (colmn_changes[0] & flag_bit) != (colmn_changes[1] & flag_bit)
+ else
+ false
+ end
+ end
+
def self.#{flag_name}_condition(options = {})
sql_condition_for_flag(:#{flag_name}, '#{colmn}', true, options[:table_alias] || self.table_name)
end
@@ -98,11 +105,12 @@ def self.unset_#{flag_name}_sql
EVAL
end
end
+
end
def check_flag(flag, colmn)
raise ArgumentError, "Column name '#{colmn}' for flag '#{flag}' is not a string" unless colmn.is_a?(String)
- raise ArgumentError, "Invalid flag '#{flag}'" if self.flag_mapping[colmn].nil? || !self.flag_mapping[colmn].include?(flag)
+ raise ArgumentError, "Invalid flag '#{flag}'" if flag_mapping[colmn].nil? || !flag_mapping[colmn].include?(flag)
end
private
@@ -126,33 +134,36 @@ def check_flag_column(colmn, custom_table_name = self.table_name)
has_ar = !!defined?(ActiveRecord) && self.respond_to?(:descends_from_active_record?)
# Supposedly Rails 2.3 takes care of this, but this precaution is needed for backwards compatibility
has_table = has_ar ? ActiveRecord::Base.connection.tables.include?(custom_table_name) : true
- logger.warn("Error: Table '#{custom_table_name}' doesn't exist") and return false unless has_table
+
if has_table
found_column = columns.find {|column| column.name == colmn}
#If you have not yet run the migration that adds the 'flags' column then we don't want to fail, because we need to be able to run the migration
#If the column is there but is of the wrong type, then we must fail, because flag_shih_tzu will not work
- case found_column
- when nil then puts "Error: Column '#{colmn}' doesn't exist on table '#{custom_table_name}'. Did you forget to run migrations?" and return false
- else raise IncorrectFlagColumnException.new("Table '#{custom_table_name}' must have an integer column named '#{colmn}' in order to use FlagShihTzu") and return false unless found_column.type == :integer
+ if found_column.nil?
+ logger.warn("Error: Column '#{colmn}' doesn't exist on table '#{custom_table_name}'. Did you forget to run migrations?") and return false
+ elsif found_column.type != :integer
+ raise IncorrectFlagColumnException.new("Table '#{custom_table_name}' must have an integer column named '#{colmn}' in order to use FlagShihTzu.") and return false
end
else
- #ActiveRecord gem probably hasn't loaded yet?
+ # ActiveRecord gem probably hasn't loaded yet?
+ logger.warn("FlagShihTzu#has_flags: Table '#{custom_table_name}' doesn't exist. Have all migrations been run?") and return false
end
+
true
end
- def sql_condition_for_flag(flag, colmn, enabled = true, table_name = self.table_name)
+ def sql_condition_for_flag(flag, colmn, enabled = true, custom_table_name = self.table_name)
check_flag(flag, colmn)
if flag_options[colmn][:flag_query_mode] == :bit_operator
# use & bit operator directly in the SQL query.
# This has the drawback of not using an index on the flags colum.
- "(#{table_name}.#{colmn} & #{flag_mapping[colmn][flag]} = #{enabled ? flag_mapping[colmn][flag] : 0})"
+ "(#{custom_table_name}.#{colmn} & #{flag_mapping[colmn][flag]} = #{enabled ? flag_mapping[colmn][flag] : 0})"
elsif flag_options[colmn][:flag_query_mode] == :in_list
# use IN() operator in the SQL query.
# This has the drawback of becoming a big query when you have lots of flags.
neg = enabled ? "" : "not "
- "(#{table_name}.#{colmn} #{neg}in (#{sql_in_for_flag(flag, colmn).join(',')}))"
+ "(#{custom_table_name}.#{colmn} #{neg}in (#{sql_in_for_flag(flag, colmn).join(',')}))"
else
raise NoSuchFlagQueryModeException
end
@@ -164,6 +175,12 @@ def sql_in_for_flag(flag, colmn)
num = 2 ** flag_mapping[flag_options[colmn][:column]].length
(1..num).select {|i| i & val == val}
end
+
+ def sql_set_for_flag(flag, colmn, enabled = true, custom_table_name = self.table_name)
+ check_flag(flag, colmn)
+
+ "#{custom_table_name}.#{colmn} = #{custom_table_name}.#{colmn} #{enabled ? "| " : "& ~" }#{flag_mapping[colmn][flag]}"
+ end
def is_valid_flag_key(flag_key)
flag_key > 0 && flag_key == flag_key.to_i
@@ -234,4 +251,3 @@ def determine_flag_colmn_for(flag)
end
end
-
View
2  lib/flag_shih_tzu/version.rb
@@ -1,3 +1,3 @@
module FlagShihTzu
- VERSION = "0.1.0.pre"
+ VERSION = "0.2.3"
end
View
18 test/database.yml
@@ -1,17 +1,13 @@
-sqlite3:
+sqlite:
adapter: sqlite3
- database: test/flag_shih_tzu_plugin.sqlite3.db
-
+ database: ":memory:"
+ timeout: 500
mysql:
adapter: mysql2
- host: localhost
- username: root
- password:
- database: flag_shih_tzu_plugin_test
-
+ database: flag_shih_tzu_test
+ username:
+ encoding: utf8
postgresql:
adapter: postgresql
+ database: flag_shih_tzu_test
username: postgres
- password:
- database: flag_shih_tzu_plugin_test
- min_messages: ERROR
View
251 test/flag_shih_tzu_test.rb
@@ -1,8 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
-load_schema
class Spaceship < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags 1 => :warpdrive,
@@ -11,36 +10,52 @@ class Spaceship < ActiveRecord::Base
end
class SpaceshipWithoutNamedScopes < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags(1 => :warpdrive, :named_scopes => false)
end
class SpaceshipWithoutNamedScopesOldStyle < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags({1 => :warpdrive}, :named_scopes => false)
end
class SpaceshipWithCustomFlagsColumn < ActiveRecord::Base
- set_table_name 'spaceships_with_custom_flags_column'
+ self.table_name = 'spaceships_with_custom_flags_column'
include FlagShihTzu
has_flags(1 => :warpdrive, 2 => :hyperspace, :column => 'bits')
end
+class SpaceshipWithColumnNameAsSymol < ActiveRecord::Base
+ self.table_name = 'spaceships_with_custom_flags_column'
+ include FlagShihTzu
+
+ has_flags(1 => :warpdrive, 2 => :hyperspace, :column => :bits)
+end
+
class SpaceshipWith2CustomFlagsColumn < ActiveRecord::Base
- set_table_name 'spaceships_with_2_custom_flags_column'
+ self.table_name = 'spaceships_with_2_custom_flags_column'
include FlagShihTzu
has_flags({ 1 => :warpdrive, 2 => :hyperspace }, :column => 'bits')
has_flags({ 1 => :jeanlucpicard, 2 => :dajanatroj }, :column => 'commanders')
end
+class SpaceshipWith3CustomFlagsColumn < ActiveRecord::Base
+ self.table_name = 'spaceships_with_3_custom_flags_column'
+ include FlagShihTzu
+
+ has_flags({ 1 => :warpdrive, 2 => :hyperspace }, :column => 'engines')
+ has_flags({ 1 => :photon, 2 => :laser, 3 => :ion_cannon, 4 => :particle_beam }, :column => 'weapons')
+ has_flags({ 1 => :power, 2 => :anti_ax_routine }, :column => 'hal3000')
+end
+
class SpaceshipWithBitOperatorQueryMode < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags(1 => :warpdrive, 2 => :shields, :flag_query_mode => :bit_operator)
@@ -54,16 +69,16 @@ class Planet < ActiveRecord::Base
end
class FlagShihTzuClassMethodsTest < Test::Unit::TestCase
-
-# def setup
-# Spaceship.destroy_all
-# end
+
+ def setup
+ Spaceship.destroy_all
+ end
def test_has_flags_should_raise_an_exception_when_flag_key_is_negative
assert_raises ArgumentError do
eval(<<-EOF
class SpaceshipWithInvalidFlagKey < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags({ -1 => :error })
@@ -77,7 +92,7 @@ def test_has_flags_should_raise_an_exception_when_flag_name_already_used
assert_raises ArgumentError do
eval(<<-EOF
class SpaceshipWithAlreadyUsedFlag < ActiveRecord::Base
- set_table_name 'spaceships_with_2_custom_flags_column'
+ self.table_name = 'spaceships_with_2_custom_flags_column'
include FlagShihTzu
has_flags({ 1 => :jeanluckpicard }, :column => 'bits')
@@ -87,14 +102,14 @@ class SpaceshipWithAlreadyUsedFlag < ActiveRecord::Base
)
end
end
-
+
def test_has_flags_should_raise_an_exception_when_desired_flag_name_method_already_defined
assert_raises ArgumentError do
eval(<<-EOF
class SpaceshipWithAlreadyUsedMethod < ActiveRecord::Base
- set_table_name 'spaceships_with_2_custom_flags_column'
+ self.table_name = 'spaceships_with_2_custom_flags_column'
include FlagShihTzu
-
+
def jeanluckpicard; end
has_flags({ 1 => :jeanluckpicard }, :column => 'bits')
@@ -104,31 +119,30 @@ def jeanluckpicard; end
end
end
-
- def test_has_flags_should_raise_an_exception_when_flag_column_defined_twice
+ def test_has_flags_should_raise_an_exception_when_flag_name_method_defined_by_flagshitzu_if_strict
assert_raises FlagShihTzu::DuplicateFlagColumnException do
eval(<<-EOF
- class SpaceshipWithDuplicateFlagsColumn < ActiveRecord::Base
- set_table_name 'spaceships_with_2_custom_flags_column'
+ class SpaceshipWithAlreadyUsedMethodByFlagshitzuStrict < ActiveRecord::Base
+ self.table_name = 'spaceships_with_2_custom_flags_column'
include FlagShihTzu
- has_flags({ 1 => :warpdrive, 2 => :hyperspace }, :column => 'bits')
- has_flags({ 1 => :jeanlucpicard, 2 => :dajanatroj }, :column => 'bits')
+ has_flags({ 1 => :jeanluckpicard }, :column => 'bits', :strict => true)
+ has_flags({ 1 => :jeanluckpicard }, :column => 'bits', :strict => true)
end
EOF
)
end
end
- def test_has_flags_should_not_raise_an_exception_when_mulitple_has_flags_definitions_on_different_columns
- assert_nothing_raised do
+ def test_has_flags_should_not_raise_an_exception_when_flag_name_method_defined_by_flagshitzu
+ assert_nothing_raised ArgumentError do
eval(<<-EOF
class SpaceshipWithAlreadyUsedMethodByFlagshitzu < ActiveRecord::Base
- set_table_name 'spaceships_with_2_custom_flags_column'
+ self.table_name = 'spaceships_with_2_custom_flags_column'
include FlagShihTzu
has_flags({ 1 => :jeanluckpicard }, :column => 'bits')
- has_flags({ 1 => :mangoes }, :column => 'commanders')
+ has_flags({ 1 => :jeanluckpicard }, :column => 'bits')
end
EOF
)
@@ -139,7 +153,7 @@ def test_has_flags_should_raise_an_exception_when_flag_name_is_not_a_symbol
assert_raises ArgumentError do
eval(<<-EOF
class SpaceshipWithInvalidFlagName < ActiveRecord::Base
- set_table_name 'spaceships'
+ self.table_name = 'spaceships'
include FlagShihTzu
has_flags({ 1 => 'error' })
@@ -154,7 +168,7 @@ def test_should_define_a_sql_condition_method_for_flag_enabled
assert_equal "(spaceships.flags in (2,3,6,7))", Spaceship.shields_condition
assert_equal "(spaceships.flags in (4,5,6,7))", Spaceship.electrolytes_condition
end
-
+
def test_should_accept_a_table_alias_option_for_sql_condition_method
assert_equal "(old_spaceships.flags in (1,3,5,7))", Spaceship.warpdrive_condition(:table_alias => 'old_spaceships')
end
@@ -171,10 +185,10 @@ def test_should_define_a_sql_condition_method_for_flag_not_enabled
assert_equal "(spaceships.flags not in (2,3,6,7))", Spaceship.not_shields_condition
assert_equal "(spaceships.flags not in (4,5,6,7))", Spaceship.not_electrolytes_condition
end
-
+
def test_should_define_a_sql_condition_method_for_flag_enabled_with_custom_table_name
- assert_equal "(custom_spaceships.flags in (1,3,5,7))", Spaceship.send( :sql_condition_for_flag, :warpdrive, 'flags', true, 'custom_spaceships')
- end
+ assert_equal "(custom_spaceships.flags in (1,3,5,7))", Spaceship.send(:sql_condition_for_flag, :warpdrive, 'flags', true, 'custom_spaceships')
+ end
def test_should_define_a_sql_condition_method_for_flag_enabled_with_2_colmns_not_enabled
assert_equal "(spaceships_with_2_custom_flags_column.bits not in (1,3))", SpaceshipWith2CustomFlagsColumn.not_warpdrive_condition
@@ -182,7 +196,7 @@ def test_should_define_a_sql_condition_method_for_flag_enabled_with_2_colmns_not
assert_equal "(spaceships_with_2_custom_flags_column.commanders not in (1,3))", SpaceshipWith2CustomFlagsColumn.not_jeanlucpicard_condition
assert_equal "(spaceships_with_2_custom_flags_column.commanders not in (2,3))", SpaceshipWith2CustomFlagsColumn.not_dajanatroj_condition
end
-
+
def test_should_define_a_sql_condition_method_for_flag_enabled_using_bit_operators
assert_equal "(spaceships.flags & 1 = 1)", SpaceshipWithBitOperatorQueryMode.warpdrive_condition
assert_equal "(spaceships.flags & 2 = 2)", SpaceshipWithBitOperatorQueryMode.shields_condition
@@ -194,45 +208,39 @@ def test_should_define_a_sql_condition_method_for_flag_not_enabled_using_bit_ope
end
def test_should_define_a_named_scope_for_flag_enabled
- assert_equal(["(spaceships.flags in (1,3,5,7))"], Spaceship.warpdrive.where_values)
- assert_equal(["(spaceships.flags in (2,3,6,7))"], Spaceship.shields.where_values)
- assert_equal(["(spaceships.flags in (4,5,6,7))"], Spaceship.electrolytes.where_values)
+ assert_where_value "(spaceships.flags in (1,3,5,7))", Spaceship.warpdrive
+ assert_where_value "(spaceships.flags in (2,3,6,7))", Spaceship.shields
+ assert_where_value "(spaceships.flags in (4,5,6,7))", Spaceship.electrolytes
end
def test_should_define_a_named_scope_for_flag_not_enabled
- assert_equal(["(spaceships.flags not in (1,3,5,7))"], Spaceship.not_warpdrive.where_values)
- assert_equal(["(spaceships.flags not in (2,3,6,7))"], Spaceship.not_shields.where_values)
- assert_equal(["(spaceships.flags not in (4,5,6,7))"], Spaceship.not_electrolytes.where_values)
+ assert_where_value "(spaceships.flags not in (1,3,5,7))", Spaceship.not_warpdrive
+ assert_where_value "(spaceships.flags not in (2,3,6,7))", Spaceship.not_shields
+ assert_where_value "(spaceships.flags not in (4,5,6,7))", Spaceship.not_electrolytes
end
- def test_should_define_a_named_scope_for_flag_enabled_with_2_columns_1
- assert_equal(["(spaceships_with_2_custom_flags_column.bits in (1,3))"], SpaceshipWith2CustomFlagsColumn.warpdrive.where_values)
- end
- def test_should_define_a_named_scope_for_flag_enabled_with_2_columns_2
- assert_equal(["(spaceships_with_2_custom_flags_column.bits in (2,3))"], SpaceshipWith2CustomFlagsColumn.hyperspace.where_values)
- end
- def test_should_define_a_named_scope_for_flag_enabled_with_2_columns_3
- assert_equal(["(spaceships_with_2_custom_flags_column.commanders in (1,3))"], SpaceshipWith2CustomFlagsColumn.jeanlucpicard.where_values)
- end
- def test_should_define_a_named_scope_for_flag_enabled_with_2_columns_4
- assert_equal(["(spaceships_with_2_custom_flags_column.commanders in (2,3))"], SpaceshipWith2CustomFlagsColumn.dajanatroj.where_values)
+ def test_should_define_a_named_scope_for_flag_enabled_with_2_columns
+ assert_where_value "(spaceships_with_2_custom_flags_column.bits in (1,3))", SpaceshipWith2CustomFlagsColumn.warpdrive
+ assert_where_value "(spaceships_with_2_custom_flags_column.bits in (2,3))", SpaceshipWith2CustomFlagsColumn.hyperspace
+ assert_where_value "(spaceships_with_2_custom_flags_column.commanders in (1,3))", SpaceshipWith2CustomFlagsColumn.jeanlucpicard
+ assert_where_value "(spaceships_with_2_custom_flags_column.commanders in (2,3))", SpaceshipWith2CustomFlagsColumn.dajanatroj
end
def test_should_define_a_named_scope_for_flag_not_enabled_with_2_columns
- assert_equal(["(spaceships_with_2_custom_flags_column.bits not in (1,3))"], SpaceshipWith2CustomFlagsColumn.not_warpdrive.where_values)
- assert_equal(["(spaceships_with_2_custom_flags_column.bits not in (2,3))"], SpaceshipWith2CustomFlagsColumn.not_hyperspace.where_values)
- assert_equal(["(spaceships_with_2_custom_flags_column.commanders not in (1,3))"], SpaceshipWith2CustomFlagsColumn.not_jeanlucpicard.where_values)
- assert_equal(["(spaceships_with_2_custom_flags_column.commanders not in (2,3))"], SpaceshipWith2CustomFlagsColumn.not_dajanatroj.where_values)
+ assert_where_value "(spaceships_with_2_custom_flags_column.bits not in (1,3))", SpaceshipWith2CustomFlagsColumn.not_warpdrive
+ assert_where_value "(spaceships_with_2_custom_flags_column.bits not in (2,3))", SpaceshipWith2CustomFlagsColumn.not_hyperspace
+ assert_where_value "(spaceships_with_2_custom_flags_column.commanders not in (1,3))", SpaceshipWith2CustomFlagsColumn.not_jeanlucpicard
+ assert_where_value "(spaceships_with_2_custom_flags_column.commanders not in (2,3))", SpaceshipWith2CustomFlagsColumn.not_dajanatroj
end
-
+
def test_should_define_a_named_scope_for_flag_enabled_using_bit_operators
- assert_equal(["(spaceships.flags & 1 = 1)"], SpaceshipWithBitOperatorQueryMode.warpdrive.where_values)
- assert_equal(["(spaceships.flags & 2 = 2)"], SpaceshipWithBitOperatorQueryMode.shields.where_values)
+ assert_where_value "(spaceships.flags & 1 = 1)", SpaceshipWithBitOperatorQueryMode.warpdrive
+ assert_where_value "(spaceships.flags & 2 = 2)", SpaceshipWithBitOperatorQueryMode.shields
end
def test_should_define_a_named_scope_for_flag_not_enabled_using_bit_operators
- assert_equal(["(spaceships.flags & 1 = 0)"], SpaceshipWithBitOperatorQueryMode.not_warpdrive.where_values)
- assert_equal(["(spaceships.flags & 2 = 0)"], SpaceshipWithBitOperatorQueryMode.not_shields.where_values)
+ assert_where_value "(spaceships.flags & 1 = 0)", SpaceshipWithBitOperatorQueryMode.not_warpdrive
+ assert_where_value "(spaceships.flags & 2 = 0)", SpaceshipWithBitOperatorQueryMode.not_shields
end
def test_should_return_the_correct_number_of_items_from_a_named_scope
@@ -273,12 +281,20 @@ def test_should_work_with_a_custom_flags_column
assert_equal "(spaceships_with_custom_flags_column.bits not in (1,3))", SpaceshipWithCustomFlagsColumn.not_warpdrive_condition
assert_equal "(spaceships_with_custom_flags_column.bits in (2,3))", SpaceshipWithCustomFlagsColumn.hyperspace_condition
assert_equal "(spaceships_with_custom_flags_column.bits not in (2,3))", SpaceshipWithCustomFlagsColumn.not_hyperspace_condition
- assert_equal(["(spaceships_with_custom_flags_column.bits in (1,3))"], SpaceshipWithCustomFlagsColumn.warpdrive.where_values)
- assert_equal(["(spaceships_with_custom_flags_column.bits not in (1,3))"], SpaceshipWithCustomFlagsColumn.not_warpdrive.where_values)
- assert_equal(["(spaceships_with_custom_flags_column.bits in (2,3))"], SpaceshipWithCustomFlagsColumn.hyperspace.where_values)
- assert_equal(["(spaceships_with_custom_flags_column.bits not in (2,3))"], SpaceshipWithCustomFlagsColumn.not_hyperspace.where_values)
+ assert_where_value "(spaceships_with_custom_flags_column.bits in (1,3))", SpaceshipWithCustomFlagsColumn.warpdrive
+ assert_where_value "(spaceships_with_custom_flags_column.bits not in (1,3))", SpaceshipWithCustomFlagsColumn.not_warpdrive
+ assert_where_value "(spaceships_with_custom_flags_column.bits in (2,3))", SpaceshipWithCustomFlagsColumn.hyperspace
+ assert_where_value "(spaceships_with_custom_flags_column.bits not in (2,3))", SpaceshipWithCustomFlagsColumn.not_hyperspace
end
-
+
+ def test_should_work_with_a_custom_flags_column_name_as_symbol
+ spaceship = SpaceshipWithColumnNameAsSymol.new
+ spaceship.enable_flag(:warpdrive)
+ spaceship.save!
+ spaceship.reload
+ assert_equal 1, spaceship.flags('bits')
+ end
+
def test_should_not_error_out_when_table_is_not_present
assert_nothing_raised(ActiveRecord::StatementInvalid) do
Planet.class_eval do
@@ -287,7 +303,14 @@ def test_should_not_error_out_when_table_is_not_present
end
end
end
-
+
+ private
+
+ def assert_where_value(expected, scope)
+ assert_equal expected,
+ ActiveRecord::VERSION::MAJOR == 2 ? scope.proxy_options[:conditions] : scope.where_values.first
+ end
+
end
class FlagShihTzuInstanceMethodsTest < Test::Unit::TestCase
@@ -386,6 +409,27 @@ def test_should_define_an_attribute_writer_method
assert @spaceship.warpdrive
end
+ def test_should_define_dirty_suffix_changed?
+ assert !@spaceship.warpdrive_changed?
+ assert !@spaceship.shields_changed?
+
+ @spaceship.enable_flag(:warpdrive)
+ assert @spaceship.warpdrive_changed?
+ assert !@spaceship.shields_changed?
+
+ @spaceship.enable_flag(:shields)
+ assert @spaceship.warpdrive_changed?
+ assert @spaceship.shields_changed?
+
+ @spaceship.disable_flag(:warpdrive)
+ assert !@spaceship.warpdrive_changed?
+ assert @spaceship.shields_changed?
+
+ @spaceship.disable_flag(:shields)
+ assert !@spaceship.warpdrive_changed?
+ assert !@spaceship.shields_changed?
+ end
+
def test_should_respect_true_values_like_active_record
[true, 1, '1', 't', 'T', 'true', 'TRUE'].each do |true_value|
@spaceship.warpdrive = true_value
@@ -398,39 +442,40 @@ def test_should_respect_true_values_like_active_record
end
end
-#This is a key operational difference between pboling branch on kuzmann
-# def test_should_ignore_has_flags_call_if_column_does_not_exist_yet
-# assert_nothing_raised do
-# eval(<<-EOF
-# class SpaceshipWithoutFlagsColumn < ActiveRecord::Base
-# set_table_name 'spaceships_without_flags_column'
-# include FlagShihTzu
-#
-# has_flags 1 => :warpdrive,
-# 2 => :shields,
-# 3 => :electrolytes
-# end
-# EOF
-# )
-# end
-#
-# assert !SpaceshipWithoutFlagsColumn.method_defined?(:warpdrive)
-# end
-
- def test_check_flag_column_raises_error_if_column_not_in_list_of_attributes
- assert_raises FlagShihTzu::IncorrectFlagColumnException do
- @spaceship.class.send(:check_flag_column, 'incorrect_flags_column')
+ def test_should_ignore_has_flags_call_if_column_does_not_exist_yet
+ assert_nothing_raised do
+ eval(<<-EOF
+ class SpaceshipWithoutFlagsColumn < ActiveRecord::Base
+ self.table_name = 'spaceships_without_flags_column'
+ include FlagShihTzu
+
+ has_flags 1 => :warpdrive,
+ 2 => :shields,
+ 3 => :electrolytes
+ end
+ EOF
+ )
end
+
+ assert !SpaceshipWithoutFlagsColumn.method_defined?(:warpdrive)
end
-
- def test_check_flag_column_raises_error_if_column_not_integer
+
+ def test_should_ignore_has_flags_call_if_column_not_integer
assert_raises FlagShihTzu::IncorrectFlagColumnException do
- Class.new(ActiveRecord::Base) do
- set_table_name 'spaceships_with_non_integer_flags_column'
- include FlagShihTzu
- has_flags 1 => :warpdrive, 2 => :hyperspace
- end
+ eval(<<-EOF
+ class SpaceshipWithNonIntegerColumn < ActiveRecord::Base
+ self.table_name ='spaceships_with_non_integer_column'
+ include FlagShihTzu
+
+ has_flags 1 => :warpdrive,
+ 2 => :shields,
+ 3 => :electrolytes
+ end
+ EOF
+ )
end
+
+ assert !SpaceshipWithoutFlagsColumn.method_defined?(:warpdrive)
end
def test_column_guessing_for_default_column
@@ -484,14 +529,14 @@ def test_should_store_the_flags_correctly
end
def test_enable_flag_should_leave_the_flag_enabled_when_called_twice
- 2.times do
+ 2.times do
@spaceship.enable_flag(:warpdrive)
assert @spaceship.flag_enabled?(:warpdrive)
end
end
def test_disable_flag_should_leave_the_flag_disabled_when_called_twice
- 2.times do
+ 2.times do
@spaceship.disable_flag(:warpdrive)
assert !@spaceship.flag_enabled?(:warpdrive)
end
@@ -517,4 +562,20 @@ def test_should_respect_true_values_like_active_record
assert !@spaceship.warpdrive
end
end
+
+ def test_should_return_a_sql_set_method_for_flag
+ assert_equal "spaceships.flags = spaceships.flags | 1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', true)
+ assert_equal "spaceships.flags = spaceships.flags & ~1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', false)
+ end
+
+end
+
+class FlagShihTzuClassMethodsTest < Test::Unit::TestCase
+
+ def test_should_track_columns_used_by_FlagShihTzu
+ assert_equal Spaceship.flag_columns, ['flags']
+ assert_equal SpaceshipWith2CustomFlagsColumn.flag_columns, ['bits', 'commanders']
+ assert_equal SpaceshipWith3CustomFlagsColumn.flag_columns, ['engines', 'weapons', 'hal3000']
+ end
+
end
View
6 test/schema.rb
@@ -14,6 +14,12 @@
t.integer :commanders, :null => false, :default => 0
end
+ create_table :spaceships_with_3_custom_flags_column, :force => true do |t|
+ t.integer :engines, :null => false, :default => 0
+ t.integer :weapons, :null => false, :default => 0
+ t.integer :hal3000, :null => false, :default => 0
+ end
+
create_table :spaceships_without_flags_column, :force => true do |t|
end
View
43 test/test_helper.rb
@@ -1,35 +1,14 @@
-ENV['RAILS_ENV'] = 'test'
-ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
+require "test/unit"
+require "yaml"
+require "logger"
+require "flag_shih_tzu"
-#exend LOAD_PATH for test with- and without Railsframework
-$LOAD_PATH << 'lib/'
-$LOAD_PATH << 'vendor/plugins/flag_shih_tzu/lib/'
+ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
-require 'test/unit'
-require 'yaml'
-require 'logger'
-require 'rubygems'
-gem 'activerecord', '~> 3.0'
-require 'active_record'
-require 'flag_shih_tzu'
+configs = YAML.load_file(File.dirname(__FILE__) + "/database.yml")
+ActiveRecord::Base.configurations = configs
-def load_schema
- config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
- ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
- db_adapter = ENV['DB'] || 'sqlite3'
-
- # no DB passed, try sqlite3 by default
- db_adapter ||=
- begin
- require 'sqlite3'
- 'sqlite3'
- rescue MissingSourceFile
- end
-
- if db_adapter.nil?
- raise "No DB Adapter selected. Configure test/database.yml and use DB=mysql|postgresql|sqlite3 to pick one. sqlite3 will be used by default (gem install sqlite3-ruby)."
- end
-
- ActiveRecord::Base.establish_connection(config[db_adapter])
- load(File.dirname(__FILE__) + "/schema.rb")
-end
+db_name = ENV["DB"] || "sqlite"
+ActiveRecord::Base.establish_connection(db_name)
+
+load(File.dirname(__FILE__) + "/schema.rb")
Please sign in to comment.
Something went wrong with that request. Please try again.