sayso-permalink_fu 0.0.1.001

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,36 @@
1
+ class Autotest
2
+ ##
3
+ # Convert a path in a string, s, into a class name, changing
4
+ # underscores to CamelCase, etc.
5
+
6
+ def path_to_classname(s)
7
+ sep = File::SEPARATOR
8
+ f = s.sub(/^test#{sep}/, '').sub(/\.rb$/, '').split(sep)
9
+ f = f.map { |path| path.split(/_|(\d+)/).map { |seg| seg.capitalize }.join }
10
+ f = f.map { |path| path =~ /Test$/ ? path : "#{path}Test" }
11
+ f.join('::')
12
+ end
13
+ end
14
+
15
+ Autotest.add_hook :initialize do |at|
16
+ unless ARGV.empty?
17
+ if ARGV[0] == '-d'
18
+ at.find_directories = ARGV[1..-1].dup
19
+ else
20
+ at.find_directories = []
21
+ at.extra_files = ARGV.dup
22
+ end
23
+ end
24
+
25
+ # doesn't seem to work
26
+ # at.clear_mappings
27
+
28
+ at.add_mapping(/^lib\/.*\.rb$/) do |filename, _|
29
+ possible = File.basename(filename, 'rb').gsub '_', '_?'
30
+ files_matching %r%^test/.*#{possible}_test\.rb$%
31
+ end
32
+
33
+ at.add_mapping(/^test.*\/.*test\.rb$/) do |filename, _|
34
+ filename
35
+ end
36
+ end
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ nbproject/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in permalink_fu.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,40 @@
1
+ PermalinkFu
2
+
3
+ This is a simple plugin extracted from Mephisto for creating permalinks from attributes.
4
+
5
+ class Article < ActiveRecord::Base
6
+ has_permalink :title
7
+ end
8
+
9
+ This will escape the title, making it fit to use in a URL in the after_validation callback.
10
+
11
+ Use PermalinkFu.escape to escape a string manually if you like.
12
+
13
+ If you're having issues with Iconv, you can manually tweak PermalinkFu.translation_to PermalinkFu.translation_from.
14
+ These are set to nil if Iconv is not loaded. You can also manually set them to nil if you don't want to use iconv.
15
+
16
+ [Added 3.13.2008 by Pat Nakajima] You can now add conditions to #has_permalink like so:
17
+
18
+ class Article < ActiveRecord::Base
19
+ has_permalink :title, :if => Proc.new { |article| article.needs_permalink? }
20
+ end
21
+
22
+ Use the :if or :unless options to specify a Proc, method, or string to be called or evaluated. The permalink
23
+ will only be generated if the option evaluates to true.
24
+
25
+
26
+ [Added 3.11.2009 by Martin Emde] Make permalink_fu update your permalink everytime the dependent field(s) change.
27
+
28
+ class Article < ActiveRecord::Base
29
+ has_permalink :title, :update => true
30
+ end
31
+
32
+ This will update your permalink every time title changes. Rails versions with _changed? methods will reduce the checks for uniqueness to only when the permalink field is changed.
33
+
34
+ Without :update set to true, your permalink will be set one time and subsequent changes to the field
35
+ (title in this example) will not affect the permalink field. To regenerate the permalink field,
36
+ set it to nil or a blank string within your model.
37
+
38
+ Old versions of rails without _changed? attribute support will result in the permalink field being regenerated every save.
39
+
40
+ [Bug Fixed 3.11.2009] Permalink was not being checked for uniqueness when set directly with permalink= on rails versions with _changed?
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rake'
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rake/testtask'
7
+ Rake::TestTask.new do |t|
8
+ t.test_files = FileList['test/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ desc 'Default: run test examples'
13
+ task :default => 'test'
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), 'permalink_fu', 'railtie')
2
+ require File.join(File.dirname(__FILE__), 'permalink_fu', 'active_record')
3
+
4
+ begin
5
+ require 'iconv'
6
+ rescue Object
7
+ puts "No Iconv found, you might want to look into it."
8
+ end
9
+
10
+ module PermalinkFu
11
+
12
+ class << self
13
+
14
+ # This method does the actual permalink escaping.
15
+ def escape(string)
16
+ result = ::ActiveSupport::Inflector.transliterate(string.to_s)
17
+ result = self.iconvify(result)
18
+ result.gsub!(/[^\x00-\x7F]+/, '') # Remove anything non-ASCII entirely (e.g. diacritics).
19
+ result.gsub!(/[^\w_ \-]+/i, '') # Remove unwanted chars.
20
+ result.gsub!(/[ \-]+/i, '-') # No more than one of the separator in a row.
21
+ result.gsub!(/^\-|\-$/i, '') # Remove leading/trailing separator.
22
+ result.downcase!
23
+ result.size.zero? ? random_permalink : result
24
+ rescue
25
+ random_permalink
26
+ end
27
+
28
+ def random_permalink
29
+ ::ActiveSupport::SecureRandom.hex(16)
30
+ end
31
+
32
+ def iconvify(string)
33
+ return string unless defined?(Iconv)
34
+ return Iconv.iconv('ascii//translit//IGNORE', 'utf-8', string).to_s
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,160 @@
1
+ module PermalinkFu
2
+
3
+ module ActiveRecord
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ # This is the plugin method available on all ActiveRecord models.
10
+ module ClassMethods
11
+ # Specifies the given field(s) as a permalink, meaning it is passed through PermalinkFu.escape and set to the permalink_field. This
12
+ # is done
13
+ #
14
+ # class Foo < ActiveRecord::Base
15
+ # # stores permalink form of #title to the #permalink attribute
16
+ # has_permalink :title
17
+ #
18
+ # # stores a permalink form of "#{category}-#{title}" to the #permalink attribute
19
+ #
20
+ # has_permalink [:category, :title]
21
+ #
22
+ # # stores permalink form of #title to the #category_permalink attribute
23
+ # has_permalink [:category, :title], :category_permalink
24
+ #
25
+ # # add a scope
26
+ # has_permalink :title, :scope => :blog_id
27
+ #
28
+ # # add a scope and specify the permalink field name
29
+ # has_permalink :title, :slug, :scope => :blog_id
30
+ #
31
+ # # do not bother checking for a unique scope
32
+ # has_permalink :title, :unique => false
33
+ #
34
+ # # update the permalink every time the attribute(s) change
35
+ # # without _changed? methods (old rails version) this will rewrite the permalink every time
36
+ # has_permalink :title, :update => true
37
+ #
38
+ # end
39
+ #
40
+ def has_permalink(attr_names = [], permalink_field = nil, options = {})
41
+ include InstanceMethods
42
+
43
+ if permalink_field.is_a?(Hash)
44
+ options = permalink_field
45
+ permalink_field = nil
46
+ end
47
+
48
+
49
+ cattr_accessor :permalink_options
50
+ cattr_accessor :permalink_attributes
51
+ cattr_accessor :permalink_field
52
+
53
+ self.permalink_attributes = Array(attr_names)
54
+ self.permalink_field = (permalink_field || 'permalink').to_s
55
+ self.permalink_options = {:unique => true}.update(options)
56
+
57
+ if self.permalink_options[:unique]
58
+ before_validation :create_unique_permalink
59
+ else
60
+ before_validation :create_common_permalink
61
+ end
62
+
63
+ define_method :"#{self.permalink_field}=" do |value|
64
+ write_attribute(self.permalink_field, value.blank? ? '' : PermalinkFu.escape(value))
65
+ end
66
+
67
+ end
68
+ end
69
+
70
+ # This contains instance methods for ActiveRecord models that have permalinks.
71
+ module InstanceMethods
72
+
73
+ protected
74
+
75
+ def create_common_permalink
76
+ return unless should_create_permalink?
77
+ if read_attribute(self.class.permalink_field).blank? || permalink_fields_changed?
78
+ send("#{self.class.permalink_field}=", create_permalink_for(self.class.permalink_attributes))
79
+ end
80
+
81
+ # Quit now if we have the changed method available and nothing has changed
82
+ permalink_changed = "#{self.class.permalink_field}_changed?"
83
+ return if respond_to?(permalink_changed) && !send(permalink_changed)
84
+
85
+ # Otherwise find the limit and crop the permalink
86
+ limit = self.class.columns_hash[self.class.permalink_field].limit
87
+ base = send("#{self.class.permalink_field}=", read_attribute(self.class.permalink_field)[0..limit - 1])
88
+ [limit, base]
89
+ end
90
+
91
+ def create_unique_permalink
92
+ limit, base = create_common_permalink
93
+ return if limit.nil? # nil if the permalink has not changed or :if/:unless fail
94
+ counter = 1
95
+ # oh how i wish i could use a hash for conditions
96
+ conditions = ["#{self.class.permalink_field} = ?", base]
97
+ unless new_record?
98
+ conditions.first << " and id != ?"
99
+ conditions << id
100
+ end
101
+ if self.class.permalink_options[:scope]
102
+ [self.class.permalink_options[:scope]].flatten.each do |scope|
103
+ value = send(scope)
104
+ if value
105
+ conditions.first << " and #{scope} = ?"
106
+ conditions << send(scope)
107
+ else
108
+ conditions.first << " and #{scope} IS NULL"
109
+ end
110
+ end
111
+ end
112
+
113
+ while ::ActiveRecord::Base.uncached{self.class.exists?(conditions)}
114
+ suffix = "-#{counter += 1}"
115
+ conditions[1] = "#{base[0..limit-suffix.size-1]}#{suffix}"
116
+ send("#{self.class.permalink_field}=", conditions[1])
117
+ end
118
+ end
119
+
120
+ def create_permalink_for(attr_names)
121
+ str = attr_names.collect { |attr_name| send(attr_name).to_s } * " "
122
+ str.blank? ? PermalinkFu.random_permalink : str
123
+ end
124
+
125
+ private
126
+ def should_create_permalink?
127
+ if self.class.permalink_field.blank?
128
+ false
129
+ elsif self.class.permalink_options[:if]
130
+ evaluate_method(self.class.permalink_options[:if])
131
+ elsif self.class.permalink_options[:unless]
132
+ !evaluate_method(self.class.permalink_options[:unless])
133
+ else
134
+ true
135
+ end
136
+ end
137
+
138
+ # Don't even check _changed? methods unless :update is set
139
+ def permalink_fields_changed?
140
+ return false unless self.class.permalink_options[:update]
141
+ self.class.permalink_attributes.any? do |attribute|
142
+ changed_method = "#{attribute}_changed?"
143
+ respond_to?(changed_method) ? send(changed_method) : true
144
+ end
145
+ end
146
+
147
+ def evaluate_method(method)
148
+ case method
149
+ when Symbol
150
+ send(method)
151
+ when String
152
+ eval(method, instance_eval { binding })
153
+ when Proc, Method
154
+ method.call(self)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ end
@@ -0,0 +1,19 @@
1
+ require 'rails'
2
+
3
+ module PermalinkFu
4
+
5
+ class Railtie < ::Rails::Railtie
6
+
7
+ initializer 'permalink_fu.insert_into_active_record' do
8
+ ::ActiveSupport.on_load :active_record do
9
+ include PermalinkFu::ActiveRecord
10
+ end
11
+ end
12
+
13
+ # rake_tasks do
14
+ # load "tasks/permalink_fu.rake"
15
+ # end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "sayso-permalink_fu"
3
+ s.version = "0.0.1.001"
4
+ s.authors = ['SaySo']
5
+ s.platform = Gem::Platform::RUBY
6
+ s.rubyforge_project = "knapo-permalink_fu"
7
+
8
+
9
+ s.homepage = "http://github.com/sayso/permalink_fu"
10
+ s.summary = 'Simple plugin extracted from Mephisto for creating permalinks from attributes - forked and gemified for sayso'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.require_paths = ["lib"]
16
+
17
+ s.add_dependency('rails', '>= 3.0.5')
18
+ s.add_dependency('activerecord', '>= 3.0.5')
19
+ s.add_dependency('activesupport', '>= 3.0.5')
20
+ end
@@ -0,0 +1,323 @@
1
+ # encoding: UTF-8
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ class PermalinkFuTest < Test::Unit::TestCase
5
+ @@samples = {
6
+ 'This IS a Tripped out title!!.!1 (well/ not really)'.freeze => 'this-is-a-tripped-out-title1-well-not-really'.freeze,
7
+ '////// meph1sto r0x ! \\\\\\'.freeze => 'meph1sto-r0x'.freeze,
8
+ 'āčēģīķļņū'.freeze => 'acegiklnu'.freeze,
9
+ '中文測試 chinese text'.freeze => 'chinese-text'.freeze,
10
+ 'fööbär'.freeze => 'foobar'.freeze
11
+ }
12
+
13
+ @@extra = { 'some-)()()-ExtRa!/// .data==?> to \/\/test'.freeze => 'some-extra-data-to-test'.freeze }
14
+
15
+ def test_basemodel
16
+ @m = BaseModel.new
17
+ assert @m.valid?
18
+ assert_equal @m.id, nil
19
+ assert_equal @m.title, nil
20
+ assert_equal @m.permalink, nil
21
+ assert_equal @m.extra, nil
22
+ assert_equal @m.foo, nil
23
+ end
24
+
25
+ def test_set_new_permalink_attributes_on_sub_class
26
+ @m = ClassModel.new
27
+ @m.title = 'foo'
28
+ @m.extra = 'bar'
29
+ assert @m.valid?
30
+ assert_equal @m.permalink, 'foo'
31
+
32
+ @m = SubClassHasPermalinkModel.new
33
+ @m.title = 'foo'
34
+ @m.extra = 'bar'
35
+ assert @m.valid?
36
+ assert_equal @m.permalink, 'foo-bar'
37
+ end
38
+
39
+ def test_should_not_inherit_permalink_attributes
40
+ @m = SubClassNoPermalinkModel.new
41
+ @m.title = 'foo'
42
+ assert @m.valid?
43
+ assert_equal @m.permalink, nil
44
+ end
45
+
46
+ def test_should_escape_permalinks
47
+ @@samples.each do |from, to|
48
+ assert_equal to, PermalinkFu.escape(from)
49
+ end
50
+ end
51
+
52
+ def test_should_escape_activerecord_model
53
+ @m = MockModel.new
54
+ @@samples.each do |from, to|
55
+ @m.title = from; @m.permalink = nil
56
+ assert @m.valid?
57
+ assert_equal to, @m.permalink
58
+ end
59
+ end
60
+
61
+ def test_should_escape_activerecord_model_with_existing_permalink
62
+ @m = MockModel.new
63
+ @@samples.each do |from, to|
64
+ @m.title = 'whatever'; @m.permalink = from
65
+ assert @m.valid?
66
+ assert_equal to, @m.permalink
67
+ end
68
+ end
69
+
70
+ def test_multiple_attribute_permalink
71
+ @m = MockModelExtra.new
72
+ @@samples.each do |from, to|
73
+ @@extra.each do |from_extra, to_extra|
74
+ @m.title = from; @m.extra = from_extra; @m.permalink = nil
75
+ assert @m.valid?
76
+ assert_equal "#{to}-#{to_extra}", @m.permalink
77
+ end
78
+ end
79
+ end
80
+
81
+ def test_should_create_unique_permalink
82
+ @m = MockModel.new
83
+ @m.title = 'foo'
84
+ assert @m.valid?
85
+ assert_equal 'foo-2', @m.permalink
86
+
87
+ @m.title = 'bar'
88
+ @m.permalink = nil
89
+ assert @m.valid?
90
+ assert_equal 'bar-3', @m.permalink
91
+ end
92
+
93
+ def test_should_create_unique_permalink_when_assigned_directly
94
+ @m = MockModel.new
95
+ @m.permalink = 'foo'
96
+ assert @m.valid?
97
+ assert_equal 'foo-2', @m.permalink
98
+
99
+ # should always check itself for uniqueness when not respond_to?(:permalink_changed?)
100
+ @m.permalink = 'bar'
101
+ assert @m.valid?
102
+ assert_equal 'bar-3', @m.permalink
103
+ end
104
+
105
+ def test_should_common_permalink_if_unique_is_false
106
+ @m = CommonMockModel.new
107
+ @m.permalink = 'foo'
108
+ assert @m.valid?
109
+ assert_equal 'foo', @m.permalink
110
+ end
111
+
112
+ def test_should_not_check_itself_for_unique_permalink_if_unchanged
113
+ @m = MockModel.new
114
+ @m.id = 2
115
+ @m.permalink = 'bar-2'
116
+ @m.instance_eval do
117
+ @changed_attributes = {}
118
+ end
119
+ assert @m.valid?
120
+ assert_equal 'bar-2', @m.permalink
121
+ end
122
+
123
+ def test_should_check_itself_for_unique_permalink_if_permalink_field_changed
124
+ @m = PermalinkChangeableMockModel.new
125
+ @m.permalink_will_change!
126
+ @m.permalink = 'foo'
127
+ assert @m.valid?
128
+ assert_equal 'foo-2', @m.permalink
129
+ end
130
+
131
+ def test_should_not_check_itself_for_unique_permalink_if_permalink_field_not_changed
132
+ @m = PermalinkChangeableMockModel.new
133
+ @m.permalink = 'foo'
134
+ assert @m.valid?
135
+ assert_equal 'foo', @m.permalink
136
+ end
137
+
138
+ def test_should_create_unique_scoped_permalink
139
+ @m = ScopedModel.new
140
+ @m.permalink = 'foo'
141
+ assert @m.valid?
142
+ assert_equal 'foo-2', @m.permalink
143
+
144
+ @m.foo = 5
145
+ @m.permalink = 'foo'
146
+ assert @m.valid?
147
+ assert_equal 'foo', @m.permalink
148
+ end
149
+
150
+ def test_should_limit_permalink
151
+ @old = MockModel.columns_hash['permalink'].instance_variable_get(:@limit)
152
+ MockModel.columns_hash['permalink'].instance_variable_set(:@limit, 2)
153
+ @m = MockModel.new
154
+ @m.title = 'BOO'
155
+ assert @m.valid?
156
+ assert_equal 'bo', @m.permalink
157
+ ensure
158
+ MockModel.columns_hash['permalink'].instance_variable_set(:@limit, @old)
159
+ end
160
+
161
+ def test_should_limit_unique_permalink
162
+ @old = MockModel.columns_hash['permalink'].instance_variable_get(:@limit)
163
+ MockModel.columns_hash['permalink'].instance_variable_set(:@limit, 3)
164
+ @m = MockModel.new
165
+ @m.title = 'foo'
166
+ assert @m.valid?
167
+ assert_equal 'f-2', @m.permalink
168
+ ensure
169
+ MockModel.columns_hash['permalink'].instance_variable_set(:@limit, @old)
170
+ end
171
+
172
+ def test_should_abide_by_if_proc_condition
173
+ @m = IfProcConditionModel.new
174
+ @m.title = 'dont make me a permalink'
175
+ assert @m.valid?
176
+ assert_nil @m.permalink
177
+ end
178
+
179
+ def test_should_abide_by_if_method_condition
180
+ @m = IfMethodConditionModel.new
181
+ @m.title = 'dont make me a permalink'
182
+ assert @m.valid?
183
+ assert_nil @m.permalink
184
+ end
185
+
186
+ def test_should_abide_by_if_string_condition
187
+ @m = IfStringConditionModel.new
188
+ @m.title = 'dont make me a permalink'
189
+ assert @m.valid?
190
+ assert_nil @m.permalink
191
+ end
192
+
193
+ def test_should_abide_by_unless_proc_condition
194
+ @m = UnlessProcConditionModel.new
195
+ @m.title = 'make me a permalink'
196
+ assert @m.valid?
197
+ assert_not_nil @m.permalink
198
+ end
199
+
200
+ def test_should_abide_by_unless_method_condition
201
+ @m = UnlessMethodConditionModel.new
202
+ @m.title = 'make me a permalink'
203
+ assert @m.valid?
204
+ assert_not_nil @m.permalink
205
+ end
206
+
207
+ def test_should_abide_by_unless_string_condition
208
+ @m = UnlessStringConditionModel.new
209
+ @m.title = 'make me a permalink'
210
+ assert @m.valid?
211
+ assert_not_nil @m.permalink
212
+ end
213
+
214
+ def test_should_allow_override_of_permalink_method
215
+ @m = OverrideModel.new
216
+ @m.write_attribute(:permalink, 'the permalink')
217
+ assert_not_equal @m.permalink, @m.read_attribute(:permalink)
218
+ end
219
+
220
+ def test_should_create_permalink_from_attribute_not_attribute_accessor
221
+ @m = OverrideModel.new
222
+ @m.title = 'the permalink'
223
+ assert @m.valid?
224
+ assert_equal 'the-permalink', @m.read_attribute(:permalink)
225
+ end
226
+
227
+ def test_should_not_update_permalink_unless_field_changed
228
+ @m = NoChangeModel.new
229
+ @m.title = 'the permalink'
230
+ @m.permalink = 'unchanged'
231
+ assert @m.valid?
232
+ assert_equal 'unchanged', @m.read_attribute(:permalink)
233
+ end
234
+
235
+ def test_should_not_update_permalink_without_update_set_even_if_field_changed
236
+ @m = ChangedWithoutUpdateModel.new
237
+ @m.title = 'the permalink'
238
+ @m.permalink = 'unchanged'
239
+ assert @m.valid?
240
+ assert_equal 'unchanged', @m.read_attribute(:permalink)
241
+ end
242
+
243
+ def test_should_update_permalink_if_changed_method_does_not_exist
244
+ @m = OverrideModel.new
245
+ @m.title = 'the permalink'
246
+ assert @m.valid?
247
+ assert_equal 'the-permalink', @m.read_attribute(:permalink)
248
+ end
249
+
250
+ def test_should_update_permalink_if_the_existing_permalink_is_nil
251
+ @m = NoChangeModel.new
252
+ @m.title = 'the permalink'
253
+ @m.permalink = nil
254
+ assert @m.valid?
255
+ assert_equal 'the-permalink', @m.read_attribute(:permalink)
256
+ end
257
+
258
+ def test_should_update_permalink_if_the_existing_permalink_is_blank
259
+ @m = NoChangeModel.new
260
+ @m.title = 'the permalink'
261
+ @m.permalink = ''
262
+ assert @m.valid?
263
+ assert_equal 'the-permalink', @m.read_attribute(:permalink)
264
+ end
265
+
266
+ def test_should_assign_a_random_permalink_if_the_title_is_nil
267
+ @m = NoChangeModel.new
268
+ @m.title = nil
269
+ assert @m.valid?
270
+ assert_not_nil @m.read_attribute(:permalink)
271
+ assert @m.read_attribute(:permalink).size > 0
272
+ end
273
+
274
+ def test_should_assign_a_random_permalink_if_the_title_has_no_permalinkable_characters
275
+ @m = NoChangeModel.new
276
+ @m.title = '////'
277
+ assert @m.valid?
278
+ assert_not_nil @m.read_attribute(:permalink)
279
+ assert @m.read_attribute(:permalink).size > 0
280
+ end
281
+
282
+ def test_should_update_permalink_the_first_time_the_title_is_set
283
+ @m = ChangedWithoutUpdateModel.new
284
+ @m.title = "old title"
285
+ assert @m.valid?
286
+ assert_equal "old-title", @m.read_attribute(:permalink)
287
+ @m.title = "new title"
288
+ assert @m.valid?
289
+ assert_equal "old-title", @m.read_attribute(:permalink)
290
+ end
291
+
292
+ def test_should_not_update_permalink_if_already_set_even_if_title_changed
293
+ @m = ChangedWithoutUpdateModel.new
294
+ @m.permalink = "old permalink"
295
+ @m.title = "new title"
296
+ assert @m.valid?
297
+ assert_equal "old-permalink", @m.read_attribute(:permalink)
298
+ end
299
+
300
+ def test_should_update_permalink_every_time_the_title_is_changed
301
+ @m = ChangedWithUpdateModel.new
302
+ @m.title = "old title"
303
+ assert @m.valid?
304
+ assert_equal "old-title", @m.read_attribute(:permalink)
305
+ @m.title = "new title"
306
+ assert @m.valid?
307
+ assert_equal "new-title", @m.read_attribute(:permalink)
308
+ end
309
+
310
+ def test_should_work_correctly_for_scoped_fields_with_nil_value
311
+ s1 = ScopedModelForNilScope.new
312
+ s1.title = 'ack'
313
+ s1.foo = 3
314
+ assert s1.valid?
315
+ assert_equal 'ack', s1.permalink
316
+
317
+ s2 = ScopedModelForNilScope.new
318
+ s2.title = 'ack'
319
+ s2.foo = nil
320
+ assert s2.valid?
321
+ assert_equal 'ack-2', s2.permalink
322
+ end
323
+ end
@@ -0,0 +1,162 @@
1
+ require 'test/unit'
2
+ require File.join(File.dirname(__FILE__), '../lib/permalink_fu')
3
+
4
+ begin
5
+ require 'rubygems'
6
+ require 'ruby-debug'
7
+ Debugger.start
8
+ rescue LoadError
9
+ # no ruby debugger
10
+ end
11
+
12
+ gem 'activerecord'
13
+ require 'active_record'
14
+ require File.join(File.dirname(__FILE__), '../init')
15
+
16
+ class BaseModel < ActiveRecord::Base
17
+ cattr_accessor :columns
18
+ @@columns ||= []
19
+
20
+ def self.column(name, sql_type = nil, default = nil, null = true)
21
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type, null)
22
+ end
23
+
24
+ def self.exists?(*args)
25
+ false
26
+ end
27
+
28
+ column :id, 'int(11)'
29
+ column :title, 'varchar(100)'
30
+ column :permalink, 'varchar(100)'
31
+ column :extra, 'varchar(100)'
32
+ column :foo, 'varchar(100)'
33
+
34
+ end
35
+
36
+ class ClassModel < BaseModel
37
+ has_permalink :title
38
+ end
39
+
40
+ class SubClassHasPermalinkModel < ClassModel
41
+ has_permalink [:title, :extra]
42
+ end
43
+
44
+ class SubClassNoPermalinkModel < ClassModel
45
+ end
46
+
47
+ class MockModel < BaseModel
48
+ def self.exists?(conditions)
49
+ if conditions[1] == 'foo' || conditions[1] == 'bar' ||
50
+ (conditions[1] == 'bar-2' && conditions[2] != 2)
51
+ true
52
+ else
53
+ false
54
+ end
55
+ end
56
+
57
+ has_permalink :title
58
+ end
59
+
60
+ class PermalinkChangeableMockModel < BaseModel
61
+ def self.exists?(conditions)
62
+ if conditions[1] == 'foo'
63
+ true
64
+ else
65
+ false
66
+ end
67
+ end
68
+
69
+ has_permalink :title
70
+
71
+ def permalink_changed?
72
+ @permalink_changed
73
+ end
74
+
75
+ def permalink_will_change!
76
+ @permalink_changed = true
77
+ end
78
+ end
79
+
80
+ class CommonMockModel < BaseModel
81
+ def self.exists?(conditions)
82
+ false # oh noes
83
+ end
84
+
85
+ has_permalink :title, :unique => false
86
+ end
87
+
88
+ class ScopedModel < BaseModel
89
+ def self.exists?(conditions)
90
+ if conditions[1] == 'foo' && conditions[2] != 5
91
+ true
92
+ else
93
+ false
94
+ end
95
+ end
96
+
97
+ has_permalink :title, :scope => :foo
98
+ end
99
+
100
+ class ScopedModelForNilScope < BaseModel
101
+ def self.exists?(conditions)
102
+ (conditions[0] == 'permalink = ? and foo IS NULL') ? (conditions[1] == 'ack') : false
103
+ end
104
+
105
+ has_permalink :title, :scope => :foo
106
+ end
107
+
108
+ class OverrideModel < BaseModel
109
+ has_permalink :title
110
+
111
+ def permalink
112
+ 'not the permalink'
113
+ end
114
+ end
115
+
116
+ class ChangedWithoutUpdateModel < BaseModel
117
+ has_permalink :title
118
+ def title_changed?; true; end
119
+ end
120
+
121
+ class ChangedWithUpdateModel < BaseModel
122
+ has_permalink :title, :update => true
123
+ def title_changed?; true; end
124
+ end
125
+
126
+ class NoChangeModel < BaseModel
127
+ has_permalink :title, :update => true
128
+ def title_changed?; false; end
129
+ end
130
+
131
+ class IfProcConditionModel < BaseModel
132
+ has_permalink :title, :if => Proc.new { |obj| false }
133
+ end
134
+
135
+ class IfMethodConditionModel < BaseModel
136
+ has_permalink :title, :if => :false_method
137
+
138
+ def false_method; false; end
139
+ end
140
+
141
+ class IfStringConditionModel < BaseModel
142
+ has_permalink :title, :if => 'false'
143
+ end
144
+
145
+ class UnlessProcConditionModel < BaseModel
146
+ has_permalink :title, :unless => Proc.new { |obj| false }
147
+ end
148
+
149
+ class UnlessMethodConditionModel < BaseModel
150
+ has_permalink :title, :unless => :false_method
151
+
152
+ def false_method; false; end
153
+ end
154
+
155
+ class UnlessStringConditionModel < BaseModel
156
+ has_permalink :title, :unless => 'false'
157
+ end
158
+
159
+ class MockModelExtra < BaseModel
160
+ has_permalink [:title, :extra]
161
+ end
162
+
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sayso-permalink_fu
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1.001
6
+ platform: ruby
7
+ authors:
8
+ - SaySo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-23 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rails
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 3.0.5
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 3.0.5
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: activesupport
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.5
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ description:
50
+ email:
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .autotest
59
+ - .gitignore
60
+ - Gemfile
61
+ - README
62
+ - Rakefile
63
+ - lib/permalink_fu.rb
64
+ - lib/permalink_fu/active_record.rb
65
+ - lib/permalink_fu/railtie.rb
66
+ - permalink_fu.gemspec
67
+ - test/permalink_fu_test.rb
68
+ - test/test_helper.rb
69
+ has_rdoc: true
70
+ homepage: http://github.com/sayso/permalink_fu
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project: knapo-permalink_fu
93
+ rubygems_version: 1.6.2
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Simple plugin extracted from Mephisto for creating permalinks from attributes - forked and gemified for sayso
97
+ test_files:
98
+ - test/permalink_fu_test.rb
99
+ - test/test_helper.rb