Bundler for Rails 2.3.x
Update RubyGems and Passenger
Bundler requires Rubygems >= 1.3.6. Run gem update --system
if you have an older version.
It also is not compatible with older versions of passenger, so bring that up to date as well (2.2.15 works).
If you installed RubyGems through apt (which you should never do!), you may see a message giving you a hint to use apt to update.
Some people advise to install the 'rubygems-update-1.3.7' gem on Ubuntu systems if you used apt to install RubyGems.
I did that - and lost all...
Using local fonts with Webpack / Webpacker
When we want to use our own (or bought) fonts in an application with Webpack(er), we have two options. We can
- put the fonts directly into your Webpack's assets folder or
- write an npm package with an own sass file that can be imported from the Webpack manifest.
Load fonts from your assets folder
The first option turns out to be straightforward: Import the stylesheets in the index.js of the pack you're using:
// webpack_source_path/application/index.js
import './stylesheets/reset'
import...
MongoMapper for Rails 2 on Ruby 1.9
MongoMapper is a MongoDB adapter for Ruby. We've forked it so it works for Rails 2.3.x applications running on Ruby 1.9. [1]
makandra/mongomapper
is based on the "official" rails2
branch [2] which contains commits that were added after 0.8.6 was released. Tests are fully passing on our fork for Ruby 1.8.7, REE, and Ruby 1.9.3.
To use it, add this to your Gemfile
:
gem 'mongo_mapper', :git => 'git://github.com/makandra/mongomapper.git', :branch => 'rails2'
...
natritmeyer/site_prism
SitePrism gives you a simple, clean and semantic DSL for describing your site using the Page Object Model pattern, for use with Capybara in automated acceptance testing.
The Page Object Model is a test automation pattern that aims to create an abstraction of your site's user interface that can be used in tests. The most common way to do this is to model each page as a class, and to then use instances of those classes in your tests.
If a class represents a page then each element of the page is represented by a method that, when cal...
Mixed Content Examples
The pages […] allow you to see different types of mixed content and test how they behave in your browser. The "Secure" pages are referencing assets with HTTPS, the "Non-Secure" pages are referencing them with HTTP. Generally, you'll observe the same behavior with both Secure pages and the Secure HTTP page for a given test; the behavior will change on the Non-Secure HTTPS page.
Also see Testing HTTPS with badssl.com.
Manually requiring your application's models will lead to trouble
In a nutshell:
If you require your Rails models manually, pay attention to the path you use. Unless you have to, don't do it at all.
Background
Consider these classes:
# app/models/user.rb
class User < ActiveRecord::Base
validate :magic
def magic
errors.add_to_base('failed') if bad_things?
end
end
^
# app/models/foo.rb
require 'user'
class Foo
# something happens here
end
Now, when your environment is booted, Rails will automatically load your models, like User
...
How to organize and execute cucumber features (e.g. in subdirectories)
In cucumber you are able to run features in whatever directory you like. This also includes executing features in subdirectories. There are only some things you have to take care of.
By default, cucumber loads all *.rb
files it can find (recursively) within the directory you passed as argument to cucumber.
$ cucumber # defaults to directory "features"
$ cucumber features
$ cucumber my/custom/features/dir
So, if you would like to organize features in subdirectories, you won't have *any problems when running the whole test...
Fix warning: Cucumber-rails required outside of env.rb
After installing Bundler 1.1 you will get the following warning when running tests:
WARNING: Cucumber-rails required outside of env.rb. The rest of loading is being defered until env.rb is called.\
To avoid this warning, move 'gem cucumber-rails' under only group :test in your Gemfile
The warning is misleading because it has nothing to do with moving cucumber-rails
into a :test
group. Instead you need to change your Gemfile
to say:
gem 'cucumber-rails', :require => false
Browsers will not send a referrer when linking from HTTPS to HTTP
- When your site is on HTTPS and you are linking or redirecting to a HTTP site, the browser will not send a referrer.
- This means the target site will see your traffic as "direct traffic", i.e. they cannot distinguish such hits from a user who directly typed in the URL.
Reasons for this behavior
It's probably because of this RFC:
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferr...
Things to consider when using Travis CI
Travis CI is a free continuous integration testing service. However, it is really fragile and will break more than it will work.
If you choose to use it anyway, learn the lessons we already learnt:
Use a compatible Rubygems for Rails 2.3 on Ruby 1.8.7
Ruby 1.8.7 is not compatible with current Rubygems versions (> 2.0). Runnig rvm rubygems latest-1.8 --force
will fix this and install Rubygems version 1.8.29.
To make Travis CI do this, add `before_script: rvm rubygems latest-1....
Deal with certain travis CI failures
Travis changed their default distribution from Ubuntu 14.04 (trusty) to 16.04 (precise). This might break your test setup for new builds.
You can solve this issue by freezing your test distribution in the .travis.yml
to Ubuntu 14.04 until you have the time to solve all the issues you will have in 16.04:
dist: trusty
Error details
Here are few indicators that you ran into this issue:
Connection to the PostgreSQL database does not work anymore
Your travis-ci builds might have started failing on the usual
psql -c...
DOM API for jQuery users
General hints on the DOM
- the root of the DOM is
document
- custom elements inherit from
HTMLElement
. They need a-
(dash) in their name, e.g.<notification-box>
. - event listeners don't have event delegation à la
.on('click', cssSelector, handler)
Comparison
Action | jQuery | DOM API equivalent |
---|---|---|
Find descendant(s) by CSS selector | .find(selector) |
one: `.querySelector(selecto... |
howto fix spreewald issue „database configuration does not specify adapter (ActiveRecord::AdapterNotSpecified)“
This error occurs when you already have a database.yml
which defines the database for the cucumber
environment instead of test
. (Spreewald database.sample.yml
has changed)
Fix
Change cucumber
to test
in your databse.yml
test: # <---
adapter: mysql2
database: spreewald_test
encoding: utf8
host: localhost
username: root
password: password
How to change the hostname in Cucumber features
Capybara uses www.example.com
as the default hostname when making requests.
If your application does something specific on certain hostnames and you want to test this in a feature, you need to tell Capybara to assume a different host.
Given /^our host is "([^\"]+)"$/ do |host|
page.config.stub app_host: "http://#{host}"
# In older Capybaras (< 2.15) you needed to do this instead:
Capybara.stub app_host: "http://#{host}"
end
You can now say:
When I go to the start page
Then I should not see "Home ...
Ruby: Writing specs for (partially) memoized code
When you're writing specs for ActiveRecord models that use memoization, a simple #reload
will not do:
it 'updates on changes' do
subject.seat_counts = [5]
subject.seat_total.should == 5
# seat_total is either memoized itself, or using some
# private memoized method
subject.seat_counts = [5, 1]
subject.seat_total.reload.should == 6 # => Still 5
end
You might be tempted to manually unmemoize any memoized internal method to get #seat_total
to update, but that has two disadvant...
Savon testing: How to expect any message
When using Savon to connect a SOAP API, you may want to use Savon::SpecHelper
to mock requests in your tests as described in their documentation.
When sending a message body, the savon
mock object requires a message to be set, like this:
savon.expects(:action_name).with(message: { user_id: 123 }).returns('<some xml>')
If you want to stub only the returned XML and do not care about request arguments, you can not omit with
as Savon's helper will complain:
savo...
rspec_candy 0.2.0 now comes with our most popular matchers
Our rspec_candy gem now gives you three matchers:
be_same_number_as
Tests if the given number is the "same" as the receiving number, regardless of whether you're comparing Fixnums
(integers), Floats
and BigDecimals
:
100.should be_same_number_as(100.0)
50.4.should be_same_number_as(BigDecimal('50.4'))
Note that "same" means "same for your purposes". Internally the matcher compares normalized results of #to_s
.
be_same_second_as
...
How to create Excel sheets with spreadsheet gem and use number formats for cells like money or date
The following snippet demonstrates how you could create excel files (with spreadsheet gem) and format columns so that they follow a specific number format like currencies or dates do.
require 'rubygems'
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet::Workbook.new
sheet1 = book.create_worksheet :name => 'test'
money_format = Spreadsheet::Format.new :number_format => "#,##0.00 [$€-407]"
date_format = Spreadsheet::Format.new :num...
SearchableTrait is now a gem: Dusen
For two years we've been using SearchableTrait
which gives models the ability to process Googlesque queries like this:
Contact.search('a mix of words "and phrases" and qualified:fields')
This trait used to be a huge blob of code without tests and documentation, so I made a gem out of it. Check out https://github.com/makandra/dusen for code, tests, and a huge README.
You should use the Dusen gem and delete SearchableTrait
in all future projects.
Note that the syntax to define query proc...
Working around OpenSSL::SSL::SSLErrors
If your requests blow up in Ruby or CURL, the server you're connecting to might only support requests with older SSL/TLS versions.
You might get an error like: OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=unknown state
SSL Server Test
This SSL Server Test can help finding out which SSL/TLS versions the server can handle.
Ruby
In Ruby, you can teach Net::HTTP
to use a specific SSL/TLS version.
uri = URI.parse(url)
ssl_options = {
use_ssl: true,
ssl_version...
Structuring Rails applications: the Modular Monorepo Monolith
Root Insurance runs their application as a monolithic Rails application – but they've modularized it inside its repository. Here is their approach in summary:
Strategy
- Keep all code in a single repository (monorepo)
- Have a Rails Engine for each logical component instead of writing a single big Rails Application
- Build database-independent components as gems
- Thus: gems/ and engines/ directories instead of app/
- Define a dependency graph of components. It should have few edges.
- Gems and Engines can be extracted easier once nece...
Capistrano 2: How to deploy a single server
When you have a multi-server setup, you'll be adding a new server from time to time. Before doing a full deploy, you might want to test that server in an isolated deploy. There is a single way to do this: the HOSTFILTER
env variable.
Commenting out "server" lines in the Capistrano deploy config will raise a Capistrano::NoMatchingServersError
with <task> is only run for servers matching {:roles=> <role>}, but no servers matched
. Instead, specify the server-under-test like this:
HOSTFILTER=separate-sidekiq.makandra.de cap productio...
Sending errors to sentry from development
For the initial setup or changes in the sentry reporting it might be useful to enabled reporting of sentry in development. Don't commit these changes and prefer to report to the staging environment. As other developers might be confused of these errors try to given them a proper message and delete them afterwards.
- Add
config.raven_dsn = 'your-dns'
inconfig/environments/development.rb
. - Add development to existing environments in the
Raven.configure
block:config.environments = ['development', 'staging', 'production']
. - ...
Linux: Create file of a given size
Sometimes you need a file of some size (possibly for testing purposes). On Linux, you can use dd
to create one.
Let's say you want a 23 MB file called test.file
. You would then run this:
dd if=/dev/zero of=test.file bs=1048576 count=23
The block size (bs
) is set to 1 MB (1024^2 bytes) here, writing 23 such chunks makes the file 23 MB big.\
Adjust to your needs.
This linux command might also come in handy in a Ruby program. It could be used like:
mb = 23
mb_string, _error_str, _status = Open3.capture3('dd if=/dev/zero...