ardb 0.28.3 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
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