3891 cards
Linked content


capybara-lockstep can help you with flaky end-to-end tests:

This Ruby gem synchronizes Capybara commands with client-side JavaScript and AJAX requests. This greatly improves the stability of a full-stack integration test suite, even if that suite has timing issues.


Ruby: Generating and parsing JSON, or: understanding JSON::ParserError "unexpected token"

json is part of the standard library of Ruby and deals with JSON, obviously. As you know, JSON is the string format that represents simple data structures. Ruby data structures that resemble Javascript objects can be serialized to JSON with #to_json. These can be restored from a JSON string with JSON.parse().

So what could go wrong here?


It will raise JSON::ParserError (784: unexpected token at '"a"'). But why?

Generating JSON vs serializing objects


Linked contentRepeats

Test your application's e-mail spam scoring with mail-tester.com

You can use mail-tester.com to check your application's e-mails for issues that might cause e-mails to be classified as spam.

They provide a one-time e-mail addresses that you can use to sign up etc. You can then check for scoring results of SpamAssassin and other potential issues.
You don't need to hit 10/10. Something around 9/10 is perfectly fine.


  • For password-protected staging sites you will get an error for links that can not be resolved. This is fine, simply check production once available.
  • ...
Linked contentRepeats

Carrierwave: Built-in RSpec matchers

CarrierWave comes with some RSpec matchers which will make testing more comfortable. Let's say you have an Uploader like this:

class MyUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  # Create different versions of your uploaded files:
  version :small do
    process resize_to_fill: [100, 100]
  version :medium do
    process resize_to_fit: [200, nil]
  version :large do
    process resize_to_limit: [400, 400]


Imagine you have a class Movie with an attribute poster. In ...

Geordi 5.4.0 released

5.4.0 2021-02-01

Compatible changes

  • Add geordi branch command that checks out a feature branch based on a story from Pivotal Tracker
  • Faster MySQL dumping with --single-transaction and --quick
  • Allow pivotal tracker ids in the global config file
  • Fix missing require for Fileutils in the dump load command (#145)
Linked content

Parsing JSON with edge cases

The linked article shows that there are unclear parts in the JSON specification and that different parsers treat them differently (which could lead to security vulnerabilities in certain cases).

I was curious what Ruby does (Ruby 2.6.6 with gem json 2.3.0, implementing RFC 7159):

Duplicate Keys

irb(main):001:0> require 'json'
=> true
irb(main):002:0> JSON.parse('{"qty": 1, "qty": -1}')
=> {"qty"=>-1}

Character Collision

irb(main):009:0> JSON.parse('{"qty": 1, "qty\ud800": -1}')
JSON::ParserError (487: incomplete sur...

Webmock < 3.12.1 cannot handle IPv6 addresses correctly

We had the issue, that a VCR spec failed, after updating CarrierWave from version 0.11.0 to 1.3.2.
In this version, CarrierWave uses the gem SsrfFilter, which retrieves the IP addresses for the given hostname and replaces the hostname in the requested url with one of them.

It works with IPv4 addresses, but not with IPv6 addresses, because WebMock cannot handle those correctly:

uri = "#{protocol}://...

Making ZSH the default shell on Ubuntu 20.04

ZSH is an alternative command line shell that includes some features like spelling correction, cd automation, better theme, and plugin support. You can replace Bash with ZSH like following:

sudo apt-get install zsh

Setting ZSH as default login shell

sudo usermod -s /usr/bin/zsh $(whoami)

Opening a new terminal window will show you a dialog where you can configure your initial ZSH config (Option 2 recommended).

Afterwards you can install the plugin manager Oh-My-ZSH and select a prop...


Too many parallel test processes may amplify flaky tests

By default parallel_tests will spawn as many test processes as you have CPUs. If you have issues with flaky tests, reducing the number of parallel processes may help.

Note that this card is only relevant if you need to run a flaky test suite that you cannot fix. If you have no issues with flaky tests you should run as many parallel test processe...

Linked contentAuto-destruct in 2 days

Updated: List of Helpful RubyMine Shortcuts

Added some shortcuts I regularly use:

CTRL + SHIFT + Backspace
: Move caret to position of last edit

CTRL + ALT + Left arrow (see this card for modern Ubuntu with Gnome)
: Move to last position

: Auto indent marked code (does not always work)

SHIFT + Click Editor tab
: Close the tab

CarrierWave: Default Configuration and Suggested Changes

The current default configuration of CarrierWave looks like this. Make sure to check and (if necessary) configure these defaults when adding CarrierWave to a project.

  config.permissions = 0644
  config.directory_permissions = 0755
  config.storage_engines = {
    :file => "CarrierWave::Storage::File",
    :fog  => "CarrierWave::Storage::Fog"
  config.fog_attributes = {}
Linked content

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.

Rails: Parsing a time in a desired timezone

Sometimes you want to have a time in a given timezone independent from you Rails timezone settings / system timezone. I usually have this use case in tests.


Time.parse('2020-08-09 00:00') will return different results e.g. 2020-08-09 00:00:00 +0200 depending on the Rails timezone settings / system timezone. But in this example we always want to have the given time in UTC because that's what the API returns.

it 'returns a valid API response', vcr: true do
  expect(client.get('/users/1')).to have_attributes(
    name: 'So...

Javascript: Comparing two arrays for equality

Don't Google this, you will lose all will to live. Instead use Object#isEqual() from Lodash or Underscore.js:

_.isEqual([1, 2], [2, 3]) // => false
_.isEqual([1, 2], [1, 2]) // => true

If your project already uses Unpoly you may also use up.util.isEqual() in the same way:

up.util.isEqual([1, 2], [2, 3]) // => false
up.util.isEqual([1, 2], [1, 2]) // => true

To compare two arrays for equality in a Jasmine spec assertion, see [Jasmine: Testing ...


Project management best practices: The story tracker

In general, the tracker should always be the definitive source of truth of what needs to be done as part of a project. If you identify a task that needs to be done, you should create a story. If you learn something that contradicts an existing story, change it.

The tracker can contain two types of stories: Developer stories, and non-developer stories.

Non-developer stories

Non-developer stories should be clearly marked. They usually belong to the PM (or maybe people from the operations team). Those story can take all forms, could just...

How to fix: WrongScopeError when using rspec_rails with Rails 6.1

tl;dr: Upgrade the gem to at least 4.0.1

When you use rspec_rails in a version < 4 with Rails 6.1 you may encounter an error like this:

  raise WrongScopeError,
    "`#{name}` is not available from within an example (e.g. an " \
    "`it` block) or from constructs that run in the scope of an " \
    "example (e.g. `before`, `let`, etc). It is only available " \
    "on an example group (e.g. a `describe` or `context` block)."
    `name` is not available from within an example (e.g. an `it` block) or from constructs that...
Linked content

Best practices for REST API design

A rough guide how to implement a REST API.

The discussion here includes some interesting points as well:

  • Timestamps: ISO8601 format ("2021-02-22T20:34:53.686Z")
  • Google API guideline: https://google.aip.dev/
  • Numbers: String vs. Number

    The JSON number type is not a double. It's just a number of arbitrary size and precision in integer/decimal/E format that can be parsed as whatever the parser finds fitting.

  • Pagination: Limit + Offset vs. Object ID / Pointer vs. System-Version...

Running old ImageMagick versions in a Docker container

If your project depends on an old version of ImageMagick that you can no longer install in your system, you can choose the run an old ImageMagick in a Docker container.

Dockerized ImageMagick commands will only work with absolute path arguments. You need to boot a corresponding docker container once before using it.

Setting up Docker

If you haven't installed Docker yet, use our guide or the [official instructions](https://docs.docker.com/get-started/...

This website uses short-lived cookies to improve usability.
Accept or learn more