#!/usr/bin/env ruby require "rubygems" # ruby1.9 doesn't "require" it though require "thor" class Roadkill < Thor include Thor::Actions def self.source_root File.dirname(__FILE__) end TEST_DIR = "tests" SAMPLE_APP_DIR = "sample_app" DEFAULT_ENVIRONMENT_URL = "http://localhost:80" DEFAULT_DATABASE_ENCODING = "utf-8" # Generate files, dirs, and sample files desc "generate", "Generate the files to start testing your application." def generate config = { database: {}, environment:{} } if yes?("Would you like to setup your tests to connect to your development database?") config[:database][:hostname] = ask "What is your database host?" config[:database][:adapter] = get_adapter_from ask("What is your database adapter? (MySQL, PostgreSQL, and SQLite3 are best supported)").downcase config[:database][:database] = ask "What is your database name?" config[:database][:username] = ask "What is your database username?" config[:database][:password] = ask "What is your database password?" encoding = ask "What is your database encoding? (default is #{DEFAULT_DATABASE_ENCODING})" encoding = DEFAULT_DATABASE_ENCODING if encoding == "" config[:database][:encoding] = encoding end uri_port = ask "What is your development URI:Port (default is #{DEFAULT_ENVIRONMENT_URL})?" uri_port = DEFAULT_ENVIRONMENT_URL if uri_port == "" unless uri_port.match /^http/ uri_port = "http://#{uri_port}" end config[:environment][:uri_port] = uri_port generate_from config end # Generate a sample rack app desc "sample_app", "Generate a sample rack app." def sample_app empty_directory self.class::SAMPLE_APP_DIR sample_app_config = { database:{}, # No database on the sample app environment: { uri_port: "http://localhost:9292" } } directory "../files/sample_app", "#{self.class::SAMPLE_APP_DIR}" generate_from sample_app_config, self.class::SAMPLE_APP_DIR + "/tests" say "Your sample app has been generated!" say "To get things working, you'll first need to bundle install in the tests dir:" say " pushd sample_app/tests" say " bundle install" say " popd" say "Alternatively, here is a one-liner that will do the same thing:" say " cd sample_app/tests && bundle install ; cd ../.." say "" say "Once this is complete, you may run the rack application with:" say " cd sample_app" say " rackup config.ru -D" say "" say "You can then run the tests with:" say " cd tests" say " rspec spec" end # Install phantomjs desc "install_phantomjs", "Install PhantomJS - provide 32bit or 64bit to identify which version to install." def install_phantomjs version = ask("What version of phantomjs would you like to install?", limited_to: ["32","64"]) sudo = yes?("Can we run the commands as sudo?") ? "sudo" : "" file = (version == "32") ? "phantomjs-1.9.1-linux-i686": "phantomjs-1.9.1-linux-x86_64" say "Installing phantom js #{version} bit" say "First, we're going to make sure you have some dependencies." run("#{sudo} apt-get install fontconfig bzip2 tar") run("wget https://phantomjs.googlecode.com/files/#{file}.tar.bz2") run("bunzip2 #{file}.tar.bz2") run("tar -xf #{file}.tar") run("#{sudo} mv #{file}/bin/phantomjs /usr/local/bin/") run("rm #{file}.tar #{file}/ -rf") say "Phantom JS #{version} bit installed." end private def get_adapter_from(database) adapter = database adapter = "mysql2" if adapter == "mysql" adapter end # Return the correct database gem for the given adapter def get_adapter_gem_from(adapter) gem = adapter gem = "pg" if adapter == "postgresql" gem end def generate_from(config, tests_dir = nil) tests_dir ||= self.class::TEST_DIR config[:gemfile] ||= {} use_database = (config[:database] and config[:database] != {}) if use_database gem = get_adapter_gem_from config[:database][:adapter] config[:gemfile][:database_gem] = "# This gem is the adapter we detected for your database connection.\ngem '#{gem}'" end empty_directory tests_dir directory "../files/generate/ready", "#{tests_dir}" template "../files/generate/templates/Gemfile.tt", "#{tests_dir}/Gemfile", config[:gemfile] if use_database template "../files/generate/templates/database.yml.tt", "#{tests_dir}/database.yml", config[:database] end template "../files/generate/templates/spec_helper.rb.tt", "#{tests_dir}/spec_helper.rb", config[:environment] say "" say "Your testing suite is ready! You can now make tests in the 'acceptance' directory." say "" if use_database say "Note: since you entered database information, we created a '.gitignore' file in the tests directory which will ignore the database.yml file by default. This is to prevent accidentally committing your database information to your repository." say "" say "In case you accidentally delete your database.yml file, we left a sample file named 'database.yml.sample' which will help you recreate your database.yml." end end end Roadkill.start