bellmyer-validates_blacklist 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README CHANGED
@@ -120,7 +120,7 @@ The only limits are your imagination, and my forethought. You can even specify
120
120
  the error message that is generated:
121
121
 
122
122
  email:
123
- - [greasy_pete@aol.com, cannot be greasy pete from biology]
123
+ - [stinky_pete@aol.com, cannot be greasy pete from biology]
124
124
 
125
125
  age:
126
126
  - [>25, cannot be a pervert]
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the validates_blacklist plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the validates_blacklist plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'ValidatesBlacklist'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1,11 @@
1
+ class BlacklistsGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.directory 'config/blacklists'
5
+
6
+ Dir["#{RAILS_ROOT}/app/models/*.rb"].each do |file|
7
+ m.file 'blacklist.yml', "config/blacklists/#{File.basename(file, '.rb')}_blacklist.yml", :collision => :skip
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # Example for a User model with name, e-mail and age attributes
2
+ #
3
+ # name:
4
+ # - Stinky Pete
5
+ # - Patchy the Pirate
6
+ #
7
+ # email:
8
+ # - stinky_pete@gmail.com
9
+ # - /@aol.com$/
10
+ #
11
+ # age:
12
+ # - < 14
13
+ # - > 25
14
+
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'bellmyer/validates_blacklist'
2
+ ActiveRecord::Base.extend Bellmyer::ValidatesBlacklist
@@ -0,0 +1,68 @@
1
+ module Bellmyer
2
+ module ValidatesBlacklist
3
+ require 'yaml'
4
+
5
+ def validates_blacklist(options = {})
6
+ options.reverse_merge!(
7
+ :message => 'is not allowed.',
8
+ :attributes => {}
9
+ )
10
+
11
+ unless included_modules.include? InstanceMethods
12
+ class_inheritable_accessor :options
13
+ class_inheritable_accessor :model
14
+
15
+ extend ClassMethods
16
+ include InstanceMethods
17
+
18
+ validate :model_blacklists
19
+
20
+ end
21
+
22
+ self.options = options
23
+ self.model = self.to_s.underscore
24
+ end
25
+
26
+ module ClassMethods
27
+ def blacklist
28
+ puts "blacklisted!"
29
+ end
30
+
31
+ def unblacklist
32
+ puts "Removed from blacklist."
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+
38
+
39
+ protected
40
+
41
+ def model_blacklists
42
+ blacklist = "#{RAILS_ROOT}/config/blacklists/#{self.class.to_s.underscore}_blacklist.yml"
43
+
44
+ # Load blacklist #
45
+ if attributes = File.open(blacklist){|f| YAML::load(f)}
46
+ # Cycle through attributes #
47
+ attributes.each do |attribute, stops|
48
+ attribute = attribute.to_sym
49
+
50
+ stops.each do |stop|
51
+ stop_name = stop.is_a?(Array) ? stop.first : stop
52
+ stop_message = stop.is_a?(Array) ? stop.last : self.options[:attributes][attribute] || self.options[:message]
53
+
54
+ # regexp #
55
+ if !self.send(attribute).nil? && stop_name =~ /^\//
56
+ errors.add(attribute, stop_message) if eval("self.#{attribute} =~ #{stop_name}")
57
+ elsif !self.send(attribute).nil? && stop_name =~ /^(\<|\>|!|=)/
58
+ errors.add(attribute, stop_message) if eval("self.#{attribute} #{stop_name}")
59
+ else
60
+ errors.add(attribute, stop_message) if self.send(attribute).to_s == stop_name
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,11 @@
1
+ name:
2
+ - Stinky Pete
3
+ - [Vanessa, is not allowed after ditching my b-day party]
4
+
5
+ email:
6
+ - stinky_pete@gmail.com
7
+ - [/@aol\.com$/, is banned until they stop sending me CD\'s]
8
+
9
+ age:
10
+ - < 14
11
+ - [\> 25, is too old and pervy!exit]
@@ -0,0 +1,20 @@
1
+ name:
2
+ - Stinky Pete
3
+ - /Pete/
4
+ - [Vanessa, is not allowed after ditching my b-day party]
5
+ - ['=~ /smurf/i', is not allowed to be a smurf!]
6
+
7
+ email:
8
+ - stinky_pete@gmail.com
9
+ - [/@aol\.com$/, is banned until they stop sending me CD\'s]
10
+
11
+ age:
12
+ - [< 14, is too young to party.]
13
+ - ['> 25', is too old and pervy!]
14
+
15
+ net_worth:
16
+ - ['<= 50_000', is too poor.]
17
+ - ['>= 150_000', is too rich.]
18
+
19
+ school:
20
+ - ['!~ /Valley/', is not Valley High School!]
@@ -0,0 +1,11 @@
1
+ name:
2
+ - Stinky Pete
3
+ - [Vanessa, is not allowed after ditching my b-day party]
4
+
5
+ email:
6
+ - stinky_pete@gmail.com
7
+ - [/@aol\.com$/, is banned until they stop sending me CD\'s]
8
+
9
+ age:
10
+ - < 14
11
+ - [\> 25, is too old and pervy!exit]
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+
3
+ require 'active_support'
4
+ require 'active_support/test_case'
5
+
6
+
@@ -0,0 +1,178 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'active_record'
4
+ $:.unshift File.dirname(__FILE__) + '/../lib'
5
+ require File.dirname(__FILE__) + '/../init'
6
+
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
8
+
9
+ # AR keeps printing annoying schema statements
10
+ $stdout = StringIO.new
11
+
12
+ RAILS_ROOT = File.dirname(__FILE__)
13
+
14
+ def setup_db
15
+ ActiveRecord::Schema.define(:version => 1) do
16
+ create_table :friends do |t|
17
+ t.string :name
18
+ t.string :email
19
+ t.integer :age
20
+ t.integer :net_worth
21
+ t.string :school
22
+ end
23
+ end
24
+ end
25
+
26
+ def teardown_db
27
+ ActiveRecord::Base.connection.tables.each do |table|
28
+ ActiveRecord::Base.connection.drop_table(table)
29
+ end
30
+ end
31
+
32
+ class Friend < ActiveRecord::Base
33
+ end
34
+
35
+ class FriendWithBlacklist < Friend
36
+ validates_blacklist
37
+ end
38
+
39
+ class FriendWithBlacklistTest < Test::Unit::TestCase
40
+ def setup
41
+ setup_db
42
+ end
43
+
44
+ def teardown
45
+ teardown_db
46
+ end
47
+
48
+ def test_should_fail_validation_on_exact_string_match
49
+ friend = FriendWithBlacklist.new(:name => 'Stinky Pete')
50
+ assert !friend.valid?
51
+ assert friend.errors.invalid?(:name)
52
+ assert friend.errors.on(:name).include?("is not allowed.")
53
+ end
54
+
55
+ def test_should_fail_validation_on_regexp_match
56
+ friend = FriendWithBlacklist.new(:name => 'Handsome Pete')
57
+ assert !friend.valid?
58
+ assert friend.errors.invalid?(:name)
59
+ assert friend.errors.on(:name).include?("is not allowed.")
60
+ end
61
+
62
+ def test_should_fail_validation_on_custom_message
63
+ friend = FriendWithBlacklist.new(:name => 'Vanessa')
64
+ assert !friend.valid?
65
+ assert friend.errors.invalid?(:name)
66
+ assert friend.errors.on(:name).include?("is not allowed after ditching my b-day party")
67
+ end
68
+
69
+ def test_should_fail_validation_on_less_than_match
70
+ friend = FriendWithBlacklist.new(:age => 12)
71
+ assert !friend.valid?
72
+ assert friend.errors.invalid?(:age)
73
+ assert friend.errors.on(:age).include?("is too young to party.")
74
+ end
75
+
76
+ def test_should_fail_validation_on_greater_than_match
77
+ friend = FriendWithBlacklist.new(:age => 55)
78
+ assert !friend.valid?
79
+ assert friend.errors.invalid?(:age)
80
+ assert friend.errors.on(:age).include?("is too old and pervy!")
81
+ end
82
+
83
+ def test_should_fail_validation_on_greater_than_or_equal_match
84
+ friend = FriendWithBlacklist.new(:net_worth => 150_000)
85
+ assert !friend.valid?
86
+ assert friend.errors.invalid?(:net_worth)
87
+ assert friend.errors.on(:net_worth).include?('is too rich.')
88
+ end
89
+
90
+ def test_should_fail_validation_on_less_than_or_equal_match
91
+ friend = FriendWithBlacklist.new(:net_worth => 50_000)
92
+ assert !friend.valid?
93
+ assert friend.errors.invalid?(:net_worth)
94
+ assert friend.errors.on(:net_worth).include?('is too poor.')
95
+ end
96
+
97
+ def test_should_fail_validation_on_explicit_nonregexp
98
+ friend = FriendWithBlacklist.new(:school => 'Mouthbreather Academy')
99
+ assert !friend.valid?
100
+ assert friend.errors.invalid?(:school)
101
+ assert friend.errors.on(:school).include?("is not Valley High School!")
102
+ end
103
+
104
+ def test_should_fail_validation_on_explicit_regexp
105
+ friend = FriendWithBlacklist.new(:name => 'Papa Smurf')
106
+ assert !friend.valid?
107
+ assert friend.errors.invalid?(:name)
108
+ assert friend.errors.on(:name).include?("is not allowed to be a smurf!")
109
+ end
110
+ end
111
+
112
+ class FriendWithCustomMessage < Friend
113
+ validates_blacklist :message => "has left the building."
114
+ end
115
+
116
+ class FriendWithCustomMessageTest < Test::Unit::TestCase
117
+ def setup
118
+ setup_db
119
+ end
120
+
121
+ def teardown
122
+ teardown_db
123
+ end
124
+
125
+ def test_global_custom_message_fails_validation_on_exact_string_match
126
+ friend = FriendWithCustomMessage.new(:name => 'Stinky Pete')
127
+ assert !friend.valid?
128
+ assert friend.errors.invalid?(:name)
129
+ assert friend.errors.on(:name).include?("has left the building.")
130
+ end
131
+ end
132
+
133
+ class FriendWithAttributeMessage < Friend
134
+ validates_blacklist :message => "has left the building.", :attributes => {:email => 'looks spammy'}
135
+ end
136
+
137
+ class FriendWithAttributeMessageTest < Test::Unit::TestCase
138
+ def setup
139
+ setup_db
140
+ end
141
+
142
+ def teardown
143
+ teardown_db
144
+ end
145
+
146
+ def test_attribute_message_fails_validation_on_exact_string_match_with_global_message
147
+ friend = FriendWithAttributeMessage.new(:name => 'Stinky Pete')
148
+ assert !friend.valid?
149
+ assert friend.errors.invalid?(:name)
150
+ assert friend.errors.on(:name).include?("has left the building.")
151
+ end
152
+
153
+ def test_attribute_message_fails_validation_on_exact_string_match_with_attrib_message
154
+ friend = FriendWithAttributeMessage.new(:email => 'stinky_pete@gmail.com')
155
+ assert !friend.valid?
156
+ assert friend.errors.invalid?(:email)
157
+ assert friend.errors.on(:email).include?('looks spammy')
158
+ end
159
+ end
160
+
161
+ class FriendWithBlankBlacklist < Friend
162
+ validates_blacklist
163
+ end
164
+
165
+ class FriendWithBlankBlacklistTest < Test::Unit::TestCase
166
+ def setup
167
+ setup_db
168
+ end
169
+
170
+ def teardown
171
+ teardown_db
172
+ end
173
+
174
+ def test_should_not_fail
175
+ friend = FriendWithBlankBlacklist.new(:name => 'Stinky Pete')
176
+ assert friend.valid?
177
+ end
178
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'validates_blacklist'
3
- s.version = '0.1.1'
3
+ s.version = '0.1.3'
4
4
  s.date = '2009-08-26'
5
5
 
6
6
  s.summary = "Allows models to be validated against yaml-based blacklists"
@@ -15,14 +15,24 @@ Gem::Specification.new do |s|
15
15
  s.extra_rdoc_files = ["README"]
16
16
 
17
17
  s.add_dependency 'rails', ['>= 2.1']
18
+ s.add_dependency 'yaml'
18
19
 
19
20
  s.files = [
21
+ "init.rb",
22
+ "MIT-LICENSE",
23
+ "Rakefile",
20
24
  "README",
21
25
  "validates_blacklist.gemspec",
22
- "lib/bellmyer-validates_blacklist.rb",
23
- "lib/active_record/validates/blacklist.rb",
26
+ "generators/blacklists/templates/blacklist.yml",
27
+ "generators/blacklists/blacklists_generator.rb",
28
+ "lib/bellmyer/validates_blacklist.rb",
29
+ "test/config/blacklists/friend_with_attribute_message_blacklist.yml",
30
+ "test/config/blacklists/friend_with_blacklist_blacklist.yml",
31
+ "test/config/blacklists/friend_with_blank_blacklist_blacklist.yml",
32
+ "test/config/blacklists/friend_with_custom_message_blacklist.yml",
33
+ "test/test_helper.rb",
34
+ "test/validates_blacklist_test.rb"
24
35
  ]
25
36
 
26
- s.test_files = ["test/blacklist_test.rb"]
27
-
37
+ s.test_files = ["test/validates_blacklist_test.rb"]
28
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bellmyer-validates_blacklist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaime Bellmyer
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "2.1"
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: yaml
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
25
35
  description: ""
26
36
  email: ruby@bellmyer.com
27
37
  executables: []
@@ -31,10 +41,20 @@ extensions: []
31
41
  extra_rdoc_files:
32
42
  - README
33
43
  files:
44
+ - init.rb
45
+ - MIT-LICENSE
46
+ - Rakefile
34
47
  - README
35
48
  - validates_blacklist.gemspec
36
- - lib/bellmyer-validates_blacklist.rb
37
- - lib/active_record/validates/blacklist.rb
49
+ - generators/blacklists/templates/blacklist.yml
50
+ - generators/blacklists/blacklists_generator.rb
51
+ - lib/bellmyer/validates_blacklist.rb
52
+ - test/config/blacklists/friend_with_attribute_message_blacklist.yml
53
+ - test/config/blacklists/friend_with_blacklist_blacklist.yml
54
+ - test/config/blacklists/friend_with_blank_blacklist_blacklist.yml
55
+ - test/config/blacklists/friend_with_custom_message_blacklist.yml
56
+ - test/test_helper.rb
57
+ - test/validates_blacklist_test.rb
38
58
  has_rdoc: true
39
59
  homepage: http://github.com/bellmyer/validates_blacklist
40
60
  licenses:
@@ -64,4 +84,4 @@ signing_key:
64
84
  specification_version: 2
65
85
  summary: Allows models to be validated against yaml-based blacklists
66
86
  test_files:
67
- - test/blacklist_test.rb
87
+ - test/validates_blacklist_test.rb
@@ -1,27 +0,0 @@
1
- module ActiveRecord
2
- module Validates #:nodoc:
3
- module Blacklist #:nodoc:
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
-
8
- module ClassMethods
9
- validates_blacklist(options = {})
10
- options.reverse_merge!(:message => 'is not allowed')
11
-
12
- include ActiveRecord::Validates::Blacklist::InstanceMethods
13
- end
14
- end
15
-
16
- module InstanceMethods
17
- def blacklist(attribute, value, message = nil)
18
- puts "blacklisted!"
19
- end
20
-
21
- def unblacklist(attribute, value)
22
- puts "unblacklisted!"
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,2 +0,0 @@
1
- require 'active_record/validates/blacklist'
2
- ActiveRecord::Base.class_eval { include ActiveRecord::Validates::Blacklist }
@@ -1,332 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'rubygems'
4
- gem 'activerecord', '>= 1.15.4.7794'
5
- require 'active_record'
6
-
7
- require "#{File.dirname(__FILE__)}/../init"
8
-
9
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
10
-
11
- def setup_db
12
- ActiveRecord::Schema.define(:version => 1) do
13
- create_table :mixins do |t|
14
- t.column :pos, :integer
15
- t.column :parent_id, :integer
16
- t.column :created_at, :datetime
17
- t.column :updated_at, :datetime
18
- end
19
- end
20
- end
21
-
22
- def teardown_db
23
- ActiveRecord::Base.connection.tables.each do |table|
24
- ActiveRecord::Base.connection.drop_table(table)
25
- end
26
- end
27
-
28
- class Mixin < ActiveRecord::Base
29
- end
30
-
31
- class ListMixin < Mixin
32
- acts_as_list :column => "pos", :scope => :parent
33
-
34
- def self.table_name() "mixins" end
35
- end
36
-
37
- class ListMixinSub1 < ListMixin
38
- end
39
-
40
- class ListMixinSub2 < ListMixin
41
- end
42
-
43
- class ListWithStringScopeMixin < ActiveRecord::Base
44
- acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}'
45
-
46
- def self.table_name() "mixins" end
47
- end
48
-
49
-
50
- class ListTest < Test::Unit::TestCase
51
-
52
- def setup
53
- setup_db
54
- (1..4).each { |counter| ListMixin.create! :pos => counter, :parent_id => 5 }
55
- end
56
-
57
- def teardown
58
- teardown_db
59
- end
60
-
61
- def test_reordering
62
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
63
-
64
- ListMixin.find(2).move_lower
65
- assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
66
-
67
- ListMixin.find(2).move_higher
68
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
69
-
70
- ListMixin.find(1).move_to_bottom
71
- assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
72
-
73
- ListMixin.find(1).move_to_top
74
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
75
-
76
- ListMixin.find(2).move_to_bottom
77
- assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
78
-
79
- ListMixin.find(4).move_to_top
80
- assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
81
- end
82
-
83
- def test_move_to_bottom_with_next_to_last_item
84
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
85
- ListMixin.find(3).move_to_bottom
86
- assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
87
- end
88
-
89
- def test_next_prev
90
- assert_equal ListMixin.find(2), ListMixin.find(1).lower_item
91
- assert_nil ListMixin.find(1).higher_item
92
- assert_equal ListMixin.find(3), ListMixin.find(4).higher_item
93
- assert_nil ListMixin.find(4).lower_item
94
- end
95
-
96
- def test_injection
97
- item = ListMixin.new(:parent_id => 1)
98
- assert_equal "parent_id = 1", item.scope_condition
99
- assert_equal "pos", item.position_column
100
- end
101
-
102
- def test_insert
103
- new = ListMixin.create(:parent_id => 20)
104
- assert_equal 1, new.pos
105
- assert new.first?
106
- assert new.last?
107
-
108
- new = ListMixin.create(:parent_id => 20)
109
- assert_equal 2, new.pos
110
- assert !new.first?
111
- assert new.last?
112
-
113
- new = ListMixin.create(:parent_id => 20)
114
- assert_equal 3, new.pos
115
- assert !new.first?
116
- assert new.last?
117
-
118
- new = ListMixin.create(:parent_id => 0)
119
- assert_equal 1, new.pos
120
- assert new.first?
121
- assert new.last?
122
- end
123
-
124
- def test_insert_at
125
- new = ListMixin.create(:parent_id => 20)
126
- assert_equal 1, new.pos
127
-
128
- new = ListMixin.create(:parent_id => 20)
129
- assert_equal 2, new.pos
130
-
131
- new = ListMixin.create(:parent_id => 20)
132
- assert_equal 3, new.pos
133
-
134
- new4 = ListMixin.create(:parent_id => 20)
135
- assert_equal 4, new4.pos
136
-
137
- new4.insert_at(3)
138
- assert_equal 3, new4.pos
139
-
140
- new.reload
141
- assert_equal 4, new.pos
142
-
143
- new.insert_at(2)
144
- assert_equal 2, new.pos
145
-
146
- new4.reload
147
- assert_equal 4, new4.pos
148
-
149
- new5 = ListMixin.create(:parent_id => 20)
150
- assert_equal 5, new5.pos
151
-
152
- new5.insert_at(1)
153
- assert_equal 1, new5.pos
154
-
155
- new4.reload
156
- assert_equal 5, new4.pos
157
- end
158
-
159
- def test_delete_middle
160
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
161
-
162
- ListMixin.find(2).destroy
163
-
164
- assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
165
-
166
- assert_equal 1, ListMixin.find(1).pos
167
- assert_equal 2, ListMixin.find(3).pos
168
- assert_equal 3, ListMixin.find(4).pos
169
-
170
- ListMixin.find(1).destroy
171
-
172
- assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
173
-
174
- assert_equal 1, ListMixin.find(3).pos
175
- assert_equal 2, ListMixin.find(4).pos
176
- end
177
-
178
- def test_with_string_based_scope
179
- new = ListWithStringScopeMixin.create(:parent_id => 500)
180
- assert_equal 1, new.pos
181
- assert new.first?
182
- assert new.last?
183
- end
184
-
185
- def test_nil_scope
186
- new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create
187
- new2.move_higher
188
- assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos')
189
- end
190
-
191
-
192
- def test_remove_from_list_should_then_fail_in_list?
193
- assert_equal true, ListMixin.find(1).in_list?
194
- ListMixin.find(1).remove_from_list
195
- assert_equal false, ListMixin.find(1).in_list?
196
- end
197
-
198
- def test_remove_from_list_should_set_position_to_nil
199
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
200
-
201
- ListMixin.find(2).remove_from_list
202
-
203
- assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
204
-
205
- assert_equal 1, ListMixin.find(1).pos
206
- assert_equal nil, ListMixin.find(2).pos
207
- assert_equal 2, ListMixin.find(3).pos
208
- assert_equal 3, ListMixin.find(4).pos
209
- end
210
-
211
- def test_remove_before_destroy_does_not_shift_lower_items_twice
212
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
213
-
214
- ListMixin.find(2).remove_from_list
215
- ListMixin.find(2).destroy
216
-
217
- assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
218
-
219
- assert_equal 1, ListMixin.find(1).pos
220
- assert_equal 2, ListMixin.find(3).pos
221
- assert_equal 3, ListMixin.find(4).pos
222
- end
223
-
224
- end
225
-
226
- class ListSubTest < Test::Unit::TestCase
227
-
228
- def setup
229
- setup_db
230
- (1..4).each { |i| ((i % 2 == 1) ? ListMixinSub1 : ListMixinSub2).create! :pos => i, :parent_id => 5000 }
231
- end
232
-
233
- def teardown
234
- teardown_db
235
- end
236
-
237
- def test_reordering
238
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
239
-
240
- ListMixin.find(2).move_lower
241
- assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
242
-
243
- ListMixin.find(2).move_higher
244
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
245
-
246
- ListMixin.find(1).move_to_bottom
247
- assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
248
-
249
- ListMixin.find(1).move_to_top
250
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
251
-
252
- ListMixin.find(2).move_to_bottom
253
- assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
254
-
255
- ListMixin.find(4).move_to_top
256
- assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
257
- end
258
-
259
- def test_move_to_bottom_with_next_to_last_item
260
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
261
- ListMixin.find(3).move_to_bottom
262
- assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
263
- end
264
-
265
- def test_next_prev
266
- assert_equal ListMixin.find(2), ListMixin.find(1).lower_item
267
- assert_nil ListMixin.find(1).higher_item
268
- assert_equal ListMixin.find(3), ListMixin.find(4).higher_item
269
- assert_nil ListMixin.find(4).lower_item
270
- end
271
-
272
- def test_injection
273
- item = ListMixin.new("parent_id"=>1)
274
- assert_equal "parent_id = 1", item.scope_condition
275
- assert_equal "pos", item.position_column
276
- end
277
-
278
- def test_insert_at
279
- new = ListMixin.create("parent_id" => 20)
280
- assert_equal 1, new.pos
281
-
282
- new = ListMixinSub1.create("parent_id" => 20)
283
- assert_equal 2, new.pos
284
-
285
- new = ListMixinSub2.create("parent_id" => 20)
286
- assert_equal 3, new.pos
287
-
288
- new4 = ListMixin.create("parent_id" => 20)
289
- assert_equal 4, new4.pos
290
-
291
- new4.insert_at(3)
292
- assert_equal 3, new4.pos
293
-
294
- new.reload
295
- assert_equal 4, new.pos
296
-
297
- new.insert_at(2)
298
- assert_equal 2, new.pos
299
-
300
- new4.reload
301
- assert_equal 4, new4.pos
302
-
303
- new5 = ListMixinSub1.create("parent_id" => 20)
304
- assert_equal 5, new5.pos
305
-
306
- new5.insert_at(1)
307
- assert_equal 1, new5.pos
308
-
309
- new4.reload
310
- assert_equal 5, new4.pos
311
- end
312
-
313
- def test_delete_middle
314
- assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
315
-
316
- ListMixin.find(2).destroy
317
-
318
- assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
319
-
320
- assert_equal 1, ListMixin.find(1).pos
321
- assert_equal 2, ListMixin.find(3).pos
322
- assert_equal 3, ListMixin.find(4).pos
323
-
324
- ListMixin.find(1).destroy
325
-
326
- assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
327
-
328
- assert_equal 1, ListMixin.find(3).pos
329
- assert_equal 2, ListMixin.find(4).pos
330
- end
331
-
332
- end