maglevrecord 0.1.1 → 0.1.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.
- data/.gitignore +7 -0
- data/.travis.yml +0 -1
- data/README.md +22 -7
- data/Rakefile +2 -2
- data/install.sh +0 -1
- data/lib/maglev_record/base.rb +10 -1
- data/lib/maglev_record/enumerable.rb +6 -1
- data/lib/maglev_record/errors.rb +3 -0
- data/lib/maglev_record/maglev_record.rb +1 -1
- data/lib/maglev_record/maglev_support/concern.rb +2 -3
- data/lib/maglev_record/maglev_support/secure_password.rb +2 -3
- data/lib/maglev_record/migration/loader.rb +1 -1
- data/lib/maglev_record/migration/migration.rb +14 -0
- data/lib/maglev_record/migration/migrator.rb +22 -4
- data/lib/maglev_record/migration/operations.rb +58 -0
- data/lib/maglev_record/persistence.rb +12 -5
- data/lib/maglev_record/read_write.rb +38 -7
- data/lib/maglev_record/rooted_enumerable.rb +6 -1
- data/lib/maglev_record/rooted_persistence.rb +4 -0
- data/lib/maglev_record/sensible.rb +2 -2
- data/lib/maglev_record/snapshot/change.rb +54 -15
- data/lib/maglev_record/snapshot/class_change.rb +66 -0
- data/lib/maglev_record/snapshot/class_snapshot.rb +63 -0
- data/lib/maglev_record/snapshot/snapshot.rb +44 -38
- data/lib/maglev_record/snapshot/snapshotable.rb +81 -26
- data/lib/maglev_record/snapshot/superclass_mismatch_change.rb +143 -0
- data/lib/maglev_record/snapshot.rb +3 -2
- data/lib/maglev_record/validations.rb +49 -0
- data/lib/maglev_record.rb +3 -2
- data/lib/tasks/database.rake +61 -17
- data/test/automigration/rake_task_base.rb +57 -0
- data/test/automigration/test_auto.slow.rb +38 -0
- data/test/automigration/test_migration_string.rb +173 -0
- data/test/automigration/test_rake_task_preconditions.slow.rb +41 -0
- data/test/automigration/test_show.slow.rb +21 -0
- data/test/automigration/test_superclass_mismatch.rb +96 -0
- data/test/example_model.rb +7 -5
- data/test/migration/base_lectures.rb +30 -0
- data/test/migration/operation_setup.rb +66 -56
- data/test/migration/projects/automigration/.gitignore +15 -0
- data/test/migration/projects/automigration/Gemfile +44 -0
- data/test/migration/projects/automigration/Gemfile.lock +115 -0
- data/test/migration/projects/automigration/README.rdoc +261 -0
- data/test/migration/projects/automigration/Rakefile +17 -0
- data/test/migration/projects/automigration/app/assets/images/rails.png +0 -0
- data/test/migration/projects/automigration/app/assets/javascripts/application.js +15 -0
- data/test/migration/projects/automigration/app/assets/stylesheets/application.css +13 -0
- data/test/migration/projects/automigration/app/controllers/application_controller.rb +3 -0
- data/test/migration/projects/automigration/app/helpers/application_helper.rb +2 -0
- data/test/migration/projects/automigration/app/mailers/.gitkeep +0 -0
- data/test/migration/projects/automigration/app/models/.gitkeep +0 -0
- data/test/migration/projects/automigration/app/models/project_model.rb +8 -0
- data/test/migration/projects/automigration/app/views/layouts/application.html.erb +14 -0
- data/test/migration/projects/automigration/config/application.rb +62 -0
- data/test/migration/projects/automigration/config/boot.rb +6 -0
- data/test/migration/projects/automigration/config/database.yml +25 -0
- data/test/migration/projects/automigration/config/environment.rb +5 -0
- data/test/migration/projects/automigration/config/environments/development.rb +37 -0
- data/test/migration/projects/automigration/config/environments/production.rb +67 -0
- data/test/migration/projects/automigration/config/initializers/backtrace_silencers.rb +7 -0
- data/test/migration/projects/automigration/config/initializers/inflections.rb +15 -0
- data/test/migration/projects/automigration/config/initializers/mime_types.rb +5 -0
- data/test/migration/projects/automigration/config/initializers/secret_token.rb +7 -0
- data/test/migration/projects/automigration/config/initializers/session_store.rb +8 -0
- data/test/migration/projects/automigration/config/initializers/wrap_parameters.rb +14 -0
- data/test/migration/projects/automigration/config/locales/en.yml +5 -0
- data/test/migration/projects/automigration/config/routes.rb +58 -0
- data/test/migration/projects/automigration/config.ru +4 -0
- data/test/migration/projects/automigration/db/seeds.rb +7 -0
- data/test/migration/projects/automigration/lib/assets/.gitkeep +0 -0
- data/test/migration/projects/automigration/lib/tasks/.gitkeep +0 -0
- data/test/migration/projects/automigration/log/.gitkeep +0 -0
- data/test/migration/projects/automigration/public/404.html +26 -0
- data/test/migration/projects/automigration/public/422.html +26 -0
- data/test/migration/projects/automigration/public/500.html +25 -0
- data/test/migration/projects/automigration/public/favicon.ico +0 -0
- data/test/migration/projects/automigration/public/index.html +241 -0
- data/test/migration/projects/automigration/public/robots.txt +5 -0
- data/test/migration/projects/automigration/script/rails +6 -0
- data/test/migration/projects/project2/Rakefile +2 -2
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.38.rb +1 -1
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.52.rb +1 -1
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.32.07.rb +1 -1
- data/test/migration/test_change_superclass.rb +111 -0
- data/test/migration/test_loader.rb +6 -0
- data/test/migration/test_project.rb +1 -29
- data/test/migration/test_project1.slow.rb +1 -0
- data/test/migration/test_project2.slow.rb +7 -0
- data/test/migration/test_remove.rb +123 -2
- data/test/migration/todo.txt +1 -1
- data/test/more_asserts.rb +1 -1
- data/test/snapshot/test_attributes.rb +33 -0
- data/test/snapshot/{test_snapshot_attributes.slow.rb → test_attributes.slow.rb} +3 -5
- data/test/snapshot/test_classes.rb +32 -0
- data/test/snapshot/{test_snapshot_classes.slow.rb → test_classes.slow.rb} +1 -1
- data/test/snapshot/test_from_file_system.rb +113 -0
- data/test/snapshot/test_methods.rb +136 -0
- data/test/snapshot/test_methods.slow.rb +67 -0
- data/test/snapshot/test_reset.rb +68 -0
- data/test/snapshot/test_snapshot.rb +41 -75
- data/test/snapshot/test_snapshot.slow.rb +98 -0
- data/test/snapshot/test_snapshotable.rb +0 -1
- data/test/temp_dir_test.rb +40 -0
- data/test/test_active_model_like_interface.rb +4 -1
- data/test/test_model_timestamps.rb +13 -5
- data/test/test_query_interface.rb +10 -0
- data/test/test_sensibles.rb +18 -10
- data/test/test_validation.rb +2 -12
- metadata +64 -5
@@ -0,0 +1,136 @@
|
|
1
|
+
require "snapshot/test_snapshot"
|
2
|
+
|
3
|
+
class FastMethodSnapshotTestBase < FastSnapshotTest
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
def Lecture.removed_method;end
|
7
|
+
Lecture.class_eval{def removed_i_method;end}
|
8
|
+
Lecture.attr_accessor :accessor1
|
9
|
+
snapshot!
|
10
|
+
def Lecture.new_method;end
|
11
|
+
Lecture.class_eval{def new_i_method;5;end}
|
12
|
+
Lecture.remove_method :removed_i_method
|
13
|
+
Lecture.singleton_class.remove_method :removed_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def test
|
17
|
+
Lecture.fill_with_examples
|
18
|
+
assert_equal 5, Lecture.first.new_i_method
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class FastMethodSnapshotEnvironmentTest < FastMethodSnapshotTestBase
|
23
|
+
|
24
|
+
# depends on FastMethodSnapshotTestBase
|
25
|
+
|
26
|
+
def test_Lecture_has_new_method
|
27
|
+
assert_include? Lecture.instance_methods, "new_i_method"
|
28
|
+
assert_include? Lecture.methods, "new_method"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_Lecture_has_no_removed_method
|
32
|
+
assert_not_include? Lecture.instance_methods, "removed_i_method"
|
33
|
+
assert_not_include? Lecture.methods, "removed_method"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_Lecture3_has_methods_of_Lecture
|
37
|
+
assert_include? Lecture3.instance_methods, "new_i_method"
|
38
|
+
assert_include? Lecture3.methods, "new_method"
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_Lecture3_has_no_removed_method
|
42
|
+
assert_not_include? Lecture3.instance_methods, "removed_i_method"
|
43
|
+
assert_not_include? Lecture3.methods, "removed_method"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class FastMethodSnapshotTest < FastMethodSnapshotTestBase
|
48
|
+
|
49
|
+
# depends on FastMethodSnapshotEnvironmentTest
|
50
|
+
|
51
|
+
def test_Lecture_has_new_method
|
52
|
+
assert_include? snapshot[Lecture].class_methods, "new_method"
|
53
|
+
assert_include? snapshot[Lecture].instance_methods, "new_i_method"
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_Lecture_has_no_removed_method
|
57
|
+
assert_not_include? snapshot[Lecture].class_methods, "removed_method"
|
58
|
+
assert_not_include? snapshot[Lecture].instance_methods, "removed_i_method"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_Lecture3_has_no_new_method
|
62
|
+
assert_not_include? snapshot[Lecture3].class_methods, "new_method"
|
63
|
+
assert_not_include? snapshot[Lecture3].instance_methods, "new_i_method"
|
64
|
+
end
|
65
|
+
def test_Lecture3_has_no_removed_method
|
66
|
+
assert_not_include? snapshot[Lecture3].class_methods, "removed_method"
|
67
|
+
assert_not_include? snapshot[Lecture3].instance_methods, "removed_i_method"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class FastMethodChangeTest < FastMethodSnapshotTestBase
|
72
|
+
|
73
|
+
# depends on FastMethodSnapshotTest
|
74
|
+
|
75
|
+
def test_only_Lecture_changed
|
76
|
+
assert_equal [], changes.new_classes
|
77
|
+
assert_equal [], changes.removed_classes
|
78
|
+
assert_equal 1, changes.changed_classes.size, "#{changes.changed_classes.size}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def lecture_changes
|
82
|
+
changes.changed_classes.first
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_removed_instance_method
|
86
|
+
assert_equal ["removed_i_method"], lecture_changes.removed_instance_methods
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_removed_class_method
|
90
|
+
assert_equal ["removed_method"], lecture_changes.removed_class_methods
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_new_instance_method
|
94
|
+
assert_equal ["new_i_method"], lecture_changes.new_instance_methods
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_new_class_method
|
98
|
+
assert_equal ["new_method"], lecture_changes.new_class_methods
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
class FastMethodVSAcessorChangeTest < FastMethodChangeTest
|
104
|
+
|
105
|
+
def setup
|
106
|
+
super
|
107
|
+
Lecture.remove_method :accessor1
|
108
|
+
Lecture.remove_method :accessor1=
|
109
|
+
Lecture.attr_accessor :accessor2
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_new_instance_method
|
113
|
+
assert_equal ["new_i_method"], lecture_changes.new_instance_methods
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_new_instance_method
|
117
|
+
assert_equal ["accessor2", "accessor2=", "new_i_method"], lecture_changes.new_instance_methods
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_removed_instance_method
|
121
|
+
assert_equal ["accessor1", "accessor1=", "removed_i_method"], lecture_changes.removed_instance_methods
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
class FastMethodVSAcessorSnapshotTest < FastMethodSnapshotTestBase
|
127
|
+
|
128
|
+
def setup
|
129
|
+
super
|
130
|
+
Lecture.remove_method :accessor1
|
131
|
+
Lecture.remove_method :accessor1=
|
132
|
+
Lecture.attr_accessor :accessor2
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# TODO add test for attr becomes method and reverse
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "snapshot/test_snapshot.slow"
|
2
|
+
|
3
|
+
class MethodSnapshotTest < SnapshotTest
|
4
|
+
|
5
|
+
def self.changes
|
6
|
+
@changes
|
7
|
+
end
|
8
|
+
|
9
|
+
as_instance_method :changes
|
10
|
+
|
11
|
+
def self.startup
|
12
|
+
super
|
13
|
+
clean
|
14
|
+
@changes = compare(
|
15
|
+
class_string('MyTestClass2', 'def exists1;end; def exists;end;def self.cls1;end;def self.cls;end;'),
|
16
|
+
class_string('MyTestClass2', 'def exists2;end; def exists;end;def self.cls2;end;def self.cls;end;'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.shutdown
|
20
|
+
super
|
21
|
+
clean
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_snapshot_without_error
|
25
|
+
assert_not_nil changes
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_no_class_removed
|
29
|
+
assert_equal changes.removed_classes, []
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_class_changed
|
33
|
+
assert_equal changes.changed_classes.size, 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_no_class_was_added
|
37
|
+
assert_equal [], changes.new_classes
|
38
|
+
end
|
39
|
+
|
40
|
+
def changed_class
|
41
|
+
assert_not_nil changes.changed_classes[0], 'a class must have changed'
|
42
|
+
changes.changed_classes[0]
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_method_added
|
46
|
+
assert_equal changed_class.new_instance_methods, ["exists2"]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_method_removed
|
50
|
+
assert_equal changed_class.removed_instance_methods, ["exists1"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_class_method_added
|
54
|
+
assert_equal changed_class.new_class_methods, ["cls2"]
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_class_method_removed
|
58
|
+
assert_equal changed_class.removed_class_methods, ["cls1"]
|
59
|
+
end
|
60
|
+
|
61
|
+
# TODO: test subclasses to not contain methods of superclasses
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "migration/operation_setup"
|
2
|
+
|
3
|
+
class ResetTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
setup_migration_operations
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
teardown_migration_operations
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_reset_an_no_methods_remain
|
14
|
+
Lecture.reset
|
15
|
+
assert_equal [], Lecture.methods(false)
|
16
|
+
assert_equal [], Lecture.instance_methods(false)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_subclasses_do_not_dfelete_superclass_methods
|
20
|
+
assert_equal Lecture, Lecture3.superclass
|
21
|
+
Lecture3.reset
|
22
|
+
assert_equal [], Lecture3.instance_methods(false)
|
23
|
+
assert_not_equal [], Lecture.instance_methods(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_also_subclasses_lose_methods
|
27
|
+
Lecture3.reset
|
28
|
+
assert_equal [], Lecture3.methods(false)
|
29
|
+
assert_not_equal [], Lecture.methods(false)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_methods_can_be_restored
|
33
|
+
m = Lecture3.methods(false)
|
34
|
+
im = Lecture3.instance_methods(false)
|
35
|
+
restore = Lecture3.reset
|
36
|
+
restore.call
|
37
|
+
assert_equal m, Lecture3.methods(false)
|
38
|
+
assert_equal im, Lecture3.instance_methods(false)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_even_new_methods_get_restored
|
42
|
+
def Lecture.something
|
43
|
+
5
|
44
|
+
end
|
45
|
+
restore = Lecture.reset
|
46
|
+
assert_raises(NoMethodError){ Lecture.something }
|
47
|
+
restore.call
|
48
|
+
assert_equal 5, Lecture.something
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_accessors
|
52
|
+
Lecture.attr_accessor :lala
|
53
|
+
assert_include? Lecture.attributes, "lala"
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_attributes_get_removed
|
57
|
+
Lecture.attr_accessor :lala
|
58
|
+
Lecture.reset
|
59
|
+
assert_equal Lecture.attributes, []
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_attributes_get_restored
|
63
|
+
Lecture.attr_accessor :lala
|
64
|
+
restore = Lecture.reset
|
65
|
+
restore.call
|
66
|
+
assert_include? Lecture.attributes, "lala"
|
67
|
+
end
|
68
|
+
end
|
@@ -1,99 +1,65 @@
|
|
1
|
-
require "maglev_record"
|
2
1
|
require "more_asserts"
|
2
|
+
require "migration/operation_setup"
|
3
3
|
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
class FastSnapshotTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def lectures
|
7
|
+
MaglevRecord::Snapshotable.snapshotable_classes.select{ |cls|
|
8
|
+
cls.name.start_with? "Lecture"
|
9
|
+
}
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
<<-EOF
|
15
|
-
$LOAD_PATH << "lib"
|
16
|
-
require "rubygems"
|
17
|
-
require "maglev_record"
|
18
|
-
load "#{module_file_path}"
|
19
|
-
Maglev::PERSISTENT_ROOT['test_snapshot'] = MaglevRecord::Snapshot.new
|
20
|
-
Maglev.commit_transaction
|
21
|
-
EOF
|
12
|
+
def assert_migration_string(string, *args)
|
13
|
+
assert_equal string, changes.migration_string(*args)
|
22
14
|
end
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
filepath = 'caller_content.rb'
|
27
|
-
File.open(filepath, 'w') { |file| file.write(snapshot_content) }
|
28
|
-
filepath
|
16
|
+
def snapshot
|
17
|
+
MaglevRecord::Snapshot.new(lectures)
|
29
18
|
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
# returns the snapshot and aborts the transaction
|
34
|
-
#
|
35
|
-
def self.snapshot(module_content)
|
36
|
-
File.open(module_file_path, 'w') { |file| file.write(module_content) }
|
37
|
-
stone = Maglev::System.stone_name
|
38
|
-
command = "export MAGLEV_OPTS=\"-W0 --stone #{stone}\" && "
|
39
|
-
command += "bundle exec "
|
40
|
-
command += "maglev-ruby #{snapshot_file_path}"
|
41
|
-
IO.popen(command) { |f|
|
42
|
-
line = f.gets
|
43
|
-
status = 1 # $? does not work here so we work around
|
44
|
-
while not line.nil?
|
45
|
-
puts line
|
46
|
-
line = f.gets
|
47
|
-
end
|
48
|
-
status
|
49
|
-
}
|
50
|
-
Maglev.abort_transaction
|
51
|
-
Maglev::PERSISTENT_ROOT['test_snapshot']
|
20
|
+
def changes
|
21
|
+
snapshot.changes_since snapshot0
|
52
22
|
end
|
53
23
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
24
|
+
def setup
|
25
|
+
setup_migration_operations
|
26
|
+
snapshot!
|
57
27
|
end
|
58
28
|
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
def self.compare(s1, s2)
|
63
|
-
s1 = snapshot(s1)
|
64
|
-
s2 = snapshot(s2)
|
65
|
-
s2.changes_since(s1) unless s1.nil? or s2.nil?
|
29
|
+
def teardown
|
30
|
+
teardown_migration_operations
|
66
31
|
end
|
67
32
|
|
68
|
-
def
|
69
|
-
|
70
|
-
include MaglevRecord::Base
|
71
|
-
self.maglev_record_persistable
|
72
|
-
# content follows
|
73
|
-
#{content}
|
74
|
-
# content ends
|
75
|
-
end"
|
33
|
+
def snapshot!
|
34
|
+
@snapshot0 = snapshot
|
76
35
|
end
|
77
36
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|
37
|
+
def snapshot0
|
38
|
+
@snapshot0
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_class(*classes)
|
81
42
|
Maglev.persistent do
|
82
|
-
|
83
|
-
Object.remove_const
|
43
|
+
classes.each { |cls|
|
44
|
+
Object.remove_const cls.name
|
45
|
+
LECTURES_NOT_TO_LOAD << cls.name
|
84
46
|
}
|
85
47
|
end
|
86
|
-
Maglev.commit_transaction
|
87
48
|
end
|
88
49
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
50
|
+
def test_removed_class
|
51
|
+
remove_class Lecture3
|
52
|
+
assert_raise(NameError) {
|
53
|
+
Lecture3
|
54
|
+
}
|
55
|
+
assert_not_include? Object.constants, "Lecture3"
|
56
|
+
assert_equal ["Lecture3"], LECTURES_NOT_TO_LOAD
|
57
|
+
Kernel.load LECTURE_TEMPFILE.path
|
58
|
+
assert_raise(NameError) {
|
59
|
+
Lecture3
|
60
|
+
}
|
97
61
|
end
|
98
62
|
|
99
63
|
end
|
64
|
+
|
65
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "more_asserts"
|
2
|
+
|
3
|
+
class SnapshotTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# the file with the content of what shell be snapshot
|
6
|
+
def self.module_file_path
|
7
|
+
# todo: pot this into a temp dir
|
8
|
+
'module_content.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
# the file content that snapshots
|
12
|
+
def self.snapshot_content
|
13
|
+
<<-EOF
|
14
|
+
$LOAD_PATH << "lib"
|
15
|
+
require "rubygems"
|
16
|
+
require "maglev_record"
|
17
|
+
load "#{module_file_path}"
|
18
|
+
Maglev::PERSISTENT_ROOT['test_snapshot'] = MaglevRecord::Snapshot.new
|
19
|
+
Maglev.commit_transaction
|
20
|
+
EOF
|
21
|
+
end
|
22
|
+
|
23
|
+
# the path of the file that snapshots
|
24
|
+
def self.snapshot_file_path
|
25
|
+
filepath = 'caller_content.rb'
|
26
|
+
File.open(filepath, 'w') { |file| file.write(snapshot_content) }
|
27
|
+
filepath
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# snapshot the program after the sting was executed
|
32
|
+
# returns the snapshot and aborts the transaction
|
33
|
+
#
|
34
|
+
def self.snapshot(module_content)
|
35
|
+
File.open(module_file_path, 'w') { |file| file.write(module_content) }
|
36
|
+
stone = Maglev::System.stone_name
|
37
|
+
command = "export MAGLEV_OPTS=\"-W0 --stone #{stone}\" && "
|
38
|
+
command += "bundle exec "
|
39
|
+
command += "maglev-ruby #{snapshot_file_path}"
|
40
|
+
IO.popen(command) { |f|
|
41
|
+
line = f.gets
|
42
|
+
status = 1 # $? does not work here so we work around
|
43
|
+
while not line.nil?
|
44
|
+
puts line
|
45
|
+
line = f.gets
|
46
|
+
end
|
47
|
+
status
|
48
|
+
}
|
49
|
+
Maglev.abort_transaction
|
50
|
+
Maglev::PERSISTENT_ROOT['test_snapshot']
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.shutdown
|
54
|
+
File.delete(snapshot_file_path)
|
55
|
+
File.delete(module_file_path) if File.file?(module_file_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# compare two sources and return the MaglevRecord Snapshot
|
60
|
+
#
|
61
|
+
def self.compare(s1, s2)
|
62
|
+
s1 = snapshot(s1)
|
63
|
+
s2 = snapshot(s2)
|
64
|
+
s2.changes_since(s1) unless s1.nil? or s2.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.class_string(name, content = '')
|
68
|
+
"class #{name}
|
69
|
+
include MaglevRecord::Base
|
70
|
+
self.maglev_record_persistable
|
71
|
+
# content follows
|
72
|
+
#{content}
|
73
|
+
# content ends
|
74
|
+
end"
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.clean
|
78
|
+
Maglev.abort_transaction
|
79
|
+
consts = [:MyTestClass, :MyTestClass2]
|
80
|
+
Maglev.persistent do
|
81
|
+
consts.each { |const|
|
82
|
+
Object.remove_const(const) if Object.const_defined? const
|
83
|
+
}
|
84
|
+
end
|
85
|
+
Maglev.commit_transaction
|
86
|
+
end
|
87
|
+
|
88
|
+
as_instance_method :class_string, :compare, :snapshot, :clean
|
89
|
+
|
90
|
+
############### Test
|
91
|
+
|
92
|
+
def test_class_string_include_class_name
|
93
|
+
s = class_string('MyTestClass123123', 'xxxx')
|
94
|
+
assert_include? s, 'class MyTestClass123123'
|
95
|
+
assert_include? s, 'xxxx'
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
#
|
5
|
+
# this test creates a temporary directory for the test
|
6
|
+
#
|
7
|
+
|
8
|
+
class TempDirTest < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
# make temporary directory
|
11
|
+
# see http://ruby-doc.org/stdlib-2.0/libdoc/tmpdir/rdoc/Dir.html#method-c-mktmpdir
|
12
|
+
@tempdir = Dir.mktmpdir
|
13
|
+
@file_count = 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
# remove the directory
|
18
|
+
FileUtils.remove_dir tempdir
|
19
|
+
end
|
20
|
+
|
21
|
+
def tempdir
|
22
|
+
@tempdir
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_to_file(content, file_path = File.join(tempdir, "x#{@file_count += 1}.rb"))
|
26
|
+
File.open(file_path, 'w'){ |f| f.write content}
|
27
|
+
file_path
|
28
|
+
end
|
29
|
+
|
30
|
+
# test the project configuration
|
31
|
+
|
32
|
+
def test_tempdir_exists
|
33
|
+
assert File.directory?(tempdir)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
@@ -6,6 +6,9 @@ class ActiveModelLikeInterfaceTest < Test::Unit::TestCase
|
|
6
6
|
include ActiveModel::Lint::Tests
|
7
7
|
|
8
8
|
def model
|
9
|
-
RootedBook.example
|
9
|
+
b = RootedBook.example
|
10
|
+
# need to trigger method_missing, because respond_to? does not call method_missing
|
11
|
+
b.valid?
|
12
|
+
b
|
10
13
|
end
|
11
14
|
end
|
@@ -8,15 +8,23 @@ class ModelTimestampTest < Test::Unit::TestCase
|
|
8
8
|
def test_time
|
9
9
|
@test_time ||= Time.local(2008, 9, 1, 10, 5, 0)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
|
+
def setup
|
12
13
|
Timecop.freeze(test_time)
|
13
|
-
model = RootedBook.example
|
14
|
-
assert_equal model.created_at, test_time
|
15
14
|
end
|
16
|
-
|
17
15
|
def teardown
|
18
16
|
Timecop.return
|
19
17
|
end
|
20
18
|
|
19
|
+
def test_created_at
|
20
|
+
model = RootedBook.example
|
21
|
+
assert_equal model.created_at, test_time
|
22
|
+
end
|
21
23
|
|
22
|
-
|
24
|
+
def test_updated_at
|
25
|
+
model = RootedBook.example
|
26
|
+
Timecop.freeze(test_time + 10)
|
27
|
+
model.author = 'Another author'
|
28
|
+
assert_equal model.updated_at, test_time + 10
|
29
|
+
end
|
30
|
+
end
|
@@ -42,4 +42,14 @@ class QueryInterfaceTest < Test::Unit::TestCase
|
|
42
42
|
assert_equal book, RootedBook.find_by_objectid(book.object_id)
|
43
43
|
end
|
44
44
|
|
45
|
+
def test_reset
|
46
|
+
book = RootedBook.find { |b| b.title == "Harry Potter and the Philosopher's stone" }
|
47
|
+
book.author = "J. R. R. Tolkien"
|
48
|
+
book.title = "The Lord of the Rings"
|
49
|
+
|
50
|
+
assert_nil RootedBook.find { |b| b.title == "Harry Potter and the Philosopher's stone" }
|
51
|
+
MaglevRecord.reset
|
52
|
+
assert_not_nil RootedBook.find { |b| b.title == "Harry Potter and the Philosopher's stone" }
|
53
|
+
end
|
54
|
+
|
45
55
|
end
|
data/test/test_sensibles.rb
CHANGED
@@ -1,16 +1,24 @@
|
|
1
1
|
require "more_asserts"
|
2
2
|
require "maglev_record"
|
3
3
|
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
class SensibleTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
Object.class_eval "
|
8
|
+
class User
|
9
|
+
include MaglevRecord::RootedBase
|
10
|
+
attr_accessor :password_digest
|
11
|
+
has_secure_password
|
12
|
+
validates_presence_of :password, :on => :create
|
13
|
+
end
|
14
|
+
User.maglev_record_persistable"
|
15
|
+
end
|
12
16
|
|
13
|
-
|
17
|
+
def teardown
|
18
|
+
Maglev.persistent do
|
19
|
+
Object.remove_const "User"
|
20
|
+
end
|
21
|
+
end
|
14
22
|
|
15
23
|
def pass
|
16
24
|
"some_pass"
|
@@ -35,4 +43,4 @@ class SensibleTest #< Test::Unit::TestCase
|
|
35
43
|
assert_equal user.password, nil
|
36
44
|
assert_equal user.password_confirmation, nil
|
37
45
|
end
|
38
|
-
end
|
46
|
+
end
|
data/test/test_validation.rb
CHANGED
@@ -10,16 +10,6 @@ class ValidationTest < Test::Unit::TestCase
|
|
10
10
|
MaglevRecord.save
|
11
11
|
end
|
12
12
|
|
13
|
-
# TODO
|
14
|
-
# def test_reset
|
15
|
-
# book = Book.find { |b| b.title == "Harry Potter and the Philosopher's stone" }
|
16
|
-
# book.author = "J. R. R. Tolkien"
|
17
|
-
# book.title = "The Lord of the Rings"
|
18
|
-
|
19
|
-
# MaglevRecord.reset
|
20
|
-
# assert_not_nil Book.find { |b| b.title == "Harry Potter and the Philosopher's stone" }
|
21
|
-
# end
|
22
|
-
|
23
13
|
def test_validation_works
|
24
14
|
book = RootedBook.new(:author => "Book")
|
25
15
|
assert book.valid?
|
@@ -28,14 +18,14 @@ class ValidationTest < Test::Unit::TestCase
|
|
28
18
|
end
|
29
19
|
|
30
20
|
def test_validation_fails
|
31
|
-
book = RootedBook.new
|
21
|
+
book = RootedBook.new
|
32
22
|
assert !book.valid?
|
33
23
|
assert book.invalid?
|
34
24
|
MaglevRecord.save
|
35
25
|
end
|
36
26
|
|
37
27
|
def test_errors_not_empty
|
38
|
-
book = RootedBook.new
|
28
|
+
book = RootedBook.new
|
39
29
|
book.valid?
|
40
30
|
assert book.errors.count > 0
|
41
31
|
end
|