ardb 0.28.3 → 0.30.0

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.
Files changed (60) hide show
  1. checksums.yaml +7 -7
  2. data/.l.yml +9 -0
  3. data/.rubocop.yml +3 -0
  4. data/.ruby-version +1 -0
  5. data/.t.yml +6 -0
  6. data/Gemfile +24 -8
  7. data/README.md +252 -3
  8. data/ardb.gemspec +14 -10
  9. data/bin/ardb +3 -1
  10. data/lib/ardb/adapter/base.rb +72 -47
  11. data/lib/ardb/adapter/mysql.rb +4 -17
  12. data/lib/ardb/adapter/postgresql.rb +51 -46
  13. data/lib/ardb/adapter/sqlite.rb +11 -15
  14. data/lib/ardb/adapter_spy.rb +18 -30
  15. data/lib/ardb/cli/clirb.rb +16 -18
  16. data/lib/ardb/cli/commands.rb +308 -129
  17. data/lib/ardb/cli.rb +29 -24
  18. data/lib/ardb/db_tests.rb +4 -4
  19. data/lib/ardb/default_order_by.rb +13 -21
  20. data/lib/ardb/migration.rb +15 -16
  21. data/lib/ardb/record_spy.rb +46 -61
  22. data/lib/ardb/relation_spy.rb +28 -32
  23. data/lib/ardb/require_autoloaded_active_record_files.rb +258 -57
  24. data/lib/ardb/test_helpers.rb +33 -29
  25. data/lib/ardb/use_db_default.rb +13 -21
  26. data/lib/ardb/version.rb +3 -1
  27. data/lib/ardb.rb +105 -86
  28. data/script/determine_autoloaded_active_record_files.rb +31 -24
  29. data/test/helper.rb +6 -13
  30. data/test/support/factory.rb +4 -3
  31. data/test/support/fake_schema.rb +3 -1
  32. data/test/support/postgresql/migrations/{.gitkeep → .keep} +0 -0
  33. data/test/support/postgresql/schema.rb +2 -1
  34. data/test/support/postgresql/setup_test_db.rb +23 -21
  35. data/test/support/relative_require_test_db_file.rb +1 -0
  36. data/test/support/require_test_db_file.rb +1 -0
  37. data/test/system/.keep +0 -0
  38. data/test/unit/adapter/base_tests.rb +80 -55
  39. data/test/unit/adapter/mysql_tests.rb +4 -19
  40. data/test/unit/adapter/postgresql_tests.rb +21 -30
  41. data/test/unit/adapter/sqlite_tests.rb +5 -11
  42. data/test/unit/adapter_spy_tests.rb +6 -17
  43. data/test/unit/ardb_tests.rb +75 -53
  44. data/test/unit/cli_tests.rb +234 -158
  45. data/test/unit/db_tests_tests.rb +7 -7
  46. data/test/unit/default_order_by_tests.rb +26 -24
  47. data/test/unit/migration_tests.rb +17 -18
  48. data/test/unit/record_spy_tests.rb +45 -41
  49. data/test/unit/relation_spy_tests.rb +40 -63
  50. data/test/unit/test_helpers_tests.rb +7 -15
  51. data/test/unit/use_db_default_tests.rb +35 -27
  52. metadata +109 -87
  53. data/lib/ardb/has_slug.rb +0 -107
  54. data/lib/ardb/migration_helpers.rb +0 -77
  55. data/lib/ardb/pg_json.rb +0 -90
  56. data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +0 -13
  57. data/test/system/pg_json_tests.rb +0 -85
  58. data/test/unit/has_slug_tests.rb +0 -341
  59. data/test/unit/migration_helpers_tests.rb +0 -65
  60. data/test/unit/pg_json_tests.rb +0 -39
@@ -1,341 +0,0 @@
1
- require 'assert'
2
- require 'ardb/has_slug'
3
-
4
- require 'much-plugin'
5
- require 'ardb/record_spy'
6
-
7
- module Ardb::HasSlug
8
-
9
- class UnitTests < Assert::Context
10
- desc "Ardb::HasSlug"
11
- setup do
12
- source_attribute = @source_attribute = Factory.string.to_sym
13
- slug_attribute = @slug_attribute = Factory.string.to_sym
14
- @record_class = Ardb::RecordSpy.new do
15
- include Ardb::HasSlug
16
- attr_accessor source_attribute, slug_attribute, DEFAULT_ATTRIBUTE
17
- attr_reader :slug_db_column_updates
18
-
19
- def update_column(*args)
20
- @slug_db_column_updates ||= []
21
- @slug_db_column_updates << args
22
- end
23
- end
24
- end
25
- subject{ @record_class }
26
-
27
- NON_WORD_CHARS = ((' '..'/').to_a + (':'..'@').to_a + ('['..'`').to_a +
28
- ('{'..'~').to_a - ['-', '_']).freeze
29
-
30
- should have_imeths :has_slug
31
- should have_imeths :ardb_has_slug_configs
32
-
33
- should "use much-plugin" do
34
- assert_includes MuchPlugin, Ardb::HasSlug
35
- end
36
-
37
- should "know its default attribute, preprocessor and separator" do
38
- assert_equal :slug, DEFAULT_ATTRIBUTE
39
- assert_equal :downcase, DEFAULT_PREPROCESSOR
40
- assert_equal '-', DEFAULT_SEPARATOR
41
- end
42
-
43
- should "not have any has-slug configs by default" do
44
- assert_equal({}, subject.ardb_has_slug_configs)
45
- end
46
-
47
- should "default the has slug config using `has_slug`" do
48
- subject.has_slug :source => @source_attribute
49
- string = Factory.string
50
- record = subject.new.tap{ |r| r.send("#{@source_attribute}=", string) }
51
-
52
- config = subject.ardb_has_slug_configs[DEFAULT_ATTRIBUTE]
53
- assert_equal DEFAULT_SEPARATOR, config[:separator]
54
- assert_false config[:allow_underscores]
55
-
56
- source_proc = config[:source_proc]
57
- assert_instance_of Proc, source_proc
58
- exp = record.send(@source_attribute)
59
- assert_equal exp, record.instance_eval(&source_proc)
60
-
61
- upcase_string = string.upcase
62
- preprocessor_proc = config[:preprocessor_proc]
63
- assert_instance_of Proc, preprocessor_proc
64
- exp = upcase_string.send(DEFAULT_PREPROCESSOR)
65
- assert_equal exp, preprocessor_proc.call(upcase_string)
66
- end
67
-
68
- should "allow customizing the has slug config using `has_slug`" do
69
- separator = NON_WORD_CHARS.sample
70
- allow_underscore = Factory.boolean
71
- subject.has_slug({
72
- :attribute => @slug_attribute,
73
- :source => @source_attribute,
74
- :preprocessor => :upcase,
75
- :separator => separator,
76
- :allow_underscores => allow_underscore
77
- })
78
-
79
- config = subject.ardb_has_slug_configs[@slug_attribute]
80
- assert_equal separator, config[:separator]
81
- assert_equal allow_underscore, config[:allow_underscores]
82
-
83
- value = Factory.string.downcase
84
- preprocessor_proc = config[:preprocessor_proc]
85
- assert_instance_of Proc, preprocessor_proc
86
- assert_equal value.upcase, preprocessor_proc.call(value)
87
- end
88
-
89
- should "add validations using `has_slug`" do
90
- subject.has_slug :source => @source_attribute
91
- exp_attr_name = DEFAULT_ATTRIBUTE
92
-
93
- validation = subject.validations.find{ |v| v.type == :presence }
94
- assert_not_nil validation
95
- assert_equal [exp_attr_name], validation.columns
96
- assert_equal :update, validation.options[:on]
97
-
98
- validation = subject.validations.find{ |v| v.type == :uniqueness }
99
- assert_not_nil validation
100
- assert_equal [exp_attr_name], validation.columns
101
- assert_equal true, validation.options[:case_sensitive]
102
- assert_nil validation.options[:scope]
103
- end
104
-
105
- should "not add a unique validation if skipping unique validation" do
106
- subject.has_slug({
107
- :source => @source_attribute,
108
- :skip_unique_validation => true
109
- })
110
-
111
- validation = subject.validations.find{ |v| v.type == :uniqueness }
112
- assert_nil validation
113
- end
114
-
115
- should "allow customizing its validations using `has_slug`" do
116
- unique_scope = Factory.string.to_sym
117
- subject.has_slug({
118
- :source => @source_attribute,
119
- :unique_scope => unique_scope
120
- })
121
-
122
- validation = subject.validations.find{ |v| v.type == :uniqueness }
123
- assert_not_nil validation
124
- assert_equal unique_scope, validation.options[:scope]
125
- end
126
-
127
- should "add callbacks using `has_slug`" do
128
- subject.has_slug :source => @source_attribute
129
-
130
- callback = subject.callbacks.find{ |v| v.type == :after_create }
131
- assert_not_nil callback
132
- assert_equal [:ardb_has_slug_generate_slugs], callback.args
133
-
134
- callback = subject.callbacks.find{ |v| v.type == :after_update }
135
- assert_not_nil callback
136
- assert_equal [:ardb_has_slug_generate_slugs], callback.args
137
- end
138
-
139
- should "raise an argument error if `has_slug` isn't passed a source" do
140
- assert_raises(ArgumentError){ subject.has_slug }
141
- end
142
-
143
- end
144
-
145
- class InitTests < UnitTests
146
- desc "when init"
147
- setup do
148
- @preprocessor = [:downcase, :upcase, :capitalize].sample
149
- @separator = NON_WORD_CHARS.sample
150
- @allow_underscores = Factory.boolean
151
-
152
- @record_class.has_slug(:source => @source_attribute)
153
- @record_class.has_slug({
154
- :attribute => @slug_attribute,
155
- :source => @source_attribute,
156
- :preprocessor => @preprocessor,
157
- :separator => @separator,
158
- :allow_underscores => @allow_underscores,
159
- })
160
-
161
- @record = @record_class.new
162
-
163
- # create a string that has mixed case and an underscore so we can test
164
- # that it uses the preprocessor and allow underscores options when
165
- # generating a slug
166
- @source_value = "#{Factory.string.downcase}_#{Factory.string.upcase}"
167
- @record.send("#{@source_attribute}=", @source_value)
168
-
169
- @exp_default_slug = Slug.new(@source_value, {
170
- :preprocessor => DEFAULT_PREPROCESSOR.to_proc,
171
- :separator => DEFAULT_SEPARATOR
172
- })
173
- @exp_custom_slug = Slug.new(@source_value, {
174
- :preprocessor => @preprocessor.to_proc,
175
- :separator => @separator,
176
- :allow_underscores => @allow_underscores
177
- })
178
- end
179
- subject{ @record }
180
-
181
- should "reset its slug using `reset_slug`" do
182
- # reset the default attribute
183
- subject.send("#{DEFAULT_ATTRIBUTE}=", Factory.slug)
184
- assert_not_nil subject.send(DEFAULT_ATTRIBUTE)
185
- subject.instance_eval{ reset_slug }
186
- assert_nil subject.send(DEFAULT_ATTRIBUTE)
187
-
188
- # reset a custom attribute
189
- subject.send("#{@slug_attribute}=", Factory.slug)
190
- assert_not_nil subject.send(@slug_attribute)
191
- sa = @slug_attribute
192
- subject.instance_eval{ reset_slug(sa) }
193
- assert_nil subject.send(@slug_attribute)
194
- end
195
-
196
- should "default its slug attribute" do
197
- subject.instance_eval{ ardb_has_slug_generate_slugs }
198
- assert_equal 2, subject.slug_db_column_updates.size
199
-
200
- exp = @exp_default_slug
201
- assert_equal exp, subject.send(DEFAULT_ATTRIBUTE)
202
- assert_includes [DEFAULT_ATTRIBUTE, exp], subject.slug_db_column_updates
203
-
204
- exp = @exp_custom_slug
205
- assert_equal exp, subject.send(@slug_attribute)
206
- assert_includes [@slug_attribute, exp], subject.slug_db_column_updates
207
- end
208
-
209
- should "not set its slug if it hasn't changed" do
210
- @record.send("#{DEFAULT_ATTRIBUTE}=", @exp_default_slug)
211
- @record.send("#{@slug_attribute}=", @exp_custom_slug)
212
-
213
- subject.instance_eval{ ardb_has_slug_generate_slugs }
214
- assert_nil subject.slug_db_column_updates
215
- end
216
-
217
- should "slug its slug attribute value if set" do
218
- @record.send("#{@slug_attribute}=", @source_value)
219
- # change the source attr to some random value, to avoid a false positive
220
- @record.send("#{@source_attribute}=", Factory.string)
221
- subject.instance_eval{ ardb_has_slug_generate_slugs }
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
226
- end
227
-
228
- should "slug its source even if its already a valid slug" do
229
- slug_source = Factory.slug
230
- @record.send("#{@source_attribute}=", slug_source)
231
- # ensure the preprocessor doesn't change our source
232
- Assert.stub(slug_source, @preprocessor){ slug_source }
233
-
234
- subject.instance_eval{ ardb_has_slug_generate_slugs }
235
-
236
- exp = Slug.new(slug_source, {
237
- :preprocessor => @preprocessor.to_proc,
238
- :separator => @separator,
239
- :allow_underscores => @allow_underscores
240
- })
241
- assert_equal exp, subject.send(@slug_attribute)
242
- assert_includes [@slug_attribute, exp], subject.slug_db_column_updates
243
- end
244
-
245
- end
246
-
247
- class SlugTests < UnitTests
248
- desc "Slug"
249
- setup do
250
- @no_op_pp = proc{ |slug| slug }
251
- @args = {
252
- :preprocessor => @no_op_pp,
253
- :separator => '-'
254
- }
255
- end
256
- subject{ Slug }
257
-
258
- should have_imeths :new
259
-
260
- should "always dup the given string" do
261
- string = Factory.string
262
- assert_not_same string, subject.new(string, @args)
263
- end
264
-
265
- should "not change strings that are made up of valid chars" do
266
- string = Factory.string
267
- assert_equal string, subject.new(string, @args)
268
-
269
- string = "#{Factory.string}-#{Factory.string.upcase}"
270
- assert_equal string, subject.new(string, @args)
271
- end
272
-
273
- should "turn invalid chars into a separator" do
274
- string = Factory.integer(3).times.map do
275
- "#{Factory.string(3)}#{NON_WORD_CHARS.sample}#{Factory.string(3)}"
276
- end.join(NON_WORD_CHARS.sample)
277
- assert_equal string.gsub(/[^\w]+/, '-'), subject.new(string, @args)
278
- end
279
-
280
- should "allow passing a custom preprocessor proc" do
281
- string = "#{Factory.string}-#{Factory.string.upcase}"
282
- exp = string.downcase
283
- assert_equal exp, subject.new(string, @args.merge(:preprocessor => :downcase.to_proc))
284
-
285
- preprocessor = proc{ |s| s.gsub(/[A-Z]/, 'a') }
286
- exp = preprocessor.call(string)
287
- assert_equal exp, subject.new(string, @args.merge(:preprocessor => preprocessor))
288
- end
289
-
290
- should "allow passing a custom separator" do
291
- separator = NON_WORD_CHARS.sample
292
-
293
- invalid_char = (NON_WORD_CHARS - [separator]).sample
294
- string = "#{Factory.string}#{invalid_char}#{Factory.string}"
295
- exp = string.gsub(/[^\w]+/, separator)
296
- assert_equal exp, subject.new(string, @args.merge(:separator => separator))
297
-
298
- # it won't change the separator in the strings
299
- string = "#{Factory.string}#{separator}#{Factory.string}"
300
- exp = string
301
- assert_equal string, subject.new(string, @args.merge(:separator => separator))
302
-
303
- # it will change the default separator now
304
- string = "#{Factory.string}-#{Factory.string}"
305
- exp = string.gsub('-', separator)
306
- assert_equal exp, subject.new(string, @args.merge(:separator => separator))
307
- end
308
-
309
- should "change underscores into its separator unless allowed" do
310
- string = "#{Factory.string}_#{Factory.string}"
311
- assert_equal string.gsub('_', '-'), subject.new(string, @args)
312
-
313
- exp = string.gsub('_', '-')
314
- assert_equal exp, subject.new(string, @args.merge(:allow_underscores => false))
315
-
316
- assert_equal string, subject.new(string, @args.merge(:allow_underscores => true))
317
- end
318
-
319
- should "not allow multiple separators in a row" do
320
- string = "#{Factory.string}--#{Factory.string}"
321
- assert_equal string.gsub(/-{2,}/, '-'), subject.new(string, @args)
322
-
323
- # remove separators that were added from changing invalid chars
324
- invalid_chars = (Factory.integer(3) + 1).times.map{ NON_WORD_CHARS.sample }.join
325
- string = "#{Factory.string}#{invalid_chars}#{Factory.string}"
326
- assert_equal string.gsub(/[^\w]+/, '-'), subject.new(string, @args)
327
- end
328
-
329
- should "remove leading and trailing separators" do
330
- string = "-#{Factory.string}-#{Factory.string}-"
331
- assert_equal string[1..-2], subject.new(string, @args)
332
-
333
- # remove separators that were added from changing invalid chars
334
- invalid_char = NON_WORD_CHARS.sample
335
- string = "#{invalid_char}#{Factory.string}-#{Factory.string}#{invalid_char}"
336
- assert_equal string[1..-2], subject.new(string, @args)
337
- end
338
-
339
- end
340
-
341
- end
@@ -1,65 +0,0 @@
1
- require 'assert'
2
- require 'ardb/migration_helpers'
3
-
4
- require 'ardb/adapter_spy'
5
-
6
- module Ardb::MigrationHelpers
7
-
8
- class UnitTests < Assert::Context
9
- desc "Ardb migration helpers"
10
- subject{ Ardb::MigrationHelpers }
11
-
12
- should have_imeths :foreign_key, :drop_foreign_key, :remove_column_with_fk
13
-
14
- end
15
-
16
- class ForeignKeyTests < UnitTests
17
- desc "ForeignKey handler"
18
- setup do
19
- @adapter_spy = nil
20
- Assert.stub(Ardb::Adapter, :new) do |*args|
21
- @adapter_spy = Ardb::AdapterSpy.new(*args)
22
- end
23
-
24
- @fk = ForeignKey.new('fromtbl', 'fromcol', 'totbl')
25
- end
26
- subject{ @fk }
27
-
28
- should have_readers :from_table, :from_column, :to_table, :to_column
29
- should have_readers :name, :adapter
30
- should have_imeths :add_sql, :drop_sql
31
-
32
- should "know its from table/column and to table" do
33
- assert_equal 'fromtbl', subject.from_table
34
- assert_equal 'fromcol', subject.from_column
35
- assert_equal 'totbl', subject.to_table
36
- end
37
-
38
- should "default its to column" do
39
- assert_equal 'id', subject.to_column
40
- end
41
-
42
- should "default its name" do
43
- exp_name = "fk_fromtbl_fromcol"
44
- assert_equal exp_name, subject.name
45
- end
46
-
47
- should "know its adapter" do
48
- assert_not_nil @adapter_spy
49
- assert_equal Ardb.config, @adapter_spy.config
50
- assert_equal @adapter_spy, subject.adapter
51
- end
52
-
53
- should "generate appropriate foreign key sql" do
54
- exp = "FAKE ADD FOREIGN KEY SQL fromtbl fromcol " \
55
- "totbl id fk_fromtbl_fromcol"
56
- assert_equal exp, subject.add_sql
57
-
58
- exp = "FAKE DROP FOREIGN KEY SQL fromtbl fromcol " \
59
- "totbl id fk_fromtbl_fromcol"
60
- assert_equal exp, subject.drop_sql
61
- end
62
-
63
- end
64
-
65
- end
@@ -1,39 +0,0 @@
1
- require 'assert'
2
- require 'ardb/pg_json'
3
-
4
- module Ardb; end
5
- module Ardb::PgJson
6
-
7
- class UnitTests < Assert::Context
8
- desc "Ardb postgresql json shim"
9
- setup do
10
- @connection_adapters = ActiveRecord::ConnectionAdapters
11
- end
12
- subject{ @connection_adapters }
13
-
14
- should "update active record postgres adapter to support json columns" do
15
- adapter_class = subject::PostgreSQLAdapter
16
- exp = { :name => 'json' }
17
- assert_equal exp, adapter_class::NATIVE_DATABASE_TYPES[:json]
18
- exp = { :name => 'jsonb' }
19
- assert_equal exp, adapter_class::NATIVE_DATABASE_TYPES[:jsonb]
20
- end
21
-
22
- should "update active record postgres column to support json columns" do
23
- column_class = subject::PostgreSQLColumn
24
- default = Factory.boolean ? "'{}'::json" : "'{}'::jsonb"
25
- assert_equal '{}', column_class.extract_value_from_default(default)
26
- default = Factory.boolean ? "'[]'::json" : "'[]'::jsonb"
27
- assert_equal '[]', column_class.extract_value_from_default(default)
28
-
29
- column = column_class.new(Factory.string, Factory.string)
30
- assert_equal :json, column.send(:simplified_type, 'json')
31
- assert_equal :jsonb, column.send(:simplified_type, 'jsonb')
32
- end
33
-
34
- # Note: The rest of the postgresql json shim logic is tested in the pg json
35
- # system tests
36
-
37
- end
38
-
39
- end