• Stars
    star
    674
  • Rank 66,980 (Top 2 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 13 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple, elegant testing for Rails Engines

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:

# gemspec
gem.add_development_dependency 'combustion', '~> 1.3'

# Gemfile
gem 'combustion', '~> 1.3'

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:

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

Please note that using :all as an argument for Combustion.initialize! will load all key parts of Rails that are considered essential for that version. For example: ActiveJob is only loaded for Rails 4.2 onwards, and Sprockets is only loaded for Rails 3.1-6.1 (as it is no longer part of the default set in 7.0).

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:

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. 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 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!:

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:

Combustion.initialize! :active_record, :action_controller,
                       :action_view, :sprockets

And then in your engine's Gemfile:

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):

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.

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:

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:

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:

Combustion.initialize! :all do
  config.active_record.whitelist_attributes = false
end

Values given through the initialize! block will be set during Rails initialization process, 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 for an example with FactoryBot.

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.

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.

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.4 to 3.1, and Rails 3.1 to 7.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 is a gem that can help with this, and a good starting reference is the Thinking Sphinx test suite, which runs against multiple versions 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. 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. 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-2021, 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.

More Repositories

1

thinking-sphinx

Sphinx/Manticore plugin for ActiveRecord/Rails
Ruby
1,620
star
2

gutentag

A good, simple, solid tagging extension for ActiveRecord.
Ruby
473
star
3

riddle

Ruby Client API for Sphinx
Ruby
136
star
4

ts-delayed-delta

Manage delta indexes via Delayed Job for Thinking Sphinx
Ruby
73
star
5

thinking-sphinx-raspell

An add-on gem for spelling suggestions in Thinking Sphinx
Ruby
58
star
6

ts-datetime-delta

Manage delta indexes via datetime columns for Thinking Sphinx
Ruby
45
star
7

fakeweb-matcher

An RSpec matcher for the Fakeweb HTTP stubbing library
Ruby
37
star
8

calendav

Interact with CalDAV via Ruby
Ruby
36
star
9

sliver

A super simple, extendable Rack API.
Ruby
30
star
10

sphinx

Free open-source SQL full-text search engine
C++
26
star
11

active-matchers

Helpful rspec matchers for testing validations and associations.
Ruby
23
star
12

ginger

Run specs/tests multiple times through different gem versions
Ruby
22
star
13

render_api

Ruby interface for the render.com API.
Ruby
19
star
14

pat.github.com

HTML
17
star
15

railscamps.com

Rails Camps Website
HTML
15
star
16

pedantic

Pares text down to the words that matter
Ruby
14
star
17

pippin

A PayPal Rails Engine that handles IPNs
Ruby
14
star
18

drumknott-server

Server for storing static site search data.
Ruby
11
star
19

gyoza

Streamlined Editing for GitHub Pages
JavaScript
11
star
20

support-act

Encouraging people to buy albums alongside their streaming, to better support artists.
Ruby
11
star
21

not-a-mock

A cleaner and DRYer alternative to mocking and stubbing with RSpec.
Ruby
10
star
22

laughtrack

A festival buzz tracker
Ruby
10
star
23

joiner

Builds ActiveRecord joins from association paths
Ruby
7
star
24

sslocal-rb

Make local environment SSL as streamlined as possible.
Ruby
7
star
25

numbr5

Thank-you bot for IRC (and maybe more)
Ruby
7
star
26

sphinx-tute

Project for the Sphinx Tutorial at RailsConf 2009
Ruby
6
star
27

ruby-netcdf

Copy of source for ruby-netcdf gem, with tweak for MRI 2.0.0
C
6
star
28

enkoder

An extension to the Rails TextHelper module that can be used to protect email addresses (or other information) by obfuscating them using JavaScript code. Written by Dan Benjamin.
Ruby
6
star
29

nudge

Simple Static Site Deployer via Git
Ruby
6
star
30

radiant-tiny-mce

Tiny MCE Filter and Asset Management (via Paperclipped)
5
star
31

tramampoline

Trampoline Website, now with registrations
HTML
5
star
32

thin-glazed

SSL Proxy for HTTP Thin servers
Ruby
5
star
33

ts-sidekiq-delta

Thinking Sphinx - Sidekiq Deltas
Ruby
5
star
34

gzipped_tar

In-memory reading/writing of .tar.gz files
Ruby
5
star
35

radiant-layout-layer

Automatically create Radiant layouts based on HTML files in other extensions
Ruby
5
star
36

inkan

Unique file markers for tracking whether files have been changed.
Ruby
4
star
37

vcr_assistant

Manages VCR cassettes and set-up logic for RSpec.
Ruby
4
star
38

beer-tracker

Website/API partner for Numbr5
3
star
39

sslocal-js

Make local environment SSL as streamlined as possible.
JavaScript
3
star
40

chargify-loops

A Rails Engine for Chargify Webhooks
Ruby
3
star
41

laughtrack-couch

Couch Logic and Views for LaughTrack
JavaScript
2
star
42

postie

Ruby
2
star
43

babushka-deps

Babushka Dependencies
Ruby
2
star
44

radiant-publican

Automatically copy Radiant extensions' public files on every load for the development environment
2
star
45

spreadsheet-excel

Resurrecting an old gem.
Ruby
2
star
46

.js

JavaScript
1
star
47

shithead

A card game
Ruby
1
star
48

bb8

Keeps Terraform state and variables secret per environment, with help from Voltos
Ruby
1
star
49

lipwig

Write group emails in Markdown, send via Postmark or SMTP.
Ruby
1
star
50

ruby-event-guides

Tips and thoughts about running Rails Camps and RubyConf AU.
1
star
51

thinking-sphinx-examples

Example of advanced search form.
Ruby
1
star
52

trampolinemelb.com

Website for Trampoline, a cross-discipline unconference.
1
star
53

livecal

Translate ical/ics files into actual calendars and events
Ruby
1
star
54

isnotagithubberyet

Because Jan said I should - and who needs a better reason than that?
Ruby
1
star
55

resque-crashlog

Resque failure handler for crashlog.io
Ruby
1
star
56

lu-tze

Automated Backup Helper for Heroku
Ruby
1
star
57

json_template_benchmarking

Ruby
1
star