diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b8ebb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +.redcar diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..cd38c6a --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source "http://rubygems.org" +gemspec +gem 'rake' +gem 'sqlite3' +gem 'activerecord',">=3.0.0" +gem 'yard' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8762ef5 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,38 @@ +PATH + remote: . + specs: + acts_as_list (0.2.5) + activerecord (>= 3.0.0) + +GEM + remote: http://rubygems.org/ + specs: + activemodel (3.2.3) + activesupport (= 3.2.3) + builder (~> 3.0.0) + activerecord (3.2.3) + activemodel (= 3.2.3) + activesupport (= 3.2.3) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activesupport (3.2.3) + i18n (~> 0.6) + multi_json (~> 1.0) + arel (3.0.2) + builder (3.0.0) + i18n (0.6.0) + multi_json (1.3.4) + rake (0.9.2.2) + sqlite3 (1.3.6) + tzinfo (0.3.33) + yard (0.8.1) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord (>= 3.0.0) + acts_as_list! + rake + sqlite3 + yard diff --git a/Rakefile b/Rakefile index e6c6369..dd635a6 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,39 @@ +require 'bundler' +Bundler::GemHelper.install_tasks require 'rake' require 'rake/testtask' +begin + require 'jeweler' + Jeweler::Tasks.new do |gem| + gem.name = "acts_as_list" + gem.summary = %Q{Gem version of acts_as_list Rails plugin} + gem.description = %Q{Gem version of acts_as_list Rails plugin} + gem.email = "victor.pereira@bigrails.com" + gem.homepage = "http://github.com/vpereira/acts_as_list" + gem.authors = ["Victor Pereira", "Ryan Bates", "Rails Core"] + gem.add_dependency "activerecord", ">= 3.0.0" + gem.add_development_dependency "yard" + end + Jeweler::GemcutterTasks.new +rescue LoadError + puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" +end + desc 'Default: run acts_as_list unit tests.' task :default => :test desc 'Test the acts_as_ordered_tree plugin.' + Rake::TestTask.new(:test) do |t| t.libs << 'lib' t.pattern = 'test/**/*_test.rb' t.verbose = true end + +require 'yard' +YARD::Rake::YardocTask.new do |t| + version = File.exist?('VERSION') ? File.read('VERSION') : "" + t.options += ['--title', "acts_as_list #{version} Documentation"] +end + diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..0c62199 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.2.1 diff --git a/acts_as_list.gemspec b/acts_as_list.gemspec new file mode 100644 index 0000000..b7dfcaa --- /dev/null +++ b/acts_as_list.gemspec @@ -0,0 +1,51 @@ +# 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{acts_as_list} + s.version = "0.2.5" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Victor Pereira", "Ryan Bates", "Rails Core"] + s.date = %q{2011-01-24} + s.description = %q{Gem version of acts_as_list Rails plugin} + s.email = %q{victor.pereira@bigrails.com} + s.extra_rdoc_files = [ + "README" + ] + s.files = [ + "README", + "Rakefile", + "VERSION", + "acts_as_list.gemspec", + "init.rb", + "lib/active_record/acts/list.rb", + "test/list_test.rb" + ] + s.homepage = %q{http://github.com/vpereira/acts_as_list} + s.require_paths = ["lib"] + s.rubygems_version = %q{1.3.7} + s.summary = %q{Gem version of acts_as_list Rails plugin} + s.test_files = [ + "test/list_test.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, [">= 3.0.0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 3.0.0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 3.0.0"]) + s.add_dependency(%q, [">= 0"]) + end +end + diff --git a/init.rb b/init.rb index eb87e87..10662a8 100644 --- a/init.rb +++ b/init.rb @@ -1,3 +1,5 @@ $:.unshift "#{File.dirname(__FILE__)}/lib" +require 'bundler/setup' +require 'active_record' require 'active_record/acts/list' ActiveRecord::Base.class_eval { include ActiveRecord::Acts::List } diff --git a/lib/active_record/acts/list.rb b/lib/active_record/acts/list.rb index ee96ea1..23749d6 100644 --- a/lib/active_record/acts/list.rb +++ b/lib/active_record/acts/list.rb @@ -31,11 +31,17 @@ module ClassMethods # to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. # Example: acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0' def acts_as_list(options = {}) - configuration = { :column => "position", :scope => "1 = 1" } + configuration = { :column => "position", :scope => "1=1",:limited_list=>false } configuration.update(options) if options.is_a?(Hash) + + + self.class.send(:define_method,"limited_list?") { configuration[:limited_list] } + + #here if your scope receives a :symbol, it will try to add "_id" to the symbol, unless it has already an id in the end configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/ + if configuration[:scope].is_a?(Symbol) scope_condition_method = %( def scope_condition @@ -55,9 +61,16 @@ def scope_condition scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end" end + + self.class_eval do + send(:scope,:list,order('position asc')) + end + + class_eval <<-EOV include ActiveRecord::Acts::List::InstanceMethods - + + def acts_as_list_class ::#{self.name} end @@ -66,8 +79,10 @@ def position_column '#{configuration[:column]}' end + #{scope_condition_method} + before_destroy :decrement_positions_on_lower_items before_create :add_to_list_bottom EOV @@ -80,7 +95,13 @@ def position_column # the first in the list of all chapters. module InstanceMethods # Insert the item at the given position (defaults to the top position of 1). + #i just changed here to verify if the limited_list is true def insert_at(position = 1) + if self.class.limited_list? + if position > bottom_position_in_list + 1 + position = bottom_position_in_list + end + end insert_at_position(position) end @@ -93,7 +114,7 @@ def move_lower increment_position end end - + # Swap positions with the next higher item, if one exists. def move_higher return unless higher_item @@ -159,17 +180,13 @@ def last? # Return the next higher item in the list. def higher_item return nil unless in_list? - acts_as_list_class.find(:first, :conditions => - "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}" - ) + acts_as_list_class.where("#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}").first end # Return the next lower item in the list. def lower_item return nil unless in_list? - acts_as_list_class.find(:first, :conditions => - "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}" - ) + acts_as_list_class.where("#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}").first end # Test if this record is in a list @@ -200,7 +217,7 @@ def bottom_position_in_list(except = nil) def bottom_item(except = nil) conditions = scope_condition conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except - acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC") + acts_as_list_class.where(conditions).order("#{position_column} DESC").first end # Forces item to assume the bottom position in the list. diff --git a/test/list_test.rb b/test/list_test.rb index 81eccd6..02e5aa1 100644 --- a/test/list_test.rb +++ b/test/list_test.rb @@ -1,20 +1,23 @@ +require File.expand_path(File.join(File.dirname(__FILE__),'..','init')) require 'test/unit' -require 'rubygems' -gem 'activerecord', '>= 1.15.4.7794' -require 'active_record' +class Array + def move(from, to) + insert(to, delete_at(from)) + end +end -require "#{File.dirname(__FILE__)}/../init" +#TODO the other tests should be refactored as ArrayScopeListTest ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") def setup_db ActiveRecord::Schema.define(:version => 1) do - create_table :mixins do |t| - t.column :pos, :integer + create_table :articles do |t| + t.column :position, :integer t.column :parent_id, :integer t.column :parent_type, :string - t.column :created_at, :datetime + t.column :created_at, :datetime t.column :updated_at, :datetime end end @@ -26,496 +29,168 @@ def teardown_db end end -class Mixin < ActiveRecord::Base -end - -class ListMixin < Mixin - acts_as_list :column => "pos", :scope => :parent - - def self.table_name() "mixins" end -end - -class ListMixinSub1 < ListMixin -end - -class ListMixinSub2 < ListMixin -end - -class ListWithStringScopeMixin < ActiveRecord::Base - acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}' - - def self.table_name() "mixins" end -end - -class ArrayScopeListMixin < Mixin - acts_as_list :column => "pos", :scope => [:parent_id, :parent_type] - - def self.table_name() "mixins" end +class Article < ActiveRecord::Base + acts_as_list :scope => :parent end class ListTest < Test::Unit::TestCase - def setup + @myItems = [] setup_db - (1..4).each { |counter| ListMixin.create! :pos => counter, :parent_id => 5 } + (1..4).each do |counter| + Article.create! :position => counter, :parent_id => 5 + @myItems.push Article.where(:parent_id=> 5).last.id + end + @articles = Article.where(:parent_id=> 5).order(:position) end def teardown teardown_db end - def test_reordering - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).move_lower - assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).move_higher - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(1).move_to_bottom - assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(1).move_to_top - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).move_to_bottom - assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(4).move_to_top - assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - end - - def test_move_to_bottom_with_next_to_last_item - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - ListMixin.find(3).move_to_bottom - assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) + def test_methods_available_for_array + myArray = [] + assert myArray.respond_to?(:move) end - def test_next_prev - assert_equal ListMixin.find(2), ListMixin.find(1).lower_item - assert_nil ListMixin.find(1).higher_item - assert_equal ListMixin.find(3), ListMixin.find(4).higher_item - assert_nil ListMixin.find(4).lower_item + def test_methods_available_for_list + @article = Article.first + assert @article.respond_to?(:move_to_bottom) + assert @article.respond_to?(:move_higher) end def test_injection - item = ListMixin.new(:parent_id => 1) - assert_equal '"mixins"."parent_id" = 1', item.scope_condition - assert_equal "pos", item.position_column + item = Article.new(:parent_id => 1) + assert_equal '"articles"."parent_id" = 1', item.scope_condition + assert_equal "position", item.position_column end def test_insert - new = ListMixin.create(:parent_id => 20) - assert_equal 1, new.pos - assert new.first? - assert new.last? - - new = ListMixin.create(:parent_id => 20) - assert_equal 2, new.pos - assert !new.first? - assert new.last? - - new = ListMixin.create(:parent_id => 20) - assert_equal 3, new.pos - assert !new.first? - assert new.last? - - new = ListMixin.create(:parent_id => 0) - assert_equal 1, new.pos - assert new.first? - assert new.last? - end - - def test_insert_at - new = ListMixin.create(:parent_id => 20) - assert_equal 1, new.pos - - new = ListMixin.create(:parent_id => 20) - assert_equal 2, new.pos - - new = ListMixin.create(:parent_id => 20) - assert_equal 3, new.pos - - new4 = ListMixin.create(:parent_id => 20) - assert_equal 4, new4.pos - - new4.insert_at(3) - assert_equal 3, new4.pos - - new.reload - assert_equal 4, new.pos - - new.insert_at(2) - assert_equal 2, new.pos - - new4.reload - assert_equal 4, new4.pos - - new5 = ListMixin.create(:parent_id => 20) - assert_equal 5, new5.pos - - new5.insert_at(1) - assert_equal 1, new5.pos - - new4.reload - assert_equal 5, new4.pos - end - - def test_delete_middle - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).destroy - - assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(1).pos - assert_equal 2, ListMixin.find(3).pos - assert_equal 3, ListMixin.find(4).pos - - ListMixin.find(1).destroy - - assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(3).pos - assert_equal 2, ListMixin.find(4).pos - end - - def test_with_string_based_scope - new = ListWithStringScopeMixin.create(:parent_id => 500) - assert_equal 1, new.pos + new = Article.create(:parent_id => 20) + assert_equal 1, new.position assert new.first? assert new.last? end - def test_nil_scope - new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create - new2.move_higher - assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos') - end - - def test_remove_from_list_should_then_fail_in_list? - assert_equal true, ListMixin.find(1).in_list? - ListMixin.find(1).remove_from_list - assert_equal false, ListMixin.find(1).in_list? - end - - def test_remove_from_list_should_set_position_to_nil - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).remove_from_list - - assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(1).pos - assert_equal nil, ListMixin.find(2).pos - assert_equal 2, ListMixin.find(3).pos - assert_equal 3, ListMixin.find(4).pos - end - - def test_remove_before_destroy_does_not_shift_lower_items_twice - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - ListMixin.find(2).remove_from_list - ListMixin.find(2).destroy - - assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(1).pos - assert_equal 2, ListMixin.find(3).pos - assert_equal 3, ListMixin.find(4).pos - end - - def test_before_destroy_callbacks_do_not_update_position_to_nil_before_deleting_the_record - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - # We need to trigger all the before_destroy callbacks without actually - # destroying the record so we can see the affect the callbacks have on - # the record. - list = ListMixin.find(2) - if list.respond_to?(:run_callbacks) - list.run_callbacks(:destroy) - else - list.send(:callback, :before_destroy) - end - - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(1).pos - assert_equal 2, ListMixin.find(2).pos - assert_equal 2, ListMixin.find(3).pos - assert_equal 3, ListMixin.find(4).pos - end - -end - -class ListSubTest < Test::Unit::TestCase - - def setup - setup_db - (1..4).each { |i| ((i % 2 == 1) ? ListMixinSub1 : ListMixinSub2).create! :pos => i, :parent_id => 5000 } - end - - def teardown - teardown_db - end - - def test_reordering - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(2).move_lower - assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(2).move_higher - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(1).move_to_bottom - assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(1).move_to_top - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(2).move_to_bottom - assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(4).move_to_top - assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - end - - def test_move_to_bottom_with_next_to_last_item - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - ListMixin.find(3).move_to_bottom - assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - end - - def test_next_prev - assert_equal ListMixin.find(2), ListMixin.find(1).lower_item - assert_nil ListMixin.find(1).higher_item - assert_equal ListMixin.find(3), ListMixin.find(4).higher_item - assert_nil ListMixin.find(4).lower_item - end - - def test_injection - item = ListMixin.new("parent_id"=>1) - assert_equal '"mixins"."parent_id" = 1', item.scope_condition - assert_equal "pos", item.position_column - end - - def test_insert_at - new = ListMixin.create("parent_id" => 20) - assert_equal 1, new.pos - - new = ListMixinSub1.create("parent_id" => 20) - assert_equal 2, new.pos - - new = ListMixinSub2.create("parent_id" => 20) - assert_equal 3, new.pos - - new4 = ListMixin.create("parent_id" => 20) - assert_equal 4, new4.pos - - new4.insert_at(3) - assert_equal 3, new4.pos - - new.reload - assert_equal 4, new.pos - - new.insert_at(2) - assert_equal 2, new.pos - - new4.reload - assert_equal 4, new4.pos - - new5 = ListMixinSub1.create("parent_id" => 20) - assert_equal 5, new5.pos - - new5.insert_at(1) - assert_equal 1, new5.pos - - new4.reload - assert_equal 5, new4.pos - end - - def test_delete_middle - assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - ListMixin.find(2).destroy - - assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(1).pos - assert_equal 2, ListMixin.find(3).pos - assert_equal 3, ListMixin.find(4).pos - - ListMixin.find(1).destroy - - assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id) - - assert_equal 1, ListMixin.find(3).pos - assert_equal 2, ListMixin.find(4).pos - end - -end - -class ArrayScopeListTest < Test::Unit::TestCase - - def setup - setup_db - (1..4).each { |counter| ArrayScopeListMixin.create! :pos => counter, :parent_id => 5, :parent_type => 'ParentClass' } - end - - def teardown - teardown_db + def test_items_are_ordered + assert_equal @myItems, @articles.all.map(&:id) end - def test_reordering - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).move_lower - assert_equal [1, 3, 2, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).move_higher - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(1).move_to_bottom - assert_equal [2, 3, 4, 1], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(1).move_to_top - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).move_to_bottom - assert_equal [1, 3, 4, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(4).move_to_top - assert_equal [4, 1, 3, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) + def test_move_lower + Article.find(2).move_lower + assert_equal @myItems.move(1,2), @articles.all.map(&:id) end - def test_move_to_bottom_with_next_to_last_item - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - ArrayScopeListMixin.find(3).move_to_bottom - assert_equal [1, 2, 4, 3], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) + def test_move_higher + Article.find(2).move_higher + assert_equal @myItems.move(0,1), @articles.all.map(&:id) end - def test_next_prev - assert_equal ArrayScopeListMixin.find(2), ArrayScopeListMixin.find(1).lower_item - assert_nil ArrayScopeListMixin.find(1).higher_item - assert_equal ArrayScopeListMixin.find(3), ArrayScopeListMixin.find(4).higher_item - assert_nil ArrayScopeListMixin.find(4).lower_item + def test_move_to_bottom + Article.first.move_to_bottom + assert_equal @myItems.move(0,-1), @articles.all.map(&:id) end - def test_injection - item = ArrayScopeListMixin.new(:parent_id => 1, :parent_type => 'ParentClass') - assert_equal '"mixins"."parent_id" = 1 AND "mixins"."parent_type" = \'ParentClass\'', item.scope_condition - assert_equal "pos", item.position_column + def test_move_to_top + Article.last.move_to_top + assert_equal @myItems.move(-1,0), @articles.all.map(&:id) end - def test_insert - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 1, new.pos - assert new.first? - assert new.last? - - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 2, new.pos - assert !new.first? - assert new.last? - - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 3, new.pos - assert !new.first? - assert new.last? - - new = ArrayScopeListMixin.create(:parent_id => 0, :parent_type => 'ParentClass') - assert_equal 1, new.pos - assert new.first? - assert new.last? - end - - def test_insert_at - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 1, new.pos - - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 2, new.pos - - new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 3, new.pos - - new4 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 4, new4.pos - - new4.insert_at(3) - assert_equal 3, new4.pos - - new.reload - assert_equal 4, new.pos - - new.insert_at(2) - assert_equal 2, new.pos - - new4.reload - assert_equal 4, new4.pos - - new5 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass') - assert_equal 5, new5.pos - - new5.insert_at(1) - assert_equal 1, new5.pos - - new4.reload - assert_equal 5, new4.pos + def test_nil_return + assert_equal Article.find(2), Article.find(1).lower_item + assert_nil Article.first.higher_item + assert_equal Article.find(3), Article.find(4).higher_item + assert_nil Article.last.lower_item end def test_delete_middle - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).destroy - - assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - assert_equal 1, ArrayScopeListMixin.find(1).pos - assert_equal 2, ArrayScopeListMixin.find(3).pos - assert_equal 3, ArrayScopeListMixin.find(4).pos - - ArrayScopeListMixin.find(1).destroy - - assert_equal [3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - assert_equal 1, ArrayScopeListMixin.find(3).pos - assert_equal 2, ArrayScopeListMixin.find(4).pos + Article.find(3).destroy + @myItems.delete_at(2) + assert_equal @myItems, Article.where(:parent_id=>5).all.map(&:id) end - - def test_remove_from_list_should_then_fail_in_list? - assert_equal true, ArrayScopeListMixin.find(1).in_list? - ArrayScopeListMixin.find(1).remove_from_list - assert_equal false, ArrayScopeListMixin.find(1).in_list? - end - - def test_remove_from_list_should_set_position_to_nil - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).remove_from_list - - assert_equal [2, 1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - assert_equal 1, ArrayScopeListMixin.find(1).pos - assert_equal nil, ArrayScopeListMixin.find(2).pos - assert_equal 2, ArrayScopeListMixin.find(3).pos - assert_equal 3, ArrayScopeListMixin.find(4).pos - end - - def test_remove_before_destroy_does_not_shift_lower_items_twice - assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - ArrayScopeListMixin.find(2).remove_from_list - ArrayScopeListMixin.find(2).destroy - - assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id) - - assert_equal 1, ArrayScopeListMixin.find(1).pos - assert_equal 2, ArrayScopeListMixin.find(3).pos - assert_equal 3, ArrayScopeListMixin.find(4).pos - end - end +#class ArrayScopeListTest < Test::Unit::TestCase +# +# def setup +# @myItems = [] +# Article.send :acts_as_list, :column => "position", :scope => [:parent_id, :parent_type] +# +# setup_db +# (1..4).each do |counter| +# Article.create! :position => counter, :parent_id => 5, :parent_type => 'ParentClass' +# @myItems.push Article.last.id +# end +# @articles = Article.where(:parent_id=> 5,:parent_type=>'ParentClass').order(:position) +# end +# +# def teardown +# teardown_db +# end +# +# def test_injection +# item = Article.new(:parent_id => 1) +# assert_equal '"articles"."parent_id" = 1 AND "articles"."parent_type" IS NULL', item.scope_condition +# assert_equal "position", item.position_column +# end +# +# def test_insert +# new = Article.create :parent_id => 20, :parent_type => 'ParentClass' +# assert_equal 1, new.position +# assert new.first? +# assert new.last? +# end +# +# def test_items_are_ordered +# assert_equal @myItems, @articles.all.map(&:id) +# end +# +# def test_move_lower +# Article.find(2).move_lower +# assert_equal @myItems.move(1,2), @articles.all.map(&:id) +# end +# +# def test_move_higher +# Article.find(2).move_higher +# assert_equal @myItems.move(0,1), @articles.all.map(&:id) +# end +# +# def test_move_to_bottom +# Article.first.move_to_bottom +# assert_equal @myItems.move(0,-1), @articles.all.map(&:id) +# end +# +# def test_move_to_top +# Article.last.move_to_top +# assert_equal @myItems.move(-1,0), @articles.all.map(&:id) +# end +# +# def test_nil_return +# assert_equal Article.find(2), Article.find(1).lower_item +# assert_nil Article.first.higher_item +# assert_equal Article.find(3), Article.find(4).higher_item +# assert_nil Article.last.lower_item +# end +#end + +#class ScopeAsStringTest < Test::Unit::TestCase +# def setup +# setup_db +# Article.send :acts_as_list, :column => "position", :scope => 'parent_id = #{parent_id}' +# end +# +# def teardown +# teardown_db +# end +# +# def test_with_string_based_scope +# new = Article.create(:parent_id => 500) +# assert_equal 1, new.position +# assert new.first? +# assert new.last? +# end +# +#end +# +# +#