automigration 0.2.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 +6 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +50 -0
- data/Rakefile +18 -0
- data/automigration.gemspec +24 -0
- data/lib/automigration/base_extention.rb +15 -0
- data/lib/automigration/fields/belongs_to.rb +29 -0
- data/lib/automigration/fields/boolean.rb +9 -0
- data/lib/automigration/fields/date.rb +9 -0
- data/lib/automigration/fields/datetime.rb +9 -0
- data/lib/automigration/fields/float.rb +9 -0
- data/lib/automigration/fields/integer.rb +9 -0
- data/lib/automigration/fields/password.rb +9 -0
- data/lib/automigration/fields/string.rb +9 -0
- data/lib/automigration/fields/sys/base.rb +95 -0
- data/lib/automigration/fields/sys/db_column.rb +36 -0
- data/lib/automigration/fields/sys/keeper.rb +113 -0
- data/lib/automigration/fields/sys/slice_creater.rb +32 -0
- data/lib/automigration/fields/text.rb +9 -0
- data/lib/automigration/fields/time.rb +9 -0
- data/lib/automigration/migrator.rb +189 -0
- data/lib/automigration/version.rb +3 -0
- data/lib/automigration.rb +42 -0
- data/lib/tasks/automigration.rake +8 -0
- data/log/.gitkeep +0 -0
- data/test/auto_migration_test.rb +186 -0
- data/test/belongs_to_test.rb +51 -0
- data/test/db_column_test.rb +23 -0
- data/test/fields/accessible_test.rb +13 -0
- data/test/fields_test.rb +34 -0
- data/test/models/accessible_model.rb +6 -0
- data/test/models/auto_migration1.rb +14 -0
- data/test/models/auto_migration1a.rb +7 -0
- data/test/models/auto_migration2.rb +8 -0
- data/test/models/auto_migration3.rb +5 -0
- data/test/models/belongs_to_model.rb +9 -0
- data/test/models/boolean_model.rb +5 -0
- data/test/models/form_field.rb +6 -0
- data/test/models/form_field2.rb +6 -0
- data/test/models/local_name.rb +5 -0
- data/test/models/local_name2.rb +5 -0
- data/test/models/not_automigrable.rb +2 -0
- data/test/models/searchable.rb +6 -0
- data/test/models/simple.rb +5 -0
- data/test/models/user1.rb +7 -0
- data/test/test_helper.rb +34 -0
- metadata +131 -0
@@ -0,0 +1,189 @@
|
|
1
|
+
module Automigration
|
2
|
+
class Migrator
|
3
|
+
mattr_reader :system_tables
|
4
|
+
mattr_reader :migrations_path
|
5
|
+
mattr_reader :models_load_path
|
6
|
+
mattr_reader :models_to_ignore
|
7
|
+
@@system_tables = []
|
8
|
+
@@migrations_path = nil
|
9
|
+
@@models_load_path = []
|
10
|
+
@@models_to_ignore = []
|
11
|
+
|
12
|
+
def self.set_system_tables(tables)
|
13
|
+
@@system_tables = tables
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.set_migrations_path(path)
|
17
|
+
@@migrations_path = path
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.set_models_load_path(paths)
|
21
|
+
@@models_load_path = paths
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.set_models_to_ignore(models)
|
25
|
+
@@models_to_ignore = models
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.all_tables
|
29
|
+
sql = "SELECT tablename FROM pg_tables WHERE schemaname = 'public';"
|
30
|
+
ActiveRecord::Base.connection.execute(sql).map do |row|
|
31
|
+
row["tablename"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_models
|
36
|
+
@@models_load_path.map do |path|
|
37
|
+
Dir[File.expand_path("**/*.rb", path)].map do |model_file|
|
38
|
+
model_name = model_file.sub(path.to_s + '/', '').sub(/.rb$/, '')
|
39
|
+
next if @@models_to_ignore.include?(model_name)
|
40
|
+
model = model_name.camelize.constantize
|
41
|
+
if model && model.is_a?(Class) && model.superclass == ActiveRecord::Base
|
42
|
+
model
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end.flatten.compact
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(options = {})
|
49
|
+
options.assert_valid_keys(:skip_output, :models)
|
50
|
+
|
51
|
+
@models = options[:models] || self.class.get_models
|
52
|
+
@options = options
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_schema!
|
56
|
+
log "Models: " + @models.map(&:to_s).join(', ')
|
57
|
+
|
58
|
+
# update tables
|
59
|
+
tables = ['schema_migrations']
|
60
|
+
@models.each do |model|
|
61
|
+
update_model_schema(model)
|
62
|
+
tables << model.table_name
|
63
|
+
|
64
|
+
# update globalize2 tables
|
65
|
+
if model.respond_to?(:translated_attribute_names)
|
66
|
+
translated_model = translated_model(model)
|
67
|
+
update_model_schema(translated_model)
|
68
|
+
tables << translated_model.table_name
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#remove unused tables
|
73
|
+
(self.class.all_tables - tables - @@system_tables).each do |table|
|
74
|
+
con.drop_table(table)
|
75
|
+
log "Remove table '#{table}'", :red
|
76
|
+
end
|
77
|
+
|
78
|
+
# clean migration table
|
79
|
+
if con.table_exists?('schema_migrations') and @@migrations_path
|
80
|
+
sql = "SELECT version FROM schema_migrations;"
|
81
|
+
|
82
|
+
migrations_in_db = con.execute(sql).map{|row| row['version']}
|
83
|
+
current_migrations = Dir[File.expand_path("*.rb", @@migrations_path)].map do |m_file|
|
84
|
+
File.basename(m_file) =~ /(\d{14})/
|
85
|
+
$1
|
86
|
+
end
|
87
|
+
|
88
|
+
(migrations_in_db - current_migrations).each do |m|
|
89
|
+
log "Clean migration '#{m}'", :red
|
90
|
+
sql = "DELETE FROM schema_migrations WHERE version = '#{m}';"
|
91
|
+
con.execute(sql)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def translated_model(model)
|
98
|
+
Class.new(ActiveRecord::Base).tap do |out|
|
99
|
+
out.set_table_name((model.model_name.underscore + '_translation').pluralize)
|
100
|
+
|
101
|
+
out.has_fields do |f|
|
102
|
+
f.integer "#{model.table_name.singularize}_id"
|
103
|
+
f.string :locale
|
104
|
+
model.translated_attribute_names.each do |attr_name|
|
105
|
+
model.fields_keeper.db_columns_for_field(attr_name).each do |column|
|
106
|
+
f.send column.type, column.name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_model_schema(model)
|
114
|
+
# 0. Create table if need
|
115
|
+
unless con.table_exists?(model.table_name)
|
116
|
+
con.create_table(model.table_name) {}
|
117
|
+
log "Create table #{model.table_name}", :green
|
118
|
+
model.reset_column_information
|
119
|
+
end
|
120
|
+
|
121
|
+
unless model.fields_keeper.auto_migrable?
|
122
|
+
log "#{model.to_s} skipped", :yellow
|
123
|
+
else
|
124
|
+
log "process #{model.to_s} ..."
|
125
|
+
auto_columns = model.fields_keeper.db_columns
|
126
|
+
auto_columns_names = auto_columns.map{|c| c.name.to_s}
|
127
|
+
auto_columns_hash = Hash[auto_columns.map{|c| [c.name.to_s, c]}]
|
128
|
+
|
129
|
+
# 1. update columns
|
130
|
+
(model.column_names & auto_columns_names).each do |name|
|
131
|
+
model_column = Fields::Sys::DbColumn.from_activerecord_column(model.columns_hash[name])
|
132
|
+
auto_column = auto_columns_hash[name]
|
133
|
+
|
134
|
+
unless model_column.the_same?(auto_column)
|
135
|
+
begin
|
136
|
+
con.change_column(model.table_name, name, auto_column.type, auto_column.to_options)
|
137
|
+
|
138
|
+
log "Update column #{name} of #{model.table_name} " +
|
139
|
+
"to :#{auto_column.type} type and options #{auto_column.to_options.inspect}", :yellow
|
140
|
+
rescue
|
141
|
+
con.remove_column(model.table_name, name)
|
142
|
+
con.add_column(model.table_name, name, auto_column.type, auto_column.to_options)
|
143
|
+
log "recreate column #{name} in #{model.table_name}", :yellow
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# 2. add new columns
|
149
|
+
(auto_columns_names - model.column_names).each do |name|
|
150
|
+
auto_column = auto_columns_hash[name]
|
151
|
+
con.add_column(model.table_name, name, auto_column.type, auto_column.to_options)
|
152
|
+
log "Add column #{name} to #{model.table_name}", :green
|
153
|
+
|
154
|
+
model.reset_column_information
|
155
|
+
|
156
|
+
if auto_column.options[:default].present?
|
157
|
+
model.update_all("#{name} = '#{auto_column.options[:default]}'")
|
158
|
+
log "Update default value for #{model.count} models", :green
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# 3. remove obsoleted columns
|
163
|
+
not_to_del = ['id'] + model.fields_keeper.migration_attrs
|
164
|
+
(model.column_names - auto_columns_names - not_to_del).each do |name|
|
165
|
+
con.remove_column(model.table_name, name)
|
166
|
+
log "Remove column #{name} from #{model.table_name}", :red
|
167
|
+
end
|
168
|
+
|
169
|
+
model.reset_column_information
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def con
|
174
|
+
ActiveRecord::Base.connection
|
175
|
+
end
|
176
|
+
|
177
|
+
def log(msg, color = nil)
|
178
|
+
puts "[auto] " + colored(msg, color) unless @options[:skip_output]
|
179
|
+
end
|
180
|
+
|
181
|
+
def colored(msg, color)
|
182
|
+
if [:red, :green, :yellow].include? color
|
183
|
+
ANSI.send(color){msg}
|
184
|
+
else
|
185
|
+
msg
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rails/engine'
|
2
|
+
require 'ansi'
|
3
|
+
require 'automigration/version'
|
4
|
+
require 'automigration/migrator'
|
5
|
+
require 'automigration/fields/sys/base'
|
6
|
+
require 'automigration/fields/belongs_to'
|
7
|
+
require 'automigration/fields/boolean'
|
8
|
+
require 'automigration/fields/date'
|
9
|
+
require 'automigration/fields/datetime'
|
10
|
+
require 'automigration/fields/float'
|
11
|
+
require 'automigration/fields/integer'
|
12
|
+
require 'automigration/fields/password'
|
13
|
+
require 'automigration/fields/string'
|
14
|
+
require 'automigration/fields/text'
|
15
|
+
require 'automigration/fields/time'
|
16
|
+
require 'automigration/fields/sys/db_column'
|
17
|
+
require 'automigration/fields/sys/keeper'
|
18
|
+
require 'automigration/fields/sys/slice_creater'
|
19
|
+
|
20
|
+
module Automigration
|
21
|
+
class Engine < ::Rails::Engine
|
22
|
+
config.automigration = ActiveSupport::OrderedOptions.new
|
23
|
+
config.automigration.system_tables = []
|
24
|
+
config.automigration.models_load_path = []
|
25
|
+
config.automigration.models_to_ignore = []
|
26
|
+
config.automigration.migrations_path = nil
|
27
|
+
|
28
|
+
initializer 'automigration' do |app|
|
29
|
+
app.config.automigration.models_load_path << Rails.root + 'app/models'
|
30
|
+
app.config.automigration.migrations_path = Rails.root + 'db/migrate'
|
31
|
+
|
32
|
+
ActiveSupport.on_load(:active_record) do
|
33
|
+
require 'automigration/base_extention'
|
34
|
+
end
|
35
|
+
|
36
|
+
Migrator.set_models_load_path(app.config.automigration.models_load_path)
|
37
|
+
Migrator.set_models_to_ignore(app.config.automigration.models_to_ignore)
|
38
|
+
Migrator.set_system_tables(app.config.automigration.system_tables)
|
39
|
+
Migrator.set_migrations_path(app.config.automigration.migrations_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/log/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Automigration
|
4
|
+
class AutoMigrationTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
@migrations_path = Migrator.migrations_path
|
7
|
+
@system_tables = Migrator.system_tables
|
8
|
+
@models_to_ignore = Migrator.models_to_ignore
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
Migrator.set_migrations_path(@migrations_path)
|
13
|
+
Migrator.set_system_tables(@system_tables)
|
14
|
+
Migrator.set_models_to_ignore(@models_to_ignore)
|
15
|
+
|
16
|
+
if connection.table_exists?('not_used_table')
|
17
|
+
connection.drop_table('not_used_table')
|
18
|
+
end
|
19
|
+
|
20
|
+
if connection.table_exists?('schema_migrations')
|
21
|
+
connection.drop_table('schema_migrations')
|
22
|
+
end
|
23
|
+
|
24
|
+
FileUtils.rm_rf(migrations_dir)
|
25
|
+
|
26
|
+
connection.drop_table('auto_migration1s') if Migrator.all_tables.index('auto_migration1s')
|
27
|
+
connection.drop_table('auto_migration2s')
|
28
|
+
Migrator.new(:skip_output => true).update_schema!
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_create_table_if_need
|
32
|
+
connection.drop_table('auto_migration1s')
|
33
|
+
assert !Migrator.all_tables.index('auto_migration1s')
|
34
|
+
|
35
|
+
Migrator.new(:skip_output => true).update_schema!
|
36
|
+
assert Migrator.all_tables.index('auto_migration1s')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_not_create_table_if_ignored
|
40
|
+
connection.drop_table('auto_migration1s')
|
41
|
+
assert !Migrator.all_tables.index('auto_migration1s')
|
42
|
+
|
43
|
+
Migrator.set_models_to_ignore(['auto_migration1'])
|
44
|
+
Migrator.new(:skip_output => true).update_schema!
|
45
|
+
assert !Migrator.all_tables.index('auto_migration1s')
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_remove_unused_table
|
49
|
+
connection.create_table('not_used_table')
|
50
|
+
assert Migrator.all_tables.index('not_used_table')
|
51
|
+
|
52
|
+
Migrator.new(:skip_output => true).update_schema!
|
53
|
+
assert !Migrator.all_tables.index('not_used_table')
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_not_remove_unused_table_if_it_checked_as_not_migratable
|
57
|
+
connection.create_table('not_used_table')
|
58
|
+
Migrator.set_system_tables(%w(not_used_table))
|
59
|
+
assert Migrator.all_tables.index('not_used_table')
|
60
|
+
|
61
|
+
Migrator.new(:skip_output => true).update_schema!
|
62
|
+
assert Migrator.all_tables.index('not_used_table')
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_clean_unused_migration
|
66
|
+
connection.create_table('schema_migrations') do |t|
|
67
|
+
t.string :version
|
68
|
+
end
|
69
|
+
connection.execute("INSERT INTO schema_migrations(version) VALUES('20110114120000')")
|
70
|
+
connection.execute("INSERT INTO schema_migrations(version) VALUES('20110114132500')")
|
71
|
+
connection.execute("INSERT INTO schema_migrations(version) VALUES('20110114193000')")
|
72
|
+
|
73
|
+
FileUtils.mkdir_p(migrations_dir)
|
74
|
+
File.open(migrations_dir + "/20110114120000_create_users.rb", "w"){|f| f.puts "# some text"}
|
75
|
+
File.open(migrations_dir + "/20110114193000_create_projects.rb", "w"){|f| f.puts "# some text"}
|
76
|
+
|
77
|
+
Migrator.set_migrations_path(migrations_dir)
|
78
|
+
|
79
|
+
count_sql = "SELECT count(*) AS count FROM schema_migrations"
|
80
|
+
assert_equal 3, connection.execute(count_sql)[0]['count'].to_i
|
81
|
+
Migrator.new(:skip_output => true).update_schema!
|
82
|
+
assert_equal 2, connection.execute(count_sql)[0]['count'].to_i
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_update_column_for_model_not_change_type_dramatically
|
86
|
+
connection.remove_column(AutoMigration1.table_name, 'string_field')
|
87
|
+
connection.add_column(AutoMigration1.table_name, 'string_field', :integer)
|
88
|
+
AutoMigration1.reset_column_information
|
89
|
+
|
90
|
+
AutoMigration1.create!(:string_field => 123)
|
91
|
+
assert_equal 123, AutoMigration1.first.string_field
|
92
|
+
|
93
|
+
Migrator.new(:skip_output => true).update_schema!
|
94
|
+
|
95
|
+
assert_equal '123', AutoMigration1.first.string_field
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_update_column_for_model_change_type_dramatically
|
99
|
+
connection.remove_column(AutoMigration1.table_name, 'integer_field')
|
100
|
+
connection.add_column(AutoMigration1.table_name, 'integer_field', :string)
|
101
|
+
AutoMigration1.reset_column_information
|
102
|
+
|
103
|
+
AutoMigration1.create!(:integer_field => 'abc')
|
104
|
+
assert_equal 'abc', AutoMigration1.first.integer_field
|
105
|
+
|
106
|
+
Migrator.new(:skip_output => true).update_schema!
|
107
|
+
|
108
|
+
assert_equal nil, AutoMigration1.first.integer_field
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_create_columns_for_model
|
112
|
+
assert AutoMigration1.new.attributes.keys.index("boolean_field")
|
113
|
+
assert AutoMigration1.new.attributes.keys.index("integer_field")
|
114
|
+
assert AutoMigration1.new.attributes.keys.index("float_field")
|
115
|
+
assert AutoMigration1.new.attributes.keys.index("string_field")
|
116
|
+
assert AutoMigration1.new.attributes.keys.index("text_field")
|
117
|
+
assert AutoMigration1.new.attributes.keys.index("datetime_field")
|
118
|
+
assert AutoMigration1.new.attributes.keys.index("date_field")
|
119
|
+
assert AutoMigration1.new.attributes.keys.index("time_field")
|
120
|
+
assert AutoMigration1.new.attributes.keys.index("additional_field")
|
121
|
+
|
122
|
+
assert AutoMigration1.new.attributes.keys.index("created_at")
|
123
|
+
assert AutoMigration1.new.attributes.keys.index("updated_at")
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_create_columns_for_model_add_field
|
127
|
+
assert AutoMigration1a.new.attributes.keys.index("additional_field")
|
128
|
+
assert AutoMigration1a.new.attributes.keys.index("integer_field")
|
129
|
+
|
130
|
+
assert AutoMigration1a.new.attributes.keys.index("created_at")
|
131
|
+
assert AutoMigration1a.new.attributes.keys.index("updated_at")
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_create_model_without_timestamps
|
135
|
+
assert !AutoMigration3.new.attributes.keys.index("created_at")
|
136
|
+
assert !AutoMigration3.new.attributes.keys.index("updated_at")
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_destroy_columns_for_model
|
140
|
+
connection.add_column(AutoMigration1.table_name, 'new_column', :string)
|
141
|
+
AutoMigration1.reset_column_information
|
142
|
+
|
143
|
+
assert AutoMigration1.column_names.index('new_column')
|
144
|
+
Migrator.new(:skip_output => true).update_schema!
|
145
|
+
assert !AutoMigration1.column_names.index('new_column')
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_destroy_columns_for_model
|
149
|
+
connection.add_column(AutoMigration1.table_name, 'new_column', :string)
|
150
|
+
AutoMigration1.reset_column_information
|
151
|
+
|
152
|
+
assert AutoMigration1.column_names.index('new_column')
|
153
|
+
Migrator.new(:skip_output => true).update_schema!
|
154
|
+
assert !AutoMigration1.column_names.index('new_column')
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_destroy_columns_for_model_if_they_are_not_migrate_attr
|
158
|
+
connection.add_column(AutoMigration2.table_name, 'some_attr1', :string)
|
159
|
+
connection.add_column(AutoMigration2.table_name, 'some_attr2', :string)
|
160
|
+
connection.add_column(AutoMigration2.table_name, 'some_attr3', :string)
|
161
|
+
connection.add_column(AutoMigration2.table_name, 'some_attr4', :string)
|
162
|
+
AutoMigration2.reset_column_information
|
163
|
+
|
164
|
+
assert AutoMigration2.column_names.index('some_attr1')
|
165
|
+
assert AutoMigration2.column_names.index('some_attr2')
|
166
|
+
assert AutoMigration2.column_names.index('some_attr3')
|
167
|
+
assert AutoMigration2.column_names.index('some_attr4')
|
168
|
+
|
169
|
+
Migrator.new(:skip_output => true).update_schema!
|
170
|
+
|
171
|
+
assert AutoMigration2.column_names.index('some_attr1')
|
172
|
+
assert AutoMigration2.column_names.index('some_attr2')
|
173
|
+
assert AutoMigration2.column_names.index('some_attr3')
|
174
|
+
assert !AutoMigration2.column_names.index('some_attr4')
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
def migrations_dir
|
179
|
+
File.expand_path("../../../tmp/migrations", __FILE__)
|
180
|
+
end
|
181
|
+
|
182
|
+
def connection
|
183
|
+
ActiveRecord::Base.connection
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Automigration
|
4
|
+
class BelongsTest < ActiveSupport::TestCase
|
5
|
+
include ActionDispatch::Assertions::SelectorAssertions
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@simple = Simple.create
|
9
|
+
@obj = BelongsToModel.create
|
10
|
+
end
|
11
|
+
|
12
|
+
teardown do
|
13
|
+
Simple.destroy_all
|
14
|
+
end
|
15
|
+
|
16
|
+
test "properties" do
|
17
|
+
assert_nil @obj.simple
|
18
|
+
assert_nil @obj.simple_id
|
19
|
+
end
|
20
|
+
|
21
|
+
test "mass assignment by object" do
|
22
|
+
@obj.update_attributes(:simple => @simple)
|
23
|
+
assert_equal @simple.id, @obj.simple_id
|
24
|
+
end
|
25
|
+
|
26
|
+
test "mass assignment by id" do
|
27
|
+
@obj.update_attributes(:simple_id => @simple.id)
|
28
|
+
assert_equal @simple.id, @obj.simple_id
|
29
|
+
end
|
30
|
+
|
31
|
+
test "use different class name" do
|
32
|
+
@obj.update_attributes(:some => @simple)
|
33
|
+
assert_equal @simple, @obj.some
|
34
|
+
end
|
35
|
+
|
36
|
+
test "raise if wrong name" do
|
37
|
+
assert_raise RuntimeError do
|
38
|
+
Fields::Sys::Base.from_meta(
|
39
|
+
:as => :belongs_to,
|
40
|
+
:name => "simple_id"
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
test "parent and children" do
|
46
|
+
child = BelongsToModel.find(BelongsToModel.create(:parent => @obj).id)
|
47
|
+
assert_equal @obj, child.parent
|
48
|
+
assert_equal @obj.id, child.parent_id
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Automigration
|
4
|
+
class DbColumnTest < ActiveSupport::TestCase
|
5
|
+
def test_the_same
|
6
|
+
a = Fields::Sys::DbColumn.new('field', 'integer',
|
7
|
+
:default => 3,
|
8
|
+
:null => true,
|
9
|
+
:limit => 3,
|
10
|
+
:scale => 1,
|
11
|
+
:precision => 2)
|
12
|
+
|
13
|
+
b = Fields::Sys::DbColumn.new('field', 'integer',
|
14
|
+
:default => 3,
|
15
|
+
:null => true,
|
16
|
+
:limit => 3,
|
17
|
+
:scale => 1,
|
18
|
+
:precision => 2)
|
19
|
+
|
20
|
+
assert a.the_same?(b)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Automigration
|
4
|
+
module Fields
|
5
|
+
class AccessbileTest < ActiveSupport::TestCase
|
6
|
+
test "mass assignment deny" do
|
7
|
+
obj = AccessibleModel.create(:first => 123, :second => 345)
|
8
|
+
assert_equal 123, obj.first
|
9
|
+
assert_equal 0, obj.second
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/test/fields_test.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Automigration
|
4
|
+
class FieldsTest < ActiveSupport::TestCase
|
5
|
+
def test_kind_of_field
|
6
|
+
assert_equal :boolean, Fields::Boolean.kind
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_automigrable_model
|
10
|
+
assert Simple.fields_keeper.auto_migrable?
|
11
|
+
assert !NotAutomigrable.fields_keeper.auto_migrable?
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_migrations_attrs
|
15
|
+
assert_equal [], AutoMigration1.fields_keeper.migration_attrs
|
16
|
+
|
17
|
+
assert_equal ['some_attr1', 'some_attr2' , 'some_attr3'],
|
18
|
+
AutoMigration2.fields_keeper.migration_attrs
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_boolean_column_false_by_default
|
22
|
+
assert_equal false, AutoMigration1.new.boolean_field
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_from_meta
|
26
|
+
assert_equal Fields::Boolean, Fields::Sys::Base.from_meta(:as => :boolean, :name => 'some').class
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_attributes_accessible
|
30
|
+
obj = AutoMigration1.create(:integer_field => 123)
|
31
|
+
assert_equal 123, obj.integer_field
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AutoMigration1 < ActiveRecord::Base
|
2
|
+
has_fields do |f|
|
3
|
+
f.integer :integer_field
|
4
|
+
f.float :float_field
|
5
|
+
f.boolean :boolean_field
|
6
|
+
f.string :string_field
|
7
|
+
f.text :text_field
|
8
|
+
f.datetime :datetime_field
|
9
|
+
f.date :date_field
|
10
|
+
f.time :time_field
|
11
|
+
end
|
12
|
+
|
13
|
+
add_field :integer, :additional_field
|
14
|
+
end
|