maglevrecord 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +0 -1
  3. data/README.md +22 -7
  4. data/Rakefile +2 -2
  5. data/install.sh +0 -1
  6. data/lib/maglev_record/base.rb +10 -1
  7. data/lib/maglev_record/enumerable.rb +6 -1
  8. data/lib/maglev_record/errors.rb +3 -0
  9. data/lib/maglev_record/maglev_record.rb +1 -1
  10. data/lib/maglev_record/maglev_support/concern.rb +2 -3
  11. data/lib/maglev_record/maglev_support/secure_password.rb +2 -3
  12. data/lib/maglev_record/migration/loader.rb +1 -1
  13. data/lib/maglev_record/migration/migration.rb +14 -0
  14. data/lib/maglev_record/migration/migrator.rb +22 -4
  15. data/lib/maglev_record/migration/operations.rb +58 -0
  16. data/lib/maglev_record/persistence.rb +12 -5
  17. data/lib/maglev_record/read_write.rb +38 -7
  18. data/lib/maglev_record/rooted_enumerable.rb +6 -1
  19. data/lib/maglev_record/rooted_persistence.rb +4 -0
  20. data/lib/maglev_record/sensible.rb +2 -2
  21. data/lib/maglev_record/snapshot/change.rb +54 -15
  22. data/lib/maglev_record/snapshot/class_change.rb +66 -0
  23. data/lib/maglev_record/snapshot/class_snapshot.rb +63 -0
  24. data/lib/maglev_record/snapshot/snapshot.rb +44 -38
  25. data/lib/maglev_record/snapshot/snapshotable.rb +81 -26
  26. data/lib/maglev_record/snapshot/superclass_mismatch_change.rb +143 -0
  27. data/lib/maglev_record/snapshot.rb +3 -2
  28. data/lib/maglev_record/validations.rb +49 -0
  29. data/lib/maglev_record.rb +3 -2
  30. data/lib/tasks/database.rake +61 -17
  31. data/test/automigration/rake_task_base.rb +57 -0
  32. data/test/automigration/test_auto.slow.rb +38 -0
  33. data/test/automigration/test_migration_string.rb +173 -0
  34. data/test/automigration/test_rake_task_preconditions.slow.rb +41 -0
  35. data/test/automigration/test_show.slow.rb +21 -0
  36. data/test/automigration/test_superclass_mismatch.rb +96 -0
  37. data/test/example_model.rb +7 -5
  38. data/test/migration/base_lectures.rb +30 -0
  39. data/test/migration/operation_setup.rb +66 -56
  40. data/test/migration/projects/automigration/.gitignore +15 -0
  41. data/test/migration/projects/automigration/Gemfile +44 -0
  42. data/test/migration/projects/automigration/Gemfile.lock +115 -0
  43. data/test/migration/projects/automigration/README.rdoc +261 -0
  44. data/test/migration/projects/automigration/Rakefile +17 -0
  45. data/test/migration/projects/automigration/app/assets/images/rails.png +0 -0
  46. data/test/migration/projects/automigration/app/assets/javascripts/application.js +15 -0
  47. data/test/migration/projects/automigration/app/assets/stylesheets/application.css +13 -0
  48. data/test/migration/projects/automigration/app/controllers/application_controller.rb +3 -0
  49. data/test/migration/projects/automigration/app/helpers/application_helper.rb +2 -0
  50. data/test/migration/projects/automigration/app/mailers/.gitkeep +0 -0
  51. data/test/migration/projects/automigration/app/models/.gitkeep +0 -0
  52. data/test/migration/projects/automigration/app/models/project_model.rb +8 -0
  53. data/test/migration/projects/automigration/app/views/layouts/application.html.erb +14 -0
  54. data/test/migration/projects/automigration/config/application.rb +62 -0
  55. data/test/migration/projects/automigration/config/boot.rb +6 -0
  56. data/test/migration/projects/automigration/config/database.yml +25 -0
  57. data/test/migration/projects/automigration/config/environment.rb +5 -0
  58. data/test/migration/projects/automigration/config/environments/development.rb +37 -0
  59. data/test/migration/projects/automigration/config/environments/production.rb +67 -0
  60. data/test/migration/projects/automigration/config/initializers/backtrace_silencers.rb +7 -0
  61. data/test/migration/projects/automigration/config/initializers/inflections.rb +15 -0
  62. data/test/migration/projects/automigration/config/initializers/mime_types.rb +5 -0
  63. data/test/migration/projects/automigration/config/initializers/secret_token.rb +7 -0
  64. data/test/migration/projects/automigration/config/initializers/session_store.rb +8 -0
  65. data/test/migration/projects/automigration/config/initializers/wrap_parameters.rb +14 -0
  66. data/test/migration/projects/automigration/config/locales/en.yml +5 -0
  67. data/test/migration/projects/automigration/config/routes.rb +58 -0
  68. data/test/migration/projects/automigration/config.ru +4 -0
  69. data/test/migration/projects/automigration/db/seeds.rb +7 -0
  70. data/test/migration/projects/automigration/lib/assets/.gitkeep +0 -0
  71. data/test/migration/projects/automigration/lib/tasks/.gitkeep +0 -0
  72. data/test/migration/projects/automigration/log/.gitkeep +0 -0
  73. data/test/migration/projects/automigration/public/404.html +26 -0
  74. data/test/migration/projects/automigration/public/422.html +26 -0
  75. data/test/migration/projects/automigration/public/500.html +25 -0
  76. data/test/migration/projects/automigration/public/favicon.ico +0 -0
  77. data/test/migration/projects/automigration/public/index.html +241 -0
  78. data/test/migration/projects/automigration/public/robots.txt +5 -0
  79. data/test/migration/projects/automigration/script/rails +6 -0
  80. data/test/migration/projects/project2/Rakefile +2 -2
  81. data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.38.rb +1 -1
  82. data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.52.rb +1 -1
  83. data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.32.07.rb +1 -1
  84. data/test/migration/test_change_superclass.rb +111 -0
  85. data/test/migration/test_loader.rb +6 -0
  86. data/test/migration/test_project.rb +1 -29
  87. data/test/migration/test_project1.slow.rb +1 -0
  88. data/test/migration/test_project2.slow.rb +7 -0
  89. data/test/migration/test_remove.rb +123 -2
  90. data/test/migration/todo.txt +1 -1
  91. data/test/more_asserts.rb +1 -1
  92. data/test/snapshot/test_attributes.rb +33 -0
  93. data/test/snapshot/{test_snapshot_attributes.slow.rb → test_attributes.slow.rb} +3 -5
  94. data/test/snapshot/test_classes.rb +32 -0
  95. data/test/snapshot/{test_snapshot_classes.slow.rb → test_classes.slow.rb} +1 -1
  96. data/test/snapshot/test_from_file_system.rb +113 -0
  97. data/test/snapshot/test_methods.rb +136 -0
  98. data/test/snapshot/test_methods.slow.rb +67 -0
  99. data/test/snapshot/test_reset.rb +68 -0
  100. data/test/snapshot/test_snapshot.rb +41 -75
  101. data/test/snapshot/test_snapshot.slow.rb +98 -0
  102. data/test/snapshot/test_snapshotable.rb +0 -1
  103. data/test/temp_dir_test.rb +40 -0
  104. data/test/test_active_model_like_interface.rb +4 -1
  105. data/test/test_model_timestamps.rb +13 -5
  106. data/test/test_query_interface.rb +10 -0
  107. data/test/test_sensibles.rb +18 -10
  108. data/test/test_validation.rb +2 -12
  109. metadata +64 -5
@@ -0,0 +1,111 @@
1
+ require "migration/operation_setup"
2
+
3
+ class ChangeSuperclassTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ setup_migration_operations
7
+ cls.fill_with_examples
8
+ @example = cls.first
9
+ assert_not_equal Lecture2, cls.superclass
10
+ assert_equal Lecture, cls.superclass
11
+ cls.change_superclass_to Lecture2
12
+ end
13
+
14
+ def cls
15
+ Lecture3
16
+ end
17
+
18
+ def teardown
19
+ teardown_migration_operations
20
+ end
21
+
22
+ def test_superclass_has_changed
23
+ assert_equal Lecture2, cls.superclass
24
+ end
25
+
26
+ def test_objects_are_still_of_that_class
27
+ assert_equal @example.class, cls
28
+ end
29
+
30
+ def test_example_is_of_own_class
31
+ Object.module_eval "
32
+ class Lecture3
33
+ def lecture3
34
+ true
35
+ end
36
+ end"
37
+ assert @example.lecture2
38
+ assert @example.lecture3
39
+ end
40
+
41
+ def test_example_is_still_in_all
42
+ assert_include? Lecture3.all, @example
43
+ end
44
+
45
+ end
46
+
47
+ class MigrationChangesSuperclassTest < Test::Unit::TestCase
48
+
49
+ def setup
50
+ setup_migration_operations
51
+ end
52
+
53
+ def teardown
54
+ teardown_migration_operations
55
+ end
56
+
57
+ def test_migrating_superclass_change
58
+ assert_not_equal Lecture2, Lecture3.superclass
59
+ assert_not_equal Object, Lecture3.superclass
60
+ MaglevRecord::Migration.new(Time.now, "change_superclass") do
61
+ def up
62
+ Lecture3.change_superclass_to Lecture2
63
+ end
64
+ end.do
65
+ assert_equal Lecture3.superclass, Lecture2
66
+ end
67
+
68
+ def test_superclass_does_not_exist
69
+ original_superclass = Lecture3.superclass
70
+ assert_raises(NameError){ SuperclassThatDoesNotExist }
71
+ MaglevRecord::Migration.new(Time.now, "change_superclass") do
72
+ def up
73
+ Lecture3.change_superclass_to SuperclassThatDoesNotExist
74
+ end
75
+ end.do
76
+ assert_equal original_superclass, Lecture3.superclass
77
+ end
78
+
79
+ def test_class_does_not_exist
80
+ assert_raises(NameError){ ClassThatDoesNotExist }
81
+ MaglevRecord::Migration.new(Time.now, "change_superclass") do
82
+ def up
83
+ ClassThatDoesNotExist.change_superclass_to Lecture3
84
+ end
85
+ end.do
86
+ assert_raises(NameError){ ClassThatDoesNotExist }
87
+ end
88
+
89
+ def test_both_classes_do_not_exist
90
+ MaglevRecord::Migration.new(Time.now, "change_superclass") do
91
+ def up
92
+ ClassThatDoesNotExist.change_superclass_to SuperclassThatDoesNotExist
93
+ end
94
+ end.do
95
+ assert_raises(NameError){ ClassThatDoesNotExist }
96
+ assert_raises(NameError){ SuperclassThatDoesNotExist }
97
+
98
+ end
99
+ end
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
@@ -64,6 +64,12 @@ MIGRATION2
64
64
  assert_equal 2014, @loader.migration_list.last.timestamp.year
65
65
  end
66
66
 
67
+ def test_an_error_is_thrown_if_no_migration_is_read
68
+ assert_raise(MaglevRecord::NoMigrationReadError) {
69
+ @loader.load_string "1 + 2"
70
+ }
71
+ end
72
+
67
73
  def test_load_from_file
68
74
  @loader.load_file(migration_folder + 'migration_1.rb')
69
75
  assert @loader.migration_list.any? { |m| m.name == "Change book title" }
@@ -1,37 +1,9 @@
1
1
  require "more_asserts"
2
2
  require "fileutils"
3
- require "tmpdir"
3
+ require "temp_dir_test"
4
4
 
5
5
  THIS_DIRECTORY = File.expand_path(File.dirname(__FILE__))
6
6
 
7
- #
8
- # this test creates a temporary directory for the test
9
- #
10
-
11
- class TempDirTest < Test::Unit::TestCase
12
- def setup
13
- # make temporary directory
14
- # see http://ruby-doc.org/stdlib-2.0/libdoc/tmpdir/rdoc/Dir.html#method-c-mktmpdir
15
- @tempdir = Dir.mktmpdir
16
- end
17
-
18
- def teardown
19
- # remove the directory.
20
- FileUtils.remove_dir tempdir
21
- end
22
-
23
- def tempdir
24
- @tempdir
25
- end
26
-
27
- # test the project configuration
28
-
29
- def test_tempdir_exists
30
- assert File.directory?(tempdir)
31
- end
32
-
33
- end
34
-
35
7
  class ProjectTest < TempDirTest
36
8
  attr_reader :maglev_record_raketask_wd
37
9
 
@@ -12,6 +12,7 @@ class MigrationTestProject1 < ProjectTest
12
12
  def test_tasks_are_listed
13
13
  output = rake("-T")
14
14
  assert_include? output, 'rake migrate:new'
15
+ assert_include? output, 'rake migrate:auto'
15
16
  assert_include? output, 'rake migrate:up'
16
17
  end
17
18
 
@@ -3,6 +3,7 @@ require "migration/test_project"
3
3
  class MigrationProject2 < ProjectTest
4
4
 
5
5
  def setup
6
+ Maglev.abort_transaction
6
7
  @project_name = 'project2'
7
8
  super
8
9
  Maglev.persistent do
@@ -15,6 +16,7 @@ class MigrationProject2 < ProjectTest
15
16
  def teardown
16
17
  super
17
18
  puts @s unless @s.nil?
19
+ Maglev.abort_transaction
18
20
  end
19
21
 
20
22
  def test_no_models
@@ -31,4 +33,9 @@ class MigrationProject2 < ProjectTest
31
33
  @s = nil
32
34
  end
33
35
 
36
+ #def test_add_more_migrations_that_will_be_tested
37
+ # # maybe we are also in the need to autoload the model files?
38
+ # #fail('todo') # TODO
39
+ #end
40
+
34
41
  end
@@ -8,8 +8,11 @@
8
8
  #
9
9
  # - classes
10
10
  #
11
+ # - instance methods
12
+ #
13
+ # - class methods
14
+ #
11
15
 
12
- require "maglev_record"
13
16
  require "migration/operation_setup"
14
17
  require "more_asserts"
15
18
  require 'time'
@@ -213,7 +216,125 @@ class TestMigrationRemoveClass < Test::Unit::TestCase
213
216
  Models::M1::Lecture
214
217
  }
215
218
  end
219
+ end
220
+
221
+ ################## remove instance methods
216
222
 
217
-
223
+ class TestMigrationRemoveInstanceMethod < Test::Unit::TestCase
224
+
225
+ def setup
226
+ setup_migration_operations
227
+ Lecture.define_method :instance_method_to_remove do 2 end
228
+ Lecture.fill_with_examples
229
+ Lecture3.fill_with_examples
230
+ end
231
+
232
+ def test_Lecture_has_instance_method
233
+ assert_equal 2, Lecture.first.instance_method_to_remove
234
+ assert_equal 2, Lecture3.first.instance_method_to_remove
235
+ end
236
+
237
+ def teardown
238
+ super
239
+ teardown_migration_operations
240
+ end
241
+
242
+ def test_migration_removes_instance_method
243
+ MaglevRecord::Migration.new(Time.now, "remove instance method") do
244
+ def up
245
+ Lecture.remove_instance_method :instance_method_to_remove
246
+ end
247
+ end.do
248
+ assert_raises(NoMethodError){
249
+ Lecture.first.instance_method_to_remove
250
+ }
251
+ assert_raises(NoMethodError){
252
+ Lecture3.first.instance_method_to_remove
253
+ }
254
+ end
255
+
256
+ def test_migration_removes_nonexistent_instance_method
257
+ MaglevRecord::Migration.new(Time.now, "remove instance method") do
258
+ def up
259
+ Lecture.remove_instance_method :instance_method_to_remove2
260
+ end
261
+ end.do
262
+ assert_equal 2, Lecture.first.instance_method_to_remove
263
+ end
264
+
265
+ def test_remove_instance_method_of_nonexistent_class
266
+ MaglevRecord::Migration.new(Time.now, "remove instance method") do
267
+ def up
268
+ AbsentLectureClass.remove_instance_method :method_not_here
269
+ end
270
+ end.do
271
+ assert_equal 2, Lecture.first.instance_method_to_remove
272
+ end
273
+
274
+ def test_remove_instance_method_of_subclass_does_not_influence_superclass
275
+ MaglevRecord::Migration.new(Time.now, "remove instance method") do
276
+ def up
277
+ Lecture3.remove_instance_method :instance_method_to_remove
278
+ end
279
+ end.do
280
+ assert_equal 2, Lecture.first.instance_method_to_remove
281
+ assert_equal 2, Lecture3.first.instance_method_to_remove
282
+ end
218
283
  end
219
284
 
285
+ ################## remove class methods
286
+
287
+ class TestMigrationRemoveClassMethod < Test::Unit::TestCase
288
+
289
+ def setup
290
+ setup_migration_operations
291
+ def Lecture.class_method_to_remove;1;end
292
+ end
293
+
294
+ def teardown
295
+ super
296
+ teardown_migration_operations
297
+ end
298
+
299
+ def test_Lecture_has_class_method
300
+ assert_equal 1, Lecture.class_method_to_remove
301
+ end
302
+
303
+ def test_migration_removes_class_method
304
+ MaglevRecord::Migration.new(Time.now, "remove class method") do
305
+ def up
306
+ Lecture.remove_class_method :class_method_to_remove
307
+ end
308
+ end.do
309
+ assert_raises(NoMethodError){
310
+ Lecture.class_method_to_remove
311
+ }
312
+ end
313
+
314
+ def test_migration_removes_nonexistent_class_method
315
+ MaglevRecord::Migration.new(Time.now, "remove class method") do
316
+ def up
317
+ Lecture.remove_class_method :class_method_to_remove2
318
+ end
319
+ end.do
320
+ assert_equal 1, Lecture.class_method_to_remove
321
+ end
322
+
323
+ def test_remove_instance_method_of_nonexistent_class
324
+ MaglevRecord::Migration.new(Time.now, "remove class method") do
325
+ def up
326
+ AbsentLectureClass.remove_class_method :method_not_here
327
+ end
328
+ end.do
329
+ assert_equal 1, Lecture.class_method_to_remove
330
+ end
331
+
332
+ def test_remove_class_method_of_subclass_does_not_influence_superclass
333
+ MaglevRecord::Migration.new(Time.now, "remove class method") do
334
+ def up
335
+ Lecture3.remove_instance_method :class_method_to_remove
336
+ end
337
+ end.do
338
+ assert_equal 1, Lecture.class_method_to_remove
339
+ end
340
+ end
@@ -3,7 +3,7 @@
3
3
  ====
4
4
 
5
5
  2) from rooted base to base
6
- 4) copy from one class to another
6
+ 4) copy from one class to another # useful when superclass mismatch
7
7
  5) rename class from submodule
8
8
  5) remove class from submodule
9
9
 
data/test/more_asserts.rb CHANGED
@@ -13,7 +13,7 @@ class Test::Unit::TestCase
13
13
  end
14
14
 
15
15
  def assert_not_include?(array, element)
16
- assert_not array.include?(element), "#{array}\n should include \n#{element}"
16
+ assert_not array.include?(element), "#{array}\n should not include \n#{element}"
17
17
  end
18
18
 
19
19
 
@@ -0,0 +1,33 @@
1
+ require "snapshot/test_snapshot"
2
+
3
+ class LocalAttibuteAddSnapshotTest < FastSnapshotTest
4
+ def test_new_attribute
5
+ Lecture.attr_accessor :test_accessor
6
+ assert_equal ["Lecture"], changes.changed_class_names
7
+ assert_equal ["test_accessor"], changes.changed_classes[0].new_attributes
8
+ assert_not changes.nothing_changed?
9
+ end
10
+ end
11
+
12
+ class LocalAttributeRemoveSnapshotTest < FastSnapshotTest
13
+
14
+ def setup
15
+ super
16
+ Lecture2.attr_accessor :test_accessor2
17
+ snapshot!
18
+ Lecture2.delete_attribute :test_accessor2
19
+ end
20
+
21
+ def test_removed_attribute
22
+ assert_equal ["Lecture2"], changes.changed_class_names
23
+ assert_equal ["test_accessor2"], changes.changed_classes[0].removed_attributes
24
+ end
25
+
26
+ def test_accessor_in_first_snapshot
27
+ assert_include? snapshot0[Lecture2].attributes, "test_accessor2"
28
+ end
29
+
30
+ def test_accessor_not_in_second_snapshot
31
+ assert_not_include? snapshot[Lecture2].attributes, "test_accessor2"
32
+ end
33
+ end
@@ -1,4 +1,4 @@
1
- require "snapshot/test_snapshot"
1
+ require "snapshot/test_snapshot.slow"
2
2
 
3
3
  class AttrSnapshotTest < SnapshotTest
4
4
 
@@ -43,15 +43,13 @@ class AttrSnapshotTest < SnapshotTest
43
43
  end
44
44
 
45
45
  def test_accessor_added
46
- assert_equal changed_class.new_attr_accessors, [:students]
46
+ assert_equal changed_class.new_attributes, ["students"]
47
47
  end
48
48
 
49
49
  def test_accessor_removed
50
- assert_equal changed_class.removed_attr_accessors, [:no_value]
50
+ assert_equal changed_class.removed_attributes, ["no_value"]
51
51
  end
52
52
 
53
- # TODO: add tests for attr_reader and attr_writer ...
54
-
55
53
  end
56
54
 
57
55
 
@@ -0,0 +1,32 @@
1
+ require "snapshot/test_snapshot"
2
+
3
+ class LocalClassSnapshotTest < FastSnapshotTest
4
+
5
+ def test_lecture_classes_exist
6
+ ['Lecture', 'Lecture2', 'Lecture3', 'Lecture4'].each { |lecture_name|
7
+ assert_include? snapshot.class_names, lecture_name
8
+ }
9
+ end
10
+
11
+ def test_class_removed
12
+ remove_class Lecture2
13
+ assert_equal 1, changes.removed_classes.size
14
+ end
15
+
16
+ def test_class_is_not_in_snashot_when_removed
17
+ remove_class Lecture2
18
+ assert_not_include? snapshot.class_names, "Lecture2"
19
+ end
20
+
21
+ def test_class_is_in_snapshot0_when_removed
22
+ remove_class Lecture2
23
+ assert_include? snapshot0.class_names, "Lecture2"
24
+ end
25
+
26
+ def test_removed_class_is_in_changes
27
+ remove_class Lecture4
28
+ assert_equal ["Lecture4"], changes.removed_class_names
29
+ assert_not changes.nothing_changed?
30
+ end
31
+
32
+ end
@@ -1,4 +1,4 @@
1
- require "snapshot/test_snapshot"
1
+ require "snapshot/test_snapshot.slow"
2
2
 
3
3
  class ClassSnapshotTest < SnapshotTest
4
4
 
@@ -0,0 +1,113 @@
1
+ require 'maglev_record'
2
+ require "temp_dir_test"
3
+ require 'more_asserts'
4
+ require 'migration/operation_setup'
5
+
6
+ class FileSystemSnapshotTest < TempDirTest
7
+
8
+ def teardown
9
+ "SomeClass AnotherClass Someclass2 NewClass A Class2 NewCls TheNew
10
+ TheClass ClassWithNoFuture".split.each{|name|
11
+ Object.remove_const name if Object.const_defined? name
12
+ }
13
+ end
14
+
15
+ def write_to_files(*file_contents)
16
+ file_paths = []
17
+ file_contents.each{ |content|
18
+ file_paths << write_to_file(content)
19
+ }
20
+ file_paths
21
+ end
22
+
23
+ def snapshot_with_files(*file_contents)
24
+ file_paths = write_to_files(*file_contents)
25
+ MaglevRecord::Snapshot.with_files file_paths
26
+ end
27
+
28
+ def changes_with_files(s, *file_contents)
29
+ @file_count = 0
30
+ if s.is_a? String
31
+ file_contents << s
32
+ s = nil
33
+ end
34
+ s = MaglevRecord::Snapshot.new if s.nil?
35
+ file_paths = write_to_files(*file_contents)
36
+ assert s.is_a?(MaglevRecord::Snapshot), s.to_s
37
+ s.changes_in_files file_paths
38
+ end
39
+
40
+ def test_new_class
41
+ s = snapshot_with_files "class SomeClass;include MaglevRecord::Base;end"
42
+ assert_include? s.snapshot_classes, SomeClass
43
+ end
44
+
45
+ def test_old_clases_are_loaded_too
46
+ file_path = write_to_file "class AnotherClass; include MaglevRecord::Base;def x;end;end"
47
+ Kernel.load file_path
48
+ s0 = MaglevRecord::Snapshot.new
49
+ write_to_file "class AnotherClass; include MaglevRecord::Base;def y;end;end", file_path
50
+ s = snapshot_with_files "class SomeClass2;include MaglevRecord::Base;def v;end;end"
51
+ assert_include? s.snapshot_classes, AnotherClass
52
+ assert_include? s.snapshot_classes, SomeClass2
53
+ assert_include? s.changes_since(s0).changed_class_names, "AnotherClass"
54
+ end
55
+
56
+ def test_snapshot_computes_changes
57
+ c = changes_with_files "class NewClass;include MaglevRecord::Base;def g;end;end"
58
+ assert_include? c.new_class_names, 'NewClass'
59
+ end
60
+
61
+ def test_many_changes
62
+ s = snapshot_with_files "class A; include MaglevRecord::Base; def g; end;end",
63
+ "class Class2; include MaglevRecord::Base; attr_accessor :tral;end"
64
+ c = changes_with_files "class A; include MaglevRecord::Base; def h; end;end",
65
+ "class Class2; include MaglevRecord::Base; attr_accessor :tral2;end",
66
+ "class NewCls; include MaglevRecord::Base; def c;end ;end"
67
+ # the following line may change some day but it can help debugging
68
+ assert_equal "#new class: NewCls\n#new instance method: A.new.h\nA.remove_instance_method :g\nClass2.rename_attribute(:tral, :tral2)\n#new instance method: Class2.new.tral2\n#new instance method: Class2.new.tral2=\nClass2.remove_instance_method :tral\nClass2.remove_instance_method :tral=",
69
+ c.migration_string
70
+ end
71
+
72
+ def test_changes_in_files_loads_all_files_required
73
+ file_path = write_to_file "class TheClass; include MaglevRecord::Base;def x;3;end;end"
74
+ Kernel.load file_path
75
+ s = MaglevRecord::Snapshot.new
76
+ write_to_file "class TheClass; include MaglevRecord::Base;def yy;end;end", file_path
77
+ file_paths = [write_to_file "class TheNew;include MaglevRecord::Base; def g;end;end"]
78
+ changes = s.changes_in_files(file_paths)
79
+ assert_include? changes.new_class_names, 'TheNew'
80
+ assert_include? changes.changed_class_names, 'TheClass'
81
+ assert_equal 3, TheClass.new.x
82
+ assert_equal changes[TheClass].new_instance_methods, ["yy"]
83
+ assert_equal changes[TheClass].removed_instance_methods, ["x"]
84
+ assert_raises(NoMethodError){
85
+ TheClass.new.yy
86
+ }
87
+ end
88
+
89
+ def test_file_was_removed
90
+ file_path = write_to_file "class ClassWithNoFuture; include MaglevRecord::Base;def h;end;end"
91
+ s = MaglevRecord::Snapshot.with_files [file_path]
92
+ File.delete file_path
93
+ changes = s.changes_in_files
94
+ assert_include? changes.removed_class_names, 'ClassWithNoFuture'
95
+ end
96
+
97
+ def test_if_error_occurs_everything_is_reset_to_normal
98
+ setup_migration_operations
99
+ begin
100
+ file_path = write_to_file "raise 'bam!'"
101
+ meth = Lecture3.methods
102
+ assert_raises(RuntimeError){
103
+ MaglevRecord::Snapshot.with_files [file_path]
104
+ }
105
+ assert_equal meth, Lecture3.methods
106
+ ensure
107
+ teardown_migration_operations
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+