Jacob Maine's blog
Interesting Things
- If you haven't noticed, Jasmine tests are at least twice as fast in Chrome as they are in Firefox. Closing the inspection pane makes it even faster. Be aware that part of the speed is from Chrome's aggressive caching, which can lead to erroneous test results.
- One team is using Backbone's local storage. When they add
model.clear()after every test run, their tests go from 20 seconds to over 100 seconds. Someone suggested thesilent: trueoption, to suppress thechangeevents thatcleartriggers. - To avoid bugs in minified JS put semicolons in the right spots. The easiest way to do that is to run a tool like JSLint or JSHint over your code. Add it to your test suite to prevent mistakes.
Ask for Help
- "In IE8 the numbers don't show up on ordered lists if we dynamically create
lis"
Or rather, they do, but only after hovering over the list. The common wisdom is that this has been broken in IE for a long time.
- "Our project does some DNS resolution. Is there a preferred way to mock this in tests?"
No suggestions.
- "When replying to an email each email system adds different junk to the message. We're processing those incoming replies. Any standard way to strip out the junk?"
Everyone is using the ugly regex approach. Are there mail gems that handle this?
Interesting Things
- There's a new release of Backbone - 0.9.0. It's billed as a release candidate for 1.0, and seems to be a bit buggy, as RCs can be. However, it's exciting to see that Backbone is getting close to that milestone.
- You should default boolean fields to true or false, at the database layer. Otherwise your queries have to deal with three-valued logic.
- Rails 3.2 has some unexpected behavior. First, the generated form ids have changed ... what used to be
id=user_newis nowid=new_user. Second, if your routes file is missing an entry, you will no longer get errors in controller tests. If you liked that behavior, try out request specs.
Ask for Help
- "Anyone seen problems with the latest REE and iconv?"
Everything works on the Linux machines, but on Macs, there's an error about an unrecognized target encoding. Iconv works on the command line, so it's something about REE.
Interesting Things
should_not render_with_layoutcan be flaky. For example, asserting that an XHR request doesn't have a layout could fail if the request renders an email template that does have a layout. These matchers are not very sophisticated, mostly doing string matching, not real template resolution.
Ask for Help
- "How do I test relative time with FixtureBuilder?"
Since the models are all built beforehand, it's tricky to write tests that make assertions about relative time. There were a variety of suggestions. You can write all the tests relative to a model: some_time.should == model.created_at - 3.days. You can wrap the entire suite and fixture generation in a Timecop block, but you'll have to deal with losing that context whenever any test calls Timecop.return.
- "How do I separate multiple FixtureBuilder files, but allow them to reference objects created in each other?"
Typically you want to separate fixtures into smaller files. But, you also often want to reference objects in other files, for example so you can assign a user from user_fixtures.rb to a post in post_fixtures.rb. One solution is to eval each file in a loop, so they can share instance variables. You can also use User.where(:name => "Tom") but that's awkward and repetitive.
- "Any suggestions for a CMS that would allow lots of different visual presentations of the content?"
The questioner is experimenting with branding. Not many suggestions... a shared database perhaps?
Interesting Things
- The GoGaRuCo call for papers is open!
- There's a Yammer Drinkup on June 8th.
- You might expect that a where clause like
id IN (NULL)would return an empty result set. Interestinglyid NOT IN (NULL)also returns an empty result set. Welcome to three-valued logic. - Be aware that tests may cast Hash to HashWithIndifferentAccess.
# controller.rb
@list = [{'key' => 'value'}]
# controller_test.rb
assigns(:list).first.should be_instance_of HashWithIndifferentAccess # passes
assigns(:list).first.should be_kind_of Hash # passes
assigns(:list).first.should be_instance_of Hash # fails
Ask for Help
- "What are some pointers for continuously deploying to staging, and maybe production?"
At a bare minimum, you'll want to deploy only green builds and have a basic monitoring tool like Pingdom. To get the full benefit of continuous deployment, though, you need to be more sophisticated. You're really interested in whether your latest deploy improved key metrics like conversion, usage and happiness. That gives you information about whether your next commit should pull out that feature or keep building on it. It's truly rapid iteration with customer feedback, but it takes a lot of charts and graphs and faith that you're measuring the right things.
Interesting Things
- Groupon Now! in San Francisco just launched. Use it to find same-day deals.
- If you haven't used it yet, the Rack perftools.rb project is amazingly useful for performance optimization of web apps. Add the gem, append a few params to your normal requests, and get served an image showing the call flow of your app, with lots of details about method timing and expense. We're trying to arrange a tech talk about perftools at Pivotal SF soon.
Interesting Things
- When jQuery attaches
<script>tags, they quickly disappear. It adds them to the DOM, executes them and then removes them. If you switch todocument.appendChild, you can search for and find the tags at a later point. jQuery may be trying to work around browser limits on the number of script tags.
Ask for Help
- "What's the best way to start a gem?"
bundle gem scaffolds a simple gem. Don't forget to add a license!
Interesting Things
- An upgrade to Rails 3.0.4 broke RSpec's
=~Array matcher (which disregards ordering). Oddly, there are times when==(which respects ordering) passes but=~fails. - Check out the Trove Hack Day. Trove lets you access photos from a variety of sites through one API.
- We're excited about the new Palm webOS App Framework, Enyo.
Ask for Help
"We're deploying green builds directly to production. But the
dependoption isn't working on the CI box. Any ideas?"
Run capistrano with trace to get reports on which dependencies are or are not being used.
Interesting Things
Report from Josh Susser:
There have been several vulnerabilities in Rails reported recently. You can check out the announcements on the google group:
Vulnerability in the Mail gem affecting Rails 3.0.x applications
CSRF Protection Bypass in Ruby on Rails
Potential SQL Injection in Rails 3.0.x
Filter Problems on Case-Insensitive Filesystems
Potential XSS Problem with mail_to :encode => :javascript
The fixes are generally to upgrade to 3.0.4 or 2.3.11. There are patches for many versions if you're stuck and can't upgrade.
If you're not on the google group, you probably should be. It's very low volume, and everything on it is critical information.
http://groups.google.com/group/rubyonrails-security
Ask for Help
- "Any suggestions for testing an Authorize.net integration?"
VCR is a good option, assuming you can get VCR to notice the initial requests.
"Running Jasmine with Selenium results in occasional port fail. Is the best solution to
sleepmore before setting up connections?""Devise seems to have the tools to set up an oauth provider. Are there any gems that pull everything together?"
Interesting Things
Trying to test functional Ruby with RSpec? Here's an idea.
Worth another pointer: Source RVM in your bash scripts if you need RVM to manage Ruby and gemsets. Some people object to using RVM in production – they prefer to set
GEM_HOMEandPATH, or use the system Ruby.
Ask for Help
- "Is there a clean way to simulate mouse events in Capybara tests?"
Capybara and Selenium don't seem to have tools for simulating mouse events other than 'click'. You can ask Selenium to execute JavaScript that triggers a mouse-up event. But is there a nicer way, either in Capybara or Selenium?
"
vestal_versionsis a popular record versioning tool for Rails. Any other suggestions?""We have a bunch of markup generated by a WYSIWYG editor. We're changing our routing and need to update all the links. Is Nokogiri the best solution?"
Help
"What's the best way to test that an array contains another array?"
A custom matcher using array - other_array was suggested.
Interesting
The team that was having problems with Prototype response codes found a partial solution.
They sometimes call abort() on the request which triggers the callbacks with a 0 response code. They found that if they set transport.onreadystatechange = function() {}; before calling abort() they could skip the callbacks, and manually call whatever clean-up they needed. That Prototype interprets 0 as a success still sounds strange.
