pax_global_header00006660000000000000000000000064135212442370014515gustar00rootroot0000000000000052 comment=d640b7617a69fa47679377b133065ed010611e8f combustion-1.1.1/000077500000000000000000000000001352124423700136775ustar00rootroot00000000000000combustion-1.1.1/.gitignore000066400000000000000000000003211352124423700156630ustar00rootroot00000000000000*.gem .bundle Gemfile.lock gemfiles/*.lock gemfiles/*.gemfile pkg/* .rubocop-*-yml .ruby-version .rvmrc spec/dummy/spec/internal/db/*.sqlite spec/dummy/spec/internal/test spec/dummy/spec/internal/test_another combustion-1.1.1/.rspec000066400000000000000000000000661352124423700150160ustar00rootroot00000000000000--color --tty --order random --require spec_helper.rb combustion-1.1.1/.rubocop.yml000066400000000000000000000012431352124423700161510ustar00rootroot00000000000000inherit_from: - https://gist.githubusercontent.com/pat/ba3b8ffb1901bfe5439b460943b6b019/raw/.rubocop.yml AllCops: TargetRubyVersion: 2.2 Bundler/OrderedGems: Exclude: - 'gemfiles/*' Layout/DotPosition: EnforcedStyle: trailing Layout/CaseIndentation: EnforcedStyle: end Layout/EndAlignment: EnforcedStyleAlignWith: variable Layout/IndentHeredoc: Enabled: false Metrics/BlockLength: Exclude: - 'combustion.gemspec' Style/ClassAndModuleChildren: Enabled: false Style/Documentation: Enabled: false Style/FrozenStringLiteralComment: Exclude: - 'gemfiles/*' Style/MultilineTernaryOperator: Exclude: - 'spec/dummy/db/migrate/*.rb' combustion-1.1.1/.travis.yml000066400000000000000000000006411352124423700160110ustar00rootroot00000000000000language: ruby dist: xenial env: matrix: - "DB_ADAPTER=sqlite3" - "DB_ADAPTER=postgresql" - "DB_ADAPTER=mysql2" rvm: - 2.2.10 - 2.3.8 - 2.4.6 - 2.5.5 - 2.6.3 before_install: - gem install bundler --version "~> 1.17" install: - bundle _1.17.3_ install --jobs=3 --retry=3 before_script: - bundle exec appraisal install script: bundle exec appraisal rake services: - mysql - postgresql combustion-1.1.1/Appraisals000066400000000000000000000026261352124423700157270ustar00rootroot00000000000000# frozen_string_literal: true if RUBY_VERSION.to_f <= 2.3 appraise "rails-3.1" do gem "rails", "~> 3.1.12" gem "mysql2", "~> 0.3.10" gem "pg", "< 1.0" gem "bundler", "~> 1.17" end appraise "rails-3.2" do gem "rails", "~> 3.2.22.5" gem "mysql2", "~> 0.3.10" gem "pg", "< 1.0" gem "bundler", "~> 1.17" end appraise "rails-4.0" do gem "rails", "~> 4.0.13" gem "mysql2", "~> 0.3.10" gem "pg", "< 1.0" gem "bundler", "~> 1.17" end appraise "rails-4.1" do gem "rails", "~> 4.1.16" gem "mysql2", "~> 0.3.13" gem "pg", "< 1.0" gem "bundler", "~> 1.17" end appraise "rails-4.2" do gem "rails", "~> 4.2.8" gem "mysql2", "~> 0.4.4" gem "pg", "< 1.0" gem "bundler", "~> 1.17" end end appraise "rails-5.0" do gem "rails", "~> 5.0.2" gem "mysql2", "~> 0.4.4" gem "pg", "< 1.0" end appraise "rails-5.1" do gem "rails", "~> 5.1.0" gem "mysql2", "~> 0.4.4" gem "pg", "< 1.0" end appraise "rails-5.2" do gem "rails", "~> 5.2.0" gem "mysql2", "~> 0.5.0" end if RUBY_VERSION.to_f >= 2.5 appraise "rails-6.0" do gem "rails", "~> 6.0.0.rc1" gem "mysql2", "~> 0.5.0" gem "sqlite3", "~> 1.4" end appraise "rails-edge" do gem "rails", :git => "https://github.com/rails/rails.git" gem "arel", :git => "https://github.com/rails/arel.git" gem "mysql2", "~> 0.5.0" gem "sqlite3", "~> 1.4" end end combustion-1.1.1/Gemfile000066400000000000000000000001411352124423700151660ustar00rootroot00000000000000# frozen_string_literal: true source "http://rubygems.org" gemspec gem "sqlite3", "~> 1.3.13" combustion-1.1.1/HISTORY000066400000000000000000000106561352124423700147730ustar00rootroot000000000000001.1.1 - August 3rd 2019 * Fix for latest Rails 6.0 release candidate. * Test suite updates (Rails edge, sqlite3, Rubocop) 1.1.0 - February 13th 2019 * Rails 6.0 support. 1.0.0 - October 3rd 2018 * No functional changes. * Added documentation about database preparation options. 0.9.1 - April 25th 2018 * Fix Rails 5.2 compatibility by not setting the deprecated secret_token configuration option. 0.9.0 - March 26th 2018 * Only reset databases that are either custom or the current one (Moritz Winter). * More consistency around environment handling (rather than presuming it's always the test environment). 0.8.0 - February 1st 2018 * Rails 5.2.0 support. * Requiring digest from std-lib directly. * Refactoring for cleaner code. 0.7.0 - June 20th 2017 * Confirm support for MRI frozen string literals. * Hide migration output (Michael Grosser). 0.6.0 - March 28th 2017 * Optionally disable database reset, schema loading, migrations (Sergey Kucher). * Allow for multiple test databases (Semyon Pupkov). 0.5.5 - July 23rd 2016 * Add PostGIS support (Roland Koch). * MySQL parameter fix (Mathieu Leduc-Hamel). 0.5.4 - January 12th 2016 * Remove silent_stream call for Rails 5.0 compatability (Bryan Ricker). * Fix duplicate migrations error (Semyon Pupkov). 0.5.3 - March 1st 2015 * Use migrations from dependent gems (Korotaev Danil, Меркушин Михаил). 0.5.2 - July 18th 2014 * Note MIT licence in gemspec (@ktdreyer). * Use local create/drop methods when resetting database (Bryan Ricker). * ERB is now supported in config/database.yml, matching Rails (@patorash). * The database now is configured before the application is loaded (@patorash). * Documentation and generated config.ru now specify explicly loading all Rails libraries by default (Pat Allan). 0.5.1 - July 25th 2013 * Mass assignment errors raise exceptions instead of just being logged (Pat Allan). * whilelist_attributes is only set for Rails 3.2 apps (Philip Arndt). * Support ActiveRecord 3.0.x (Philip Arndt). * Allow custom application configuration (Pablo Herrero). 0.5.0 - May 1st 2013 * whitelist_attributes is now set within configure_for_combustion, as it depends on which Railties are loaded. * Make sure Rails gems are loaded before the engine's gem (Pablo Herrero). * Fixed Rails version comparison (Josh Adam). 0.4.0 - March 16th 2013 * Don't delete the SQLite test database if it doesn't exist (Michael Gee, Alexander Rozumiy). * Support for secret_key_base for Rails 4 apps (Philip Arndt). * eager_load is set to true when using the production environment (Philip Arndt). * whiny_nils is not set if using Rails 4 (Philip Arndt). * Mysql2 can raise Mysql::Error with JRuby (Philip Arndt). * Whitelist attributes typo is fixed (Geoff Hodgson). * Mass assignment checks are now turned on, so errors are raised. This matches Rails' defaults for test environments (Josh Adams). * Combustion no longer loads all of the Rails stack by default, just Railties and ActiveSupport. A combustion-rails gem will be created that uses all of Rails by default (Philip Arndt). * Combustion classes now all define the outer module, so each can be required by themselves, should you desire (Philip Arndt). 0.3.3 - December 23rd 2012 * Removing version file - version number can just live in the gemspec. * Load ActionController and ActionMailer via their Railties, not non-existent Engines (Chris Beer). * SQL Schema support (Geoff Hodgson). * Documentation fixes (Philip Arndt, Inge Jørgensen, Erkan Yilmaz). * Include migrations from the internal app when migrating the database (Warren Seen). * Correctly drop the test database when using SQLite (Warren Seen). * Don't attempt to load sprockets for Rails 3.0.x (Alex Rozumey). 0.3.2 - March 3rd 2012 * Tentative Rails 3.0 and migrations support. * Allow for different internal app directory. 0.3.1 - September 12th 2011 * Allow for different versions of Capybara (Leo Liang). * Including Capybara::DSL instead of Capybara. * Require 3.1.0 or better. * Allow for JRuby in the database.yml template (Philip Arndt). 0.3.0 - September 2nd 2011 * Simple generator to create a pretty minimal internal Rails app. 0.2.0 - August 30th 2011 * Documentation. * Allow developers to choose which Rails modules they wish to be loaded. * Load Rails routes and Capybara helpers into RSpec examples when appropriate. 0.1.1 - August 24th 2011 * Support assets properly by loading ActionView and Sprockets railties. 0.1.0 - August 19th 2011 * First release, extracted from Dobro for HyperTiny. combustion-1.1.1/LICENCE000066400000000000000000000020351352124423700146640ustar00rootroot00000000000000Copyright (c) 2011 Pat Allan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. combustion-1.1.1/README.md000066400000000000000000000211761352124423700151650ustar00rootroot00000000000000# Combustion Combustion is a library to help you test your Rails Engines in a simple and effective manner, instead of creating a full Rails application in your spec or test folder. It allows you to write your specs within the context of your engine, using only the parts of a Rails app you need. ## Usage Get the gem into either your gemspec or your Gemfile, depending on how you manage your engine's dependencies: ```ruby # gemspec gem.add_development_dependency 'combustion', '~> 1.1' # Gemfile gem 'combustion', '~> 1.1' ``` In your `spec_helper.rb`, get Combustion to set itself up - which has to happen before you introduce `rspec/rails` and - if being used - `capybara/rails`. Here's an example within context: ```ruby require 'bundler' Bundler.require :default, :development # If you're using all parts of Rails: Combustion.initialize! :all # Or, load just what you need: # Combustion.initialize! :active_record, :action_controller require 'rspec/rails' # If you're using Capybara: # require 'capybara/rails' RSpec.configure do |config| config.use_transactional_fixtures = true end ``` You'll also want to run the generator that creates a minimal set of files expected by Rails - run this in the directory of your engine: ```shell combust # or, if bundling with the git repo: bundle exec combust ``` Minitest support is considered to be experimental, but it's certainly working [for some](https://github.com/pat/combustion/issues/78). Comments on others' experiences are welcome! What Combustion is doing is setting up a Rails application at `spec/internal` - but you only need to add the files within that directory that you're going to use. Read on for some detail about what that involves. If you want to use Cucumber, I recommend starting with [these notes in issue #16](https://github.com/pat/combustion/issues/16) from Niklas Cathor. ### Configuring a different test app directory If you want your app to be located somewhere other than `spec/internal`, then make sure you configure it before you call `Combustion.initialize!`: ```ruby Combustion.path = 'spec/dummy' Combustion.initialize! :all ``` ### Configuring which Rails modules should be loaded. By default, Combustion doesn't come with any of the Rails stack. You can customise this though - just pass in what you'd like loaded to the `Combustion.initialize!` call: ```ruby Combustion.initialize! :active_record, :action_controller, :action_view, :sprockets ``` And then in your engine's Gemfile: ```ruby group :test do gem 'activerecord' gem 'actionpack' # action_controller, action_view gem 'sprockets' end ``` Make sure to specify the appropriate version that you want to use. ActiveSupport and Railties are always loaded, as they're an integral part of Rails. ### Using Models and ActiveRecord If you're using ActiveRecord, then there are two critical files within your internal Rails app at `spec/internal` that you'll need to modify: * config/database.yml * db/schema.rb Both follow the same structure as in any normal Rails application - and the schema file lets you avoid migrations, as it gets run whenever the test suite starts. Here's a quick sample (note that tables are overwritten if they already exist - this is necessary): ```ruby ActiveRecord::Schema.define do create_table(:pages, :force => true) do |t| t.string :name t.text :content t.timestamps end end ``` #### Disabling Database Preparation If you are preparing your own database manually or through different processes, you can disable different parts of the setup process by the following flags: `:database_reset`, `:load_schema`, and `:database_migrate`. All default to true. ```ruby Combustion.initialize! :active_record, :database_reset => false, :load_schema => false ``` ### Configuring Combustion to initialise the test db from a .sql file instead of schema.rb Name the file structure.sql and configure Combustion to use it before initialising: ```ruby Combustion.schema_format = :sql Combustion.initialize! :all ``` Any models that aren't provided by your engine should be located at `spec/internal/app/models`. ### Using ActionController and ActionView You'll only need to add controllers and views to your internal Rails app for whatever you're testing that your engine doesn't provide - this may be nothing at all, so perhaps you don't even need `spec/internal/app/views` or `spec/internal/app/controllers` directories. However, if you're doing any testing of your engine's controllers or views, then you're going to need routes set up for them - so modify `spec/internal/config/routes.rb` accordingly: ```ruby Rails.application.routes.draw do resources :pages end ``` Just like in a standard Rails app, if you have a mounted engine, then its routes are accessible through whatever it has been loaded as. ### Customizing Rails application settings If you would like to specify any Rails configuration parameter, you can do it without creating any environment file, simply passing a block to Combustion.initialize! like this: ```ruby Combustion.initialize! :all do config.active_record.whitelist_attributes = false end ``` Values given through the initialize! block will be set during Rails initialization proccess, exactly before the corresponding environment file inside `spec/internals/config/enviroments` is loaded (when that file exists), overriding Combustion's defaults. Parameters defined in, for instance, `spec/internals/config/environments/test.rb`, would override Combustion's defaults and also config settings passed to initialize!. ### Using other Rails-focused libraries Be aware that other gems may require parts of Rails when they're loaded, and this could cause some issues with Combustion's own setup. You may need to manage the loading yourself by setting `:require` to false in your Gemfile for the gem in question, and then requiring it manually in your spec_helper. View [issue #33](https://github.com/pat/combustion/issues/33) for an example with FactoryGirl. ### Environment and Logging Your tests will execute within the test environment for the internal Rails app - and so logs are available at `spec/internal/log/test.log`. You should probably create that log directory so Rails doesn't complain. ### Rack it up Once you've got this set up, you can fire up your test environment quite easily with Rack - a `config.ru` file is provided by the generator. Just run `rackup` and visit [http://localhost:9292](http://localhost:9292). ### Get your test on! Now you're good to go - you can write specs within your engine's spec directory just like you were testing a full Rails application - models in `spec/models`, controllers in `spec/controllers`. If you bring Capybara into the mix, then the standard helpers from that will be loaded as well. ```ruby require 'spec_helper' describe Page do describe '#valid' do it 'requires a name' do # This is just an example. Go write your own tests! end end end ``` ## Compatibility The current test matrix covers MRI 2.2 to 2.4, and Rails 3.1 to 5.0. It will possibly work on older versions and other Ruby implementations as well. You can also use Combustion with multiple versions of Rails to test compatibility across them. [Appraisal](https://github.com/thoughtbot/appraisal) is a gem that can help with this, and a good starting reference is the [Thinking Sphinx](https://github.com/pat/thinking-sphinx) test suite, which runs against [multiple versions](https://github.com/pat/thinking-sphinx/blob/master/Appraisals) of Rails. ## Limitations and Known Issues Combustion is currently written with the expectation it'll be used with RSpec, but others have got it working with [Minitest](https://github.com/pat/combustion/issues/78). I'd love to make this more flexible - if you want to give it a shot before I get around to it, patches are very much welcome. I've not tried using this with Cucumber, but it should work in theory without too much hassle. Let me know if I'm wrong! ## Contributing Please note that this project now has a [Contributor Code of Conduct](http://contributor-covenant.org/version/1/0/0/). By participating in this project you agree to abide by its terms. Contributions are very much welcome - but keep in mind the following: * Keep patches in a separate branch * Don't mess with the version or history file. I'll take care of that when the patch is merged in. The tests are extremely minimal, and patches to extend the suite are especially welcome. ## Credits Copyright (c) 2011-2017, Combustion is developed and maintained by Pat Allan, and is released under the open MIT Licence. Many thanks to HyperTiny for encouraging its development, and [all who have contributed patches](https://github.com/pat/combustion/contributors). combustion-1.1.1/Rakefile000066400000000000000000000004401352124423700153420ustar00rootroot00000000000000# frozen_string_literal: true require "bundler/gem_tasks" require "rspec/core/rake_task" require "rubocop/rake_task" RSpec::Core::RakeTask.new(:spec) RuboCop::RakeTask.new(:rubocop) Rake::Task["default"].clear if Rake::Task.task_defined?("default") task :default => %i[ rubocop spec ] combustion-1.1.1/combustion.gemspec000066400000000000000000000021631352124423700174300ustar00rootroot00000000000000# frozen_string_literal: true Gem::Specification.new do |s| s.name = "combustion" s.version = "1.1.1" s.authors = ["Pat Allan"] s.email = ["pat@freelancing-gods.com"] s.homepage = "https://github.com/pat/combustion" s.summary = "Elegant Rails Engine Testing" s.description = "Test your Rails Engines without needing a full Rails app" s.license = "MIT" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- exe/*`.split("\n").map do |file| File.basename(file) end s.bindir = "exe" s.require_paths = ["lib"] s.add_runtime_dependency "activesupport", ">= 3.0.0" s.add_runtime_dependency "railties", ">= 3.0.0" s.add_runtime_dependency "thor", ">= 0.14.6" s.add_development_dependency "appraisal", "~> 2.1.0" s.add_development_dependency "mysql2" s.add_development_dependency "pg" s.add_development_dependency "rails" s.add_development_dependency "rspec" s.add_development_dependency "rubocop", "~> 0.68.0" s.add_development_dependency "sqlite3" end combustion-1.1.1/exe/000077500000000000000000000000001352124423700144605ustar00rootroot00000000000000combustion-1.1.1/exe/combust000077500000000000000000000002311352124423700160560ustar00rootroot00000000000000#!/usr/bin/env ruby # -*- mode: ruby -*- # frozen_string_literal: true require "combustion" require "combustion/generator" Combustion::Generator.start combustion-1.1.1/lib/000077500000000000000000000000001352124423700144455ustar00rootroot00000000000000combustion-1.1.1/lib/combustion.rb000066400000000000000000000040121352124423700171510ustar00rootroot00000000000000# frozen_string_literal: true require "rails" require "active_support/dependencies" module Combustion module Configurations end mattr_accessor :path, :schema_format, :setup_environment self.path = "/spec/internal" self.schema_format = :ruby MODULES = if Rails.version.to_f >= 3.1 %w[ active_record action_controller action_view action_mailer sprockets ] else %w[ active_record action_controller action_view action_mailer ] end def self.initialize!(*modules, &block) self.setup_environment = block if block_given? options = modules.extract_options! modules = MODULES if modules == [:all] modules.each { |mod| require "#{mod}/railtie" } Bundler.require :default, Rails.env Combustion::Application.configure_for_combustion include_database modules, options Combustion::Application.initialize! include_rspec end def self.include_database(modules, options) return unless modules.map(&:to_s).include? "active_record" Combustion::Application.config.to_prepare do Combustion::Database.setup(options) end end def self.include_rspec return unless defined?(RSpec) && RSpec.respond_to?(:configure) RSpec.configure do |config| include_capybara_into config config.include Combustion::Application.routes.url_helpers if Combustion::Application.routes.respond_to?(:mounted_helpers) config.include Combustion::Application.routes.mounted_helpers end end end def self.include_capybara_into(config) return unless defined?(Capybara) config.include Capybara::RSpecMatchers if defined?(Capybara::RSpecMatchers) config.include Capybara::DSL if defined?(Capybara::DSL) return if defined?(Capybara::RSpecMatchers) || defined?(Capybara::DSL) config.include Capybara end end require "combustion/application" require "combustion/configurations/action_controller" require "combustion/configurations/action_mailer" require "combustion/configurations/active_record" require "combustion/database" combustion-1.1.1/lib/combustion/000077500000000000000000000000001352124423700166275ustar00rootroot00000000000000combustion-1.1.1/lib/combustion/application.rb000066400000000000000000000027171352124423700214660ustar00rootroot00000000000000# frozen_string_literal: true require "securerandom" require "digest" Rails.env = ENV["RAILS_ENV"] || "test" module Combustion class Application < Rails::Application version = Rails.version.to_f # Core Settings config.cache_classes = true config.consider_all_requests_local = true config.eager_load = Rails.env.production? config.secret_key_base = SecureRandom.hex if version >= 4.0 config.whiny_nils = true if version < 4.0 config.secret_token = Digest::SHA1.hexdigest Time.now.to_s if version < 5.2 # ActiveSupport Settings config.active_support.deprecation = :stderr # Some settings we're not sure if we want, so let's not load them by # default. Instead, wait for this method to be invoked (to get around # load-order complications). def self.configure_for_combustion config.root = File.expand_path File.join(Dir.pwd, Combustion.path) Combustion::Configurations::ActiveRecord.call config Combustion::Configurations::ActionController.call config Combustion::Configurations::ActionMailer.call config config.assets.enabled = true if defined?(Sprockets) end initializer( :load_customized_environment_for_combustion, :before => :load_environment_config, :group => :all ) do next unless Combustion.setup_environment Combustion::Application.class_eval(&Combustion.setup_environment) end end end combustion-1.1.1/lib/combustion/configurations/000077500000000000000000000000001352124423700216615ustar00rootroot00000000000000combustion-1.1.1/lib/combustion/configurations/action_controller.rb000066400000000000000000000005451352124423700257320ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Configurations::ActionController def self.call(config) return unless defined?(ActionController::Railtie) config.action_dispatch.show_exceptions = false config.action_controller.perform_caching = false config.action_controller.allow_forgery_protection = false end end combustion-1.1.1/lib/combustion/configurations/action_mailer.rb000066400000000000000000000004441352124423700250160ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Configurations::ActionMailer def self.call(config) return unless defined?(ActionMailer::Railtie) config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = {:host => "www.example.com"} end end combustion-1.1.1/lib/combustion/configurations/active_record.rb000066400000000000000000000007361352124423700250250ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Configurations::ActiveRecord def self.call(config) return unless defined?(ActiveRecord::Railtie) return unless ::ActiveRecord.constants.include?(:MassAssignmentSecurity) # Turn on ActiveRecord attribute whitelisting # This way the dummy app matches new rails apps re: this setting config.active_record.whitelist_attributes = true config.active_record.mass_assignment_sanitizer = :strict end end combustion-1.1.1/lib/combustion/database.rb000066400000000000000000000016441352124423700207250ustar00rootroot00000000000000# frozen_string_literal: true module Combustion module Databases end class Database DEFAULT_OPTIONS = { :database_reset => true, :load_schema => true, :database_migrate => true }.freeze def self.setup(options = {}) options = DEFAULT_OPTIONS.merge options Combustion::Database::Reset.call if options[:database_reset] Combustion::Database::LoadSchema.call if options[:load_schema] Combustion::Database::Migrate.call if options[:database_migrate] end end end require "combustion/databases/base" require "combustion/databases/firebird" require "combustion/databases/mysql" require "combustion/databases/oracle" require "combustion/databases/postgresql" require "combustion/databases/sql_server" require "combustion/databases/sqlite" require "combustion/database/load_schema" require "combustion/database/migrate" require "combustion/database/reset" combustion-1.1.1/lib/combustion/database/000077500000000000000000000000001352124423700203735ustar00rootroot00000000000000combustion-1.1.1/lib/combustion/database/load_schema.rb000066400000000000000000000012521352124423700231570ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Database::LoadSchema UnknownSchemaFormat = Class.new StandardError def self.call new.call end def call ActiveRecord::Schema.verbose = false case schema_format when :ruby load_ruby_schema when :sql load_sql_schema else raise UnknownSchemaFormat, "Unknown schema format: #{schema_format}" end end private def load_ruby_schema load Rails.root.join("db", "schema.rb") end def load_sql_schema ActiveRecord::Base.connection.execute( File.read(Rails.root.join("db", "structure.sql")) ) end def schema_format Combustion.schema_format end end combustion-1.1.1/lib/combustion/database/migrate.rb000066400000000000000000000025471352124423700223600ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Database::Migrate def self.call new.call end def call if ActiveRecord::VERSION::STRING.to_f >= 5.2 migration_context.migrate elsif ActiveRecord::VERSION::STRING.to_f >= 3.1 migrator.migrate paths, nil else paths.each { |path| migrator.migrate path, nil } end end private def base_migration_paths if migrator.respond_to?(:migrations_paths) migrator.migrations_paths else Array("db/migrate/") end end def engine_migration_paths migration_paths = Rails.application.paths["db/migrate"].to_a if engine_paths_exist_in?(migration_paths) migration_paths else base_migration_paths + migration_paths end end def engine_path Rails.application.root.sub(::Combustion.path, "") end def engine_paths_exist_in?(paths) paths.include?(engine_path.join("db/migrate").to_s) end def migration_context if ActiveRecord::MigrationContext.instance_method(:initialize).arity <= 1 ActiveRecord::MigrationContext.new paths else ActiveRecord::MigrationContext.new( paths, ActiveRecord::Base.connection.schema_migration ) end end def migrator @migrator ||= ActiveRecord::Migrator end def paths (engine_migration_paths + [File.join(Rails.root, "db/migrate")]).uniq end end combustion-1.1.1/lib/combustion/database/reset.rb000066400000000000000000000033411352124423700220430ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Database::Reset UnsupportedDatabase = Class.new StandardError OPERATOR_PATTERNS = { Combustion::Databases::MySQL => [/mysql/], Combustion::Databases::PostgreSQL => [/postgres/, /postgis/], Combustion::Databases::SQLite => [/sqlite/], Combustion::Databases::SQLServer => [/sqlserver/], Combustion::Databases::Oracle => %w[ oci oracle ], Combustion::Databases::Firebird => %w[ firebird ] }.freeze RAILS_DEFAULT_ENVIRONMENTS = %w[ development production test ].freeze def self.call new.call end def initialize ActiveRecord::Base.configurations = YAML.safe_load( ERB.new(database_yaml).result, [], [], true ) end def call resettable_db_configs.each_value do |configuration| adapter = configuration["adapter"] || configuration["url"].split("://").first operator_class(adapter).new(configuration).reset end end private def database_yaml File.read "#{Rails.root}/config/database.yml" end def operator_class(adapter) klass = nil OPERATOR_PATTERNS.each do |operator, keys| klass = operator if keys.any? { |key| adapter[key] } end return klass if klass raise UnsupportedDatabase, "Unsupported database type: #{adapter}" end # All database configs except Rails default environments # that are not currently in use def resettable_db_configs all_configurations = ActiveRecord::Base.configurations.to_h unused_environments = RAILS_DEFAULT_ENVIRONMENTS - [Rails.env.to_s] resettable_environments = all_configurations.keys - unused_environments all_configurations.select { |name| resettable_environments.include?(name) } end end combustion-1.1.1/lib/combustion/databases/000077500000000000000000000000001352124423700205565ustar00rootroot00000000000000combustion-1.1.1/lib/combustion/databases/base.rb000066400000000000000000000006441352124423700220210ustar00rootroot00000000000000# frozen_string_literal: true require "active_support/core_ext/module/delegation" class Combustion::Databases::Base def initialize(configuration) @configuration = configuration end def reset drop create establish_connection Rails.env.to_sym end private attr_reader :configuration delegate :establish_connection, :connection, :to => :base def base ActiveRecord::Base end end combustion-1.1.1/lib/combustion/databases/firebird.rb000066400000000000000000000003051352124423700226670ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Databases::Firebird < Combustion::Databases::Base def reset establish_connection Rails.env.to_sym connection.recreate_database! end end combustion-1.1.1/lib/combustion/databases/mysql.rb000066400000000000000000000042371352124423700222560ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Databases::MySQL < Combustion::Databases::Base ACCESS_DENIED_ERROR = 10_145 def reset establish_connection(configuration.merge("database" => nil)) super end private def charset configuration["charset"] || ENV["CHARSET"] || "utf8" end def charset_error return "" unless config["charset"] "(if you set the charset manually, make sure you have a matching collation)" end def collation configuration["collation"] || ENV["COLLATION"] || "utf8_unicode_ci" end def create connection.create_database configuration["database"], creation_options establish_connection configuration rescue error_class => error rescue_create_from error end def create_as_root(error) establish_connection configuration.merge( "database" => nil, "username" => "root", "password" => request_password(error) ) connection.create_database config["database"], creation_options connection.execute grant_statement establish_connection configuration end def creation_options {:charset => charset, :collation => collation} end def drop connection.drop_database configuration["database"] end def error_class if configuration["adapter"][/jdbc/] # FIXME: After Jdbcmysql gives this class require "active_record/railties/jdbcmysql_error" ArJdbcMySQL::Error elsif config["adapter"][/mysql2/] && defined?(Mysql2) Mysql2::Error else Mysql::Error end end def grant_statement <<-SQL GRANT ALL PRIVILEGES ON #{configuration["database"]}.* TO '#{configuration["username"]}'@'localhost' IDENTIFIED BY '#{configuration["password"]}' WITH GRANT OPTION; SQL end def request_password(error) print <<-TXT.strip #{error.error}. Please provide the root password for your mysql installation > TXT $stdin.gets.strip end def rescue_create_from(error) if error.errno == ACCESS_DENIED_ERROR create_as_root(error) return end warn <<-TXT #{error.error} Couldn't create database for #{config.inspect}, charset: #{charset}, collation: #{collation} #{charset_error} TXT end end combustion-1.1.1/lib/combustion/databases/oracle.rb000066400000000000000000000004021352124423700223440ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Databases::Oracle < Combustion::Databases::Base def reset establish_connection Rails.env.to_sym connection.structure_drop.split(";\n\n").each do |ddl| connection.execute(ddl) end end end combustion-1.1.1/lib/combustion/databases/postgresql.rb000066400000000000000000000016231352124423700233100ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Databases::PostgreSQL < Combustion::Databases::Base def reset base.clear_active_connections! establish_connection(postgres_configuration) super end private def create connection.create_database( configuration["database"], configuration.merge("encoding" => encoding) ) rescue StandardError => error warn error, *error.backtrace warn "Couldn't create database for #{configuration.inspect}" end def drop connection.drop_database(configuration["database"]) end def encoding configuration["encoding"] || ENV["CHARSET"] || "utf8" end def postgres_configuration configuration.merge( "database" => "postgres", "schema_search_path" => schema_search_path ) end def schema_search_path configuration["adapter"][/postgis/] ? "public, postgis" : "public" end end combustion-1.1.1/lib/combustion/databases/sql_server.rb000066400000000000000000000003731352124423700232730ustar00rootroot00000000000000# frozen_string_literal: true class Combustion::Databases::SQLServer < Combustion::Databases::Base def reset establish_connection configuration.merge("database" => "master") connection.recreate_database! configuration["database"] end end combustion-1.1.1/lib/combustion/databases/sqlite.rb000066400000000000000000000012711352124423700224050ustar00rootroot00000000000000# frozen_string_literal: true require "fileutils" require "pathname" class Combustion::Databases::SQLite < Combustion::Databases::Base private def create if exists? warn "#{config["database"]} already exists" return end establish_connection configuration connection rescue StandardError => error warn error, *error.backtrace warn "Couldn't create database for #{configuration.inspect}" end def drop FileUtils.rm_f file if exists? end def exists? File.exist? file end def file @file ||= path.absolute? ? path.to_s : File.join(Rails.root, path) end def path @path ||= Pathname.new configuration["database"] end end combustion-1.1.1/lib/combustion/generator.rb000066400000000000000000000017121352124423700211430ustar00rootroot00000000000000# frozen_string_literal: true require "thor/group" module Combustion class Generator < Thor::Group include Thor::Actions def self.source_root File.expand_path File.join(File.dirname(__FILE__), "..", "..") end def create_directories empty_directory "spec/internal" empty_directory "spec/internal/config" empty_directory "spec/internal/db" empty_directory "spec/internal/log" empty_directory "spec/internal/public" end def create_files template "templates/routes.rb", "spec/internal/config/routes.rb" template "templates/database.yml", "spec/internal/config/database.yml" template "templates/schema.rb", "spec/internal/db/schema.rb" template "templates/config.ru", "config.ru" create_file "spec/internal/public/favicon.ico" create_file "spec/internal/log/.gitignore" do "*.log" end end end end combustion-1.1.1/spec/000077500000000000000000000000001352124423700146315ustar00rootroot00000000000000combustion-1.1.1/spec/database_spec.rb000066400000000000000000000020071352124423700177330ustar00rootroot00000000000000# frozen_string_literal: true module Combustion describe Database do before(:all) do Dir.chdir(File.expand_path("dummy", __dir__)) do Combustion.initialize! :active_record end end it "creates dummy table from migration in base database" do expect(Model.connection.table_exists?("dummy_table")).to eq true expect(Model.connection.table_exists?("dummy_in_another_db")).to eq false end it "creates another dummy table from another database" do expect(ModelInAnotherDb.connection.table_exists?("dummy_table")). to eq false expect(ModelInAnotherDb.connection.table_exists?("dummy_in_another_db")). to eq true end it "returns test database for model with default connection" do expect(Model.connection_config[:database]).to match(/test/) end it "returns test_another for model with connection to second database" do expect(ModelInAnotherDb.connection_config[:database]). to match(/test_another/) end end end combustion-1.1.1/spec/dummy/000077500000000000000000000000001352124423700157645ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/db/000077500000000000000000000000001352124423700163515ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/db/migrate/000077500000000000000000000000001352124423700200015ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/db/migrate/20150717075542_create_dummy_test_table.rb000066400000000000000000000003461352124423700266720ustar00rootroot00000000000000# frozen_string_literal: true superclass = ActiveRecord::VERSION::MAJOR < 5 ? ActiveRecord::Migration : ActiveRecord::Migration[4.2] class CreateDummyTestTable < superclass def change create_table "dummy_table" end end combustion-1.1.1/spec/dummy/db/migrate/20150717075543_create_dummy_test_table_in_another_db.rb000066400000000000000000000004611352124423700315440ustar00rootroot00000000000000# frozen_string_literal: true superclass = ActiveRecord::VERSION::MAJOR < 5 ? ActiveRecord::Migration : ActiveRecord::Migration[4.2] class CreateDummyTestTableInAnotherDb < superclass def change create_table "dummy_in_another_db" end def connection ModelInAnotherDb.connection end end combustion-1.1.1/spec/dummy/lib/000077500000000000000000000000001352124423700165325ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/lib/engine.rb000066400000000000000000000003531352124423700203250ustar00rootroot00000000000000# frozen_string_literal: true module Dummy class Engine < ::Rails::Engine initializer :dummy, :before => :load_init_rb do |app| app.config.paths["db/migrate"].concat(config.paths["db/migrate"].expanded) end end end combustion-1.1.1/spec/dummy/spec/000077500000000000000000000000001352124423700167165ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/000077500000000000000000000000001352124423700205325ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/app/000077500000000000000000000000001352124423700213125ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/app/models/000077500000000000000000000000001352124423700225755ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/app/models/model.rb000066400000000000000000000001461352124423700242230ustar00rootroot00000000000000# frozen_string_literal: true class Model < ActiveRecord::Base self.table_name = "dummy_table" end combustion-1.1.1/spec/dummy/spec/internal/app/models/model_in_another_db.rb000066400000000000000000000002371352124423700270770ustar00rootroot00000000000000# frozen_string_literal: true class ModelInAnotherDb < ActiveRecord::Base self.table_name = "dummy_in_another_db" establish_connection :test_another end combustion-1.1.1/spec/dummy/spec/internal/config/000077500000000000000000000000001352124423700217775ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/config/database.yml000066400000000000000000000004311352124423700242640ustar00rootroot00000000000000test: &defaults adapter: <%= ENV.fetch("DB_ADAPTER") %> database: test <% if ENV["DB_HOST"] %> host: <%= ENV["DB_HOST"] %> <% end %> <% if ENV["DB_USERNAME"] %> username: <%= ENV["DB_USERNAME"] %> <% end %> test_another: <<: *defaults database: test_another combustion-1.1.1/spec/dummy/spec/internal/config/routes.rb000066400000000000000000000002251352124423700236440ustar00rootroot00000000000000# frozen_string_literal: true Rails.application.routes.draw do # Add your own routes here, or remove this file if you don't have need for it. end combustion-1.1.1/spec/dummy/spec/internal/db/000077500000000000000000000000001352124423700211175ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/db/schema.rb000066400000000000000000000002431352124423700227030ustar00rootroot00000000000000# frozen_string_literal: true ActiveRecord::Schema.define do # Set up any tables you need to exist for your test suite that don't belong # in migrations. end combustion-1.1.1/spec/dummy/spec/internal/log/000077500000000000000000000000001352124423700213135ustar00rootroot00000000000000combustion-1.1.1/spec/dummy/spec/internal/log/.gitignore000066400000000000000000000000051352124423700232760ustar00rootroot00000000000000*.logcombustion-1.1.1/spec/spec_helper.rb000066400000000000000000000006251352124423700174520ustar00rootroot00000000000000# frozen_string_literal: true require "bundler/setup" require "combustion" if Rails::VERSION::STRING.to_f < 4.1 require "active_record" require "active_record/connection_adapters/mysql2_adapter" class ActiveRecord::ConnectionAdapters::Mysql2Adapter NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY" end end require File.expand_path("dummy/lib/engine.rb", __dir__) combustion-1.1.1/templates/000077500000000000000000000000001352124423700156755ustar00rootroot00000000000000combustion-1.1.1/templates/config.ru000066400000000000000000000002451352124423700175130ustar00rootroot00000000000000# frozen_string_literal: true require "rubygems" require "bundler" Bundler.require :default, :development Combustion.initialize! :all run Combustion::Application combustion-1.1.1/templates/database.yml000066400000000000000000000001471352124423700201660ustar00rootroot00000000000000test: adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3 database: db/combustion_test.sqlite combustion-1.1.1/templates/routes.rb000066400000000000000000000002251352124423700175420ustar00rootroot00000000000000# frozen_string_literal: true Rails.application.routes.draw do # Add your own routes here, or remove this file if you don't have need for it. end combustion-1.1.1/templates/schema.rb000066400000000000000000000002431352124423700174610ustar00rootroot00000000000000# frozen_string_literal: true ActiveRecord::Schema.define do # Set up any tables you need to exist for your test suite that don't belong # in migrations. end