When I started on my first Angular+Rails
project around 12 months ago, there wasn't a lot of guidance around code
organization, interop, and testing, and we got a lot of these things wrong.
Since then, I've worked on several additional projects using the same tech
stack and have had several more chances to screw it up all over again. After
a few of these, I feel like I've finally got some conventions in place that
work well for better code organization, interop, and testing.
This morning the team over at Localytics (hi Raj!) wrote up a good
retrospective on their use of Angular + Rails
over the past year, including lessons they learned and ongoing challenges. They
touch on several of the same issues that my colleagues and I have run into, and
the writeup inspired me to dust off my old busted blog to document some of my
One area that I felt like needed some further clarity was testing. In particular,
how a Rails-centric application can cleanly and easily integrate tests around
Angular frontend logic. Fortunately, once you figure out how to set this up,
you'll find that unit testing Angular code in Jasmine -- especially controller
and factory code -- is surprisingly easy to do. It's really the first time I've
been sufficiently happy with a frontend testing configuration.
To see a working example for yourself and hack around with it, go snag the
I pushed up to GitHub. Bundle and run it, and play around with the shockingly
awesome todo list application. Because the world really needed another one of
those. When you've had enough of that, take a look at the contents of the
We're using the jasmine-rails test
runner with CoffeeScript here, because that's what works for me (sorry Karma).
Pay close attention to the spec_helper.coffee, which does much of
the dependency injection needed to provide clean and intuitively named
interfaces in our example controller spec.
This gives us nice ways to interface with the factories and controllers we're
defining, as well as Angular's own ngMock
library (super useful for stubbing server-side endpoints), the event loop, and
even template compilation for partials and directives. A couple of these are
illustrated in the sample controller spec shown here:
Jasmine's syntax should be very familiar to anyone who does RSpec BDD work, and
the work we've done in our spec helper really cleans up the beforeEach setup
that's required in each individual controller spec. These particular tests make
heavy use of ngMock, which you won't always need to use, and the calls to
flush() are required to fulfill pending requests, preserving the
async nature of the backend but allowing the tests to execute synchronously.
Testing Continuously With Guard
Although the Jasmine web interface is nice, but I'm a big fan of using Guard
in order to watch for filesystem events and kick off automated test runs from the
command line. By including the guard-jasmine
gem and updating our Guardfile we can continuously test both our server-side
RSpec logic and the Jasmine unit tests all at the same time through a single
One thing I haven't addressed here is directive testing, which can be a bit more
difficult. I'll try to address that in a future post, or if you have your own
recipes, feel free to link em up in the comments.
Special thanks to Mark Bates for working with me on
early versions of this approach, and convincing me that Angular was worth
looking at in the first place.
Kickstarter is awesome for funding creative projects. It's one of my
favorite startups at the moment, and it's important. I lurves it. But I
wish I could use something like it to invest in actual companies -- both the tech
startup variety that my friends work tirelessly on as well as the hyper local
variety that make those special tapas that my neighbors are raving
Soon, new laws may allow us to do just that.
To raise awareness of these initiatives, a few friends and I tossed together the
Wefunder petition to support HR2930
and Brown's Democratizing Access to Capital Act (S.1791) that's
currently being debated in the US Senate. Please go sign it (click the
"learn more" link on the site for more background information and links).
These changes could have huge impacts for both entrepreneurs and
investors, allowing bold new ideas to surface and creating a ton of
important jobs and opportunities. I know that sounds like marketing
speak, but it's true. This matters.
We'll be going to DC next week to talk to Senator Brown's people
and see what else we can do to push this forward. We've also been
fortunate enough to get some great coverage for our efforts at BoingBoing and ReadWriteWeb.
Now go sign it already and help us send a message. And thanks!
I gave a talk earlier today at the Beijing Ruby group today about my
experiences building native Android applications with
Mirah and Pindah.
Although I generally prefer building mobile web apps over native
development when possible, Mirah is a really promising alternative to
Java if you have to go native. Check out the
below and get involved in the growing Mirah / Android community.
This afternoon I'm leaving Dalian, Liaoning, China for a 10-day journey
across China's tech ecosystem with a bunch of awesome startup founders.
By train. Because planes and
buses are so last year (kidding!)
With stops scheduled in both Beijing and Shanghai and a number of events
on the schedule including tech meetups, company visits, mentor meetings,
and a 10x10 mini conference in each city, it's bound to be a fun -- and
delightfully chaotic -- experience. I've really been looking forward to it.
Geeks on a Train (affectionately referred to as "GOAT") is part of the Dalian-based
Chinaccelerator program, which
is a Chinese startup accelerator run by program director Cyril Ebersweiler
and the good folks at SOS Ventures. I was fortunate enough
to meet them through TechStars in
2010 and am really honored that they
invited me over to work with some of the young teams that were accepted
into the program this year. How could I say no?
Chinaccelerator itself is much like TechStars, but with a
brilliant international twist. The startups here aren't just from China,
they're from all over the world, with founders from Malaysia, Canada,
Italy, the Phillipines, India, and England, as well as China and the
United States. It's really fascinating to experience both the similarities and
differences of startup life on the other side of the world, but a couple
philosophies remain as constants: heartfelt motivation and
JFDI are key.
In the two weeks I've been here thus far, I've seen the founders produce
some truly great work and make impressive progress. It's good stuff. There's
nothing more inspiring than being trapped in a room full of crazy entrepreneurs
with wildly different backgrounds who are trying to change the world.
But I can only imagine what it's going to be like trapped on an
overnight train with them :).
2011 has been a busy year so far, full of interesting contract work,
side projects, research for the next startup biz, upcoming travel plans,
and not-so-fun family health issues. It's also been a busy year for the
other Rails Rumble organizers, and
as such there's currently no date set for the 2011 contest. Sorry about
However, I did find a few hours last weekend to design / develop a
Rumble-related mini-site that's been long, long overdue...
Rumble Alumni Archive is a
searchable archive of websites and applications that were developed
during contests past and present. It's a great way to see what entries
are still online and browse them by year (2007-2010), country of origin,
Over 80 entries that were developed during Rumble events are still
online, most of which have evolved pretty significantly since their
initial weekend development sprint. For just a couple examples, check out
Awesome Fontstacks, and
IOU Mate (formerly "nDebted"). Go
poke around the archive
to see others; there's some really great stuff in there. And please
let us know (contact organizers at railsrumble dot com) if we've
left anybody out.
I know I've said it before, but it's really inspiring to me when I think
about how many of these polished web apps started off as as disposable
weekend experiments. Kick. Ass.
Over the past few years I’ve been involved with a number of music-related web projects, including Loudwerkz, DMOD (RIP), and Ink19. Although I make my living on the web and love what I do, I suppose I’ve always been secretly jealous of those snobby record store employees who hear the latest cuts first, troll naive customers, and argue with their coworkers about song meanings :).
Fortunately, the web has lowered the bar to all of that stuff. What would we do without Pandora, Last.fm, and (more recently) Turntable? The one missing piece for me has always been a good song lyrics site. Sure, there are lots of lyrics engines on the web, but they’re all dreadfully designed, spam-centric, and just scuzzy feeling in general. Search for lyrics for your favorite song on Google, and you’re bound to end up looking at popup ads for diet pills.
If you’re like me, this makes you sad. And irritated. So there I was, bitching about this on Twitter one evening, when Seth Banks proposed that we actually do something about it. So we did.
Last week, Seth and I launched Lyricful, which aims to be the first classy lyrics site. We started with a nice clean design and paired it with a sizable lyrics database (growing every day), an intuitive search interface, and some SEO know-how. We’ve also added a few other things we felt fans would find useful, like song previews, concert information, and easy sharing features.
Most importantly, Lyricful isn’t running any invasive eyeball-bleeding advertising. The only ads on the site are in the form of song preview links and concert ticket referrals, relevant to the artist you’re currently browsing (which directly benefits the artist). We built this for ourselves, as music lovers and fans, which means that we wanted to make it as easy as possible to get right to transcribing, discussing, and sharing your favorite lyrics.
Since the soft launch, we’ve started working with a number of artists who were interested in Lyricful and its sister site, MusicNewsHQ. To start with, we’ve added featured / verified artist spots, which will help promote up and coming artists and ensure accuracy of the site contents. Double win. I’m really looking forward to seeing how this project evolves, having both artists and their fans involved in the process. Got feedback for us? We’d love to hear it!
StartupWorkaway is something Nick, Zach, and I have been talking about for quite awhile. We actually built most of the website back in February when we rented a house together up in Quebec City during Winter Carnaval. Nick polished it up and posted it to Hacker News the other day and the response has been pretty incredible so far.
Visit StartupWorkaway for all the gory details. The application deadline is May 6th.
A long while back I wrote a post about Twitter auth integration testing using Cucumber. Back then OAuth was just beginning to see widespread use, but it was nowhere near as popular as it seems to be today. In my latest side project, all logins are from Twitter or Facebook because there’s simply no need for local accounts (due to the nature of the app). But that also means that we needed an easy way to support third-party authentication in our integration tests.
We’re using OmniAuth to handle auth here, which is absolutely awesome. And we’re also using the equally-awesome Capybara for integration testing. Cucumber is no longer part of my standard testing repertoire. I could go into a long rambling post as to why, but chances are you already have some pretty good ideas about that. If you haven’t felt that pain, and Cucumber works for you, that’s great. Seriously. I’m extremely happy for you.
On the other hand, if you’re dissatisfied… Capy 1.0 comes with a swanky new minimalist RSpec-friendly acceptance testing DSL that you really ought to take a look at. The 1.0 gem hasn’t been released yet, but you can pull it into your project directly from the GitHub source if you specify it in your Gemfile. It’s really quite nice and simple, and I’m very happy with it so far.
If you want OAuth integration testing to be easy, you’ll want to make sure you’re using the OmniAuth 0.2.0 or later. Among it’s many fine features is a new integration test_mode that makes testing OAuth logins less sucky than it’s ever been before. Fortunately for us, Capybara and OmniAuth go together like giant chocholate swamp rat and creamy peanut butter. It pretty much works right out of the box.
To demonstrate, let’s add a nice little integration auth helper method that we can use in our request specs to log a user in (I like to put this in spec/support/integration_spec_helper.rb):
def login_with_oauth(service = :twitter)
Finally, let’s take a look at an example RSpec request spec that leverages this helper to test a workflow where a user login is required:
feature 'testing oauth' do
scenario 'should create a new tiger' do
visit new_tiger_path fill_in 'tiger_name', :with => 'Charlie'
fill_in 'tiger_blood', :with => 'yes' click_on 'Create Tiger' page.should have_content("Thanks! You are a winner!")
That’s it. OmniAuth’s test mode automatically mocks out the authentication workflow, allowing us to supply our own auth results hash. Requests made to the usual /auth/provider URL will redirect immediately to the provider callback, which means we never have to hit the actual provider while testing (which also means that webmock or fakeweb remain happy).
This might seem simple, and it is. And that’s kind of a big deal. So now we can get back to writing stuff that isn’t plumbing and focusing on solving real problems ;).
Amazon are the undisputed kings of the developer plumbing revolution. EC2 and S3 are so ubiquitious to deploying web applications that sometimes it seems difficult to remember when we had to self-host so much of this stuff. But sometimes managing my access keys can be a pain. Or even worse: a security hazard.
On one hand, I don’t want to create a new account with different billing information for every single client project demo or collaboration that I roll out. Yet on the other, I’m hesitant to use my own set of keys in places where another person might have access to them. One set of keys to the entire kingdom seems like a bad idea.
The solution to this problem is Amazon’s Identity and Access Management product beta. IAM allows you to create different users and groups, and attach those to your account. So, for example, if you’re a company or a group of people who needs to share a single AWS account, you could create separate identities with separate security credentials (access key ID + secret access key) for each individual. Or if you run several different projects and want to segregate those by account, you can do that too.
Even better, you can control which AWS services that those users (or groups) have access to via policy documents. A common example might be giving a user identified as ‘projectx’ access to only a ‘projectx’ S3 bucket and no others. This way, you can keep your accounts separate, and limit them to only what they need. And if you ever need to revoke or regenerate keys because a single application is compromised, it’s far less of a problem.
Anyway, outside of Amazon’s own documentation, I couldn’t find a hell of a lot of information about using IAM in the real world, so I thought I’d demonstrate how I’m using it with Fog, which is an absolutely awesome cloud services library for Ruby.
Annotated example code seems like the right way to go here. Let’s generate a new IAM user and a set of keys for him, and give him permission to only a single bucket, which we’ll create (note that your bucket name must be unique so don’t use the sample one shown here).
First, we set up the new user name and the bucket name that we want to create, and establish our AWS credentials:
Fog also provides a lightweight wrapper around IAMAPI methods. Using this, we can create the new user and create an access key. Assuming this is successful, we’ll end up with the user ARN (which we’ll need later) and a new set of credentials.
We also want to grant them access to the bucket we created. But only our bucket and no others. If you think constructing policy documents by hand is shitty, you’re right. Fortunately the AWS Policy Generator can help us generate the nasty bits. Check it out.
Note that you can use the keys that are generated in place of your normal account keys pretty much anywhere, as demonstrated. However, if you’re limiting bucket access as we’ve done here, be aware that you won’t be able to do a list command to retrieve all buckets accessible to a user. I had an incredibly frustrating couple of hours the other day trying to figure out why s3cmd and the Firefox S3 Organizer wouldn’t work with my newly generated IAM keys, and the reason was simply that they were trying to get a list of buckets first, which was returning an access denied message. D’oh. (and thanks to crazed for helping me see the light on that.)
If you’re not a Ruby developer, or you just need command line access, you can also use the IAM command line tools provided by Amazon, and you should definitely check out their Getting Started guide. Hopefully IAM will find its way into the AWS Console so routine management tasks are a bit easier in the future. In the meantime, creating policy documents by hand is a big pain in the ass, but at least the Policy Generator takes a little bit of the suck out of it.
My pal and “prolific prototyper” Nick Tommarello just released his latest project into the wild… Stomp.io is a social adventure and travel guide that aims to make it easier for you to find fun things to do while at home or on the go. Stomp debuted at the Launch conference run by former TC50 founder Jason Calacanis, and has gotten some great media coverage over the past couple days. Like pitches? You can watch Nick’s presentation here.
If you’re in SF, NYC, or Boston, make sure to give it a try. Hopefully it won’t take too long to spread to other areas too. Some of the challenges are… kind of nuts. Others are a bit more laid back. And there’s a lot more in-between so I’m pretty sure you’ll find something you like there. You can install the mobile version of the app on both the iPhone and Android
Oh and if you’re having problems with the Android version of the app you can yell at me. Working with Nick on Stomp was a great excuse for me to level up on Android development. There’s no better way to come up to speed on a new platform than to dive in and deliver a working application. That said, the app is still young and a bit sparse, and I’m sure there are still a few bugs hiding in the woods; Crash reports and feature requests are very welcome :). Thanks in advance!