-
-
Save roman/316337 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The Traveling Hacker -------------------- | |
Today you will be building a tool for a travel agency that determines the | |
total distance traveled on a tour with many stops. As luck would have it, some | |
of the core functionality you need has already been implemented, and you won't | |
need to worry about coding a mileage and routing system from scratch. | |
But there's a catch: The mileage and routing system you'll be using lies on | |
the other side of a service boundary, and only minimal work has been done on | |
the client side. Essentially, all that has been written so far is a bit of | |
code that allows you to hit a URL via the usual HTTP verbs, pass any relevant | |
parameters, and get back a raw Ruby structure de-serialized from a JSON | |
response. | |
Here's an example of a successful call: | |
RoutingService.get("/distance", :origin => "Naugatuck, CT", | |
:destination => "New Haven, CT") | |
#=> { "distance" => 17.4 } | |
While the client-side networking code has been tested, you don't have access | |
to a live running service. Instead, all you have is a basic outline of the | |
sorts of requests and responses the service accepts. You'll find that | |
specification linked in the resources section at the end of this document. | |
There aren't many calls you'll need though, so with a little help from one of | |
the many mocking frameworks in Ruby, you'll still be able to develop your | |
part of this application test-first. And there is no better time than the | |
present to discuss what exactly you need to build. | |
YOUR TASK: | |
You'll be building a Trip object that makes use of the RoutingService. Here | |
are the stories associated with it: | |
* A trip should be able to have an arbitrary amount of stops | |
* When adding a new stop, the trip object should determine whether the stop | |
name is valid without triggering a server error, and raise an error | |
client-side when it is not. | |
* A trip is broken up into legs, e.g. a tour from A->B->C has two legs, the | |
one from A->B, and the one from B->C. | |
* Each leg is defined by an origin, destination, and the distance between the | |
two. | |
* The total distance of the trip is the sum of the distance traveled at each | |
leg. | |
* The trip should have a human readable string representation that breaks | |
down the distances by legs and also displays the total distance. | |
You are expected to implement the above functionality with complete test | |
coverage. You are encouraged to write the tests before your implementation | |
code, and will most likely want to substitute a mock object in place of your | |
RoutingService calls. You'll want to code your Trip object against the | |
interface described in the service specification, so that things will work the | |
same in the live production environment as they do in your tests. | |
If all goes well, you'll get all your tests to pass, and when the app is | |
dropped into production, things will "just work" even though you've never | |
directly ran tests against the service. But don't worry about that side of | |
things for now, just focus on the logic for your Trip object, and we | |
can resolve any minor server communication issues later when things move into | |
staging. | |
------ | |
(here I would put links to relevant external resources, websites, support | |
documents, and of course, sections and chapters of the freely released content | |
from my book) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment