maglevrecord 0.0.3 → 0.1.1
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 +35 -0
- data/.travis.yml +19 -0
- data/Gemfile +13 -0
- data/README.md +89 -0
- data/Rakefile +22 -0
- data/install.sh +238 -0
- data/lib/maglev_record/base.rb +10 -62
- data/lib/maglev_record/enumerable.rb +13 -24
- data/lib/maglev_record/errors.rb +10 -0
- data/lib/maglev_record/integration.rb +7 -0
- data/lib/maglev_record/maglev_record.rb +13 -0
- data/lib/maglev_record/maglev_support/active_support_patch.rb +31 -0
- data/lib/maglev_record/maglev_support/concern.rb +19 -0
- data/lib/maglev_record/maglev_support/maglev_support.rb +15 -0
- data/lib/maglev_record/maglev_support/secure_password.rb +39 -0
- data/lib/maglev_record/migration/loader.rb +38 -0
- data/lib/maglev_record/migration/migration.rb +142 -0
- data/lib/maglev_record/migration/migrator.rb +40 -0
- data/lib/maglev_record/migration/operations.rb +92 -0
- data/lib/maglev_record/migration.rb +5 -0
- data/lib/maglev_record/persistence.rb +23 -48
- data/lib/maglev_record/raketasks.rb +9 -0
- data/lib/maglev_record/read_write.rb +20 -10
- data/lib/maglev_record/rooted_base.rb +8 -0
- data/lib/maglev_record/rooted_enumerable.rb +25 -0
- data/lib/maglev_record/rooted_persistence.rb +36 -0
- data/lib/maglev_record/sensible.rb +28 -0
- data/lib/maglev_record/snapshot/change.rb +53 -0
- data/lib/maglev_record/snapshot/snapshot.rb +67 -0
- data/lib/maglev_record/snapshot/snapshotable.rb +58 -0
- data/lib/maglev_record/snapshot.rb +5 -0
- data/lib/maglev_record/tools/object_reference.rb +189 -0
- data/lib/maglev_record/tools/submodule_finder.rb +42 -0
- data/lib/maglev_record/tools.rb +2 -0
- data/lib/maglev_record.rb +60 -4
- data/lib/tasks/database.rake +38 -0
- data/maglevrecord.gemspec +17 -0
- data/rails/init.rb +1 -0
- data/test/_test_object_reference.rb +70 -0
- data/test/example_model.rb +26 -13
- data/test/migration/dummy_migrations/migration_1.rb +8 -0
- data/test/migration/dummy_migrations/migration_2.rb +8 -0
- data/test/migration/dummy_migrations/migration_3.rb +8 -0
- data/test/migration/migrations/migration_1.rb +12 -0
- data/test/migration/migrations/migration_2.rb +12 -0
- data/test/migration/migrations/migration_3.rb +12 -0
- data/test/migration/operation_setup.rb +91 -0
- data/test/migration/projects/project1/.gitignore +15 -0
- data/test/migration/projects/project1/Gemfile +43 -0
- data/test/migration/projects/project1/Gemfile.lock +114 -0
- data/test/migration/projects/project1/README.rdoc +261 -0
- data/test/migration/projects/project1/Rakefile +17 -0
- data/test/migration/projects/project1/app/assets/images/rails.png +0 -0
- data/test/migration/projects/project1/app/assets/javascripts/application.js +15 -0
- data/test/migration/projects/project1/app/assets/stylesheets/application.css +13 -0
- data/test/migration/projects/project1/app/controllers/application_controller.rb +3 -0
- data/test/migration/projects/project1/app/helpers/application_helper.rb +2 -0
- data/test/migration/projects/project1/app/mailers/.gitkeep +0 -0
- data/test/migration/projects/project1/app/models/.gitkeep +0 -0
- data/test/migration/projects/project1/app/views/layouts/application.html.erb +14 -0
- data/test/migration/projects/project1/config/application.rb +62 -0
- data/test/migration/projects/project1/config/boot.rb +6 -0
- data/test/migration/projects/project1/config/database.yml +25 -0
- data/test/migration/projects/project1/config/environment.rb +5 -0
- data/test/migration/projects/project1/config/environments/development.rb +37 -0
- data/test/migration/projects/project1/config/environments/production.rb +67 -0
- data/test/migration/projects/project1/config/initializers/backtrace_silencers.rb +7 -0
- data/test/migration/projects/project1/config/initializers/inflections.rb +15 -0
- data/test/migration/projects/project1/config/initializers/mime_types.rb +5 -0
- data/test/migration/projects/project1/config/initializers/secret_token.rb +7 -0
- data/test/migration/projects/project1/config/initializers/session_store.rb +8 -0
- data/test/migration/projects/project1/config/initializers/wrap_parameters.rb +14 -0
- data/test/migration/projects/project1/config/locales/en.yml +5 -0
- data/test/migration/projects/project1/config/routes.rb +58 -0
- data/test/migration/projects/project1/config.ru +4 -0
- data/test/migration/projects/project1/db/seeds.rb +7 -0
- data/test/migration/projects/project1/lib/assets/.gitkeep +0 -0
- data/test/migration/projects/project1/lib/tasks/.gitkeep +0 -0
- data/test/migration/projects/project1/log/.gitkeep +0 -0
- data/test/migration/projects/project1/public/404.html +26 -0
- data/test/migration/projects/project1/public/422.html +26 -0
- data/test/migration/projects/project1/public/500.html +25 -0
- data/test/migration/projects/project1/public/favicon.ico +0 -0
- data/test/migration/projects/project1/public/index.html +241 -0
- data/test/migration/projects/project1/public/robots.txt +5 -0
- data/test/migration/projects/project1/script/rails +6 -0
- data/test/migration/projects/project2/.gitignore +15 -0
- data/test/migration/projects/project2/Gemfile +44 -0
- data/test/migration/projects/project2/Gemfile.lock +115 -0
- data/test/migration/projects/project2/README.rdoc +261 -0
- data/test/migration/projects/project2/Rakefile +17 -0
- data/test/migration/projects/project2/app/assets/images/rails.png +0 -0
- data/test/migration/projects/project2/app/assets/javascripts/application.js +15 -0
- data/test/migration/projects/project2/app/assets/stylesheets/application.css +13 -0
- data/test/migration/projects/project2/app/controllers/application_controller.rb +3 -0
- data/test/migration/projects/project2/app/helpers/application_helper.rb +2 -0
- data/test/migration/projects/project2/app/mailers/.gitkeep +0 -0
- data/test/migration/projects/project2/app/models/.gitkeep +0 -0
- data/test/migration/projects/project2/app/models/project_model.rb +8 -0
- data/test/migration/projects/project2/app/views/layouts/application.html.erb +14 -0
- data/test/migration/projects/project2/config/application.rb +62 -0
- data/test/migration/projects/project2/config/boot.rb +6 -0
- data/test/migration/projects/project2/config/database.yml +25 -0
- data/test/migration/projects/project2/config/environment.rb +5 -0
- data/test/migration/projects/project2/config/environments/development.rb +37 -0
- data/test/migration/projects/project2/config/environments/production.rb +67 -0
- data/test/migration/projects/project2/config/initializers/backtrace_silencers.rb +7 -0
- data/test/migration/projects/project2/config/initializers/inflections.rb +15 -0
- data/test/migration/projects/project2/config/initializers/mime_types.rb +5 -0
- data/test/migration/projects/project2/config/initializers/secret_token.rb +7 -0
- data/test/migration/projects/project2/config/initializers/session_store.rb +8 -0
- data/test/migration/projects/project2/config/initializers/wrap_parameters.rb +14 -0
- data/test/migration/projects/project2/config/locales/en.yml +5 -0
- data/test/migration/projects/project2/config/routes.rb +58 -0
- data/test/migration/projects/project2/config.ru +4 -0
- data/test/migration/projects/project2/db/seeds.rb +7 -0
- data/test/migration/projects/project2/lib/assets/.gitkeep +0 -0
- data/test/migration/projects/project2/lib/tasks/.gitkeep +0 -0
- data/test/migration/projects/project2/log/.gitkeep +0 -0
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.38.rb +16 -0
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.31.52.rb +16 -0
- data/test/migration/projects/project2/migrations/migration_2013-04-Apr-23_17.32.07.rb +16 -0
- data/test/migration/projects/project2/public/404.html +26 -0
- data/test/migration/projects/project2/public/422.html +26 -0
- data/test/migration/projects/project2/public/500.html +25 -0
- data/test/migration/projects/project2/public/favicon.ico +0 -0
- data/test/migration/projects/project2/public/index.html +241 -0
- data/test/migration/projects/project2/public/robots.txt +5 -0
- data/test/migration/projects/project2/script/rails +6 -0
- data/test/migration/test_loader.rb +78 -0
- data/test/migration/test_migration.rb +127 -0
- data/test/migration/test_nonexistent_classes.rb +120 -0
- data/test/migration/test_operations_fit_together.rb +68 -0
- data/test/migration/test_project.rb +105 -0
- data/test/migration/test_project1.slow.rb +58 -0
- data/test/migration/test_project2.slow.rb +34 -0
- data/test/migration/test_remove.rb +219 -0
- data/test/migration/test_rename.rb +238 -0
- data/test/migration/test_scenario.rb +37 -0
- data/test/migration/todo.txt +17 -0
- data/test/more_asserts.rb +63 -0
- data/test/snapshot/test_snapshot.rb +99 -0
- data/test/snapshot/test_snapshot_attributes.slow.rb +57 -0
- data/test/snapshot/test_snapshot_classes.slow.rb +32 -0
- data/test/snapshot/test_snapshotable.rb +53 -0
- data/test/test_accessors.rb +46 -0
- data/test/test_active_model_like_interface.rb +1 -1
- data/test/test_model_timestamps.rb +22 -0
- data/test/test_more_asserts.rb +68 -0
- data/test/test_naming.rb +22 -0
- data/test/test_persistence.rb +127 -0
- data/test/test_query_interface.rb +20 -25
- data/test/test_sensibles.rb +38 -0
- data/test/test_validation.rb +20 -57
- data/todo.txt +1 -0
- data/update.sh +180 -0
- metadata +156 -12
- data/lib/maglev_record/model_not_saved_or_reset.rb +0 -15
- data/test/test_dirty_object.rb +0 -50
- data/test/test_maglev_record_base.rb +0 -22
- data/test/test_maglev_simple_persistance.rb +0 -45
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
####
|
|
2
|
+
#
|
|
3
|
+
# Test Cases for removing
|
|
4
|
+
#
|
|
5
|
+
# - instance variables
|
|
6
|
+
#
|
|
7
|
+
# - attributes
|
|
8
|
+
#
|
|
9
|
+
# - classes
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
require "maglev_record"
|
|
13
|
+
require "migration/operation_setup"
|
|
14
|
+
require "more_asserts"
|
|
15
|
+
require 'time'
|
|
16
|
+
|
|
17
|
+
################## remove instance_variable
|
|
18
|
+
|
|
19
|
+
class TestMigrationRemoveInstanceVariable < Test::Unit::TestCase
|
|
20
|
+
|
|
21
|
+
def setup
|
|
22
|
+
setup_migration_operations
|
|
23
|
+
Lecture.fill_with_examples
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def migration1
|
|
27
|
+
MaglevRecord::Migration.new(Time.now, "remove instance variable") do
|
|
28
|
+
def up
|
|
29
|
+
Lecture.delete_instance_variable(:@lecturer)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_instance_variable_is_removed
|
|
35
|
+
migration1.do
|
|
36
|
+
assert_not Lecture.first.instance_variable_defined?(:@lecturer)
|
|
37
|
+
assert_nil Lecture.first.instance_variable_get(:@lecturer)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def migration2
|
|
41
|
+
MaglevRecord::Migration.new(Time.now, "delete instance variable") do
|
|
42
|
+
def up
|
|
43
|
+
@lecturers = []
|
|
44
|
+
Lecture.delete_instance_variable(:@lecturer) {
|
|
45
|
+
|lecturer|
|
|
46
|
+
# you could do some garbage collection help here
|
|
47
|
+
# inthis case we just save the contents of the variable
|
|
48
|
+
# to prove the block is called with the right argument
|
|
49
|
+
@lecturers << lecturer
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
def lecturers
|
|
53
|
+
@lecturers
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_instance_variable_is_removed_with_block
|
|
59
|
+
migration2.do
|
|
60
|
+
assert_not Lecture.first.instance_variable_defined?(:@lecturer)
|
|
61
|
+
assert_nil Lecture.first.instance_variable_get(:@lecturer)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_block_is_called_with_deleted_content
|
|
65
|
+
lecturers = Lecture.collect{ |l| l.instance_variable_get(:@lecturer)}
|
|
66
|
+
migration = migration2
|
|
67
|
+
migration.do
|
|
68
|
+
assert_equal lecturers.sort, migration.lecturers.sort
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_first_lecture_has_lecturer
|
|
72
|
+
assert Lecture.first.instance_variable_defined?(:@lecturer)
|
|
73
|
+
assert_not_nil Lecture.first.instance_variable_get(:@lecturer)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
################## remove attribute
|
|
79
|
+
|
|
80
|
+
class TestMigrationRemoveAttribute < Test::Unit::TestCase
|
|
81
|
+
|
|
82
|
+
def setup
|
|
83
|
+
setup_migration_operations
|
|
84
|
+
Lecture2.fill_with_examples
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def migration1
|
|
88
|
+
MaglevRecord::Migration.new(Time.now, "remove attribute") do
|
|
89
|
+
def up
|
|
90
|
+
Lecture2.delete_attribute(:lecturer)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_attribute_is_removed
|
|
96
|
+
migration1.do
|
|
97
|
+
assert_nil Lecture2.first.lecturer
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def migration2
|
|
101
|
+
MaglevRecord::Migration.new(Time.now, "remove attribute lecturer") do
|
|
102
|
+
def up
|
|
103
|
+
@lecturers = []
|
|
104
|
+
Lecture2.delete_attribute(:lecturer) {
|
|
105
|
+
|lecturer|
|
|
106
|
+
# you could do some garbage collection help here
|
|
107
|
+
# inthis case we just save the contents of the variable
|
|
108
|
+
# to prodo some garbage collection help
|
|
109
|
+
@lecturers << lecturer
|
|
110
|
+
}
|
|
111
|
+
end
|
|
112
|
+
def lecturers
|
|
113
|
+
@lecturers
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_attribute_is_removed_with_block
|
|
119
|
+
migration2.do
|
|
120
|
+
assert_nil Lecture2.first.lecturer
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def test_block_is_called_with_deleted_content
|
|
124
|
+
lecturers = Lecture2.collect{ |l| l.lecturer }
|
|
125
|
+
migration = migration2
|
|
126
|
+
migration.do
|
|
127
|
+
assert_equal lecturers.sort, migration.lecturers.sort
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_first_lecture_has_lecturer
|
|
131
|
+
assert_not_nil Lecture2.first.lecturer
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
################## remove classes
|
|
137
|
+
|
|
138
|
+
class TestMigrationRemoveClass < Test::Unit::TestCase
|
|
139
|
+
|
|
140
|
+
def setup
|
|
141
|
+
setup_migration_operations
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def migration1
|
|
145
|
+
MaglevRecord::Migration.new(Time.now, "remove class Lecture") do
|
|
146
|
+
def up
|
|
147
|
+
delete_class(Lecture)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def test_class_is_not_present_after_deletion
|
|
153
|
+
migration1.do
|
|
154
|
+
assert_raise(NameError) {
|
|
155
|
+
Lecture
|
|
156
|
+
}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def test_objects_are_not_referenced_by_object_pool_after_deletion
|
|
160
|
+
object_pool = Lecture.object_pool
|
|
161
|
+
migration1.do
|
|
162
|
+
assert object_pool.empty?
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def migration2
|
|
166
|
+
MaglevRecord::Migration.new(Time.now, "remove class Lecture") do
|
|
167
|
+
def up
|
|
168
|
+
@lectures = []
|
|
169
|
+
delete_class(Lecture) {
|
|
170
|
+
|lecture|
|
|
171
|
+
@lectures << lecture
|
|
172
|
+
}
|
|
173
|
+
end
|
|
174
|
+
def lectures
|
|
175
|
+
@lectures
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_block_yields_all_instances_of_lecture
|
|
181
|
+
migration = migration2
|
|
182
|
+
instances = Lecture.all
|
|
183
|
+
migration.do
|
|
184
|
+
assert_equal instances.sort, migration.lectures.sort
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_object_pool_is_existent_before_delete
|
|
188
|
+
pool_dict = Maglev::PERSISTENT_ROOT[MaglevRecord::PERSISTENT_ROOT_KEY]
|
|
189
|
+
object_pool = Lecture.object_pool
|
|
190
|
+
assert pool_dict.values.any?{|v| v.equal? object_pool}
|
|
191
|
+
# this test belongs to test_object_pool_removed_from_pool_dict
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_object_pool_removed_from_pool_dict
|
|
195
|
+
pool_dict = Maglev::PERSISTENT_ROOT[MaglevRecord::PERSISTENT_ROOT_KEY]
|
|
196
|
+
object_pool = Lecture.object_pool
|
|
197
|
+
migration1.do
|
|
198
|
+
assert_not pool_dict.values.any?{|v| v.equal? object_pool}
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def migration_remove_nested_class
|
|
202
|
+
MaglevRecord::Migration.new(Time.now, "remove class Lecture") do
|
|
203
|
+
def up
|
|
204
|
+
delete_class(Models::M1::Lecture)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def test_remove_nested_class
|
|
210
|
+
Models::M1::Lecture
|
|
211
|
+
migration_remove_nested_class.do
|
|
212
|
+
assert_raise(NameError){
|
|
213
|
+
Models::M1::Lecture
|
|
214
|
+
}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
####
|
|
2
|
+
#
|
|
3
|
+
# Test Cases for renaming
|
|
4
|
+
#
|
|
5
|
+
# - instance variables
|
|
6
|
+
#
|
|
7
|
+
# - attributes
|
|
8
|
+
#
|
|
9
|
+
# - classes
|
|
10
|
+
#
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
require "maglev_record"
|
|
16
|
+
require "migration/operation_setup"
|
|
17
|
+
require "more_asserts"
|
|
18
|
+
require 'time'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
################## rename instance variables
|
|
22
|
+
|
|
23
|
+
class TestMigrationRenameInstanceVariable < Test::Unit::TestCase
|
|
24
|
+
|
|
25
|
+
def setup
|
|
26
|
+
setup_migration_operations
|
|
27
|
+
Lecture.fill_with_examples
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def m1
|
|
31
|
+
MaglevRecord::Migration.new(Time.now, "rename instance variable") do
|
|
32
|
+
def up
|
|
33
|
+
Lecture.rename_instance_variable(:@lecturer , :@lecturers) {
|
|
34
|
+
|lecturer|
|
|
35
|
+
[lecturer]
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_rename_inst_var_with_block
|
|
42
|
+
lecturer = Lecture.first.instance_variable_get(:@lecturer)
|
|
43
|
+
m1.do
|
|
44
|
+
assert_equal Lecture.first.instance_variable_get(:@lecturers), [lecturer]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_lecturer_exists
|
|
48
|
+
assert_not_nil Lecture.first.instance_variable_get(:@lecturer)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def m2
|
|
52
|
+
MaglevRecord::Migration.new(Time.now, "rename instance variable") do
|
|
53
|
+
def up
|
|
54
|
+
Lecture.rename_instance_variable(:@users , :@attendees)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_rename_inst_var
|
|
60
|
+
users = Lecture.first.instance_variable_get(:@users)
|
|
61
|
+
m2.do
|
|
62
|
+
assert_equal Lecture.first.instance_variable_get(:@attendees), users
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_users_exists
|
|
66
|
+
assert_not_nil Lecture.first.instance_variable_get(:@users)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_old_instance_variable_is_removed_after_renaming
|
|
70
|
+
m2.do
|
|
71
|
+
assert_not Lecture.first.instance_variable_defined?(:@users)
|
|
72
|
+
assert_nil Lecture.first.instance_variable_get(:@users)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
################## rename attributes
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TestMigrationRenameAttributes < Test::Unit::TestCase
|
|
80
|
+
|
|
81
|
+
def setup
|
|
82
|
+
setup_migration_operations
|
|
83
|
+
Lecture2.fill_with_examples
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def m3
|
|
87
|
+
MaglevRecord::Migration.new(Time.now, "rename attribute") do
|
|
88
|
+
def up
|
|
89
|
+
Lecture2.rename_attribute(:lecturer , :lecturers) {
|
|
90
|
+
|lecturer|
|
|
91
|
+
[lecturer]
|
|
92
|
+
}
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def test_rename_attribute_with_block
|
|
98
|
+
lecturer = Lecture2.first.lecturer
|
|
99
|
+
m3.do
|
|
100
|
+
assert_equal Lecture2.first.lecturers, [lecturer]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_attr_lecturer_exists
|
|
104
|
+
assert_not_nil Lecture2.first.lecturer
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def m4
|
|
108
|
+
MaglevRecord::Migration.new(Time.now, "rename attribute") do
|
|
109
|
+
def up
|
|
110
|
+
Lecture2.rename_attribute(:users , :attendees)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_rename_attribute
|
|
116
|
+
users = Lecture2.first.users
|
|
117
|
+
m4.do
|
|
118
|
+
assert_equal Lecture2.first.attendees, users
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_attr_users_exists
|
|
122
|
+
assert_not_nil Lecture2.first.users
|
|
123
|
+
assert_not_equal Lecture2.first.users, []
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
################## rename classes
|
|
129
|
+
|
|
130
|
+
class TestMigrationRenameClass < Test::Unit::TestCase
|
|
131
|
+
|
|
132
|
+
def setup
|
|
133
|
+
setup_migration_operations
|
|
134
|
+
Lecture3.fill_with_examples
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def migration
|
|
138
|
+
MaglevRecord::Migration.new(Time.now, "rename attribute") do
|
|
139
|
+
def up
|
|
140
|
+
rename_class Lecture3, :Lecture4
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_objects_are_in_renamed_class
|
|
146
|
+
obj = Lecture3.first
|
|
147
|
+
migration.do
|
|
148
|
+
assert_equal Lecture4.first, obj
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test_class_has_objects
|
|
152
|
+
assert_not_equal Lecture3.all, []
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_class_with_same_name_as_renamed_class_has_no_objects
|
|
156
|
+
migration.up
|
|
157
|
+
redefine_migration_classes
|
|
158
|
+
assert_equal Lecture3.all, []
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_renamed_class_does_not_exist
|
|
162
|
+
migration.up
|
|
163
|
+
assert_raise(NameError) {
|
|
164
|
+
Lecture3
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def test_unrenamed_classes_have_distinct_objects
|
|
169
|
+
Lecture3.each{ |lecture3|
|
|
170
|
+
assert_not_include? Lecture4.all, lecture3
|
|
171
|
+
}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_objects_are_of_renamed_class
|
|
175
|
+
assert_equal Lecture3.first.class, Lecture3
|
|
176
|
+
migration.do
|
|
177
|
+
assert_equal Lecture4.first.class, Lecture4
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_objects_are_not_of_original_class
|
|
181
|
+
assert_equal Lecture3.first.class, Lecture3
|
|
182
|
+
migration.do
|
|
183
|
+
redefine_migration_classes
|
|
184
|
+
assert_not_equal Lecture4.first.class, Lecture3
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_migration_changes_class_name
|
|
188
|
+
migration.do
|
|
189
|
+
assert_equal Lecture4.first.class.name, "Lecture4"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
class TestNestingList < Test::Unit::TestCase
|
|
195
|
+
|
|
196
|
+
def setup
|
|
197
|
+
setup_migration_operations
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_Lecture_is_not_nested
|
|
201
|
+
assert_equal Lecture.nesting_list, [Object, Lecture]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def test_Models_M1_Lecture_lists_submodules_in_nesting_list
|
|
205
|
+
assert_equal Models::M1::Lecture.nesting_list, [
|
|
206
|
+
Object, Models, Models::M1, Models::M1::Lecture]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def migration_rename_Lecture4
|
|
210
|
+
MaglevRecord::Migration.new(Time.now, "rename Lecture") do
|
|
211
|
+
def up
|
|
212
|
+
rename_class Lecture4, :Lecture5
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_renamed_models_have_different_nesting_list
|
|
218
|
+
migration_rename_Lecture4.do
|
|
219
|
+
assert_equal Lecture5.nesting_list, [Object, Lecture5]
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def migration_rename_nested_Lecture
|
|
223
|
+
MaglevRecord::Migration.new(Time.now, "rename Lecture") do
|
|
224
|
+
def up
|
|
225
|
+
rename_class Models::M1::Lecture, :Lecture3
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_nested_renamed_class_has_different_nesting_list
|
|
231
|
+
migration_rename_nested_Lecture.do
|
|
232
|
+
assert_equal Models::M1::Lecture3.nesting_list, [
|
|
233
|
+
Object, Models, Models::M1, Models::M1::Lecture3 ]
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "more_asserts"
|
|
2
|
+
require "example_model"
|
|
3
|
+
|
|
4
|
+
class MigrationScenarioTest < Test::Unit::TestCase
|
|
5
|
+
Migration = MaglevRecord::Migration
|
|
6
|
+
MigrationLoader = MaglevRecord::MigrationLoader
|
|
7
|
+
Migrator = MaglevRecord::Migrator
|
|
8
|
+
|
|
9
|
+
attr_reader :loader
|
|
10
|
+
|
|
11
|
+
def setup
|
|
12
|
+
MaglevRecord.reset
|
|
13
|
+
RootedBook.clear
|
|
14
|
+
Maglev::PERSISTENT_ROOT[Migrator::MIGRATION_KEY] = Array.new
|
|
15
|
+
@loader = MigrationLoader.new
|
|
16
|
+
RootedBook.new(:title => "Harry Potter and the Philosopher's stone")
|
|
17
|
+
RootedBook.new(:title => "Harry Potter and the Chamber of Secrets")
|
|
18
|
+
RootedBook.new(:title => "Harry Potter and the Prisoner of Azkaban")
|
|
19
|
+
MaglevRecord.save
|
|
20
|
+
loader.load_directory(migration_directory)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def migration_directory
|
|
24
|
+
File.dirname(__FILE__) + '/migrations'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_migration_loader_loads_correct_number_of_migrations
|
|
28
|
+
assert_equal 3, loader.migration_list.size
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_migration_loader
|
|
32
|
+
migration_list = loader.migration_list
|
|
33
|
+
migrator = Migrator.new(migration_list)
|
|
34
|
+
migrator.up
|
|
35
|
+
assert_equal "The most recent book title", RootedBook.first.title
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'maglev_record'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def assert_not(bool, message = nil)
|
|
8
|
+
assert_equal false, bool, message
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def assert_include?(array, element)
|
|
12
|
+
assert array.include?(element), "#{array}\n should include \n#{element}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def assert_not_include?(array, element)
|
|
16
|
+
assert_not array.include?(element), "#{array}\n should include \n#{element}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# run once before all tests
|
|
21
|
+
def self.startup
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# run once after all tests
|
|
25
|
+
def self.shutdown
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
alias :old_suite :suite
|
|
30
|
+
|
|
31
|
+
def suite
|
|
32
|
+
mysuite = old_suite
|
|
33
|
+
#puts "suite: #{mysuite}"
|
|
34
|
+
def mysuite.run(*args)
|
|
35
|
+
@tests.first.class.startup() unless @tests.empty?
|
|
36
|
+
super
|
|
37
|
+
@tests.first.class.shutdown() unless @tests.empty?
|
|
38
|
+
end
|
|
39
|
+
mysuite
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# make the class methods available as instance methods
|
|
45
|
+
#
|
|
46
|
+
def self.as_instance_method(*names)
|
|
47
|
+
names.each{ |name|
|
|
48
|
+
name = name.to_s
|
|
49
|
+
self.class_eval "def #{name}(*args); self.class.#{name}(*args);end"
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# class MyTest < Test::Unit::TestCase
|
|
56
|
+
# def self.startup
|
|
57
|
+
# puts 'runs only once at start2'
|
|
58
|
+
# end
|
|
59
|
+
# def self.shutdown
|
|
60
|
+
# puts 'runs only once at end2'
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require "maglev_record"
|
|
2
|
+
require "more_asserts"
|
|
3
|
+
|
|
4
|
+
class SnapshotTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
# the file with the content of what shell be snapshot
|
|
7
|
+
def self.module_file_path
|
|
8
|
+
# todo: pot this into a temp dir
|
|
9
|
+
'module_content.rb'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# the file content that snapshots
|
|
13
|
+
def self.snapshot_content
|
|
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
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# the path of the file that snapshots
|
|
25
|
+
def self.snapshot_file_path
|
|
26
|
+
filepath = 'caller_content.rb'
|
|
27
|
+
File.open(filepath, 'w') { |file| file.write(snapshot_content) }
|
|
28
|
+
filepath
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# snapshot the program after the sting was executed
|
|
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']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.shutdown
|
|
55
|
+
File.delete(snapshot_file_path)
|
|
56
|
+
File.delete(module_file_path) if File.file?(module_file_path)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# compare two sources and return the MaglevRecord Snapshot
|
|
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?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.class_string(name, content = '')
|
|
69
|
+
"class #{name}
|
|
70
|
+
include MaglevRecord::Base
|
|
71
|
+
self.maglev_record_persistable
|
|
72
|
+
# content follows
|
|
73
|
+
#{content}
|
|
74
|
+
# content ends
|
|
75
|
+
end"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def self.clean
|
|
79
|
+
Maglev.abort_transaction
|
|
80
|
+
consts = [:MyTestClass, :MyTestClass2]
|
|
81
|
+
Maglev.persistent do
|
|
82
|
+
consts.each { |const|
|
|
83
|
+
Object.remove_const(const) if Object.const_defined? const
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
Maglev.commit_transaction
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
as_instance_method :class_string, :compare, :snapshot, :clean
|
|
90
|
+
|
|
91
|
+
############### Test
|
|
92
|
+
|
|
93
|
+
def test_class_string_include_class_name
|
|
94
|
+
s = class_string('MyTestClass123123', 'xxxx')
|
|
95
|
+
assert_include? s, 'class MyTestClass123123'
|
|
96
|
+
assert_include? s, 'xxxx'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|