slugged 0.3.2

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,8 @@
1
+ module Slugged
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 3
5
+ PATCH = 2
6
+ STRING = [MAJOR, MINOR, PATCH].join(".")
7
+ end
8
+ end
@@ -0,0 +1,77 @@
1
+ require 'helper'
2
+
3
+ class CachingTest < Test::Unit::TestCase
4
+ with_tables :slugs, :users do
5
+
6
+ setup { Slugged::MemoryCache.reset! }
7
+
8
+ context 'with the default slug setup' do
9
+
10
+ setup { setup_slugs! }
11
+
12
+ should 'store a cache automatically after finding it' do
13
+ assert_has_no_cache_for "bob"
14
+ u = User.create :name => "Bob"
15
+ assert_has_cache_for "bob"
16
+ Slugged::MemoryCache.reset!
17
+ assert_has_no_cache_for "bob"
18
+ assert_same_as_slug u, "bob"
19
+ assert_has_cache_for "bob"
20
+ assert_same_as_slug u, "bob"
21
+ end
22
+
23
+ should 'automatically keep cache entries for history by default' do
24
+ setup_slugs!
25
+ assert_has_no_cache_for "bob"
26
+ assert_has_no_cache_for "red"
27
+ assert_has_no_cache_for "sam"
28
+ user = User.create :name => "bob"
29
+ assert_has_cache_for "bob"
30
+ assert_has_no_cache_for "red"
31
+ assert_has_no_cache_for "sam"
32
+ user.update_attributes :name => "Red"
33
+ assert_has_cache_for "bob"
34
+ assert_has_cache_for "red"
35
+ assert_has_no_cache_for "sam"
36
+ user.update_attributes :name => "Sam"
37
+ assert_has_cache_for "bob"
38
+ assert_has_cache_for "red"
39
+ assert_has_cache_for "sam"
40
+ end
41
+
42
+ end
43
+
44
+ should 'remove cache on models without history' do
45
+ setup_slugs! :history => false
46
+ u = User.create :name => "Bob"
47
+ assert_has_cache_for "bob"
48
+ assert_has_no_cache_for "red"
49
+ assert_has_no_cache_for "sam"
50
+ u.update_attributes :name => "Red"
51
+ u.update_attributes :name => "Sam"
52
+ assert_has_no_cache_for "bob"
53
+ assert_has_no_cache_for "red"
54
+ assert_has_cache_for "sam"
55
+ end
56
+
57
+ should 'allow you to disable caching' do
58
+ setup_slugs! :use_cache => false
59
+ assert !User.respond_to?(:has_cache_for_slug?)
60
+ end
61
+
62
+ # Ensure we destroy the contents of the cache after each test.
63
+ teardown { Slugged::MemoryCache.reset! }
64
+
65
+ end
66
+
67
+ protected
68
+
69
+ def assert_has_cache_for(key)
70
+ assert User.has_cache_for_slug?(key), "User should have a cache entry for #{key.inspect}"
71
+ end
72
+
73
+ def assert_has_no_cache_for(key)
74
+ assert !User.has_cache_for_slug?(key), "User should not have a cache entry for #{key.inspect}"
75
+ end
76
+
77
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,44 @@
1
+ $KCODE = 'UTF8'
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ Bundler.setup
6
+ Bundler.require
7
+
8
+ require 'test/unit'
9
+ require 'shoulda'
10
+ require 'redgreen' if RUBY_VERSION < '1.9'
11
+ require 'ruby-debug' if ENV['DEBUG']
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'slugged'
16
+ require 'model_definitions'
17
+
18
+ # Use a memory cache for testing.
19
+ Slugged.cache = Slugged::MemoryCache
20
+
21
+ class Test::Unit::TestCase
22
+ extend ReversibleData::ShouldaMacros
23
+
24
+ def setup_slugs!(*args)
25
+ options = args.extract_options!
26
+ field = args.pop || :name
27
+ User.is_sluggable field, options
28
+ end
29
+
30
+ def assert_same_as_slug(user, slug, options = {})
31
+ found_user = User.find_using_slug(slug, options)
32
+ assert_equal user, found_user, "#{slug.inspect} should return #{user.inspect}, got #{found_user.inspect}"
33
+ end
34
+
35
+ def assert_different_to_slug(user, slug, options = {})
36
+ found_user = User.find_using_slug(slug, options)
37
+ assert_not_equal user, found_user, "#{slug.inspect} should not return #{user.inspect}, got same record."
38
+ end
39
+
40
+ def assert_none_for_slug(slug)
41
+ assert User.find_using_slug(slug).blank?, "slug #{slug.inspect} should not return any records."
42
+ end
43
+
44
+ end
@@ -0,0 +1,155 @@
1
+ require 'helper'
2
+ require 'digest/md5'
3
+
4
+ class IsSluggableTest < Test::Unit::TestCase
5
+ with_tables :slugs, :users do
6
+
7
+ class StringWrapper < String
8
+ def to_url; "my-demo-slug"; end
9
+ end
10
+
11
+ context 'with the default slug options' do
12
+
13
+ setup { setup_slugs! }
14
+
15
+ should 'correctly sluggify a value' do
16
+ user = User.create(:name => "Bob")
17
+ assert_equal "bob", user.to_param
18
+ assert_equal "bob", user.cached_slug
19
+ end
20
+
21
+ should 'generate a uuid in place of a slug' do
22
+ user = User.create(:name => '')
23
+ assert user.cached_slug.present?
24
+ end
25
+
26
+ should 'return need to generate a slug when the cahced slug is blank' do
27
+ user = User.new(:name => "Ninja Stuff")
28
+ assert user.cached_slug.blank?
29
+ assert user.should_generate_slug?
30
+ user.save
31
+ assert user.cached_slug.present?
32
+ assert !user.should_generate_slug?
33
+ user.name = 'Awesome'
34
+ assert user.should_generate_slug?
35
+ end
36
+
37
+ should "let you find a record by it's id as needed" do
38
+ user = User.create :name => "Bob"
39
+ assert_equal user, User.find_using_slug(user.id)
40
+ assert_equal user, User.find_using_slug(user.id.to_i)
41
+ end
42
+
43
+ should 'return nil for unfound slugs by default' do
44
+ assert_nil User.find_using_slug("awesome")
45
+ end
46
+
47
+ should 'let you find slugs and raise an exception' do
48
+ assert_raises(ActiveRecord::RecordNotFound) do
49
+ User.find_using_slug!("awesome")
50
+ end
51
+ end
52
+
53
+ should 'default to generate a uuid' do
54
+ user = User.create :name => ""
55
+ assert_match /\A[a-zA-Z0-9]{32}\Z/, user.cached_slug.gsub("-", "")
56
+ user = User.create
57
+ assert_match /\A[a-zA-Z0-9]{32}\Z/, user.cached_slug.gsub("-", "")
58
+ end
59
+
60
+ should 'automatically append a sequence to the end of conflicting slugs' do
61
+ u1 = User.create :name => "ninjas Are awesome"
62
+ u2 = User.create :name => "Ninjas are awesome"
63
+ assert_equal "ninjas-are-awesome", u1.to_slug
64
+ assert_equal "ninjas-are-awesome--1", u2.to_slug
65
+ end
66
+
67
+ should 'let you find out if there is a better way of finding a slug' do
68
+ user = User.create :name => "Bob"
69
+ user.update_attributes! :name => "Ralph"
70
+ assert !User.find_using_slug("ralph").has_better_slug?
71
+ assert User.find_using_slug("bob").has_better_slug?
72
+ assert User.find_using_slug(user.id).has_better_slug?
73
+ end
74
+
75
+ should 'not keep a users slug when updating themselves' do
76
+ user = User.create :name => "bob is awesome"
77
+ assert_equal "bob-is-awesome", user.to_param
78
+ assert !user.new_record?
79
+ user.update_attributes :name => "BOB-is-AWESOME"
80
+ assert_equal "bob-is-awesome", user.to_param
81
+ end
82
+
83
+ end
84
+
85
+ context 'with slug syncing disabled' do
86
+ setup { setup_slugs! :sync => false }
87
+
88
+ should 'let you disable syncing a slug' do
89
+ user = User.create(:name => "Ninja User")
90
+ assert !user.should_generate_slug?
91
+ user.name = "Another User Name"
92
+ assert !user.should_generate_slug?
93
+ end
94
+
95
+ should 'let you force slug generation' do
96
+ user = User.create(:name => "Ninja User")
97
+ assert_equal "ninja-user", user.to_slug
98
+ user.update_attributes :name => "Test User"
99
+ assert_equal "ninja-user", user.to_slug
100
+ user.generate_slug!
101
+ assert_equal "test-user", user.to_slug
102
+ user.reload
103
+ assert_equal "test-user", user.to_slug
104
+ end
105
+
106
+ should 'let you force the update of all slugs' do
107
+ user_a = User.create(:name => "User A")
108
+ user_b = User.create(:name => "User B")
109
+ user_c = User.create(:name => "User C")
110
+ user_a.update_attributes :name => "User A-1"
111
+ user_b.update_attributes :name => "User B-1"
112
+ user_c.update_attributes :name => "User C-1"
113
+ assert_equal "user-a", user_a.to_slug
114
+ assert_equal "user-b", user_b.to_slug
115
+ assert_equal "user-c", user_c.to_slug
116
+ User.update_all_slugs!
117
+ user_a.reload
118
+ user_b.reload
119
+ user_c.reload
120
+ assert_equal "user-a-1", user_a.to_slug
121
+ assert_equal "user-b-1", user_b.to_slug
122
+ assert_equal "user-c-1", user_c.to_slug
123
+ end
124
+
125
+ end
126
+
127
+ context 'setting slug convertors' do
128
+
129
+ should 'let you specify a symbol' do
130
+ setup_slugs! :convertor => :upcase
131
+ assert_equal "AWESOME USER", User.create(:name => "Awesome User").to_slug
132
+ end
133
+
134
+ should 'let you specify a proc' do
135
+ setup_slugs! :convertor => proc { |r| r.reverse.upcase }
136
+ assert_equal "RESU EMOSEWA", User.create(:name => "Awesome User").to_slug
137
+ end
138
+
139
+ should 'call to_url if available by default' do
140
+ setup_slugs!
141
+ original_value = StringWrapper.new("Awesome User")
142
+ assert_equal "my-demo-slug", User.create(:name => original_value).to_slug
143
+ end
144
+
145
+ end
146
+
147
+ should 'set the cached slug to nil if uuid is nil and the source value is blank' do
148
+ setup_slugs! :uuid => nil
149
+ record = User.create(:name => "")
150
+ assert_nil record.cached_slug
151
+ assert_equal record.id.to_s, record.to_slug
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,19 @@
1
+ require 'reversible_data'
2
+
3
+ ReversibleData.in_memory!
4
+
5
+ # Define models here.
6
+
7
+ ReversibleData.add :slugs do |t|
8
+ t.string :scope
9
+ t.string :slug
10
+ t.integer :record_id
11
+ t.datetime :created_at
12
+ end
13
+
14
+ ReversibleData.add :users do |u|
15
+ u.string :name
16
+ u.string :address
17
+ u.string :cached_slug
18
+ u.timestamps
19
+ end
@@ -0,0 +1,86 @@
1
+ require 'helper'
2
+
3
+ class FakedModel
4
+ attr_reader :id
5
+ def self.slug_scope_key; "faked_models"; end
6
+ def initialize(id); @id = id; end
7
+ end
8
+
9
+ class SlugHistoryTest < Test::Unit::TestCase
10
+ with_tables :slugs, :users do
11
+
12
+ context 'for arbitrary models' do
13
+
14
+ setup do
15
+ @record_a = FakedModel.new(12)
16
+ @record_b = FakedModel.new(4)
17
+ Slugged.record_slug(@record_a, "awesome")
18
+ Slugged.record_slug(@record_b, "awesome-1")
19
+ Slugged.record_slug(@record_a, "ninjas")
20
+ end
21
+
22
+ should 'let you lookup a given record id easily' do
23
+ assert Slugged.last_known_slug_id(FakedModel, "felafel").blank?
24
+ assert Slugged.last_known_slug_id(FakedModel, "ninjas-2").blank?
25
+ assert_equal 12, Slugged.last_known_slug_id(FakedModel, "awesome")
26
+ assert_equal 4, Slugged.last_known_slug_id(FakedModel, "awesome-1")
27
+ assert_equal 12, Slugged.last_known_slug_id(FakedModel, "ninjas")
28
+ end
29
+
30
+ should 'let you return slug history for a given record'
31
+
32
+ end
33
+
34
+ context 'on a specific record' do
35
+
36
+ should 'by default record slug history' do
37
+ setup_slugs!
38
+ user = User.create :name => "Bob"
39
+ assert_equal [], user.previous_slugs
40
+ user.update_attributes! :name => "Sal"
41
+ user.update_attributes! :name => "Red"
42
+ user.update_attributes! :name => "Jim"
43
+ assert_same_as_slug user, "red"
44
+ assert_same_as_slug user, "sal"
45
+ assert_same_as_slug user, "bob"
46
+ assert_same_as_slug user, "jim"
47
+ end
48
+
49
+ should 'let you reset history for a slug' do
50
+ setup_slugs!
51
+ user = User.create :name => "Bob"
52
+ user.update_attributes! :name => "Sal"
53
+ user.update_attributes! :name => "Red"
54
+ user.update_attributes! :name => "Jim"
55
+ assert_equal ["red", "sal", "bob"], user.previous_slugs
56
+ user.remove_slug_history!
57
+ assert_equal [], user.previous_slugs
58
+ assert_none_for_slug "red"
59
+ assert_none_for_slug "sal"
60
+ assert_none_for_slug "bob"
61
+ end
62
+
63
+ should 'let you disable recording of slug history' do
64
+ setup_slugs! :history => false
65
+ user = User.create(:name => "Bob")
66
+ assert !user.respond_to?(:previous_slugs)
67
+ user.update_attributes! :name => "Red"
68
+ assert_same_as_slug user, "red"
69
+ assert_different_to_slug user, "bob"
70
+ assert_none_for_slug "bob"
71
+ end
72
+
73
+ should 'remove slug history for a record by default on destroy' do
74
+ setup_slugs!
75
+ user = User.create :name => "Bob"
76
+ user.update_attributes! :name => "Sal"
77
+ user.update_attributes! :name => "Red"
78
+ user.update_attributes! :name => "Jim"
79
+ assert_equal ["red", "sal", "bob"], user.previous_slugs
80
+ user.destroy
81
+ assert_equal [], user.previous_slugs
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+
3
+ class SluggedTest < Test::Unit::TestCase
4
+
5
+ class SlugScopeTest
6
+ cattr_accessor :slug_scope_key
7
+ self.slug_scope_key = "my-test-scope"
8
+ end
9
+
10
+ should 'return the correct counter versions' do
11
+ assert_equal 'awesome', Slugged.with_counter('awesome')
12
+ assert_equal 'awesome', Slugged.with_counter('awesome', 0)
13
+ assert_equal 'awesome', Slugged.with_counter('awesome', -1)
14
+ assert_equal 'awesome--2', Slugged.with_counter('awesome', 2)
15
+ assert_equal 'awesome--100', Slugged.with_counter('awesome', 100)
16
+ end
17
+
18
+ should 'correct allow you to slug scope keys' do
19
+ assert_equal "my-test-scope", Slugged.key_for_scope(SlugScopeTest)
20
+ assert_equal "my-test-scope", Slugged.key_for_scope(SlugScopeTest.new)
21
+ assert_equal "my-test-scope", Slugged.key_for_scope("my-test-scope")
22
+ assert_equal "", Slugged.key_for_scope(nil)
23
+ assert_equal "1", Slugged.key_for_scope(1)
24
+ assert_equal "awesome", Slugged.key_for_scope(:awesome)
25
+ end
26
+
27
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slugged
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 2
10
+ version: 0.3.2
11
+ platform: ruby
12
+ authors:
13
+ - Darcy Laycock
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-30 00:00:00 +08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: activerecord
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 3
33
+ - 0
34
+ - 0
35
+ version: 3.0.0
36
+ requirement: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ type: :runtime
40
+ name: activesupport
41
+ version_requirements: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 7
47
+ segments:
48
+ - 3
49
+ - 0
50
+ - 0
51
+ version: 3.0.0
52
+ requirement: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ type: :runtime
56
+ name: uuid
57
+ version_requirements: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirement: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ prerelease: false
69
+ type: :development
70
+ name: shoulda
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirement: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ prerelease: false
83
+ type: :development
84
+ name: reversible_data
85
+ version_requirements: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirement: *id005
95
+ description: Super simple slugs for ActiveRecord 3.0 and higher, with support for slug history
96
+ email: sutto@sutto.net
97
+ executables: []
98
+
99
+ extensions: []
100
+
101
+ extra_rdoc_files:
102
+ - LICENSE
103
+ - README.md
104
+ files:
105
+ - .document
106
+ - .gitignore
107
+ - .rvmrc
108
+ - Gemfile
109
+ - Gemfile.lock
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - lib/generators/slugged/slug_migration/slug_migration_generator.rb
114
+ - lib/generators/slugged/slug_migration/templates/migration.erb
115
+ - lib/generators/slugged/slugs/slugs_generator.rb
116
+ - lib/generators/slugged/slugs/templates/migration.erb
117
+ - lib/slugged.rb
118
+ - lib/slugged/active_record_methods.rb
119
+ - lib/slugged/caching.rb
120
+ - lib/slugged/finders.rb
121
+ - lib/slugged/memory_cache.rb
122
+ - lib/slugged/railtie.rb
123
+ - lib/slugged/scopes.rb
124
+ - lib/slugged/slug.rb
125
+ - lib/slugged/slug_history.rb
126
+ - lib/slugged/version.rb
127
+ - metrics/.gitignore
128
+ - test/caching_test.rb
129
+ - test/helper.rb
130
+ - test/is_sluggable_test.rb
131
+ - test/model_definitions.rb
132
+ - test/slug_history_test.rb
133
+ - test/slugged_test.rb
134
+ has_rdoc: true
135
+ homepage: http://github.com/Sutto/slugged
136
+ licenses: []
137
+
138
+ post_install_message:
139
+ rdoc_options:
140
+ - --charset=UTF-8
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ hash: 3
149
+ segments:
150
+ - 0
151
+ version: "0"
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ hash: 3
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ requirements: []
162
+
163
+ rubyforge_project:
164
+ rubygems_version: 1.3.7
165
+ signing_key:
166
+ specification_version: 3
167
+ summary: Super simple slugs for ActiveRecord 3.0 and higher, with support for slug history
168
+ test_files:
169
+ - test/caching_test.rb
170
+ - test/helper.rb
171
+ - test/is_sluggable_test.rb
172
+ - test/model_definitions.rb
173
+ - test/slug_history_test.rb
174
+ - test/slugged_test.rb