much-slug 0.1.0 → 0.1.1

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # this file is automatically required when you run `assert`
2
4
  # put any test helpers here
3
5
 
@@ -5,17 +7,8 @@
5
7
  $LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
6
8
 
7
9
  # require pry for debugging (`binding.pry`)
8
- require 'pry'
9
-
10
- require 'test/support/factory'
11
-
12
- # 1.8.7 backfills
10
+ require "pry"
13
11
 
14
- # Array#sample
15
- if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
16
- class Array
17
- alias_method :sample, :choice
18
- end
19
- end
12
+ require "test/support/factory"
20
13
 
21
14
  # TODO: put test helpers here...
@@ -1,15 +1,16 @@
1
- require 'assert/factory'
1
+ # frozen_string_literal: true
2
+
3
+ require "assert/factory"
2
4
 
3
5
  module Factory
4
6
  extend Assert::Factory
5
7
 
6
8
  def self.non_word_chars
7
- ( (" ".."/").to_a +
9
+ ((" ".."/").to_a +
8
10
  (":".."@").to_a +
9
11
  ("[".."`").to_a +
10
12
  ("{".."~").to_a -
11
13
  ["-", "_"]
12
14
  ).freeze
13
15
  end
14
-
15
16
  end
@@ -1,18 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "assert"
2
4
  require "much-slug/activerecord"
3
5
 
4
- require "much-plugin"
5
6
  require "ardb/record_spy"
6
7
 
7
8
  module MuchSlug::ActiveRecord
8
9
  class UnitTests < Assert::Context
9
10
  desc "MuchSlug::ActiveRecord"
11
+ subject{ unit_module }
12
+
13
+ let(:unit_module){ MuchSlug::ActiveRecord }
14
+ end
15
+
16
+ class ReceiverTests < UnitTests
17
+ desc "receiver"
18
+ subject{ receiver_class }
19
+
10
20
  setup do
11
- source_attribute = @source_attribute = Factory.string.to_sym
12
- slug_attribute = @slug_attribute = Factory.string
13
- @record_class = Ardb::RecordSpy.new do
21
+ Assert.stub_tap_on_call(
22
+ receiver_class.much_slug_has_slug_registry,
23
+ :register,
24
+ ) do |_, call|
25
+ @register_call = call
26
+ end
27
+ end
28
+
29
+ let(:receiver_class) do
30
+ attr_source_attribute = source_attribute
31
+ attr_slug_attribute = slug_attribute
32
+
33
+ Ardb::RecordSpy.new do
14
34
  include MuchSlug::ActiveRecord
15
- attr_accessor source_attribute, slug_attribute, MuchSlug.default_attribute
35
+ attr_accessor attr_source_attribute, attr_slug_attribute
36
+ attr_accessor MuchSlug.default_attribute
16
37
  attr_reader :slug_db_column_updates
17
38
  attr_reader :save_called, :save_bang_called
18
39
 
@@ -21,208 +42,222 @@ module MuchSlug::ActiveRecord
21
42
  @slug_db_column_updates << args
22
43
  end
23
44
  end
24
-
25
- @has_slug_attribute = Factory.string
26
- @has_slug_preprocessor = :downcase
27
- @has_slug_separator = Factory.non_word_chars.sample
28
- @has_slug_allow_underscores = Factory.boolean
29
-
30
- Assert.stub_tap(@record_class.much_slug_has_slug_registry, :register) { |**kargs|
31
- @register_called_with = kargs
32
- }
33
45
  end
34
- subject{ @record_class }
46
+ let(:source_attribute){ Factory.symbol }
47
+ let(:slug_attribute){ Factory.string }
48
+
49
+ let(:has_slug_attribute){ Factory.string }
50
+ let(:has_slug_preprocessor){ :downcase }
51
+ let(:has_slug_separator){ Factory.non_word_chars.sample }
52
+ let(:has_slug_allow_underscores){ Factory.boolean }
35
53
 
36
54
  should have_imeths :has_slug
37
55
  should have_imeths :much_slug_has_slug_registry
38
56
 
39
57
  should "not have any has_slug registry entries by default" do
40
- assert_kind_of MuchSlug::HasSlugRegistry, subject.much_slug_has_slug_registry
41
- assert_empty subject.much_slug_has_slug_registry
58
+ assert_that(subject.much_slug_has_slug_registry)
59
+ .is_an_instance_of(MuchSlug::HasSlugRegistry)
60
+ assert_that(subject.much_slug_has_slug_registry.empty?).is_true
42
61
  end
43
62
 
44
63
  should "register a new has_slug entry using `has_slug`" do
45
64
  subject.has_slug(
46
- source: @source_attribute,
47
- attribute: @has_slug_attribute,
48
- preprocessor: @has_slug_preprocessor,
49
- separator: @has_slug_separator,
50
- allow_underscores: @has_slug_allow_underscores
65
+ source: source_attribute,
66
+ attribute: has_slug_attribute,
67
+ preprocessor: has_slug_preprocessor,
68
+ separator: has_slug_separator,
69
+ allow_underscores: has_slug_allow_underscores,
51
70
  )
52
71
 
53
- exp_kargs = {
54
- attribute: @has_slug_attribute,
55
- source: @source_attribute,
56
- preprocessor: @has_slug_preprocessor,
57
- separator: @has_slug_separator,
58
- allow_underscores: @has_slug_allow_underscores
59
- }
60
- assert_equal exp_kargs, @register_called_with
72
+ assert_that(@register_call.kargs)
73
+ .equals(
74
+ attribute: has_slug_attribute,
75
+ source: source_attribute,
76
+ preprocessor: has_slug_preprocessor,
77
+ separator: has_slug_separator,
78
+ allow_underscores: has_slug_allow_underscores,
79
+ )
61
80
  end
62
81
 
63
82
  should "add validations using `has_slug`" do
64
83
  subject.has_slug(
65
- source: @source_attribute,
66
- attribute: @has_slug_attribute
84
+ source: source_attribute,
85
+ attribute: has_slug_attribute,
67
86
  )
68
- exp_attr_name = @has_slug_attribute
69
87
 
70
88
  validation = subject.validations.find{ |v| v.type == :presence }
71
- assert_not_nil validation
72
- assert_equal [exp_attr_name], validation.columns
73
- assert_equal :update, validation.options[:on]
89
+ assert_that(validation).is_not_nil
90
+ assert_that(validation.columns).equals([has_slug_attribute])
91
+ assert_that(validation.options[:on]).equals(:update)
74
92
 
75
93
  validation = subject.validations.find{ |v| v.type == :uniqueness }
76
- assert_not_nil validation
77
- assert_equal [exp_attr_name], validation.columns
78
- assert_equal true, validation.options[:case_sensitive]
79
- assert_nil validation.options[:scope]
80
- assert_equal true, validation.options[:allow_nil]
81
- assert_equal true, validation.options[:allow_blank]
94
+ assert_that(validation).is_not_nil
95
+ assert_that(validation.columns).equals([has_slug_attribute])
96
+ assert_that(validation.options[:case_sensitive]).is_true
97
+ assert_that(validation.options[:scope]).is_nil
98
+ assert_that(validation.options[:allow_nil]).is_true
99
+ assert_that(validation.options[:allow_blank]).is_true
82
100
  end
83
101
 
84
102
  should "not add a unique validation if skipping unique validation" do
85
103
  subject.has_slug(
86
- source: @source_attribute,
87
- attribute: @has_slug_attribute,
88
- skip_unique_validation: true
104
+ source: source_attribute,
105
+ attribute: has_slug_attribute,
106
+ skip_unique_validation: true,
89
107
  )
90
108
 
91
109
  validation = subject.validations.find{ |v| v.type == :uniqueness }
92
- assert_nil validation
110
+ assert_that(validation).is_nil
93
111
  end
94
112
 
95
113
  should "allow customizing its validations using `has_slug`" do
96
114
  unique_scope = Factory.string.to_sym
97
115
  subject.has_slug(
98
- source: @source_attribute,
99
- attribute: @has_slug_attribute,
100
- unique_scope: unique_scope
116
+ source: source_attribute,
117
+ attribute: has_slug_attribute,
118
+ unique_scope: unique_scope,
101
119
  )
102
120
 
103
121
  validation = subject.validations.find{ |v| v.type == :uniqueness }
104
- assert_not_nil validation
105
- assert_equal unique_scope, validation.options[:scope]
122
+ assert_that(validation).is_not_nil
123
+ assert_that(validation.options[:scope]).equals(unique_scope)
106
124
  end
107
125
 
108
126
  should "add callbacks using `has_slug`" do
109
- subject.has_slug(source: @source_attribute)
127
+ subject.has_slug(source: source_attribute)
110
128
 
111
129
  callback = subject.callbacks.find{ |v| v.type == :after_create }
112
- assert_not_nil callback
113
- assert_equal [:much_slug_has_slug_update_slug_values], callback.args
130
+ assert_that(callback).is_not_nil
131
+ assert_that(callback.args)
132
+ .equals([:much_slug_has_slug_update_slug_values])
114
133
 
115
134
  callback = subject.callbacks.find{ |v| v.type == :after_update }
116
- assert_not_nil callback
117
- assert_equal [:much_slug_has_slug_update_slug_values], callback.args
135
+ assert_that(callback).is_not_nil
136
+ assert_that(callback.args)
137
+ .equals([:much_slug_has_slug_update_slug_values])
118
138
  end
119
139
 
120
140
  should "raise an argument error if `has_slug` isn't passed a source" do
121
- assert_raises(ArgumentError){ subject.has_slug }
141
+ assert_that{
142
+ subject.has_slug
143
+ }.raises(ArgumentError)
122
144
  end
123
145
  end
124
146
 
125
- class InitTests < UnitTests
147
+ class ReceiverInitTests < ReceiverTests
126
148
  desc "when init"
149
+ subject{ receiver }
150
+
127
151
  setup do
128
- @preprocessor = [:downcase, :upcase, :capitalize].sample
129
- @separator = Factory.non_word_chars.sample
130
- @allow_underscores = Factory.boolean
131
-
132
- @registered_default_attribute =
133
- @record_class.has_slug(source: @source_attribute)
134
-
135
- source_attribute = @source_attribute
136
- @registered_custom_attribute =
137
- @record_class.has_slug(
138
- source: -> { self.send(source_attribute) },
139
- attribute: @slug_attribute,
140
- preprocessor: @preprocessor,
141
- separator: @separator,
142
- allow_underscores: @allow_underscores
143
- )
152
+ registered_default_attribute
153
+ registered_custom_attribute
144
154
 
145
- @record = @record_class.new
155
+ subject.public_send("#{source_attribute}=", source_value)
156
+ end
146
157
 
147
- # create a string that has mixed case and an underscore so we can test
148
- # that it uses the preprocessor and allow underscores options when
149
- # generating a slug
150
- @source_value = "#{Factory.string.downcase}_#{Factory.string.upcase}"
151
- @record.send("#{@source_attribute}=", @source_value)
158
+ let(:receiver){ receiver_class.new }
152
159
 
153
- @exp_default_slug =
154
- MuchSlug::Slug.new(
155
- @source_value,
156
- preprocessor: MuchSlug.default_preprocessor.to_proc,
157
- separator: MuchSlug.default_separator,
158
- allow_underscores: false
159
- )
160
- @exp_custom_slug =
161
- MuchSlug::Slug.new(
162
- @source_value,
163
- preprocessor: @preprocessor.to_proc,
164
- separator: @separator,
165
- allow_underscores: @allow_underscores
166
- )
160
+ let(:registered_default_attribute) do
161
+ receiver_class.has_slug(source: source_attribute)
162
+ end
163
+ let(:registered_custom_attribute) do
164
+ block_source_attribute = source_attribute
165
+
166
+ receiver_class.has_slug(
167
+ source: ->{ public_send(block_source_attribute) },
168
+ attribute: slug_attribute,
169
+ preprocessor: preprocessor,
170
+ separator: separator,
171
+ allow_underscores: allow_underscores,
172
+ )
173
+ end
174
+ let(:preprocessor){ [:downcase, :upcase, :capitalize].sample }
175
+ let(:separator){ Factory.non_word_chars.sample }
176
+ let(:allow_underscores){ Factory.boolean }
177
+
178
+ # create a string that has mixed case and an underscore so we can test
179
+ # that it uses the preprocessor and allow underscores options when
180
+ # generating a slug
181
+ let(:source_value) do
182
+ "#{Factory.string.downcase}_#{Factory.string.upcase}"
183
+ end
184
+
185
+ let(:exp_default_slug) do
186
+ MuchSlug::Slug.new(
187
+ source_value,
188
+ preprocessor: MuchSlug.default_preprocessor.to_proc,
189
+ separator: MuchSlug.default_separator,
190
+ allow_underscores: false,
191
+ )
192
+ end
193
+ let(:exp_custom_slug) do
194
+ MuchSlug::Slug.new(
195
+ source_value,
196
+ preprocessor: preprocessor.to_proc,
197
+ separator: separator,
198
+ allow_underscores: allow_underscores,
199
+ )
167
200
  end
168
- subject{ @record }
169
201
 
170
202
  should "default its slug attribute" do
171
- assert_equal MuchSlug.default_attribute, @registered_default_attribute
172
- assert_equal @slug_attribute, @registered_custom_attribute
203
+ assert_that(registered_default_attribute)
204
+ .equals(MuchSlug.default_attribute)
205
+ assert_that(registered_custom_attribute).equals(slug_attribute)
173
206
 
174
207
  subject.instance_eval{ much_slug_has_slug_update_slug_values }
175
- assert_equal 2, subject.slug_db_column_updates.size
208
+ assert_that(subject.slug_db_column_updates.size).equals(2)
176
209
 
177
- exp = @exp_default_slug
178
- assert_equal exp, subject.send(MuchSlug.default_attribute)
179
- assert_includes [MuchSlug.default_attribute, exp], subject.slug_db_column_updates
210
+ assert_that(subject.public_send(MuchSlug.default_attribute))
211
+ .equals(exp_default_slug)
212
+ assert_that(subject.slug_db_column_updates)
213
+ .includes([MuchSlug.default_attribute, exp_default_slug])
180
214
 
181
- exp = @exp_custom_slug
182
- assert_equal exp, subject.send(@slug_attribute)
183
- assert_includes [@slug_attribute, exp], subject.slug_db_column_updates
215
+ assert_that(subject.public_send(slug_attribute)).equals(exp_custom_slug)
216
+ assert_that(subject.slug_db_column_updates)
217
+ .includes([slug_attribute, exp_custom_slug])
184
218
  end
185
219
 
186
220
  should "not set its slug if it hasn't changed" do
187
- subject.send("#{MuchSlug.default_attribute}=", @exp_default_slug)
188
- subject.send("#{@slug_attribute}=", @exp_custom_slug)
221
+ subject.public_send("#{MuchSlug.default_attribute}=", exp_default_slug)
222
+ subject.public_send("#{slug_attribute}=", exp_custom_slug)
189
223
 
190
224
  subject.instance_eval{ much_slug_has_slug_update_slug_values }
191
- assert_nil subject.slug_db_column_updates
225
+ assert_that(subject.slug_db_column_updates).is_nil
192
226
  end
193
227
 
194
228
  should "slug its source even if its already a valid slug" do
195
229
  slug_source = Factory.slug
196
- subject.send("#{@source_attribute}=", slug_source)
230
+ subject.public_send("#{source_attribute}=", slug_source)
197
231
  # ensure the preprocessor doesn't change our source
198
- Assert.stub(slug_source, @preprocessor){ slug_source }
232
+ Assert.stub(slug_source, preprocessor){ slug_source }
199
233
 
200
234
  subject.instance_eval{ much_slug_has_slug_update_slug_values }
201
235
 
202
236
  exp =
203
237
  MuchSlug::Slug.new(
204
238
  slug_source,
205
- preprocessor: @preprocessor.to_proc,
206
- separator: @separator,
207
- allow_underscores: @allow_underscores
239
+ preprocessor: preprocessor.to_proc,
240
+ separator: separator,
241
+ allow_underscores: allow_underscores,
208
242
  )
209
- assert_equal exp, subject.send(@slug_attribute)
210
- assert_includes [@slug_attribute, exp], subject.slug_db_column_updates
243
+ assert_that(subject.public_send(slug_attribute)).equals(exp)
244
+ assert_that(subject.slug_db_column_updates)
245
+ .includes([slug_attribute, exp])
211
246
  end
212
247
 
213
248
  should "manually update slugs" do
214
- result = MuchSlug.update_slugs(@record)
215
-
216
- assert_true result
217
- assert_equal 2, subject.slug_db_column_updates.size
218
-
219
- exp = @exp_default_slug
220
- assert_equal exp, subject.send(MuchSlug.default_attribute)
221
- assert_includes [MuchSlug.default_attribute, exp], subject.slug_db_column_updates
222
-
223
- exp = @exp_custom_slug
224
- assert_equal exp, subject.send(@slug_attribute)
225
- assert_includes [@slug_attribute, exp], subject.slug_db_column_updates
249
+ result = MuchSlug.update_slugs(subject)
250
+ assert_that(result).is_true
251
+ assert_that(subject.slug_db_column_updates.size).equals(2)
252
+
253
+ assert_that(subject.public_send(MuchSlug.default_attribute))
254
+ .equals(exp_default_slug)
255
+ assert_that(subject.slug_db_column_updates)
256
+ .includes([MuchSlug.default_attribute, exp_default_slug])
257
+
258
+ assert_that(subject.public_send(slug_attribute)).equals(exp_custom_slug)
259
+ assert_that(subject.slug_db_column_updates)
260
+ .includes([slug_attribute, exp_custom_slug])
226
261
  end
227
262
  end
228
263
  end
@@ -1,95 +1,90 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "assert"
2
4
  require "much-slug/has_slug_registry"
3
5
 
4
6
  class MuchSlug::HasSlugRegistry
5
7
  class UnitTests < Assert::Context
6
8
  desc "MuchSlug::HasSlugRegistry"
7
- setup do
8
- @class = MuchSlug::HasSlugRegistry
9
- end
10
- subject{ @class }
9
+ subject{ unit_class }
11
10
 
12
- should "subclass Hash" do
13
- assert subject < ::Hash
11
+ let(:unit_class){ MuchSlug::HasSlugRegistry }
12
+
13
+ should "be a Hash" do
14
+ assert_that(subject < ::Hash).is_true
14
15
  end
15
16
  end
16
17
 
17
18
  class InitTests < UnitTests
18
19
  desc "when init"
19
- setup do
20
- @attribute = Factory.string.to_sym
21
- @source = :to_s
22
- @preprocessor = :downcase
23
- @separator = "|"
24
- @allow_underscores = Factory.boolean
25
-
26
- @registry = @class.new
27
- end
28
- subject{ @registry }
20
+ subject{ unit_class.new }
21
+
22
+ let(:attribute){ Factory.symbol }
23
+ let(:source){ :to_s }
24
+ let(:preprocessor){ :downcase }
25
+ let(:separator){ "|" }
26
+ let(:allow_underscores){ Factory.boolean }
29
27
 
30
28
  should have_imeths :register
31
29
 
32
30
  should "default empty entries for unregisterd attributes" do
33
- entry = subject[Factory.string]
34
- assert_kind_of @class::Entry, entry
31
+ assert_that(subject[Factory.string]).is_an_instance_of(unit_class::Entry)
35
32
  end
36
33
 
37
34
  should "register new entries" do
38
35
  registered_attribute =
39
36
  subject.register(
40
- attribute: @attribute,
41
- source: @source,
42
- preprocessor: @preprocessor,
43
- separator: @separator,
44
- allow_underscores: @allow_underscores
37
+ attribute: attribute,
38
+ source: source,
39
+ preprocessor: preprocessor,
40
+ separator: separator,
41
+ allow_underscores: allow_underscores,
45
42
  )
46
43
 
47
- assert_equal @attribute.to_s, registered_attribute
44
+ assert_that(registered_attribute).equals(attribute.to_s)
48
45
 
49
46
  entry = subject[registered_attribute]
50
- assert_kind_of @class::Entry, entry
51
- assert_equal @source.to_proc, entry.source_proc
52
- assert_equal @preprocessor.to_proc, entry.preprocessor_proc
53
- assert_equal @separator, entry.separator
54
- assert_equal @allow_underscores, entry.allow_underscores
47
+ assert_that(entry).is_an_instance_of(unit_class::Entry)
48
+ assert_that(entry.source_proc).equals(source.to_proc)
49
+ assert_that(entry.preprocessor_proc).equals(preprocessor.to_proc)
50
+ assert_that(entry.separator).equals(separator)
51
+ assert_that(entry.allow_underscores).equals(allow_underscores)
55
52
 
56
- assert_same entry, subject[registered_attribute]
53
+ assert_that(subject[registered_attribute]).is(entry)
57
54
  end
58
55
 
59
56
  should "default registered settings if none are provided" do
60
57
  registered_attribute =
61
58
  subject.register(
62
- attribute: nil,
63
- source: @source,
64
- preprocessor: nil,
65
- separator: nil,
66
- allow_underscores: nil
59
+ attribute: nil,
60
+ source: source,
61
+ preprocessor: nil,
62
+ separator: nil,
63
+ allow_underscores: nil,
67
64
  )
68
65
 
69
- assert_equal MuchSlug.default_attribute.to_s, registered_attribute
66
+ assert_that(registered_attribute).equals(MuchSlug.default_attribute.to_s)
70
67
 
71
68
  entry = subject[registered_attribute]
72
- assert_equal MuchSlug.default_preprocessor.to_proc, entry.preprocessor_proc
73
- assert_equal MuchSlug.default_separator, entry.separator
74
- assert_equal MuchSlug.default_allow_underscores, entry.allow_underscores
69
+ assert_that(entry.preprocessor_proc)
70
+ .equals(MuchSlug.default_preprocessor.to_proc)
71
+ assert_that(entry.separator).equals(MuchSlug.default_separator)
72
+ assert_that(entry.allow_underscores)
73
+ .equals(MuchSlug.default_allow_underscores)
75
74
  end
76
75
  end
77
76
 
78
77
  class EntryUnitTests < UnitTests
79
78
  desc "Entry"
80
- setup do
81
- @entry_class = MuchSlug::HasSlugRegistry::Entry
82
- end
83
- subject{ @entry_class }
79
+
80
+ let(:entry_class){ MuchSlug::HasSlugRegistry::Entry }
84
81
  end
85
82
 
86
83
  class EntryInitTests < EntryUnitTests
87
84
  desc "when init"
88
- setup do
89
- @entry = @entry_class.new
90
- end
91
- subject{ @entry }
85
+ subject{ entry_class.new }
92
86
 
93
- should have_accessors :source_proc, :preprocessor_proc, :separator, :allow_underscores
87
+ should have_accessors :source_proc, :preprocessor_proc, :separator
88
+ should have_accessors :allow_underscores
94
89
  end
95
90
  end