Josh Thompson     about     archive     tags

Testing Rake Tasks in Rails

I recently wrote a rake task to update some values we’ve got stored in the database. The rake task itself isn’t important in this post, but testing it is.

We’ve got many untested rake tasks in the database, so when our senior dev suggested adding a test, I had to build ours from scratch.

I did a bit more whack-a-moling with error messages than I’d hoped, so here’s a template of that test, along with some details that might save you some time, next time you are writing tests for your rake tasks.

We’re in a not-new version of Rails, and using Minitest. I’ve anonymized it. Hope it’s useful!

# test/tasks/rake_task_file_test.rb

require 'test_helper'
require 'rake'

class RakeTaskFileTaskTest < ActiveSupport::TestCase

  describe 'namespace:task_name' do

    def setup
      @tt = Fabricate(:object_with_attributes_i_need_to_change)
      ApplicationName::Application.load_tasks
      Rake::Task["namespace:task_name"].invoke
    end

    it "should change 'thing I don't want'" do
      @tt.reload
      values = @tt.attribute_i_changed
      refute_includes values, "thing I don't want"
      assert_includes values, "thing I do want"
    end

  end
end
>> Read more

Array divergence in Ruby

Lets say you have a list of valid items, and you want to run another array against it, and pull out the items that don’t match.

You don’t want to iterate through all of the items in one array, calling other_array.include?(item). (That’s computationally expensive)

valid_people = ["Sarah Connor", "John Connor"]

visitor_logs = ["Sarah Connor", "John Connor", "Terminator Robot"]

You want to find any item in visitor_logs that isn’t on the approved list. How to do that?

in Ruby, you can just “subtract” one array from another:

unwanted_visitors = visitor_logs - valid_people
=> ["Terminator Robot"]
>> Read more

Take Back Your Attention

note: this page has 17Mb of gifs and images. I don’t really want to take the time to manually trim the gifs from >3Mb/each to <1Mb each, so I didn’t. If you’re on mobile, or trying to conserve data, you might want to come back to this one later.

I value my attention and focus. I resent strongly when someone tries to take it away from me.

Someone tries to derail my attention pretty much any time I browse the internet. Little pop-ups, auto-playing videos, click-baity headlines, etc.

I’ve settled on a pretty good system for blocking annoying crap on the internet.

Here’s the elements on a few different websites that I visit regularly, with the elements I’m going to remove highlighted.

We’re going to take this:

crappy twitter

To this:

better twitter

>> Read more

Recommended books from 2017

I read many books in 2017. I’m listing them out here, along with recommendations. Here’s the recommendation “key”:

  • 👍 = I recommend this book. This is intentionally fuzzy.
  • 😔 = This book influenced my mental model of the world/reality/myself
  • 🏢 = Book topic is architecture and/or urbanism
  • 💵 = Book topic is finance/economics/politics
  • 😫 = This book is hard to get through. Lengthy and/or academic (or both)
  • 🐲 = Fiction (most of the fiction I read had fantastic(al) creatures in them, hence the dragon)

January

>> Read more

MySQL concatenation and casting

I recently set up my environment for working through SQL for Mere Mortals.

I’ll record some interested tidbits here as I go.

Chapter 5: Concatenation without the || operator

I use MySQL at work, and MySQL doesn’t support the || operator for string concatenation.

So, in the book, an expression like:

ItemOne || ItemTwo

evaluates to ItemOneItemTwo

In MySQL, || is a logical operator, just like in Ruby, so to get the above evaluation, you’d need to use:

CONCAT(ItemOne, ItemTwo)

That would give you ItemOneItemTwo. Of course, string concatenation pairs well with spaces between the strings you’re trying to concatenate, so please know that the CONCAT function can take any number of arguments, for example:

CONCAT(ItemOne, ' ', ItemTwo)

would return ItemOne ItemTwo

>> Read more