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.
- checksums.yaml +4 -4
- data/.l.yml +8 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.t.yml +4 -0
- data/Gemfile +4 -2
- data/README.md +10 -20
- data/lib/much-slug.rb +11 -8
- data/lib/much-slug/activerecord.rb +48 -49
- data/lib/much-slug/has_slug_registry.rb +37 -24
- data/lib/much-slug/slug.rb +17 -15
- data/lib/much-slug/version.rb +3 -1
- data/log/{.gitkeep → .keep} +0 -0
- data/much-slug.gemspec +10 -7
- data/test/helper.rb +4 -11
- data/test/support/factory.rb +4 -3
- data/test/unit/activerecord_tests.rb +161 -126
- data/test/unit/has_slug_registry_tests.rb +43 -48
- data/test/unit/much-slug_tests.rb +7 -8
- data/test/unit/slug_tests.rb +62 -46
- metadata +33 -15
data/test/helper.rb
CHANGED
@@ -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
|
9
|
-
|
10
|
-
require 'test/support/factory'
|
11
|
-
|
12
|
-
# 1.8.7 backfills
|
10
|
+
require "pry"
|
13
11
|
|
14
|
-
|
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...
|
data/test/support/factory.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
|
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
|
-
(
|
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
|
-
|
12
|
-
|
13
|
-
|
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
|
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
|
-
|
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
|
-
|
41
|
-
|
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:
|
47
|
-
attribute:
|
48
|
-
preprocessor:
|
49
|
-
separator:
|
50
|
-
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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:
|
66
|
-
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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:
|
87
|
-
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
|
-
|
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:
|
99
|
-
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
|
-
|
105
|
-
|
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:
|
127
|
+
subject.has_slug(source: source_attribute)
|
110
128
|
|
111
129
|
callback = subject.callbacks.find{ |v| v.type == :after_create }
|
112
|
-
|
113
|
-
|
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
|
-
|
117
|
-
|
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
|
-
|
141
|
+
assert_that{
|
142
|
+
subject.has_slug
|
143
|
+
}.raises(ArgumentError)
|
122
144
|
end
|
123
145
|
end
|
124
146
|
|
125
|
-
class
|
147
|
+
class ReceiverInitTests < ReceiverTests
|
126
148
|
desc "when init"
|
149
|
+
subject{ receiver }
|
150
|
+
|
127
151
|
setup do
|
128
|
-
|
129
|
-
|
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
|
-
|
155
|
+
subject.public_send("#{source_attribute}=", source_value)
|
156
|
+
end
|
146
157
|
|
147
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
172
|
-
|
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
|
-
|
208
|
+
assert_that(subject.slug_db_column_updates.size).equals(2)
|
176
209
|
|
177
|
-
|
178
|
-
|
179
|
-
|
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
|
-
|
182
|
-
|
183
|
-
|
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.
|
188
|
-
subject.
|
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
|
-
|
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.
|
230
|
+
subject.public_send("#{source_attribute}=", slug_source)
|
197
231
|
# ensure the preprocessor doesn't change our source
|
198
|
-
Assert.stub(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:
|
206
|
-
separator:
|
207
|
-
allow_underscores:
|
239
|
+
preprocessor: preprocessor.to_proc,
|
240
|
+
separator: separator,
|
241
|
+
allow_underscores: allow_underscores,
|
208
242
|
)
|
209
|
-
|
210
|
-
|
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(
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
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
|
-
|
8
|
-
@class = MuchSlug::HasSlugRegistry
|
9
|
-
end
|
10
|
-
subject{ @class }
|
9
|
+
subject{ unit_class }
|
11
10
|
|
12
|
-
|
13
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
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:
|
41
|
-
source:
|
42
|
-
preprocessor:
|
43
|
-
separator:
|
44
|
-
allow_underscores:
|
37
|
+
attribute: attribute,
|
38
|
+
source: source,
|
39
|
+
preprocessor: preprocessor,
|
40
|
+
separator: separator,
|
41
|
+
allow_underscores: allow_underscores,
|
45
42
|
)
|
46
43
|
|
47
|
-
|
44
|
+
assert_that(registered_attribute).equals(attribute.to_s)
|
48
45
|
|
49
46
|
entry = subject[registered_attribute]
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
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:
|
63
|
-
source:
|
64
|
-
preprocessor:
|
65
|
-
separator:
|
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
|
-
|
66
|
+
assert_that(registered_attribute).equals(MuchSlug.default_attribute.to_s)
|
70
67
|
|
71
68
|
entry = subject[registered_attribute]
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
81
|
-
|
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
|
-
|
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
|
87
|
+
should have_accessors :source_proc, :preprocessor_proc, :separator
|
88
|
+
should have_accessors :allow_underscores
|
94
89
|
end
|
95
90
|
end
|