Rspec Quick Reference

I’ve been working to rewrite the test suite for one of the apps I’ve made from Minitest/Fixtures to Rspec/Factory Girl. My favorite thing about Minitest is that it’s simple to understand since it’s just Ruby, but I wanted to explore what Rspec has to offer. I’ve seen alot of Rspec in the open source projects I’ve looked into and in many of the tutorials I follow. Even though the syntax is easy to understand, using it to code was harder than I thought. I started a quick reference sheet from cheat sheats I found on the internet and the documentation for the gems. They don’t give a full explanation on what they do, but I found that the syntax is expressive enough that being able to see an example is enough to use it.

Structure

describe <class> do
  it "description of what happens" do 
    <setup code>
    <exercise code>
    <expectation code>
    <cleanup code>
  end
end

Setup code

before { <setup code> }
let( <variable> ) { <object instantiate> }

## Test doubles
book = double("book")
book = instance_double("book")
allow(book).to receive(:title).and_return("The Rspec Book")
allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
spy("invitation")
instance_spy("invitation")
class_spy("invitation")
object_spy("invitation")

Exercise code

## Model Tests from shoulda-matchers gem documentation

it { should <should-matchers code> }

allow_value('http://foo.com', 'http://bar.com/baz').for(:website_url)
validate_confirmation_of(:email)
validate_length_of(:password).is_at_least(10).on(:create)
validate_numericality_of(:age).only_integer
validate_presence_of(:password)
belong_to(:organization)
accept_nested_attributes_for(:mirrors).allow_destroy(true)
have_many(:friends)
have_one(:partner)
have_and_belong_to_many(:awards)

## Controller Tests

get :new

Article.should_receive(:new).with(title: 'The New Article Title').and_return(article)
post :create, message: { title: 'The New Article Title' }

article.should_receive(:save)
post :create

article.stub(:save)
post :create
response.should redirect_to(action: 'index')
flash[:notice].should eq('The article was saved successfully.')

## Feature Tests with Capybara

visit book_path
fill_in 'Email', :with => 'user@example.com'
click_on "Submit"
click_link('Link Text')
choose('A Radio Button')
check('A Checkbox')
uncheck('A Checkbox')
find_field('First Name').value
find_link('Hello').visible?
find_button('Send').click

Expectation code

expect(<expectation code>).to      eq(<value>)
expect(<expectation code>).not_to  eq(<value>)

## Paired with spy

expect(invitation).to have_received(:accept).with(mailer)

# Values that can be used 

be_true
be_false
be_nil
match /regex/
start_with 
end_with
match_array [array]
be_a_kind_of <class name>
be_an_instance_of <class name>
have(<number>).things
have_at_least(<number>).things
have_at_most(<number>).things
raise_error <optional error>

## Controller specific

assigns[:article].should be_a_new Article
response.should render_template :new

Thoughtbot articles on testing

I’ve been reading about testing philosophies and watching tutorials on TDD. I’ve been going through a lot of the blog posts on the thoughtbot because I started learning about Rspec in general from their Upcase trails and using many of their tools. These are a few of the articles I’ve read that helped me get a grip on the way people test and the terms they use.

Commands I’ve learned

  • git log --grep searches the commit messages
  • git log -S searches the code in the repo and can take Regex
  • tar xvf archive_name.tar extracting from a tar file
  • unzip test.zip extracting from a zip file

Links

  • Functional Programming and Ruby This video was showing functional programming principles that I’ve been seeing more and more when I looked into open source projects. This mindset for programming has been difficult to wrap my head around but I can see a lot of uses for it.

  • Using Ruby Forwardable contains ways to use the delegation pattern with the Forwardable module.

  • 7 Unusual Datastores shows datastores I’m not too familiar with like Marshal and ObjectSpace. I have read that the latter is used for finding things like memory leaks or benchmarking to figure out a good garbage collector setting.

  • Keyword Arguments introduced a way to use keyword arguments in Ruby 2.0+. I’ve been using the older syntax all this time so finding out about this one has been great. It also goes into different ways you could use it.

  • Rails enums talks about the enum method in Rails 4 which I’ve seen a few times but never really looked into completely.

More Debugging With Deployment

While I was experimenting with the dotenv-heroku gem, the app I was deploying started showing the app crashed error message. I ran all my tests before pushing the code to heroku so I was sure that the problem had something to do with the configuration.

First suspect: Devise secret key

Since I had just extracted the secret key for Devise into an environment variable, I thought that the problem was because the Rails app was throwing an error since Devise couldn’t read the environment variable. I undid my commit but the app still wouldn’t start. I added heroku-repo to see if the problem could be fixed by rebuilding the repository with different keys for the environment variable.

Second suspect: database.yml

I tried to see if I could access the app from the command line. I ran heroku run rails console and received the error:

  • active_record/connection_adapters/connection_specification.rb:37:in `initialize': undefined method `tr' for nil:NilClass (NoMethodError)

That led me to question if my configuration in the database.yml was wrong or that the yaml file wasn’t properly formatted. I played around with different settings with no luck. After searching through articles and Heroku’s devcenter, I found out that Heroku bypasses that file and only needs the url for the database.

Third suspect: DATABASE_URL

The corresponding method was:

def initialize(url)
  raise "Database URL cannot be empty" if url.blank?
  @uri     = uri_parser.parse(url)
  @adapter = @uri.scheme.tr('-', '_')
  @adapter = "postgresql" if @adapter == "postgres"
  if @uri.opaque
    @uri.opaque, @query = @uri.opaque.split('?', 2)
  else
    @query = @uri.query
  end
end

Since the first line wasn’t raised, the url was not blank. The method was reading the DATABASE_URL variable but was having problems afterwards. Something was happening in the next two lines. The instance variable @uri was calling a method:

def uri_parser
    @uri_parser ||= URI::Parser.new
end

URI::Parser is part of a Ruby standard library that deals with a string of characters representing a uniform resource identifier. The uri_parser method instantiates a new URI object and the parse method then tries to create a uri object from the url passed in. The @adapter tries to read the resulting variable with the scheme method and that was when the tr method throws an error because scheme can’t read the object. After reading the documention for the parse method, I realized that the DATABASE_URL variable that was set in the environment was not properly formatted.

Solution

At some point when I first tried to push the .env file to Heroku, the url changed and the colon characters turned into equal characters. I’m not sure if the dotenv-heroku gem did this but I exchanged the gem for heroku-config instead and set the variables that way.

Easier way to debug

I realized later that above the initialize method was an example comment:

    # == Example
    #
    #   url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
    #   ConnectionUrlResolver.new(url).to_hash
    #   # => {
    #     "adapter"  => "postgresql",
    #     "host"     => "localhost",
    #     "port"     => 9000,
    #     "database" => "foo_test",
    #     "username" => "foo",
    #     "password" => "bar",
    #     "pool"     => "5",
    #     "timeout"  => "3000"
    #   }

If I read the example for the url I would have seen that the DATABASE_URL was not properly formatted. I appreciate that I’m now able to dig into Rails to figure out what’s wrong, but reading the error message and corresponding comments carefully could have saved me hours of time. A lesson learned for the next time I have problems pushing environment variables.

Links

  • Summary of Ruby Collections This was an interesting article on Ruby collections, which I feel is the type of object that I use the most. Most of it is a refresher but I did learn that Ruby has tuples in one of its libraries and how it could be used.

  • Intro to Devise This link was also a little bit of a refresher but it’s very thorough and it did go through how to configure the mailer with delayed job. Also, the author is doing a whole series on authentication with Rails and I’m looking forward to the next one.

  • Rails API tips I’ve been trying to learn more about creating a Rails API that could go with a Javascript frontend and this artcle gave really good tips about problems I didn’t consider. I’m particularly interested in learning about the two Rack middlewares he suggested; rack-cors and heroku-deflator.

  • Regex This post goes deep into how a regular expression is parsed. The author was explaining how he structured his gem to create regex examples.

Easy Wins Versus Hard Wins

One of the most difficult things for me was keeping up my motivation while learning how to code. My biggest solution to this was something I learned from The 7 Habits of Highly Effective People and that was a four quadrant chart separated into:

  • Important and Urgent
  • Important but not Urgent
  • Not Important but Urgent
  • Not Important and not Urgent

I used to write this chart every day as a way to manage my time but I focus on the first two now and created two todo lists. The important and urgent category is always the priority but I further split the last one into easy wins and hard wins because those are the challenges you can be flexible with it.

One of the things a lot of people have suggested is taking a deep dive into programming, program 10 hours straight per day to quickly reach the 10,000 hours for mastery mentioned in Outliers. That mindset disregards burnout and that is especially discouraging for a beginner. It’s one of those cases where the process is much more important than the goal because of how overwhelming programming can be; there are a lot of things to learn, it’s important to be able to decide what abstractions are ok to work with as is and what topics are uncomfortable enough to stretch your abilities without breaking your motivations. Easy wins and hard wins is a way I manage that. I focus on harder problems but I would do something from the easy category when I knew that I needed a little break but also stay productive. It’s very important though to make sure that everything in that category is still important to make sure that it’s not another form of procrastination.

Example grouping for the categories

For me, the important and urgent category was filled with services I’m paying for which included Treehouse, Codeschool, Upcase, and any other online subscription or working on an app I can show as a code sample in the future. The important but not urgent category had two subclasses. The easy wins includes learning a single command, an easy code kata/exercise, or reading a chapter for a programming book. The hard wins include reading source code to figure out how a method works, learning a design pattern, or learning a new tool like a text editor or tmux.

Commands I learned recently

  • sudo update-alternatives --config editor The default editor for my laptop was nano and I wanted to switch to vim.

  • When I was working on Windows 8 and Vagrant, I used a program that GitHub provided. I knew a handful of commands but I’m trying to learn enough so that I won’t depend on the GUI.

  • git branch -a This list all the branches for a git repo.

  • git branch -d branch_to_delete This deletes a branch.

  • git remote add origin remote repository_URL This adds a remote repository I can push and pull to.

  • git blame directory/to/file.rb I learned this from Justin Weiss’s blog post and it’s been useful to track down changes in git’s history.

Links

  • Postgres management A lot of the things in this article is taken care of by rails but I wanted to learn more commands in psql so that I can poke around the database when I need to.

  • Migrating Rails to Postgres I knew how to set up Postgres but this page also added how to migrate data from sqlite to postgres through the taps gem.

  • Adding blog to a rails app I followed this article to add a blog into a rails app that uses markdown syntax.

  • Brakeman gem I was seeing this gem a lot in different blog posts and I wanted to try it out. I still need to learn the warnings and what they mean but I was able to fix unsafe redirects and cross site scripting with the first pass through.

  • Setting up email in rails This article went through how to set up emails in a rails app through Gmail or Mailgun. I went through the first part and I want to see how to set up the other in the future.

Sorcerer's Apprentice - Problems With Deploying

I was browsing through Netflix trying to find something to fill the room with white noise while I studied when I decided on Fantasia. At one point during the movie, the conductor turns towards the audience to explain the concept behind one of the pieces; Sorcerer’s Apprentice. An apprentice tried to use magic that he couldn’t control and wasn’t stopped until his master came to fix the situation. I think programming has a lot of these situations and the scariest mistake for me is deployment.

Even little tests apps scare me because of the possibility that I’m sharing api keys or passwords. Right now, the only key I’m using that shouldn’t be in the repository is the SECRET_KEY_BASE generated by rake secret. I’m currently learning about the use of dotenv which extracts the key into a .env file and substitutes an environment variable in config/secrets.yml. Before this method, I wouldn’t commit the secrets.yml into the repository.

With a particular app, I was having problems with deploying it after I updated the gems. I incrementally updated Rails and Ruby versions making sure that all the tests pass. Because of this process, I was sure that the problem involves the database or gem/feature I added but didn’t test. The app was hosted on heroku and the first thing I did was look at the log by running heroku logs --tail. I wasn’t sure what the error message was saying so my first instinct was to reproduce the situation on my computer.

Before this, I was using vagrant to configure my environment and the Vagrantfile was configuring the database for me. Now that I’ve installed Ubuntu Gnome on my computer, I needed to create a Postgres database for a local development environment along with an associated user. After installing Postgres, I created a database and an associated user for the app.

Postgres commands I needed to use: Stackoverflow link

create user username with password 'password';

alter user username superuser;

create database projectname_development;

grant all privileges on database projectname_development to username;

Fixing the problem

After going through these steps and connecting Postgres with the development environment by editing the database.yml file, I found the same error recorded at the heroku logs. The error message was saying that it was using a Ruby version 2.2.0 when I was using 2.2.1 and that there was a problem parsing the yaml file of the Jekyll blog. I was able to fix it on my computer by resetting rvm and making sure it was using the correct Ruby version, but I didn’t know how to do the same thing for heroku. Based on the messages during deployment, the problem seems like it originates from my Gemfile.lock file. I originally started working on the app in a Windows environment, migrating it to a virtual machine through Vagrant, and then to an Ubuntu laptop now. Heroku had to redo bundle install after each deployment because of the fact that it doesn’t use the Gemfile.lock file due to the Windows line endings.

I deleted that file and reran bundle install. Also, since the bloggy gem was throwing the error and I was already planning to remove it in the future, I decided to uninstall it as well. I’m aiming to add a different blogging engine or a basic Rails one so that the layouts would not be separate from the Rails app. This way, I would be able to write unit tests for it in the future. Jekyll is a static site generator and I don’t know how to create a proper test for it besides making sure that jekyll build wasn’t throwing any errors. Afterwards, heroku run rake db:migrate was successful and the app was running again.

Links I’ve been reading

  • Ruby 2.1 - Fun with underscores, ampersands and asterisks: I’ve used asterisks as a splat operator and ampersands for blocks but this is the first time that I’ve seen underscores used to fill in for an unneeded argument.

  • A Closer Look at Test Spies: This article is exploring the use of the spy method instead of double to set up tests. The main difference is using the spy method would automatically spy on all methods without having to stub it out. The main issue is that stubbing is usually a good indicator of the class’s design. You should’t have to stub multiple methods to pass a test for classes that are designed well because it would have to many responsibilities

  • Hooks: I’ve only seen extended and included as hooks and this blog post provides a whole list of hooks used in Ruby.

  • Understanding Rack Apps and Middleware: This is an in-depth post about Rack. I’ve read about them from different articles before but this one incorporates a lot of information into a single post.

  • Nginx Guide: Introduction: This article is an introduction of what Nginx is and its advantages. I’m not familiar with how servers are set up because Heroku handles it’s management but it’s something I want to learn more about in the future.

  • Animation Principles for the Web: This article applies Disney’s 12 Principles of Animation to CSS. I was introduced to those CSS properties in Upcase’s CSS trails and this article was trying to illustrate how to use those properties effectively.

  • Ruby on Rails Podcast: Darrell Silver from Thinkful: I was listening to this podcast and the part where Sean Devine talked about his experience trying a service that helps beginners resonated with me. He talked about the other person’s guilt because they had been working so much and they felt like they should already know the answer. Even though the solution was technically simple, the host was saying most of the problem was dealing with that guilt and leading them to a place where they could program again.

Accounts I Should Have Had From the Beginning

When I first started learning about coding, I was reading through Zed Shaw’s book about Python. The very first program I made was based on the text game in one of the exercises. It was a game that would give me suggestions or try to motivate me in some way based on how I answered questions. It was a really bad example of programming with many nested if..else statements, but I believe that working through that game was ultimately the reason why I kept trying to learn. Unfortunately, I lost that game when my computer was stolen. Which brings me to the first thing I should have gotten when I started, a way to backup my files.

Github is the most popular choice from but I was always afraid to show really bad code or accidently sharing something personal like passwords or api keys. That’s the reason that I put off starting one for a long time. I became more diligent about backups after losing all the tutorial applications and links that I was saving. Around that time, I created an account at Bitbucket because it allowed free private repositories and it helped me get started using git commands. Starting with Github first would have helped me get over the hump about sharing or talking with other programmers but if that barrier is too big at the moment, it’s better to go with the alternative than not at all.

Another thing I should have started from the beginning was working through an app from rails new appname to deploying it. I put off this part for awhile and it was a huge detriment later on. Personally, my fear of deploying a demo was similar to my fear of the command line in the beginning. A major part of that was connecting and using a Database that wasn’t sqlite along with the other configurations. I knew enough about SQL and databases in general to work with it in a Rails app but that was different from having to configure it outside a development environment. For demos and trying to deploy the first time, heroku is my number one choice because it was the most painless for me, the most that I had to do was extract out some keys to environment variables and add a different Ruby server besides WEBrick. Their articles guided me on how to deploy for the first time and the reasons why they require programs to be deployed in that way.

The last thing I focused on in the beginning was that I put a lot of time doing exercises like ruby koans and exercism because it abstracted out a lot of parts that I couldn’t get my head around yet. I only found these exercises through GitHub and in the latter’s case, it’s the only way to access the exercises and let other users comment on your work. I was ignorant to the design patterns other people were using since I was so focused on just making the tests pass, but I used them to become familiar with the syntax and the way Ruby solved problems. Aiming to work on one problem a day was an attainable enough goal to create a habit and eventually fall in love with the process. As an added benefit, those exercises gave me a great appreciation of testing in general because that was the only way I knew if I was doing the right things.

Taking the Simple Programmer Blog Course

For the past few weeks I’ve been taking an email course by John Somez on blogging and it has been a great way to refocus on the possible content for this site. One of the first suggestions I ever heard about learning how to program was that I should blog as much as possible, but I kept struggling with deciding what I should write about and being consistent with it.

Choosing a theme

When I started exploring web development and programming, there were so many choices and possible paths that I became hesitant and afraid to make the wrong decision. I tried a little bit of everything because of that fear. I would try all the beginner courses on Treehouse covering JavaScript, Python, PHP, and Ruby when I should have stuck with one. Choosing a theme reminded me of that indecisiveness. It eventually came down to writing about something I’m familiar with (Ruby on Rails) or something that I need to learn more about (JavaScript frameworks). I eventually decided to write about Ruby because its the topic I’m most confident in and a language I really enjoy using. I also believe that there is a big jump between introductory tutorials on Rails and intermediate level stuff that I could help fill with my blog posts. If I’m able to, I want to incorporate a magic theme because I always hear about the magic that goes in the background of a Rails application. One of my favorite Ruby books, called Metaprogramming Ruby 2, had a section called spell book that prompted me to record and study design patterns or quirky Ruby behavior in notebooks as if I was writing my own Ruby spellbooks. While learning on my own, little motivations like that can sometimes help the most and it’s a fun way to think about programming.

Creating the blog

I had already created this blog by forking a pre-made jekyll repo, following its instructions and reading an article on setting it up. I was able to host it on my account’s github page and the repo itself included plugins for disqus and most common social media accounts. I read a blog post about the advantages of a static site generators and since jekyll was written in Ruby, I was more inclined to use it as a blogging platform instead of Wordpress. I’m aiming to improve the styling for this blog in the future or even migrate it to a Middleman project since that one more closely resembles a Rails app.

Blog post ideas

When I was struggling to come up with blog post ideas before this course, I don’t know why I didn’t think of sitting down and brainstorming 30 to 50 ideas at once. It seems obvious now and I can definitely see it helping in a lot of ways. I can start writing drafts days before I need to publish them or even create drafts for other posts. This will enable me to check my work and add more relevant details that come up after multiple proofreadings. This reduces the fear I have with putting my writing out there and would encourage more creative ideas. Also, I came up with a lot of things I wish I knew when I started and those are the blog posts I want to write first.

Consistency

Consistency might be the most difficult part of writing a blog. Staying consistent and forming good habits is very important because if I can’t be disciplined enough to write regularly, why should the readers care about following my posts? I want to publish as much as I can to show and share how much I’ve learned, become better as a writer, and get called out if I don’t fully understand what I’m talking about. In a way, writing without comments or feedback is like coding without tests, you won’t really know if what you’re doing is wrong until a bigger problem occurs down the road.

Web traffic

This is another tough one. There are so many blogs out there and standing out will take a lot of time and effort. It involves following other people’s blogs, commenting with relevant information, and providing value in some way. I’m still figuring out how to engage with the comments section for blogs that I follow and trusting myself enough to voice an opinion, but everything is always a work in progress. Writing more blog posts would probably help in that department too.