From f3bc5290eedbd60cce4ccd5d9ef8b6010d608fec Mon Sep 17 00:00:00 2001 From: Jared Beck Date: Sun, 3 Jun 2018 22:49:23 -0400 Subject: [PATCH] Automate test setup Goal: rake default task can do everything without manual setup Also delete `spec/dummy_app/db/schema.rb`. People forget (understandably) to update it. As long as we don't use the db:setup task first, we don't need it. --- .github/CONTRIBUTING.md | 94 +---------- .gitignore | 1 + .travis.yml | 14 -- Rakefile | 44 ++++- spec/dummy_app/db/schema.rb | 319 ------------------------------------ 5 files changed, 52 insertions(+), 420 deletions(-) delete mode 100644 spec/dummy_app/db/schema.rb diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8e66934f..23c41fec 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -30,118 +30,40 @@ Testing is a little awkward because the test suite: 1. Contains a "dummy" rails app with three databases (test, foo, and bar) 1. Supports three different RDBMS': sqlite, mysql, and postgres -### Test sqlite, AR 4.2 +### Test sqlite, AR 4 ``` -rm spec/dummy_app/db/*.sqlite3 - -# Create the appropriate database config. file -rm spec/dummy_app/config/database.yml -DB=sqlite bundle exec rake prepare - -# If this is the first test run ever, create databases. -# We can't use `appraisal` inside the dummy app, so we must set `BUNDLE_GEMFILE`. -# See spec/dummy_app/config/boot.rb for a complete explanation. -cd spec/dummy_app -export BUNDLE_GEMFILE=../../gemfiles/ar_4.2.gemfile -RAILS_ENV=test bundle exec rake db:setup -RAILS_ENV=foo bundle exec rake db:setup -RAILS_ENV=bar bundle exec rake db:setup -unset BUNDLE_GEMFILE -cd ../.. - -# Run tests DB=sqlite bundle exec appraisal ar-4.2 rake # Run a single test -DB=sqlite bundle exec appraisal ar-4.2 rspec spec/paper_trail/serializers/json_spec.rb +DB=sqlite bundle exec appraisal ar-4.2 rspec spec/paper_trail_spec.rb ``` ### Test sqlite, AR 5 ``` -rm spec/dummy_app/db/*.sqlite3 - -# Create the appropriate database config. file -rm spec/dummy_app/config/database.yml -DB=sqlite bundle exec rake prepare - -# If this is the first test run ever, create databases. -# We can't use `appraisal` inside the dummy app, so we must set `BUNDLE_GEMFILE`. -# See spec/dummy_app/config/boot.rb for a complete explanation. -cd spec/dummy_app -export BUNDLE_GEMFILE=../../gemfiles/ar_5.2.gemfile -RAILS_ENV=test bundle exec rake db:environment:set db:setup -RAILS_ENV=foo bundle exec rake db:environment:set db:setup -RAILS_ENV=bar bundle exec rake db:environment:set db:setup -unset BUNDLE_GEMFILE -cd ../.. - -# Run tests DB=sqlite bundle exec appraisal ar-5.2 rake ``` ### Test mysql, AR 5 ``` -# Create the appropriate database config. file -rm spec/dummy_app/config/database.yml -DB=mysql bundle exec rake prepare - -# If this is the first test run ever, create databases. -# We can't use `appraisal` inside the dummy app, so we must set `BUNDLE_GEMFILE`. -# See spec/dummy_app/config/boot.rb for a complete explanation. -cd spec/dummy_app -export BUNDLE_GEMFILE=../../gemfiles/ar_5.2.gemfile -RAILS_ENV=test bundle exec rake db:setup db:environment:set -RAILS_ENV=foo bundle exec rake db:setup db:environment:set -RAILS_ENV=bar bundle exec rake db:setup db:environment:set -unset BUNDLE_GEMFILE -cd ../.. - -# Run tests DB=mysql bundle exec appraisal ar-5.2 rake ``` ### Test postgres, AR 5 ``` -# Create the appropriate database config. file -rm spec/dummy_app/config/database.yml -DB=postgres bundle exec rake prepare - -# If this is the first test run ever, create databases. -# Unlike mysql, use create/migrate instead of setup. -# We can't use `appraisal` inside the dummy app, so we must set `BUNDLE_GEMFILE`. -# See spec/dummy_app/config/boot.rb for a complete explanation. -cd spec/dummy_app -export BUNDLE_GEMFILE=../../gemfiles/ar_5.2.gemfile -DB=postgres RAILS_ENV=test bundle exec rake db:environment:set db:drop db:create db:migrate -DB=postgres RAILS_ENV=foo bundle exec rake db:environment:set db:drop db:create db:migrate -DB=postgres RAILS_ENV=bar bundle exec rake db:environment:set db:drop db:create db:migrate -unset BUNDLE_GEMFILE -cd ../.. - -# Run tests -DB=postgres bundle exec rake +createuser --superuser postgres DB=postgres bundle exec appraisal ar-5.2 rake ``` -## Editing the migration +## Adding new schema -After editing `spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb` .. - -``` -cd spec/dummy_app -export BUNDLE_GEMFILE=../../gemfiles/ar_5.1.gemfile -RAILS_ENV=test bundle exec rake db:environment:set db:drop db:create db:migrate -RAILS_ENV=foo bundle exec rake db:environment:set db:drop db:create db:migrate -RAILS_ENV=bar bundle exec rake db:environment:set db:drop db:create db:migrate -unset BUNDLE_GEMFILE -cd ../.. -``` - -Don't forget to commit changes to `schema.rb`. +Edit `spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb`. Migration +will be performed by `spec_helper.rb`, so you can just run rake as shown above. +Also, `spec/dummy_app/db/schema.rb` is deliberately `.gitignore`d, we don't use +it. ## Documentation diff --git a/.gitignore b/.gitignore index a52ef39f..9fa29808 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ gemfiles/*.lock pkg/* spec/dummy/ spec/dummy_app/config/database.yml +spec/dummy_app/db/schema.rb spec/dummy_app/db/*.sqlite3 spec/dummy_app/log/* spec/dummy_app/tmp/* diff --git a/.travis.yml b/.travis.yml index e4ce40a9..b5411d57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,26 +15,12 @@ env: - DB=mysql - DB=postgres - DB=sqlite - sudo: false - -before_script: - - mysql --version - - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_test;'; fi" - - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_bar; '; fi" - - sh -c "if [ \"$DB\" = 'mysql' ]; then mysql -e 'create database paper_trail_foo; '; fi" - - psql --version - - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_test;' -U postgres; fi" - - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_bar;' -U postgres; fi" - - sh -c "if [ \"$DB\" = 'postgres' ]; then psql -c 'create database paper_trail_foo;' -U postgres; fi" - gemfile: - gemfiles/ar_4.2.gemfile - gemfiles/ar_5.1.gemfile - gemfiles/ar_5.2.gemfile - matrix: fast_finish: true - addons: postgresql: "9.4" diff --git a/Rakefile b/Rakefile index 7f23a697..ba1eab5a 100644 --- a/Rakefile +++ b/Rakefile @@ -1,15 +1,57 @@ # frozen_string_literal: true +require "fileutils" require "bundler" Bundler::GemHelper.install_tasks +desc "Delete generated files and databases" +task :clean do + # It's tempting to use `git clean` here, but this rake task will be run by + # people working on changes that haven't been committed yet, so we have to + # be more selective with what we delete. + ::FileUtils.rm("spec/dummy_app/db/database.yml", force: true) + case ENV["DB"] + when "mysql" + %w[test foo bar].each do |db| + system("mysqladmin drop -f paper_trail_#{db} > /dev/null 2>&1") + end + when "postgres" + %w[test foo bar].each do |db| + system("dropdb --if-exists paper_trail_#{db} > /dev/null 2>&1") + end + when nil, "sqlite" + ::FileUtils.rm(::Dir.glob("spec/dummy_app/db/*.sqlite3")) + else + raise "Don't know how to clean specified RDBMS: #{ENV['DB']}" + end +end + desc "Write a database.yml for the specified RDBMS" -task :prepare do +task prepare: [:clean] do ENV["DB"] ||= "sqlite" FileUtils.cp( "spec/dummy_app/config/database.#{ENV['DB']}.yml", "spec/dummy_app/config/database.yml" ) + case ENV["DB"] + when "mysql" + %w[test foo bar].each do |db| + system("mysqladmin create paper_trail_#{db}") + # Migration happens later in spec_helper. + end + when "postgres" + %w[test foo bar].each do |db| + system("createdb paper_trail_#{db}") + # Migration happens later in spec_helper. + end + when nil, "sqlite" + # noop. test.sqlite3 will be created when migration happens in spec_helper. + # Shortly thereafter, foo and bar.sqlite3 are created when + # spec/support/alt_db_init.rb is `require`d. + nil + else + raise "Don't know how to create specified DB: #{ENV['DB']}" + end end require "rspec/core/rake_task" diff --git a/spec/dummy_app/db/schema.rb b/spec/dummy_app/db/schema.rb deleted file mode 100644 index 5421c3b8..00000000 --- a/spec/dummy_app/db/schema.rb +++ /dev/null @@ -1,319 +0,0 @@ -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema.define(version: 20110208155312) do - - create_table "animals", force: :cascade do |t| - t.string "name" - t.string "species" - end - - create_table "articles", force: :cascade do |t| - t.string "title" - t.string "content" - t.string "abstract" - t.string "file_upload" - end - - create_table "authorships", force: :cascade do |t| - t.integer "book_id" - t.integer "author_id" - end - - create_table "banana_versions", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object" - t.datetime "created_at", limit: 6 - t.index ["item_type", "item_id"], name: "index_banana_versions_on_item_type_and_item_id" - end - - create_table "bananas", force: :cascade do |t| - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "bar_habtms", force: :cascade do |t| - t.string "name" - end - - create_table "bar_habtms_foo_habtms", id: false, force: :cascade do |t| - t.integer "foo_habtm_id" - t.integer "bar_habtm_id" - t.index ["bar_habtm_id"], name: "index_bar_habtms_foo_habtms_on_bar_habtm_id" - t.index ["foo_habtm_id"], name: "index_bar_habtms_foo_habtms_on_foo_habtm_id" - end - - create_table "books", force: :cascade do |t| - t.string "title" - end - - create_table "boolits", force: :cascade do |t| - t.string "name" - t.boolean "scoped", default: true - end - - create_table "callback_modifiers", force: :cascade do |t| - t.string "some_content" - t.boolean "deleted", default: false - end - - create_table "chapters", force: :cascade do |t| - t.string "name" - end - - create_table "citations", force: :cascade do |t| - t.integer "quotation_id" - end - - create_table "custom_primary_key_record_versions", force: :cascade do |t| - t.string "item_type", null: false - t.string "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object" - t.datetime "created_at", limit: 6 - t.index ["item_type", "item_id"], name: "idx_cust_pk_item" - end - - create_table "custom_primary_key_records", primary_key: "uuid", id: :string, force: :cascade do |t| - t.string "name" - t.index ["uuid"], unique: true - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "customers", force: :cascade do |t| - t.string "name" - end - - create_table "documents", force: :cascade do |t| - t.string "name" - end - - create_table "editors", force: :cascade do |t| - t.string "name" - end - - create_table "editorships", force: :cascade do |t| - t.integer "book_id" - t.integer "editor_id" - end - - create_table "families", force: :cascade do |t| - t.string "name" - t.integer "parent_id" - t.integer "partner_id" - end - - create_table "family_lines", force: :cascade do |t| - t.integer "parent_id" - t.integer "grandson_id" - end - - create_table "fluxors", force: :cascade do |t| - t.integer "widget_id" - t.string "name" - end - - create_table "foo_habtms", force: :cascade do |t| - t.string "name" - end - - create_table "fruits", force: :cascade do |t| - t.string "name" - t.string "color" - end - - create_table "gadgets", force: :cascade do |t| - t.string "name" - t.string "brand" - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "legacy_widgets", force: :cascade do |t| - t.string "name" - t.integer "version" - end - - create_table "line_items", force: :cascade do |t| - t.integer "order_id" - t.string "product" - end - - create_table "not_on_updates", force: :cascade do |t| - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "on_create", force: :cascade do |t| - t.string "name", null: false - end - - create_table "on_destroy", force: :cascade do |t| - t.string "name", null: false - end - - create_table "on_empty_array", force: :cascade do |t| - t.string "name", null: false - end - - create_table "on_touch", force: :cascade do |t| - t.string "name", null: false - end - - create_table "on_update", force: :cascade do |t| - t.string "name", null: false - end - - create_table "orders", force: :cascade do |t| - t.integer "customer_id" - t.string "order_date" - end - - create_table "paragraphs", force: :cascade do |t| - t.integer "section_id" - t.string "name" - end - - create_table "people", force: :cascade do |t| - t.string "name" - t.string "time_zone" - t.integer "mentor_id" - end - - create_table "pets", force: :cascade do |t| - t.integer "owner_id" - t.integer "animal_id" - end - - create_table "post_versions", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object" - t.datetime "created_at", limit: 6 - t.string "ip" - t.string "user_agent" - t.index ["item_type", "item_id"], name: "index_post_versions_on_item_type_and_item_id" - end - - create_table "post_with_statuses", force: :cascade do |t| - t.integer "status" - t.datetime "created_at", null: false, limit: 6 - t.datetime "updated_at", null: false, limit: 6 - end - - create_table "posts", force: :cascade do |t| - t.string "title" - t.string "content" - end - - create_table "quotations", force: :cascade do |t| - t.integer "chapter_id" - end - - create_table "sections", force: :cascade do |t| - t.integer "chapter_id" - t.string "name" - end - - create_table "skippers", force: :cascade do |t| - t.string "name" - t.datetime "another_timestamp", limit: 6 - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "songs", force: :cascade do |t| - t.integer "length" - end - - create_table "things", force: :cascade do |t| - t.string "name" - end - - create_table "translations", force: :cascade do |t| - t.string "headline" - t.string "content" - t.string "language_code" - t.string "type" - end - - create_table "vehicles", force: :cascade do |t| - t.string "name", null: false - t.string "type", null: false - t.integer "owner_id" - t.datetime "created_at", null: false, limit: 6 - t.datetime "updated_at", null: false, limit: 6 - end - - create_table "version_associations", force: :cascade do |t| - t.integer "version_id" - t.string "foreign_key_name", null: false - t.integer "foreign_key_id" - t.index ["foreign_key_name", "foreign_key_id"], name: "index_version_associations_on_foreign_key" - t.index ["version_id"], name: "index_version_associations_on_version_id" - end - - create_table "versions", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object", limit: 1073741823 - t.text "object_changes", limit: 1073741823 - t.integer "transaction_id" - t.datetime "created_at", limit: 6 - t.integer "answer" - t.string "action" - t.string "question" - t.integer "article_id" - t.string "title" - t.string "ip" - t.string "user_agent" - t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" - end - - create_table "whatchamajiggers", force: :cascade do |t| - t.string "owner_type" - t.integer "owner_id" - t.string "name" - end - - create_table "widgets", force: :cascade do |t| - t.string "name" - t.text "a_text" - t.integer "an_integer" - t.float "a_float" - t.decimal "a_decimal", precision: 6, scale: 4 - t.datetime "a_datetime", limit: 6 - t.time "a_time" - t.date "a_date" - t.boolean "a_boolean" - t.string "type" - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - - create_table "wotsits", force: :cascade do |t| - t.integer "widget_id" - t.string "name" - t.datetime "created_at", limit: 6 - t.datetime "updated_at", limit: 6 - end - -end