migrant 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +24 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +124 -0
  4. data/Rakefile +46 -0
  5. data/VERSION +1 -0
  6. data/lib/datatype/base.rb +65 -0
  7. data/lib/datatype/boolean.rb +15 -0
  8. data/lib/datatype/currency.rb +11 -0
  9. data/lib/datatype/date.rb +13 -0
  10. data/lib/datatype/float.rb +11 -0
  11. data/lib/datatype/foreign_key.rb +9 -0
  12. data/lib/datatype/hash.rb +10 -0
  13. data/lib/datatype/polymorphic.rb +8 -0
  14. data/lib/datatype/range.rb +13 -0
  15. data/lib/datatype/string.rb +22 -0
  16. data/lib/datatype/symbol.rb +10 -0
  17. data/lib/datatype/time.rb +5 -0
  18. data/lib/migrant/migration_generator.rb +123 -0
  19. data/lib/migrant/model_extensions.rb +37 -0
  20. data/lib/migrant/schema.rb +91 -0
  21. data/lib/migrant.rb +16 -0
  22. data/lib/railtie.rb +11 -0
  23. data/lib/tasks/db.rake +11 -0
  24. data/migrant.gemspec +167 -0
  25. data/test/additional_models/review.rb +10 -0
  26. data/test/helper.rb +38 -0
  27. data/test/rails_app/.gitignore +4 -0
  28. data/test/rails_app/README +256 -0
  29. data/test/rails_app/Rakefile +7 -0
  30. data/test/rails_app/app/controllers/application_controller.rb +3 -0
  31. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  32. data/test/rails_app/app/models/business.rb +22 -0
  33. data/test/rails_app/app/models/business_category.rb +6 -0
  34. data/test/rails_app/app/models/category.rb +9 -0
  35. data/test/rails_app/app/models/customer.rb +7 -0
  36. data/test/rails_app/app/models/user.rb +8 -0
  37. data/test/rails_app/app/views/layouts/application.html.erb +14 -0
  38. data/test/rails_app/config/application.rb +16 -0
  39. data/test/rails_app/config/boot.rb +13 -0
  40. data/test/rails_app/config/database.yml +7 -0
  41. data/test/rails_app/config/environment.rb +5 -0
  42. data/test/rails_app/config/environments/development.rb +26 -0
  43. data/test/rails_app/config/environments/production.rb +49 -0
  44. data/test/rails_app/config/environments/test.rb +35 -0
  45. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/rails_app/config/initializers/inflections.rb +10 -0
  47. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  48. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  49. data/test/rails_app/config/initializers/session_store.rb +8 -0
  50. data/test/rails_app/config/locales/en.yml +5 -0
  51. data/test/rails_app/config/routes.rb +58 -0
  52. data/test/rails_app/config.ru +4 -0
  53. data/test/rails_app/db/schema.rb +82 -0
  54. data/test/rails_app/db/seeds.rb +7 -0
  55. data/test/rails_app/lib/tasks/.gitkeep +0 -0
  56. data/test/rails_app/public/404.html +26 -0
  57. data/test/rails_app/public/422.html +26 -0
  58. data/test/rails_app/public/500.html +26 -0
  59. data/test/rails_app/script/rails +6 -0
  60. data/test/rails_app/test/performance/browsing_test.rb +9 -0
  61. data/test/rails_app/test/test_helper.rb +13 -0
  62. data/test/rails_app/vendor/plugins/.gitkeep +0 -0
  63. data/test/test_data_schema.rb +85 -0
  64. data/test/test_migration_generator.rb +114 -0
  65. data/test/verified_output/migrations/business_id.rb +10 -0
  66. data/test/verified_output/migrations/create_business_categories.rb +14 -0
  67. data/test/verified_output/migrations/create_businesses.rb +28 -0
  68. data/test/verified_output/migrations/create_categories.rb +13 -0
  69. data/test/verified_output/migrations/create_reviews.rb +17 -0
  70. data/test/verified_output/migrations/create_users.rb +18 -0
  71. data/test/verified_output/migrations/estimated_value_notes.rb +11 -0
  72. data/test/verified_output/migrations/landline.rb +9 -0
  73. metadata +270 -0
@@ -0,0 +1,26 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # In the development environment your application's code is reloaded on
5
+ # every request. This slows down response time but is perfect for development
6
+ # since you don't have to restart the webserver when you make code changes.
7
+ config.cache_classes = false
8
+
9
+ # Log error messages when you accidentally call methods on nil.
10
+ config.whiny_nils = true
11
+
12
+ # Show full error reports and disable caching
13
+ config.consider_all_requests_local = true
14
+ config.action_view.debug_rjs = true
15
+ config.action_controller.perform_caching = false
16
+
17
+ # Don't care if the mailer can't send
18
+ config.action_mailer.raise_delivery_errors = false
19
+
20
+ # Print deprecation notices to the Rails logger
21
+ config.active_support.deprecation = :log
22
+
23
+ # Only use best-standards-support built into browsers
24
+ config.action_dispatch.best_standards_support = :builtin
25
+ end
26
+
@@ -0,0 +1,49 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # The production environment is meant for finished, "live" apps.
5
+ # Code is not reloaded between requests
6
+ config.cache_classes = true
7
+
8
+ # Full error reports are disabled and caching is turned on
9
+ config.consider_all_requests_local = false
10
+ config.action_controller.perform_caching = true
11
+
12
+ # Specifies the header that your server uses for sending files
13
+ config.action_dispatch.x_sendfile_header = "X-Sendfile"
14
+
15
+ # For nginx:
16
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
17
+
18
+ # If you have no front-end server that supports something like X-Sendfile,
19
+ # just comment this out and Rails will serve the files
20
+
21
+ # See everything in the log (default is :info)
22
+ # config.log_level = :debug
23
+
24
+ # Use a different logger for distributed setups
25
+ # config.logger = SyslogLogger.new
26
+
27
+ # Use a different cache store in production
28
+ # config.cache_store = :mem_cache_store
29
+
30
+ # Disable Rails's static asset server
31
+ # In production, Apache or nginx will already do this
32
+ config.serve_static_assets = false
33
+
34
+ # Enable serving of images, stylesheets, and javascripts from an asset server
35
+ # config.action_controller.asset_host = "http://assets.example.com"
36
+
37
+ # Disable delivery errors, bad email addresses will be ignored
38
+ # config.action_mailer.raise_delivery_errors = false
39
+
40
+ # Enable threaded mode
41
+ # config.threadsafe!
42
+
43
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44
+ # the I18n.default_locale when a translation can not be found)
45
+ config.i18n.fallbacks = true
46
+
47
+ # Send deprecation notices to registered listeners
48
+ config.active_support.deprecation = :notify
49
+ end
@@ -0,0 +1,35 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Log error messages when you accidentally call methods on nil.
11
+ config.whiny_nils = true
12
+
13
+ # Show full error reports and disable caching
14
+ config.consider_all_requests_local = true
15
+ config.action_controller.perform_caching = false
16
+
17
+ # Raise exceptions instead of rendering exception templates
18
+ config.action_dispatch.show_exceptions = false
19
+
20
+ # Disable request forgery protection in test environment
21
+ config.action_controller.allow_forgery_protection = false
22
+
23
+ # Tell Action Mailer not to deliver emails to the real world.
24
+ # The :test delivery method accumulates sent emails in the
25
+ # ActionMailer::Base.deliveries array.
26
+ config.action_mailer.delivery_method = :test
27
+
28
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
29
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
30
+ # like if you have constraints or database-specific column types
31
+ # config.active_record.schema_format = :sql
32
+
33
+ # Print deprecation notices to the stderr
34
+ config.active_support.deprecation = :stderr
35
+ end
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,10 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ RailsApp::Application.config.secret_token = '0a64f43c365ab41db0a8f00833a483f6c2aa59c81cd8bae410671abd416208a055de76df00205ea06cbe4e97f4a903284e6de40671b426f37cd942d7fd61ce7a'
@@ -0,0 +1,8 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ RailsApp::Application.config.session_store :cookie_store, :key => '_rails_app_session'
4
+
5
+ # Use the database for sessions instead of the cookie-based default,
6
+ # which shouldn't be used to store highly confidential information
7
+ # (create the session table with "rake db:sessions:create")
8
+ # RailsApp::Application.config.session_store :active_record_store
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,58 @@
1
+ RailsApp::Application.routes.draw do
2
+ # The priority is based upon order of creation:
3
+ # first created -> highest priority.
4
+
5
+ # Sample of regular route:
6
+ # match 'products/:id' => 'catalog#view'
7
+ # Keep in mind you can assign values other than :controller and :action
8
+
9
+ # Sample of named route:
10
+ # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
11
+ # This route can be invoked with purchase_url(:id => product.id)
12
+
13
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
14
+ # resources :products
15
+
16
+ # Sample resource route with options:
17
+ # resources :products do
18
+ # member do
19
+ # get 'short'
20
+ # post 'toggle'
21
+ # end
22
+ #
23
+ # collection do
24
+ # get 'sold'
25
+ # end
26
+ # end
27
+
28
+ # Sample resource route with sub-resources:
29
+ # resources :products do
30
+ # resources :comments, :sales
31
+ # resource :seller
32
+ # end
33
+
34
+ # Sample resource route with more complex sub-resources
35
+ # resources :products do
36
+ # resources :comments
37
+ # resources :sales do
38
+ # get 'recent', :on => :collection
39
+ # end
40
+ # end
41
+
42
+ # Sample resource route within a namespace:
43
+ # namespace :admin do
44
+ # # Directs /admin/products/* to Admin::ProductsController
45
+ # # (app/controllers/admin/products_controller.rb)
46
+ # resources :products
47
+ # end
48
+
49
+ # You can have the root of your site routed with "root"
50
+ # just remember to delete public/index.html.
51
+ # root :to => "welcome#index"
52
+
53
+ # See how all your routes lay out with "rake routes"
54
+
55
+ # This is a legacy wild controller route that's not recommended for RESTful applications.
56
+ # Note: This route will make all actions in every controller accessible via GET requests.
57
+ # match ':controller(/:action(/:id(.:format)))'
58
+ end
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run RailsApp::Application
@@ -0,0 +1,82 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended to check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(:version => 20101028205511) do
14
+
15
+ create_table "business_categories", :force => true do |t|
16
+ t.integer "business_id"
17
+ t.integer "category_id"
18
+ t.decimal "test_currency_mockup", :precision => 10, :scale => 2
19
+ t.datetime "test_date_mockup"
20
+ t.float "test_float_mockup"
21
+ t.integer "test_range_mockup"
22
+ end
23
+
24
+ add_index "business_categories", ["business_id"], :name => "index_business_categories_on_business_id"
25
+ add_index "business_categories", ["category_id"], :name => "index_business_categories_on_category_id"
26
+
27
+ create_table "businesses", :force => true do |t|
28
+ t.integer "user_id"
29
+ t.string "owner_type"
30
+ t.integer "owner_id"
31
+ t.string "name"
32
+ t.string "website"
33
+ t.text "address"
34
+ t.string "summary"
35
+ t.text "description"
36
+ t.text "landline", :limit => 255
37
+ t.string "mobile"
38
+ t.integer "operating_days", :limit => 1
39
+ t.datetime "date_established"
40
+ t.datetime "next_sale"
41
+ t.boolean "verified"
42
+ t.string "location", :limit => 127
43
+ t.float "estimated_value"
44
+ t.string "notes"
45
+ end
46
+
47
+ add_index "businesses", ["owner_id"], :name => "index_businesses_on_owner_id"
48
+ add_index "businesses", ["owner_type", "owner_id"], :name => "index_businesses_on_owner_type_and_owner_id"
49
+ add_index "businesses", ["user_id"], :name => "index_businesses_on_user_id"
50
+
51
+ create_table "categories", :force => true do |t|
52
+ t.string "title"
53
+ t.string "summary"
54
+ end
55
+
56
+ add_index "categories", ["title"], :name => "index_categories_on_title"
57
+
58
+ create_table "reviews", :force => true do |t|
59
+ t.integer "business_id"
60
+ t.integer "user_id"
61
+ t.string "name"
62
+ t.integer "rating", :limit => 1
63
+ t.text "body"
64
+ end
65
+
66
+ add_index "reviews", ["business_id"], :name => "index_reviews_on_business_id"
67
+ add_index "reviews", ["user_id"], :name => "index_reviews_on_user_id"
68
+
69
+ create_table "users", :force => true do |t|
70
+ t.string "name"
71
+ t.string "email"
72
+ t.string "encrypted_password", :limit => 48
73
+ t.string "password_salt", :limit => 42
74
+ t.decimal "money_spent", :precision => 10, :scale => 2
75
+ t.decimal "money_gifted", :precision => 10, :scale => 2
76
+ t.float "average_rating"
77
+ t.integer "business_id"
78
+ end
79
+
80
+ add_index "users", ["business_id"], :name => "index_users_on_business_id"
81
+
82
+ end
@@ -0,0 +1,7 @@
1
+ # This file should contain all the record creation needed to seed the database with its default values.
2
+ # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3
+ #
4
+ # Examples:
5
+ #
6
+ # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
7
+ # Mayor.create(:name => 'Daley', :city => cities.first)
File without changes
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/404.html -->
21
+ <div class="dialog">
22
+ <h1>The page you were looking for doesn't exist.</h1>
23
+ <p>You may have mistyped the address or the page may have moved.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ <p>We've been notified about this issue and we'll take a look at it shortly.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'rails/performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionDispatch::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ require 'rails/test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7
+ #
8
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
9
+ # -- they do not yet inherit this setting
10
+ fixtures :all
11
+
12
+ # Add more helper methods to be used by all tests here...
13
+ end
File without changes
@@ -0,0 +1,85 @@
1
+ require 'helper'
2
+
3
+ def assert_schema(model, name, options = {})
4
+ field = model.schema.column_migrations.detect {|m| m.first == name}
5
+ assert_not_nil(field, 'Migration was not generated')
6
+ options.each do |key, correct_value|
7
+ assert_equal(correct_value, field[1][key])
8
+ end
9
+ end
10
+
11
+ class TestDataSchema < Test::Unit::TestCase
12
+ context "The schema generator" do
13
+ should "generate a foreign key field for a belongs_to association" do
14
+ assert_schema(Business, :user_id, :type => :integer)
15
+ assert_schema(BusinessCategory, :business_id, :type => :integer)
16
+ assert_schema(BusinessCategory, :category_id, :type => :integer)
17
+ end
18
+
19
+ should "generate foreign key fields for a *polymorphic* belongs_to association" do
20
+ assert_schema(Business, :owner_id, :type => :integer)
21
+ assert_schema(Business, :owner_type, :type => :string)
22
+ end
23
+
24
+ should "generate a string column when given a string example" do
25
+ assert_schema(Business, :name)
26
+ end
27
+
28
+ should "generate a datetime column when given a date or time example" do
29
+ assert_schema(Business, :date_established, :type => :datetime)
30
+ assert_schema(Business, :next_sale, :type => :datetime)
31
+ end
32
+
33
+ should "generate a smallint column when given a small range" do
34
+ assert_schema(Business, :operating_days, :limit => 1, :type => :integer)
35
+ end
36
+
37
+ should "generate a string column when given a sentence" do
38
+ assert_schema(Business, :summary, :type => :string)
39
+ end
40
+
41
+ should "generate a text column when given a long paragraph" do
42
+ assert_schema(Business, :description, :type => :text)
43
+ assert_schema(Business, :address, :type => :text)
44
+ end
45
+
46
+ should "generate a boolean column when a true or false is given" do
47
+ assert_schema(Business, :verified, :type => :boolean)
48
+ end
49
+
50
+ should "generate a column verbatim if no type is specified" do
51
+ assert_schema(Business, :location, :type => :string, :limit => 127)
52
+ end
53
+
54
+ should "generate a string column when no options are given" do
55
+ assert_schema(Category, :title, :type => :string)
56
+ assert_schema(Category, :summary, :type => :string)
57
+ end
58
+
59
+ should "generate a decimal column when a currency is given" do
60
+ assert_schema(User, :money_spent, :type => :decimal, :scale => 2)
61
+ assert_schema(User, :money_gifted, :type => :decimal, :scale => 2)
62
+ end
63
+
64
+ should "generate a floating point column when a decimal is given" do
65
+ assert_schema(User, :average_rating, :type => :float)
66
+ end
67
+
68
+ should "generate a string column when an email example or class is given" do
69
+ assert_schema(User, :email, :type => :string)
70
+ end
71
+
72
+ should "generate indexes for all foreign keys automatically" do
73
+ assert_contains(Business.schema.indexes, :user_id, 'Missing index on belongs_to')
74
+ assert_contains(Business.schema.indexes, [:owner_type, :owner_id], 'Missing index on polymorphic belongs_to')
75
+ assert_contains(BusinessCategory.schema.indexes, :business_id, 'Missing index on belongs_to')
76
+ assert_contains(BusinessCategory.schema.indexes, :category_id, 'Missing index on belongs_to')
77
+ end
78
+
79
+ should "generate indexes on any column when explicitly asked to" do
80
+ assert_contains(Category.schema.indexes, :title, 'Missing index on :index => true column')
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,114 @@
1
+ require 'helper'
2
+ require 'rake'
3
+
4
+ def rake_migrate
5
+ Dir.chdir(Rails.root.join('.')) do
6
+ Rake::Task['db:migrate'].execute
7
+ end
8
+ end
9
+
10
+
11
+ class TestMigrationGenerator < Test::Unit::TestCase
12
+ def run_against_template(template)
13
+ assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
14
+ Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).each do |migration_file|
15
+ if migration_file.include?(template)
16
+ correct = File.join(File.dirname(__FILE__), 'verified_output', 'migrations', template+'.rb')
17
+ assert_equal(File.open(correct, 'r') { |r| r.read}.strip,
18
+ File.open(migration_file, 'r') { |r| r.read}.strip,
19
+ "Generated migration #{migration_file} does not match template #{correct}")
20
+ rake_migrate
21
+ return
22
+ end
23
+ end
24
+ flunk "No migration could be found"
25
+ end
26
+
27
+ context "The migration generator" do
28
+ should "create migrations for all new tables" do
29
+ assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
30
+ Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).each do |migration_file|
31
+ correct = File.join(File.dirname(__FILE__), 'verified_output', 'migrations', migration_file.sub(/^.*\d+_/, ''))
32
+ assert_equal(File.open(correct, 'r') { |r| r.read}.strip,
33
+ File.open(migration_file, 'r') { |r| r.read}.strip,
34
+ "Generated migration #{migration_file} does not match template #{correct}")
35
+ end
36
+ rake_migrate
37
+ end
38
+
39
+ should "generate a migration for new added fields" do
40
+ Business.structure do
41
+ estimated_value 5000.0
42
+ notes
43
+ end
44
+ run_against_template('estimated_value_notes')
45
+ end
46
+
47
+ should "generate a migration to alter existing columns where no data loss would occur" do
48
+ Business.structure do
49
+ landline :text
50
+ end
51
+
52
+ run_against_template('landline')
53
+ end
54
+
55
+ should "generate a migration to alter existing columns while adding a new table" do
56
+ load File.join(File.dirname(__FILE__), 'additional_models', 'review.rb')
57
+ User.belongs_to(:business) # To generate a business_id on a User
58
+ User.no_structure # To force schema update
59
+
60
+ run_against_template('create_reviews')
61
+ run_against_template('business_id')
62
+ end
63
+
64
+ should "not change existing columns where data loss may occur" do
65
+ Business.structure do
66
+ landline :integer # Was previously a string, which obviously may incur data loss
67
+ end
68
+ assert_equal(false, Migrant::MigrationGenerator.new.run, "MigrationGenerator ran a dangerous migration!")
69
+ Business.structure do
70
+ landline :text # Undo our bad for the next tests
71
+ end
72
+ end
73
+
74
+ should "exit immediately if there are pending migrations" do
75
+ manual_migration = Rails.root.join("db/migrate/9999999999999999_my_new_migration.rb")
76
+ File.open(manual_migration, 'w') { |f| f.write ' ' }
77
+ assert_equal(false, Migrant::MigrationGenerator.new.run)
78
+ File.delete(manual_migration)
79
+ end
80
+
81
+ should "still create sequential migrations for the folks not using timestamps" do
82
+ Business.structure do
83
+ new_field_i_made_up
84
+ end
85
+ # Remove migrations
86
+ ActiveRecord::Base.timestamped_migrations = false
87
+ assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
88
+ ActiveRecord::Base.timestamped_migrations = true
89
+
90
+ assert_equal(Dir.glob(File.join(File.dirname(__FILE__), 'rails_app', 'db' ,'migrate', '*.rb')).select { |migration_file| migration_file.include?('new_field_i_made_up') }.length,
91
+ 1,
92
+ "Migration should have been generated (without a duplicate)")
93
+ end
94
+
95
+ should "recursively generate mocks for every model" do
96
+ BusinessCategory.structure do
97
+ test_currency_mockup DataType::Currency
98
+ test_date_mockup DataType::Date
99
+ test_float_mockup DataType::Float
100
+ test_range_mockup DataType::Range
101
+
102
+ end
103
+ BusinessCategory.belongs_to(:nonexistant_class, :polymorphic => true)
104
+ assert_equal true, Migrant::MigrationGenerator.new.run, "Migration Generator reported an error"
105
+ rake_migrate
106
+ BusinessCategory.reset_column_information
107
+ mock = BusinessCategory.mock
108
+ assert_not_nil(mock)
109
+ # TODO: Spice this up a bit .. it covers everything, but doesn't test output
110
+ end
111
+
112
+ end
113
+ end
114
+
@@ -0,0 +1,10 @@
1
+ class UsersModifyFieldsBusinessId < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :business_id, :integer
4
+ add_index :users, :business_id
5
+ end
6
+
7
+ def self.down
8
+ remove_column :users, :business_id
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ class CreateBusinessCategories < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :business_categories do |t|
4
+ t.integer :business_id
5
+ t.integer :category_id
6
+ end
7
+ add_index :business_categories, :business_id
8
+ add_index :business_categories, :category_id
9
+ end
10
+
11
+ def self.down
12
+ drop_table :business_categories
13
+ end
14
+ end