Initial import
This commit is contained in:
74
vendor/plugins/acts_as_paranoid/CHANGELOG
vendored
Normal file
74
vendor/plugins/acts_as_paranoid/CHANGELOG
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
* (4 Oct 2007)
|
||||
|
||||
Update for Edge rails: remove support for legacy #count args
|
||||
|
||||
* (2 Feb 2007)
|
||||
|
||||
Add support for custom primary keys [Jeff Dean]
|
||||
|
||||
* (2 July 2006)
|
||||
|
||||
Add paranoid delete_all implementation [Marshall Roch]
|
||||
|
||||
* (23 May 2006)
|
||||
|
||||
Allow setting of future dates for content expiration.
|
||||
|
||||
* (15 May 2006)
|
||||
|
||||
Added support for dynamic finders
|
||||
|
||||
* (28 Mar 2006)
|
||||
|
||||
Updated for Rails 1.1. I love removing code.
|
||||
|
||||
Refactored #find method
|
||||
Nested Scopes
|
||||
|
||||
*0.3.1* (20 Dec 2005)
|
||||
|
||||
* took out deleted association code for 'chainsaw butchery of base classes' [sorry Erik Terpstra]
|
||||
* verified tests pass on Rails 1.0
|
||||
|
||||
*0.3* (27 Nov 2005)
|
||||
|
||||
* Deleted models will find deleted associations by default now [Erik Terpstra]
|
||||
* Added :group as valid option for find [Michael Dabney]
|
||||
* Changed the module namespace to Caboose::Acts::Paranoid
|
||||
|
||||
*0.2.0* (6 Nov 2005)
|
||||
|
||||
* Upgrade to Rails 1.0 RC4. ActiveRecord::Base#constrain has been replaced with scope_with.
|
||||
|
||||
*0.1.7* (22 Oct 2005)
|
||||
|
||||
* Added :with_deleted as a valid option of ActiveRecord::Base#find
|
||||
|
||||
*0.1.6* (25 Sep 2005)
|
||||
|
||||
* Fixed bug where nested constrains would get clobbered after multiple queries
|
||||
|
||||
*0.1.5* (22 Sep 2005)
|
||||
|
||||
* Fixed bug where acts_as_paranoid would clobber other constrains
|
||||
* Simplified acts_as_paranoid mixin including.
|
||||
|
||||
*0.1.4* (18 Sep 2005)
|
||||
|
||||
* First RubyForge release
|
||||
|
||||
*0.1.3* (18 Sep 2005)
|
||||
|
||||
* ignore multiple calls to acts_as_paranoid on the same model
|
||||
|
||||
*0.1.2* (18 Sep 2005)
|
||||
|
||||
* fixed a bug that kept you from selecting the first deleted record
|
||||
|
||||
*0.1.1* (18 Sep 2005)
|
||||
|
||||
* Fixed bug that kept you from selecting deleted records by ID
|
||||
|
||||
*0.1* (17 Sep 2005)
|
||||
|
||||
* Initial gem
|
||||
20
vendor/plugins/acts_as_paranoid/MIT-LICENSE
vendored
Normal file
20
vendor/plugins/acts_as_paranoid/MIT-LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2005 Rick Olson
|
||||
|
||||
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.
|
||||
26
vendor/plugins/acts_as_paranoid/README
vendored
Normal file
26
vendor/plugins/acts_as_paranoid/README
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
= acts_as_paranoid
|
||||
|
||||
Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the
|
||||
current timestamp. ActiveRecord is required.
|
||||
|
||||
== Resources
|
||||
|
||||
Install
|
||||
|
||||
* gem install acts_as_paranoid
|
||||
|
||||
Rubyforge project
|
||||
|
||||
* http://rubyforge.org/projects/ar-paranoid
|
||||
|
||||
RDocs
|
||||
|
||||
* http://ar-paranoid.rubyforge.org
|
||||
|
||||
Subversion
|
||||
|
||||
* http://techno-weenie.net/svn/projects/acts_as_paranoid
|
||||
|
||||
Collaboa
|
||||
|
||||
* http://collaboa.techno-weenie.net/repository/browse/acts_as_paranoid
|
||||
41
vendor/plugins/acts_as_paranoid/RUNNING_UNIT_TESTS
vendored
Normal file
41
vendor/plugins/acts_as_paranoid/RUNNING_UNIT_TESTS
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
== Creating the test database
|
||||
|
||||
The default name for the test databases is "activerecord_paranoid". If you
|
||||
want to use another database name then be sure to update the connection
|
||||
adapter setups you want to test with in test/connections/<your database>/connection.rb.
|
||||
When you have the database online, you can import the fixture tables with
|
||||
the test/fixtures/db_definitions/*.sql files.
|
||||
|
||||
Make sure that you create database objects with the same user that you specified in i
|
||||
connection.rb otherwise (on Postgres, at least) tests for default values will fail.
|
||||
|
||||
== Running with Rake
|
||||
|
||||
The easiest way to run the unit tests is through Rake. The default task runs
|
||||
the entire test suite for all the adapters. You can also run the suite on just
|
||||
one adapter by using the tasks test_mysql_ruby, test_ruby_mysql, test_sqlite,
|
||||
or test_postresql. For more information, checkout the full array of rake tasks with "rake -T"
|
||||
|
||||
Rake can be found at http://rake.rubyforge.org
|
||||
|
||||
== Running by hand
|
||||
|
||||
Unit tests are located in test directory. If you only want to run a single test suite,
|
||||
or don't want to bother with Rake, you can do so with something like:
|
||||
|
||||
cd test; ruby -I "connections/native_mysql" base_test.rb
|
||||
|
||||
That'll run the base suite using the MySQL-Ruby adapter. Change the adapter
|
||||
and test suite name as needed.
|
||||
|
||||
== Faster tests
|
||||
|
||||
If you are using a database that supports transactions, you can set the
|
||||
"AR_TX_FIXTURES" environment variable to "yes" to use transactional fixtures.
|
||||
This gives a very large speed boost. With rake:
|
||||
|
||||
rake AR_TX_FIXTURES=yes
|
||||
|
||||
Or, by hand:
|
||||
|
||||
AR_TX_FIXTURES=yes ruby -I connections/native_sqlite3 base_test.rb
|
||||
180
vendor/plugins/acts_as_paranoid/Rakefile
vendored
Normal file
180
vendor/plugins/acts_as_paranoid/Rakefile
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
require 'rubygems'
|
||||
|
||||
Gem::manage_gems
|
||||
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/packagetask'
|
||||
require 'rake/gempackagetask'
|
||||
require 'rake/testtask'
|
||||
require 'rake/contrib/rubyforgepublisher'
|
||||
|
||||
PKG_NAME = 'acts_as_paranoid'
|
||||
PKG_VERSION = '0.3.1'
|
||||
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
||||
PROD_HOST = "technoweenie@bidwell.textdrive.com"
|
||||
RUBY_FORGE_PROJECT = 'ar-paranoid'
|
||||
RUBY_FORGE_USER = 'technoweenie'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the calculations plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Generate documentation for the acts_as_paranoid plugin.'
|
||||
Rake::RDocTask.new do |rdoc|
|
||||
rdoc.rdoc_dir = 'html'
|
||||
rdoc.title = "#{PKG_NAME} -- protect your ActiveRecord objects from accidental deletion"
|
||||
rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object'
|
||||
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
||||
rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
spec = Gem::Specification.new do |s|
|
||||
s.name = PKG_NAME
|
||||
s.version = PKG_VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.summary = "acts_as_paranoid keeps models from actually being deleted by setting a deleted_at field."
|
||||
s.files = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
|
||||
s.files.delete "acts_as_paranoid_plugin.sqlite.db"
|
||||
s.files.delete "acts_as_paranoid_plugin.sqlite3.db"
|
||||
s.require_path = 'lib'
|
||||
s.autorequire = 'acts_as_paranoid'
|
||||
s.has_rdoc = true
|
||||
s.test_files = Dir['test/**/*_test.rb']
|
||||
s.author = "Rick Olson"
|
||||
s.email = "technoweenie@gmail.com"
|
||||
s.homepage = "http://techno-weenie.net"
|
||||
end
|
||||
|
||||
Rake::GemPackageTask.new(spec) do |pkg|
|
||||
pkg.need_tar = true
|
||||
end
|
||||
|
||||
desc "Publish the API documentation"
|
||||
task :pdoc => [:rdoc] do
|
||||
Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
|
||||
end
|
||||
|
||||
desc 'Publish the gem and API docs'
|
||||
task :publish => [:pdoc, :rubyforge_upload]
|
||||
|
||||
desc "Publish the release files to RubyForge."
|
||||
task :rubyforge_upload => :package do
|
||||
files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
|
||||
|
||||
if RUBY_FORGE_PROJECT then
|
||||
require 'net/http'
|
||||
require 'open-uri'
|
||||
|
||||
project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
|
||||
project_data = open(project_uri) { |data| data.read }
|
||||
group_id = project_data[/[?&]group_id=(\d+)/, 1]
|
||||
raise "Couldn't get group id" unless group_id
|
||||
|
||||
# This echos password to shell which is a bit sucky
|
||||
if ENV["RUBY_FORGE_PASSWORD"]
|
||||
password = ENV["RUBY_FORGE_PASSWORD"]
|
||||
else
|
||||
print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
|
||||
password = STDIN.gets.chomp
|
||||
end
|
||||
|
||||
login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
||||
data = [
|
||||
"login=1",
|
||||
"form_loginname=#{RUBY_FORGE_USER}",
|
||||
"form_pw=#{password}"
|
||||
].join("&")
|
||||
http.post("/account/login.php", data)
|
||||
end
|
||||
|
||||
cookie = login_response["set-cookie"]
|
||||
raise "Login failed" unless cookie
|
||||
headers = { "Cookie" => cookie }
|
||||
|
||||
release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
|
||||
release_data = open(release_uri, headers) { |data| data.read }
|
||||
package_id = release_data[/[?&]package_id=(\d+)/, 1]
|
||||
raise "Couldn't get package id" unless package_id
|
||||
|
||||
first_file = true
|
||||
release_id = ""
|
||||
|
||||
files.each do |filename|
|
||||
basename = File.basename(filename)
|
||||
file_ext = File.extname(filename)
|
||||
file_data = File.open(filename, "rb") { |file| file.read }
|
||||
|
||||
puts "Releasing #{basename}..."
|
||||
|
||||
release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
|
||||
release_date = Time.now.strftime("%Y-%m-%d %H:%M")
|
||||
type_map = {
|
||||
".zip" => "3000",
|
||||
".tgz" => "3110",
|
||||
".gz" => "3110",
|
||||
".gem" => "1400"
|
||||
}; type_map.default = "9999"
|
||||
type = type_map[file_ext]
|
||||
boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
|
||||
|
||||
query_hash = if first_file then
|
||||
{
|
||||
"group_id" => group_id,
|
||||
"package_id" => package_id,
|
||||
"release_name" => PKG_FILE_NAME,
|
||||
"release_date" => release_date,
|
||||
"type_id" => type,
|
||||
"processor_id" => "8000", # Any
|
||||
"release_notes" => "",
|
||||
"release_changes" => "",
|
||||
"preformatted" => "1",
|
||||
"submit" => "1"
|
||||
}
|
||||
else
|
||||
{
|
||||
"group_id" => group_id,
|
||||
"release_id" => release_id,
|
||||
"package_id" => package_id,
|
||||
"step2" => "1",
|
||||
"type_id" => type,
|
||||
"processor_id" => "8000", # Any
|
||||
"submit" => "Add This File"
|
||||
}
|
||||
end
|
||||
|
||||
query = "?" + query_hash.map do |(name, value)|
|
||||
[name, URI.encode(value)].join("=")
|
||||
end.join("&")
|
||||
|
||||
data = [
|
||||
"--" + boundary,
|
||||
"Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
|
||||
"Content-Type: application/octet-stream",
|
||||
"Content-Transfer-Encoding: binary",
|
||||
"", file_data, ""
|
||||
].join("\x0D\x0A")
|
||||
|
||||
release_headers = headers.merge(
|
||||
"Content-Type" => "multipart/form-data; boundary=#{boundary}"
|
||||
)
|
||||
|
||||
target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
|
||||
http.post(target + query, data, release_headers)
|
||||
end
|
||||
|
||||
if first_file then
|
||||
release_id = release_response.body[/release_id=(\d+)/, 1]
|
||||
raise("Couldn't get release id") unless release_id
|
||||
end
|
||||
|
||||
first_file = false
|
||||
end
|
||||
end
|
||||
end
|
||||
16
vendor/plugins/acts_as_paranoid/init.rb
vendored
Normal file
16
vendor/plugins/acts_as_paranoid/init.rb
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
class << ActiveRecord::Base
|
||||
def belongs_to_with_deleted(association_id, options = {})
|
||||
with_deleted = options.delete :with_deleted
|
||||
returning belongs_to_without_deleted(association_id, options) do
|
||||
if with_deleted
|
||||
reflection = reflect_on_association(association_id)
|
||||
association_accessor_methods(reflection, Caboose::Acts::BelongsToWithDeletedAssociation)
|
||||
association_constructor_method(:build, reflection, Caboose::Acts::BelongsToWithDeletedAssociation)
|
||||
association_constructor_method(:create, reflection, Caboose::Acts::BelongsToWithDeletedAssociation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :belongs_to, :deleted
|
||||
end
|
||||
ActiveRecord::Base.send :include, Caboose::Acts::Paranoid
|
||||
14
vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb
vendored
Normal file
14
vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
module Caboose # :nodoc:
|
||||
module Acts # :nodoc:
|
||||
class BelongsToWithDeletedAssociation < ActiveRecord::Associations::BelongsToAssociation
|
||||
private
|
||||
def find_target
|
||||
@reflection.klass.find_with_deleted(
|
||||
@owner[@reflection.primary_key_name],
|
||||
:conditions => conditions,
|
||||
:include => @reflection.options[:include]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
148
vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb
vendored
Normal file
148
vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
module Caboose #:nodoc:
|
||||
module Acts #:nodoc:
|
||||
# Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the current timestamp.
|
||||
# This assumes the table has a deleted_at date/time field. Most normal model operations will work, but there will be some oddities.
|
||||
#
|
||||
# class Widget < ActiveRecord::Base
|
||||
# acts_as_paranoid
|
||||
# end
|
||||
#
|
||||
# Widget.find(:all)
|
||||
# # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
|
||||
#
|
||||
# Widget.find(:first, :conditions => ['title = ?', 'test'], :order => 'title')
|
||||
# # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test' ORDER BY title LIMIT 1
|
||||
#
|
||||
# Widget.find_with_deleted(:all)
|
||||
# # SELECT * FROM widgets
|
||||
#
|
||||
# Widget.find(:all, :with_deleted => true)
|
||||
# # SELECT * FROM widgets
|
||||
#
|
||||
# Widget.find_with_deleted(1).deleted?
|
||||
# # Returns true if the record was previously destroyed, false if not
|
||||
#
|
||||
# Widget.count
|
||||
# # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL
|
||||
#
|
||||
# Widget.count ['title = ?', 'test']
|
||||
# # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test'
|
||||
#
|
||||
# Widget.count_with_deleted
|
||||
# # SELECT COUNT(*) FROM widgets
|
||||
#
|
||||
# Widget.delete_all
|
||||
# # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36'
|
||||
#
|
||||
# Widget.delete_all!
|
||||
# # DELETE FROM widgets
|
||||
#
|
||||
# @widget.destroy
|
||||
# # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36' WHERE id = 1
|
||||
#
|
||||
# @widget.destroy!
|
||||
# # DELETE FROM widgets WHERE id = 1
|
||||
#
|
||||
module Paranoid
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def acts_as_paranoid(options = {})
|
||||
unless paranoid? # don't let AR call this twice
|
||||
cattr_accessor :deleted_attribute
|
||||
self.deleted_attribute = options[:with] || :deleted_at
|
||||
alias_method :destroy_without_callbacks!, :destroy_without_callbacks
|
||||
class << self
|
||||
alias_method :find_every_with_deleted, :find_every
|
||||
alias_method :calculate_with_deleted, :calculate
|
||||
alias_method :delete_all!, :delete_all
|
||||
end
|
||||
end
|
||||
include InstanceMethods
|
||||
end
|
||||
|
||||
def paranoid?
|
||||
self.included_modules.include?(InstanceMethods)
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods #:nodoc:
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def find_with_deleted(*args)
|
||||
options = args.extract_options!
|
||||
validate_find_options(options)
|
||||
set_readonly_option!(options)
|
||||
options[:with_deleted] = true # yuck!
|
||||
|
||||
case args.first
|
||||
when :first then find_initial(options)
|
||||
when :all then find_every(options)
|
||||
else find_from_ids(args, options)
|
||||
end
|
||||
end
|
||||
|
||||
def count_with_deleted(*args)
|
||||
calculate_with_deleted(:count, *construct_count_options_from_args(*args))
|
||||
end
|
||||
|
||||
def count(*args)
|
||||
with_deleted_scope { count_with_deleted(*args) }
|
||||
end
|
||||
|
||||
def calculate(*args)
|
||||
with_deleted_scope { calculate_with_deleted(*args) }
|
||||
end
|
||||
|
||||
def delete_all(conditions = nil)
|
||||
self.update_all ["#{self.deleted_attribute} = ?", current_time], conditions
|
||||
end
|
||||
|
||||
protected
|
||||
def current_time
|
||||
default_timezone == :utc ? Time.now.utc : Time.now
|
||||
end
|
||||
|
||||
def with_deleted_scope(&block)
|
||||
with_scope({:find => { :conditions => ["#{table_name}.#{deleted_attribute} IS NULL OR #{table_name}.#{deleted_attribute} > ?", current_time] } }, :merge, &block)
|
||||
end
|
||||
|
||||
private
|
||||
# all find calls lead here
|
||||
def find_every(options)
|
||||
options.delete(:with_deleted) ?
|
||||
find_every_with_deleted(options) :
|
||||
with_deleted_scope { find_every_with_deleted(options) }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_without_callbacks
|
||||
unless new_record?
|
||||
self.class.update_all self.class.send(:sanitize_sql, ["#{self.class.deleted_attribute} = ?", self.class.send(:current_time)]), ["#{self.class.primary_key} = ?", id]
|
||||
end
|
||||
freeze
|
||||
end
|
||||
|
||||
def destroy_with_callbacks!
|
||||
return false if callback(:before_destroy) == false
|
||||
result = destroy_without_callbacks!
|
||||
callback(:after_destroy)
|
||||
result
|
||||
end
|
||||
|
||||
def destroy!
|
||||
transaction { destroy_with_callbacks! }
|
||||
end
|
||||
|
||||
def deleted?
|
||||
!!read_attribute(:deleted_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
18
vendor/plugins/acts_as_paranoid/test/database.yml
vendored
Normal file
18
vendor/plugins/acts_as_paranoid/test/database.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
sqlite:
|
||||
:adapter: sqlite
|
||||
:dbfile: acts_as_paranoid_plugin.sqlite.db
|
||||
sqlite3:
|
||||
:adapter: sqlite3
|
||||
:dbfile: acts_as_paranoid_plugin.sqlite3.db
|
||||
postgresql:
|
||||
:adapter: postgresql
|
||||
:username: postgres
|
||||
:password: postgres
|
||||
:database: acts_as_paranoid_plugin_test
|
||||
:min_messages: ERROR
|
||||
mysql:
|
||||
:adapter: mysql
|
||||
:host: localhost
|
||||
:username: rails
|
||||
:password:
|
||||
:database: acts_as_paranoid_plugin_test
|
||||
19
vendor/plugins/acts_as_paranoid/test/fixtures/categories.yml
vendored
Normal file
19
vendor/plugins/acts_as_paranoid/test/fixtures/categories.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
category_1:
|
||||
id: 1
|
||||
widget_id: 1
|
||||
title: 'category 1'
|
||||
category_2:
|
||||
id: 2
|
||||
widget_id: 1
|
||||
title: 'category 2'
|
||||
deleted_at: '2005-01-01 00:00:00'
|
||||
category_3:
|
||||
id: 3
|
||||
widget_id: 2
|
||||
title: 'category 3'
|
||||
deleted_at: '2005-01-01 00:00:00'
|
||||
category_4:
|
||||
id: 4
|
||||
widget_id: 2
|
||||
title: 'category 4'
|
||||
deleted_at: '2005-01-01 00:00:00'
|
||||
12
vendor/plugins/acts_as_paranoid/test/fixtures/categories_widgets.yml
vendored
Normal file
12
vendor/plugins/acts_as_paranoid/test/fixtures/categories_widgets.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
cw_1:
|
||||
category_id: 1
|
||||
widget_id: 1
|
||||
cw_2:
|
||||
category_id: 2
|
||||
widget_id: 1
|
||||
cw_3:
|
||||
category_id: 3
|
||||
widget_id: 2
|
||||
cw_4:
|
||||
category_id: 4
|
||||
widget_id: 2
|
||||
8
vendor/plugins/acts_as_paranoid/test/fixtures/widgets.yml
vendored
Normal file
8
vendor/plugins/acts_as_paranoid/test/fixtures/widgets.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
widget_1:
|
||||
id: 1
|
||||
title: 'widget 1'
|
||||
widget_2:
|
||||
id: 2
|
||||
title: 'deleted widget 2'
|
||||
deleted_at: '2005-01-01 00:00:00'
|
||||
category_id: 3
|
||||
217
vendor/plugins/acts_as_paranoid/test/paranoid_test.rb
vendored
Normal file
217
vendor/plugins/acts_as_paranoid/test/paranoid_test.rb
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
require File.join(File.dirname(__FILE__), 'test_helper')
|
||||
|
||||
class Widget < ActiveRecord::Base
|
||||
acts_as_paranoid
|
||||
has_many :categories, :dependent => :destroy
|
||||
has_and_belongs_to_many :habtm_categories, :class_name => 'Category'
|
||||
has_one :category
|
||||
belongs_to :parent_category, :class_name => 'Category'
|
||||
end
|
||||
|
||||
class Category < ActiveRecord::Base
|
||||
belongs_to :widget
|
||||
belongs_to :any_widget, :class_name => 'Widget', :foreign_key => 'widget_id', :with_deleted => true
|
||||
acts_as_paranoid
|
||||
|
||||
def self.search(name, options = {})
|
||||
find :all, options.merge(:conditions => ['LOWER(title) LIKE ?', "%#{name.to_s.downcase}%"])
|
||||
end
|
||||
|
||||
def self.search_with_deleted(name, options = {})
|
||||
find_with_deleted :all, options.merge(:conditions => ['LOWER(title) LIKE ?', "%#{name.to_s.downcase}%"])
|
||||
end
|
||||
end
|
||||
|
||||
class NonParanoidAndroid < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class ParanoidTest < Test::Unit::TestCase
|
||||
fixtures :widgets, :categories, :categories_widgets
|
||||
|
||||
def test_should_count_with_deleted
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 2, Widget.count_with_deleted
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_set_deleted_at
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 1, Category.count
|
||||
widgets(:widget_1).destroy
|
||||
assert_equal 0, Widget.count
|
||||
assert_equal 0, Category.count
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
assert_equal 4, Category.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_destroy
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 1, Category.count
|
||||
widgets(:widget_1).destroy!
|
||||
assert_equal 0, Widget.count
|
||||
assert_equal 0, Category.count
|
||||
assert_equal 1, Widget.calculate_with_deleted(:count, :all)
|
||||
# Category doesn't get destroyed because the dependent before_destroy callback uses #destroy
|
||||
assert_equal 4, Category.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_delete_all
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
assert_equal 1, Category.count
|
||||
Widget.delete_all
|
||||
assert_equal 0, Widget.count
|
||||
# delete_all doesn't call #destroy, so the dependent callback never fires
|
||||
assert_equal 1, Category.count
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_delete_all_with_conditions
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
Widget.delete_all("id < 3")
|
||||
assert_equal 0, Widget.count
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_delete_all2
|
||||
assert_equal 1, Category.count
|
||||
assert_equal 4, Category.calculate_with_deleted(:count, :all)
|
||||
Category.delete_all!
|
||||
assert_equal 0, Category.count
|
||||
assert_equal 0, Category.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_delete_all_with_conditions2
|
||||
assert_equal 1, Category.count
|
||||
assert_equal 4, Category.calculate_with_deleted(:count, :all)
|
||||
Category.delete_all!("id < 3")
|
||||
assert_equal 0, Category.count
|
||||
assert_equal 2, Category.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_not_count_deleted
|
||||
assert_equal 1, Widget.count
|
||||
assert_equal 1, Widget.count(:all, :conditions => ['title=?', 'widget 1'])
|
||||
assert_equal 2, Widget.calculate_with_deleted(:count, :all)
|
||||
end
|
||||
|
||||
def test_should_not_find_deleted
|
||||
assert_equal [widgets(:widget_1)], Widget.find(:all)
|
||||
assert_equal [1, 2], Widget.find_with_deleted(:all, :order => 'id').collect { |w| w.id }
|
||||
end
|
||||
|
||||
def test_should_not_find_deleted_has_many_associations
|
||||
assert_equal 1, widgets(:widget_1).categories.size
|
||||
assert_equal [categories(:category_1)], widgets(:widget_1).categories
|
||||
end
|
||||
|
||||
def test_should_not_find_deleted_habtm_associations
|
||||
assert_equal 1, widgets(:widget_1).habtm_categories.size
|
||||
assert_equal [categories(:category_1)], widgets(:widget_1).habtm_categories
|
||||
end
|
||||
|
||||
def test_should_not_find_deleted_belongs_to_associations
|
||||
assert_nil Category.find_with_deleted(3).widget
|
||||
end
|
||||
|
||||
def test_should_find_belongs_to_assocation_with_deleted
|
||||
assert_equal Widget.find_with_deleted(2), Category.find_with_deleted(3).any_widget
|
||||
end
|
||||
|
||||
def test_should_find_first_with_deleted
|
||||
assert_equal widgets(:widget_1), Widget.find(:first)
|
||||
assert_equal 2, Widget.find_with_deleted(:first, :order => 'id desc').id
|
||||
end
|
||||
|
||||
def test_should_find_single_id
|
||||
assert Widget.find(1)
|
||||
assert Widget.find_with_deleted(2)
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Widget.find(2) }
|
||||
end
|
||||
|
||||
def test_should_find_multiple_ids
|
||||
assert_equal [1,2], Widget.find_with_deleted(1,2).sort_by { |w| w.id }.collect { |w| w.id }
|
||||
assert_equal [1,2], Widget.find_with_deleted([1,2]).sort_by { |w| w.id }.collect { |w| w.id }
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Widget.find(1,2) }
|
||||
end
|
||||
|
||||
def test_should_ignore_multiple_includes
|
||||
Widget.class_eval { acts_as_paranoid }
|
||||
assert Widget.find(1)
|
||||
end
|
||||
|
||||
def test_should_not_override_scopes_when_counting
|
||||
assert_equal 1, Widget.send(:with_scope, :find => { :conditions => "title = 'widget 1'" }) { Widget.count }
|
||||
assert_equal 0, Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.count }
|
||||
assert_equal 1, Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.calculate_with_deleted(:count, :all) }
|
||||
end
|
||||
|
||||
def test_should_not_override_scopes_when_finding
|
||||
assert_equal [1], Widget.send(:with_scope, :find => { :conditions => "title = 'widget 1'" }) { Widget.find(:all) }.ids
|
||||
assert_equal [], Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.find(:all) }.ids
|
||||
assert_equal [2], Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.find_with_deleted(:all) }.ids
|
||||
end
|
||||
|
||||
def test_should_allow_multiple_scoped_calls_when_finding
|
||||
Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) do
|
||||
assert_equal [2], Widget.find_with_deleted(:all).ids
|
||||
assert_equal [2], Widget.find_with_deleted(:all).ids, "clobbers the constrain on the unmodified find"
|
||||
assert_equal [], Widget.find(:all).ids
|
||||
assert_equal [], Widget.find(:all).ids, 'clobbers the constrain on a paranoid find'
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_allow_multiple_scoped_calls_when_counting
|
||||
Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) do
|
||||
assert_equal 1, Widget.calculate_with_deleted(:count, :all)
|
||||
assert_equal 1, Widget.calculate_with_deleted(:count, :all), "clobbers the constrain on the unmodified find"
|
||||
assert_equal 0, Widget.count
|
||||
assert_equal 0, Widget.count, 'clobbers the constrain on a paranoid find'
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_give_paranoid_status
|
||||
assert Widget.paranoid?
|
||||
assert !NonParanoidAndroid.paranoid?
|
||||
end
|
||||
|
||||
def test_should_give_record_status
|
||||
assert_equal false, Widget.find(1).deleted?
|
||||
Widget.find(1).destroy
|
||||
assert Widget.find_with_deleted(1).deleted?
|
||||
end
|
||||
|
||||
def test_should_find_deleted_has_many_assocations_on_deleted_records_by_default
|
||||
w = Widget.find_with_deleted 2
|
||||
assert_equal 2, w.categories.find_with_deleted(:all).length
|
||||
assert_equal 2, w.categories.find_with_deleted(:all).size
|
||||
end
|
||||
|
||||
def test_should_find_deleted_habtm_assocations_on_deleted_records_by_default
|
||||
w = Widget.find_with_deleted 2
|
||||
assert_equal 2, w.habtm_categories.find_with_deleted(:all).length
|
||||
assert_equal 2, w.habtm_categories.find_with_deleted(:all).size
|
||||
end
|
||||
|
||||
def test_dynamic_finders
|
||||
assert Widget.find_by_id(1)
|
||||
assert_nil Widget.find_by_id(2)
|
||||
end
|
||||
|
||||
def test_custom_finder_methods
|
||||
w = Widget.find_with_deleted(:all).inject({}) { |all, w| all.merge(w.id => w) }
|
||||
assert_equal [1], Category.search('c').ids
|
||||
assert_equal [1,2,3,4], Category.search_with_deleted('c', :order => 'id').ids
|
||||
assert_equal [1], widgets(:widget_1).categories.search('c').collect(&:id)
|
||||
assert_equal [1,2], widgets(:widget_1).categories.search_with_deleted('c').ids
|
||||
assert_equal [], w[2].categories.search('c').ids
|
||||
assert_equal [3,4], w[2].categories.search_with_deleted('c').ids
|
||||
end
|
||||
end
|
||||
|
||||
class Array
|
||||
def ids
|
||||
collect &:id
|
||||
end
|
||||
end
|
||||
20
vendor/plugins/acts_as_paranoid/test/schema.rb
vendored
Normal file
20
vendor/plugins/acts_as_paranoid/test/schema.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
ActiveRecord::Schema.define(:version => 1) do
|
||||
|
||||
create_table :widgets, :force => true do |t|
|
||||
t.column :title, :string, :limit => 50
|
||||
t.column :category_id, :integer
|
||||
t.column :deleted_at, :timestamp
|
||||
end
|
||||
|
||||
create_table :categories, :force => true do |t|
|
||||
t.column :widget_id, :integer
|
||||
t.column :title, :string, :limit => 50
|
||||
t.column :deleted_at, :timestamp
|
||||
end
|
||||
|
||||
create_table :categories_widgets, :force => true, :id => false do |t|
|
||||
t.column :category_id, :integer
|
||||
t.column :widget_id, :integer
|
||||
end
|
||||
|
||||
end
|
||||
33
vendor/plugins/acts_as_paranoid/test/test_helper.rb
vendored
Normal file
33
vendor/plugins/acts_as_paranoid/test/test_helper.rb
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'test/unit'
|
||||
require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
|
||||
require 'rubygems'
|
||||
require 'active_record/fixtures'
|
||||
|
||||
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
||||
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
||||
ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
|
||||
|
||||
load(File.dirname(__FILE__) + "/schema.rb")
|
||||
|
||||
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
||||
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
|
||||
|
||||
class Test::Unit::TestCase #:nodoc:
|
||||
def create_fixtures(*table_names)
|
||||
if block_given?
|
||||
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
|
||||
else
|
||||
Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
|
||||
end
|
||||
end
|
||||
|
||||
# Turn off transactional fixtures if you're working with MyISAM tables in MySQL
|
||||
self.use_transactional_fixtures = true
|
||||
|
||||
# Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
|
||||
self.use_instantiated_fixtures = false
|
||||
|
||||
# Add more helper methods to be used by all tests here...
|
||||
end
|
||||
Reference in New Issue
Block a user