mini_record 0.4.1 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee891eba3f9e58c760acce562bd83a6595c4b9ef
4
- data.tar.gz: 9aba338c47d2a027e73c4b81347a4f4cf35d0964
3
+ metadata.gz: 09d1ec6c447a806ef8ecc9c33e51c52404ccc948
4
+ data.tar.gz: 23f2145d50bfc6b57bd3517af5312b9ca57d04fa
5
5
  SHA512:
6
- metadata.gz: eee2c19a616f355e653d37be8c7a9a913d001c01af3486cde45ca6ba755d35152b872ed803786efdbe6e79730c679dd053bea90e9c648951b66446e82a0013d9
7
- data.tar.gz: 90e4353472d858b08a3124e8ac56d265cb4d2a0326583c89375f4ed0dd1c3a6f8019ea82a7782e1e0ca151765741ed4afb0ab9442f99eecdc56a8b3d63cd7dc8
6
+ metadata.gz: b0a1daa513f1d05437be824e33672092e79b699848678dbafc9c743904694aa83c079caa20d770862311e39bf6ab82f0b7bcc78af9bb72b33d7aac847e18c2ad
7
+ data.tar.gz: ba06f494683ca8028b95985cc2ee9a7735b25d01d497f5fb6d47f92fc065881b17312f058a0b947777d128e5d091c9a529249f9c094453f422453225d365f28b
data/README.md CHANGED
@@ -25,6 +25,14 @@ Add to your `Gemfile`:
25
25
  gem 'mini_record'
26
26
  ```
27
27
 
28
+ To optionally block any destructive actions on the database, create a file `config/initializers/mini_record.rb` and add:
29
+
30
+ ```ruby
31
+ MiniRecord.configure do |config|
32
+ config.destructive = false
33
+ end
34
+ ```
35
+
28
36
  That's all!
29
37
 
30
38
  ## Examples
@@ -3,7 +3,7 @@ module MiniRecord
3
3
  def self.included(base)
4
4
  base.extend(ClassMethods)
5
5
  end
6
-
6
+
7
7
  module ClassMethods
8
8
  def init_table_definition(connection)
9
9
  #connection.create_table(table_name) unless connection.table_exists?(table_name)
@@ -23,7 +23,7 @@ module MiniRecord
23
23
  "Unsupported number of args for ActiveRecord::ConnectionAdapters::TableDefinition.new()"
24
24
  end
25
25
  end
26
-
26
+
27
27
  def schema_tables
28
28
  @@_schema_tables ||= []
29
29
  end
@@ -158,6 +158,7 @@ module MiniRecord
158
158
  end
159
159
 
160
160
  def clear_tables!
161
+ return unless MiniRecord.configuration.destructive == true
161
162
  (connection.tables - schema_tables).each do |name|
162
163
  connection.drop_table(name)
163
164
  schema_tables.delete(name)
@@ -172,6 +173,7 @@ module MiniRecord
172
173
 
173
174
  # Remove foreign keys for indexes with :foreign=>false option
174
175
  def remove_foreign_keys
176
+ return unless MiniRecord.configuration.destructive == true
175
177
  indexes.each do |name, options|
176
178
  if options[:foreign]==false
177
179
  foreign_key = foreign_keys.detect { |fk| fk.options[:column] == options[:column].to_s }
@@ -260,20 +262,73 @@ module MiniRecord
260
262
  index inheritance_column
261
263
  end
262
264
 
263
- # Rename fields
264
- rename_fields.each do |old_name, new_name|
265
- old_column = fields_in_db[old_name.to_s]
266
- new_column = fields_in_db[new_name.to_s]
267
- if old_column && !new_column
268
- connection.rename_column(table_name, old_column.name, new_name)
265
+ # Group Destructive Actions
266
+ if MiniRecord.configuration.destructive == true
267
+
268
+ # Rename fields
269
+ rename_fields.each do |old_name, new_name|
270
+ old_column = fields_in_db[old_name.to_s]
271
+ new_column = fields_in_db[new_name.to_s]
272
+ if old_column && !new_column
273
+ connection.rename_column(table_name, old_column.name, new_name)
274
+ end
269
275
  end
270
- end
276
+
277
+ # Remove fields from db no longer in schema
278
+ columns_to_delete = fields_in_db.keys - fields.keys & fields_in_db.keys
279
+ columns_to_delete.each do |field|
280
+ column = fields_in_db[field]
281
+ connection.remove_column table_name, column.name
282
+ end
283
+
284
+ # Change attributes of existent columns
285
+ (fields.keys & fields_in_db.keys).each do |field|
286
+ if field != primary_key #ActiveRecord::Base.get_primary_key(table_name)
287
+ changed = false # flag
288
+ new_attr = {}
289
+
290
+ # Special catch for precision/scale, since *both* must be specified together
291
+ # Always include them in the attr struct, but they'll only get applied if changed = true
292
+ new_attr[:precision] = fields[field][:precision]
293
+ new_attr[:scale] = fields[field][:scale]
294
+
295
+ # If we have precision this is also the limit
296
+ fields[field][:limit] ||= fields[field][:precision]
297
+
298
+ # Next, iterate through our extended attributes, looking for any differences
299
+ # This catches stuff like :null, :precision, etc
300
+ # Ignore junk attributes that different versions of Rails include
301
+ [:name, :limit, :precision, :scale, :default, :null].each do |att|
302
+ value = fields[field][att]
303
+ value = true if att == :null && value.nil?
304
+
305
+ # Skip unspecified limit/precision/scale as DB will set them to defaults,
306
+ # and on subsequent runs, this will be erroneously detected as a change.
307
+ next if value.nil? and [:limit, :precision, :scale].include?(att)
308
+
309
+ old_value = fields_in_db[field].send(att)
310
+ if value != old_value
311
+ logger.debug "[MiniRecord] Detected schema change for #{table_name}.#{field}##{att} " +
312
+ "from #{old_value.inspect} to #{value.inspect}" if logger
313
+ new_attr[att] = value
314
+ changed = true
315
+ end
316
+ end
317
+
318
+ # Change the column if applicable
319
+ new_type = fields[field].type.to_sym
320
+ connection.change_column table_name, field, new_type, new_attr if changed
321
+ end
322
+ end
323
+
324
+ remove_foreign_keys if connection.respond_to?(:foreign_keys)
271
325
 
272
- # Remove fields from db no longer in schema
273
- columns_to_delete = fields_in_db.keys - fields.keys & fields_in_db.keys
274
- columns_to_delete.each do |field|
275
- column = fields_in_db[field]
276
- connection.remove_column table_name, column.name
326
+ # Remove old index
327
+ index_names = indexes.collect{|name,opts| opts[:name] || name }
328
+ (indexes_in_db.keys - index_names).each do |name|
329
+ connection.remove_index(table_name, :name => name)
330
+ end
331
+
277
332
  end
278
333
 
279
334
  # Add fields to db new to schema
@@ -286,54 +341,6 @@ module MiniRecord
286
341
  connection.add_column table_name, column.name, column.type.to_sym, options
287
342
  end
288
343
 
289
- # Change attributes of existent columns
290
- (fields.keys & fields_in_db.keys).each do |field|
291
- if field != primary_key #ActiveRecord::Base.get_primary_key(table_name)
292
- changed = false # flag
293
- new_attr = {}
294
-
295
- # Special catch for precision/scale, since *both* must be specified together
296
- # Always include them in the attr struct, but they'll only get applied if changed = true
297
- new_attr[:precision] = fields[field][:precision]
298
- new_attr[:scale] = fields[field][:scale]
299
-
300
- # If we have precision this is also the limit
301
- fields[field][:limit] ||= fields[field][:precision]
302
-
303
- # Next, iterate through our extended attributes, looking for any differences
304
- # This catches stuff like :null, :precision, etc
305
- # Ignore junk attributes that different versions of Rails include
306
- [:name, :limit, :precision, :scale, :default, :null].each do |att|
307
- value = fields[field][att]
308
- value = true if att == :null && value.nil?
309
-
310
- # Skip unspecified limit/precision/scale as DB will set them to defaults,
311
- # and on subsequent runs, this will be erroneously detected as a change.
312
- next if value.nil? and [:limit, :precision, :scale].include?(att)
313
-
314
- old_value = fields_in_db[field].send(att)
315
- if value != old_value
316
- logger.debug "[MiniRecord] Detected schema change for #{table_name}.#{field}##{att} " +
317
- "from #{old_value.inspect} to #{value.inspect}" if logger
318
- new_attr[att] = value
319
- changed = true
320
- end
321
- end
322
-
323
- # Change the column if applicable
324
- new_type = fields[field].type.to_sym
325
- connection.change_column table_name, field, new_type, new_attr if changed
326
- end
327
- end
328
-
329
- remove_foreign_keys if connection.respond_to?(:foreign_keys)
330
-
331
- # Remove old index
332
- index_names = indexes.collect{|name,opts| opts[:name] || name }
333
- (indexes_in_db.keys - index_names).each do |name|
334
- connection.remove_index(table_name, :name => name)
335
- end
336
-
337
344
  # Add indexes
338
345
  indexes.each do |name, options|
339
346
  options = options.dup
@@ -0,0 +1,22 @@
1
+ module MiniRecord
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ def self.configure
7
+ self.configuration ||= Configuration.new
8
+ yield(configuration)
9
+ end
10
+
11
+ def self.reset_configuration!
12
+ self.configuration = Configuration.new
13
+ end
14
+
15
+ class Configuration
16
+ attr_accessor :destructive
17
+
18
+ def initialize
19
+ @destructive = true
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module MiniRecord
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
data/lib/mini_record.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  require 'rubygems' unless defined?(Gem)
2
2
  require 'active_record'
3
+ require 'mini_record/configuration'
3
4
  require 'mini_record/auto_schema'
4
5
 
6
+ MiniRecord.configure do |config|
7
+ end
5
8
  ActiveRecord::Base.send(:include, MiniRecord::AutoSchema)
@@ -11,6 +11,7 @@ describe MiniRecord do
11
11
  ActiveSupport::DescendantsTracker.direct_descendants(ActiveRecord::Base).clear
12
12
  load File.expand_path('../models.rb', __FILE__)
13
13
  ActiveRecord::Base.auto_upgrade!
14
+ MiniRecord.reset_configuration!
14
15
  end
15
16
 
16
17
  it 'has #schema inside model' do
@@ -264,6 +265,31 @@ describe MiniRecord do
264
265
  refute_includes Foo.db_columns, 'image_id'
265
266
  assert_empty Foo.db_indexes
266
267
  end
268
+
269
+ it 'doesnt remove a column and index when relation is removed and destructive is false' do
270
+ MiniRecord.configuration.destructive = false
271
+ class Foo < ActiveRecord::Base
272
+ key :name
273
+ belongs_to :image, :polymorphic => true
274
+ end
275
+ Foo.auto_upgrade!
276
+ assert_includes Foo.db_columns, 'name'
277
+ assert_includes Foo.db_columns, 'image_type'
278
+ assert_includes Foo.db_columns, 'image_id'
279
+ assert_includes Foo.db_indexes, 'index_foos_on_image_id_and_image_type'
280
+
281
+ Foo.class_eval do
282
+ reset_table_definition!
283
+ reflections.clear
284
+ indexes.clear
285
+ key :name
286
+ end
287
+ Foo.auto_upgrade!
288
+ assert_includes Foo.db_columns, 'name'
289
+ assert_includes Foo.db_columns, 'image_type'
290
+ assert_includes Foo.db_columns, 'image_id'
291
+ assert_includes Foo.db_indexes, 'index_foos_on_image_id_and_image_type'
292
+ end
267
293
 
268
294
  it 'creates columns and index based on polymorphic relation' do
269
295
  Attachment.create(:name => 'Avatar', :attachable_id => 1, :attachable_type => 'Post')
@@ -363,6 +389,32 @@ describe MiniRecord do
363
389
 
364
390
  assert_nil connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'publisher_id'}
365
391
  end
392
+
393
+ it 'doesnt remove foreign key with :foreign option, when Foreigner gem used on mysql and destructive = false' do
394
+ MiniRecord.configuration.destructive = false
395
+ skip unless conn.adapter_name =~ /mysql/i
396
+
397
+ class Book < ActiveRecord::Base
398
+ belongs_to :publisher
399
+ index :publisher_id, :foreign => true
400
+ end
401
+ Book.auto_upgrade!
402
+
403
+ assert_includes Book.db_columns, 'publisher_id'
404
+ assert_includes Book.db_indexes, 'index_books_on_publisher_id'
405
+
406
+ assert connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'publisher_id'}
407
+
408
+ Object.send(:remove_const, :Book)
409
+ class Book < ActiveRecord::Base
410
+ belongs_to :publisher
411
+ index :publisher_id, :foreign => false
412
+ end
413
+ Book.auto_upgrade!
414
+
415
+ assert_includes Book.db_columns, 'publisher_id'
416
+ assert_includes Book.db_indexes, 'index_books_on_publisher_id'
417
+ end
366
418
 
367
419
  it 'add/remove named foreign key with :foreign option, when Foreigner gem used on mysql' do
368
420
  skip unless conn.adapter_name =~ /mysql/i
@@ -388,6 +440,33 @@ describe MiniRecord do
388
440
  assert_nil connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'publisher_id'}
389
441
  Object.send(:remove_const, :Book)
390
442
  end
443
+
444
+ it 'doesnt remove named foreign key with :foreign option, when Foreigner gem used on mysql and destructive = false' do
445
+ MiniRecord.configuration.destructive = false
446
+ skip unless conn.adapter_name =~ /mysql/i
447
+
448
+ class Book < ActiveRecord::Base
449
+ belongs_to :publisher
450
+ index :publisher_id, :name => 'my_super_publisher_id_fk', :foreign => true
451
+ end
452
+ Book.auto_upgrade!
453
+
454
+ assert_includes Book.db_columns, 'publisher_id'
455
+ assert_includes Book.db_indexes, 'my_super_publisher_id_fk'
456
+
457
+ assert connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'publisher_id'}
458
+
459
+ Object.send(:remove_const, :Book)
460
+ class Book < ActiveRecord::Base
461
+ belongs_to :publisher
462
+ index :publisher_id, :name => 'my_super_publisher_id_fk', :foreign => false
463
+ end
464
+ Book.auto_upgrade!
465
+
466
+ assert_includes Book.db_columns, 'publisher_id'
467
+ assert_includes Book.db_indexes, 'my_super_publisher_id_fk'
468
+ Object.send(:remove_const, :Book)
469
+ end
391
470
 
392
471
  it 'support :foreign option in the index with custom :foreign_key in the belong_to association' do
393
472
  skip unless conn.adapter_name =~ /mysql/i
@@ -412,6 +491,32 @@ describe MiniRecord do
412
491
 
413
492
  assert_nil connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'second_publisher_id'}
414
493
  end
494
+
495
+ it 'support :foreign option in the index with custom :foreign_key in the belong_to association and wont remove if destructive = false' do
496
+ MiniRecord.configuration.destructive = false
497
+ skip unless conn.adapter_name =~ /mysql/i
498
+
499
+ class Book < ActiveRecord::Base
500
+ belongs_to :second_publisher, :foreign_key => 'second_publisher_id', :class_name => 'Publisher'
501
+ index :second_publisher_id, :foreign => true
502
+ end
503
+ Book.auto_upgrade!
504
+
505
+ assert_includes Book.db_columns, 'second_publisher_id'
506
+ assert_includes Book.db_indexes, 'index_books_on_second_publisher_id'
507
+
508
+ assert connection.foreign_keys(:books).detect {|fk| fk.options[:column] == 'second_publisher_id'}
509
+
510
+ Object.send(:remove_const, :Book)
511
+ class Book < ActiveRecord::Base
512
+ belongs_to :second_publisher, :foreign_key => 'second_publisher_id', :class_name => 'Publisher'
513
+ index :second_publisher_id, :foreign => false
514
+ end
515
+ Book.auto_upgrade!
516
+
517
+ assert_includes Book.db_columns, 'second_publisher_id'
518
+ assert_includes Book.db_indexes, 'index_books_on_second_publisher_id'
519
+ end
415
520
 
416
521
  end
417
522
 
@@ -436,6 +541,19 @@ describe MiniRecord do
436
541
  ActiveRecord::Base.clear_tables!
437
542
  refute_includes Tool.connection.tables, 'purposes_tools'
438
543
  end
544
+
545
+ it 'keeps join table if has_and_belongs_to_many relation is deleted and destructive = false' do
546
+ MiniRecord.configuration.destructive = false
547
+
548
+ tables = Tool.connection.tables
549
+ assert_includes tables, 'purposes_tools'
550
+
551
+ Tool.schema_tables.delete('purposes_tools')
552
+ refute_includes ActiveRecord::Base.schema_tables, 'purposes_tools'
553
+
554
+ ActiveRecord::Base.clear_tables!
555
+ assert_includes Tool.connection.tables, 'purposes_tools'
556
+ end
439
557
 
440
558
  it 'has_and_belongs_to_many with custom join_table and foreign keys' do
441
559
  class Foo < ActiveRecord::Base
@@ -534,6 +652,47 @@ describe MiniRecord do
534
652
  refute_empty Foo.queries
535
653
  assert_equal 255, Foo.db_fields[:string].limit
536
654
  end
655
+
656
+ it 'should not change #limit if destructive = false' do
657
+ MiniRecord.configuration.destructive = false
658
+ class Foo < ActiveRecord::Base
659
+ key :number, :as => :integer
660
+ key :string, :limit => 100
661
+ end
662
+ Foo.auto_upgrade!
663
+ assert_match /CREATE TABLE/, Foo.queries
664
+
665
+ Foo.auto_upgrade!
666
+ refute_match /alter/i, Foo.queries
667
+
668
+ # According to this:
669
+ # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb#L476-487
670
+ Foo.key :number, :as => :integer, :limit => 4
671
+ Foo.auto_upgrade!
672
+ case conn.adapter_name
673
+ when /sqlite/i
674
+ # In sqlite there is a difference between limit: 4 and limit: 11
675
+ assert_match Foo.queries, ""
676
+ assert_equal nil, Foo.db_fields[:number].limit
677
+ assert_equal 4, Foo.schema_fields[:number].limit
678
+ when /mysql/i
679
+ # In mysql according to this: http://goo.gl/bjZE7 limit: 4 is same of limit:11
680
+ assert_empty Foo.queries
681
+ assert_equal nil, Foo.db_fields[:number].limit
682
+ assert_equal 4, Foo.schema_fields[:number].limit
683
+ when /postgres/i
684
+ # In postgres limit: 4 will be translated to nil
685
+ assert_match Foo.queries, ""
686
+ assert_equal nil, Foo.db_fields[:number].limit
687
+ assert_equal 4, Foo.schema_fields[:number].limit
688
+ end
689
+
690
+ # Change limit to string
691
+ Foo.key :string, :limit => 255
692
+ Foo.auto_upgrade!
693
+ assert_empty Foo.queries
694
+ assert_equal 100, Foo.db_fields[:string].limit
695
+ end
537
696
 
538
697
  it 'should change #null' do
539
698
  class Foo < ActiveRecord::Base
@@ -558,6 +717,31 @@ describe MiniRecord do
558
717
  assert_match /alter/i, Foo.queries
559
718
  refute Foo.db_fields[:string].null
560
719
  end
720
+
721
+ it 'should not change #null if destructive = false' do
722
+ MiniRecord.configuration.destructive = false
723
+ class Foo < ActiveRecord::Base
724
+ key :string
725
+ end
726
+ Foo.auto_upgrade!
727
+ assert Foo.db_fields[:string].null
728
+
729
+ # Same as above
730
+ Foo.key :string, :null => true
731
+ Foo.auto_upgrade!
732
+ refute_match /alter/i, Foo.queries
733
+ assert Foo.db_fields[:string].null
734
+
735
+ Foo.key :string, :null => nil
736
+ Foo.auto_upgrade!
737
+ refute_match /alter/i, Foo.queries
738
+ assert Foo.db_fields[:string].null
739
+
740
+ Foo.key :string, :null => false
741
+ Foo.auto_upgrade!
742
+ assert_match "", Foo.queries
743
+ assert Foo.db_fields[:string].null
744
+ end
561
745
 
562
746
  it 'should change #scale #precision' do
563
747
  class Foo < ActiveRecord::Base
@@ -578,6 +762,27 @@ describe MiniRecord do
578
762
  assert_equal 2, Foo.db_fields[:currency].scale
579
763
  assert_equal 4, Foo.db_fields[:currency].limit
580
764
  end
765
+
766
+ it 'should not change #scale #precision if destructive = false' do
767
+ MiniRecord.configuration.destructive = false
768
+ class Foo < ActiveRecord::Base
769
+ field :currency, :as => :decimal, :precision => 8, :scale => 2
770
+ end
771
+ Foo.auto_upgrade!
772
+ assert_equal 8, Foo.db_fields[:currency].precision
773
+ assert_equal 2, Foo.db_fields[:currency].scale
774
+ assert_equal 8, Foo.db_fields[:currency].limit
775
+
776
+ Foo.auto_upgrade!
777
+ refute_match /alter/i, Foo.queries
778
+
779
+ Foo.field :currency, :as => :decimal, :precision => 4, :scale => 2, :limit => 5
780
+ Foo.auto_upgrade!
781
+ assert_match "", Foo.queries
782
+ assert_equal 8, Foo.db_fields[:currency].precision
783
+ assert_equal 2, Foo.db_fields[:currency].scale
784
+ assert_equal 8, Foo.db_fields[:currency].limit
785
+ end
581
786
 
582
787
  it 'should ignore abstract classes' do
583
788
  class Foo < ActiveRecord::Base
@@ -649,4 +854,37 @@ describe MiniRecord do
649
854
  assert_match '', Foo.queries
650
855
 
651
856
  end
857
+
858
+ it 'should note rename a column specified by rename_field if destructive = false' do
859
+ MiniRecord.configuration.destructive = false
860
+ class Foo < ActiveRecord::Base
861
+ field :currency, :limit => 3
862
+ end
863
+ Foo.auto_upgrade!
864
+ assert_match /CREATE TABLE/, Foo.queries
865
+
866
+ Foo.create :currency => 'USD'
867
+
868
+ Foo.rename_field :currency, :new_name => :currency_iso
869
+ Foo.field :currency_iso, :limit => 3
870
+
871
+ Foo.auto_upgrade!
872
+
873
+ case conn.adapter_name
874
+ when /sqlite/i
875
+ assert_match "", Foo.queries
876
+ when /mysql/i
877
+ assert_match "", Foo.queries
878
+ when /postgres/i
879
+ assert_match "", Foo.queries
880
+ end
881
+
882
+ cols = conn.columns('foos').map(&:name)
883
+ assert_includes cols, "currency_iso"
884
+ assert_includes cols, "currency"
885
+
886
+ Foo.auto_upgrade!
887
+ assert_match '', Foo.queries
888
+
889
+ end
652
890
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davide D'Agostino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-18 00:00:00.000000000 Z
11
+ date: 2014-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -40,6 +40,7 @@ files:
40
40
  - Rakefile
41
41
  - lib/mini_record.rb
42
42
  - lib/mini_record/auto_schema.rb
43
+ - lib/mini_record/configuration.rb
43
44
  - lib/mini_record/version.rb
44
45
  - mini_record.gemspec
45
46
  - test/helper.rb