<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>Tate Johnson</title>
 <link href="http://tatey.com/atom.xml" rel="self"/>
 <link href="http://tatey.com/"/>
 <updated>2015-12-13T20:38:16+10:00</updated>
 <id>http://tatey.com/</id>
 <author>
   <name>Tate Johnson</name>
   <email>tate@tatey.com</email>
 </author>
 
   <entry>
     <title>Shipped&amp;#58; Maps for Antenna Mate</title>
     <link href="http://tatey.com/2014/01/19/shipped-maps-for-antenna-map/"/>
     <updated>2014-01-19T00:00:00+10:00</updated>
     <id>http://tatey.com/2014/01/19/shipped-maps-for-antenna-map</id>
     <content type="html">&lt;p&gt;&lt;a href=&quot;http://maps.antennamate.com&quot;&gt;Maps for Antenna Mate&lt;/a&gt; is an experimental web application for finding and linking to transmitters in your browser. It&amp;#39;s built entirely with AngularJS + Jekyll and hosted on S3 + Cloudfront for extra low latency goodness.&lt;/p&gt;

&lt;p&gt;I decided to &lt;a href=&quot;https://github.com/tatey/maps.antennamate.com&quot;&gt;open source the code&lt;/a&gt; as a learning tool for new developers. When I started with AngularJS I wish I could have gotten my hands on real-world code. There are thousands of snippets scattered over blogs but by themselves you get an incomplete picture. How do you run tests? Where should files be placed? How do you perform a deploy?&lt;/p&gt;

&lt;p&gt;I&amp;#39;m also hoping it will boost the sales of &lt;a href=&quot;http://antennamate.com&quot;&gt;Antenna Mate for iOS&lt;/a&gt;, or at least compliment it. Maps is for finding transmitters ahead of time and requires an internet connection. The app is for finding the best transmitter from your current location and plotting a bearing. It&amp;#39;s blazingly fast and doesn&amp;#39;t require an internet connection. By having distinct applications it allows me to keep the products simple and the scope tight.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://angularjs.org&quot;&gt;AngularJS&lt;/a&gt; is an absolute joy to develop with. What Ruby on Rails did for the backend in 2007, AngularJS is doing for the frontend in 2014.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Shipped&amp;#58; Tug for Continuous Deployment</title>
     <link href="http://tatey.com/2013/10/23/shipped-tug-for-continuous-deployment/"/>
     <updated>2013-10-23T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/10/23/shipped-tug-for-continuous-deployment</id>
     <content type="html">&lt;p&gt;In April I wrote about &lt;a href=&quot;/2013/05/06/experimenting-with-continuous-deployment-for-feature-branches&quot;&gt;experimenting with continuous deployment for feature branches&lt;/a&gt;. Now I&amp;#39;m happy to announce &lt;a href=&quot;http://tugapp.com&quot;&gt;Tug is available to everyone for free while in beta&lt;/a&gt;. Basically, you configure a template and then it creates a staging instance on Heroku for every branch that&amp;#39;s pushed to GitHub. When the branch is merged, the instance is torn down. Everything is logged for troubleshooting and the dashboard shows you what is deployed and where.&lt;/p&gt;

&lt;p&gt;At work it&amp;#39;s become an integral part of shipping. We use Tug to get product changes in the hands of everyone at the company. That means developers can focus on slinging code and non-technical people can quickly give feedback. In addition, because our staging environments are identical to our production environments it lets us experiment with changing the stack, switching environment variables and getting external testers on board. Basically, we know that if our tests pass and staging deploys then we can confidently ship to production.&lt;/p&gt;

&lt;p&gt;Now your team can get from this this too. &lt;a href=&quot;http://tugapp.com&quot;&gt;Try out Tug&lt;/a&gt;. Would love to get your feedback.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Ahri-ly Liked This Birthday Message</title>
     <link href="http://tatey.com/2013/09/26/ahri-ly-liked-this-birthday-message/"/>
     <updated>2013-09-26T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/09/26/ahri-ly-liked-this-birthday-message</id>
     <content type="html">&lt;p&gt;I like puns and I like &lt;a href=&quot;http://leagueoflegends.com&quot;&gt;League of Legends&lt;/a&gt;. My friend &lt;a href=&quot;http://www.hannahhaysom.com/&quot;&gt;Hannah Haysom&lt;/a&gt; managed to combine the two into a pun-tastic birthday message.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dear Tate,&lt;/p&gt;

&lt;p&gt;Lee Sin up, because I have a birthday message for you, and I hope it won’t be in Vayne.&lt;/p&gt;

&lt;p&gt;I’ve got a Zilean things I could say on this special occasion. For example, I wish you all the Lux in the world, and I hope you never have to deal with any Graves Miss Fortune. I’d also like to think I could Ryze to the occasion on your birthday and make a few puns (because you love them), but I can’t think of Annie. I then thought that I could make a joke, but chances are it would Nocturne out the way Irelia want it to. Udyr, I seem to be rambling. &lt;/p&gt;

&lt;p&gt;Joking aside, let’s get Ezreal for a second. You’re a Sivir-ly awesome guy – and not to mention Talon-ted. As a Sion-tist, I can say that with authority. I think you’ve got a lot of good Karma built up.&lt;/p&gt;

&lt;p&gt;So on this special occasion, get ready to Rumble, pop a Corki or two, and I Garen-tee you’ll have a good time!&lt;/p&gt;

&lt;p&gt;HAPPY BIRTHDAY!&lt;/p&gt;

&lt;p&gt;P.S. Don’t get Singed by the candles on your birthday cake (it’s Poppy-seed)!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahri-ly liked it.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tatey Open Sourced Tatey/NextStop</title>
     <link href="http://tatey.com/2013/08/24/tatey-open-sourced-tatey-nextstop/"/>
     <updated>2013-08-24T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/08/24/tatey-open-sourced-tatey-nextstop</id>
     <content type="html">&lt;p&gt;I spent many &lt;a href=&quot;https://github.com/tatey/NextStop/graphs/punch-card&quot;&gt;nights and weekends&lt;/a&gt; on Next Stop to make catching public transport in Brisbane better for everyone. Then I moved to Sydney and stopped catching public transport altogether in favour of walking and riding. There were people building &lt;a href=&quot;http://www.triptasticapp.com/&quot;&gt;better&lt;/a&gt; &lt;a href=&quot;http://www.skedgo.com/tripgo&quot;&gt;apps&lt;/a&gt; than Next Stop and my focus shifted to &lt;a href=&quot;https://www.thebestday.com&quot;&gt;other&lt;/a&gt; &lt;a href=&quot;https://tugapp.com&quot;&gt;things&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/2013-08-24-tatey-open-sourced-tatey-nextstop/feeditem-f9d5d0e9559427f23c8d92ff08bc7081.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Now I&amp;#39;m happy to announce that &lt;a href=&quot;https://github.com/tatey/NextStop&quot;&gt;Next Stop is available as an open source project&lt;/a&gt;. There are things I&amp;#39;d do differently next time round, but it&amp;#39;s better to be open than gathering virtual dust on my hard drive. Maybe you can learn something from it.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Shipped&amp;#58; Delayed::Web GUI for Delayed::Job</title>
     <link href="http://tatey.com/2013/08/24/shipped-delayed-web-gui-for-delayed-job/"/>
     <updated>2013-08-24T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/08/24/shipped-delayed-web-gui-for-delayed-job</id>
     <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/thebestday/delayed-web&quot;&gt;Delayed::Web&lt;/a&gt; is a rails engine that provides a simple web interface for exposing the &lt;a href=&quot;https://github.com/collectiveidea/delayed_job&quot;&gt;Delayed::Job&lt;/a&gt; queue. Installation is simple. Add one line to your gemfile and mount the engine in your routes file.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/posts/2013-08-24-shipped-delayed-web-gui-for-delayed-job/687474703a2f2f662e636c2e6c792f6974656d732f316a326d326732323373337133333134305333482f53637265656e25323053686f74253230323031332d30362d3133253230617425323031312e34372e3537253230504d2e706e67-6b8f71b809ad7a6de3787ea7d95955b2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Despite the popularity of Redis backed queues we use Delayed::Job. We intentionally strive to keep our stack as simple as possible. Delayed::Job lets us keep a single database. Secondly, we&amp;#39;re hiring at &lt;a href=&quot;https://www.thebestday.com&quot;&gt;TheBestDay&lt;/a&gt; and I wanted to show off the way we think about writing code to potential candidates.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;re interested in working with us, &lt;a href=&quot;mailto:tate@tatey.com&quot;&gt;drop me an email&lt;/a&gt;.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Don&#39;t Care About the Return Value of Outgoing Commands</title>
     <link href="http://tatey.com/2013/08/24/dont-care-about-the-return-value-of-outgoing-commands/"/>
     <updated>2013-08-24T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/08/24/dont-care-about-the-return-value-of-outgoing-commands</id>
     <content type="html">&lt;p&gt;When writing unit tests we set &lt;a href=&quot;https://speakerdeck.com/skmetz/magic-tricks-of-testing-railsconf&quot;&gt;expectations that outgoing commands will be sent&lt;/a&gt;. We verify that the command was sent, but we don&amp;#39;t care about the return value. Testing libraries like RSpec force you to specify a return value when using the short-hand syntax.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Logger&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Message&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Message&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_received&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Message&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That innocent looking return value is an assumption being made about an object that our unit test doesn&amp;#39;t own. It&amp;#39;s susceptible to API drift and is a distraction from the test at hand. Instead of making an assumption, lets be explicit and say that we don&amp;#39;t care.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Logger&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dont_care&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Message&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_received&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Message&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By being explicit we&amp;#39;re giving a clue to the next programmer that the return value doesn&amp;#39;t matter. We don&amp;#39;t do anything with the return value and &lt;code&gt;Logger&lt;/code&gt; has its own suite of unit tests which verify the behaviour of the &lt;code&gt;info&lt;/code&gt; method. Our implementation of &lt;code&gt;dont_care&lt;/code&gt; is simple.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# spec/support/dont_care.rb&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Support&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DontCare&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dont_care&lt;/span&gt;
        &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Support&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:DontCare&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It doesn&amp;#39;t matter that we return &lt;code&gt;nil&lt;/code&gt;. It&amp;#39;s used only for outgoing commands and we never do anything with the return value. When you put it all together you end up with small, readable unit tests that look like this.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# spec/interactors/task/restart_process_spec.rb&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:RestartProcesses&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;#run_with_error&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;HerokuClient&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_ps_restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dont_care&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Logger&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dont_care&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:RestartProcesses&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Inject Dependencies&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# Run&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run_with_error&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;restarts processes&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_received&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:post_ps_restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;logs&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_received&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Restarting processes&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Updated 2013-08-24&lt;/h4&gt;

&lt;p&gt;David Chelimsky &lt;a href=&quot;https://gist.github.com/dchelimsky/6327095&quot;&gt;showed another approach&lt;/a&gt; to setting expectations without caring about the return value using &lt;a href=&quot;https://www.relishapp.com/rspec/rspec-mocks/docs/method-stubs/as-null-object&quot;&gt;as_null_object&lt;/a&gt;. The big advantage of this approach is that it&amp;#39;s built into RSpec.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Experimenting With Continuous Deployment for Feature Branches</title>
     <link href="http://tatey.com/2013/05/06/experimenting-with-continuous-deployment-for-feature-branches/"/>
     <updated>2013-05-06T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/05/06/experimenting-with-continuous-deployment-for-feature-branches</id>
     <content type="html">&lt;p&gt;At work we&amp;#39;ve been &lt;a href=&quot;https://twitter.com/tatejohnson/status/311268504995254273&quot;&gt;experimenting with a tool&lt;/a&gt; that deploys our project to a staging environment every time a developer pushes to GitHub. If the branch has already been deployed, it will drop, create and seed the database. If the branch has never been deployed, it will provision a new instance. The end result is the same. A usable, working instance of the project accessible to anyone in the company, especially non-developers. You could think of it as continuous deployment for feature branches.&lt;/p&gt;

&lt;p&gt;Internally the tool is known as Tug and it deploys straight from GitHub to Heroku. Tug announces when the deploy has finished in Campfire along with the URL. There&amp;#39;s also a dashboard for quickly seeing which branches have been deployed and their URLs. You can also get a log of the output captured from the API and command line to troubleshoot any problems. To date, we&amp;#39;ve had 10 failed deploys out of 460.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/posts/2013-05-06-experimenting-with-continuous-deployment-for-feature-branches/tug-a1ed703c4e0f35b7b9d318be849faf50.png&quot;&gt;&lt;img src=&quot;/assets/posts/2013-05-06-experimenting-with-continuous-deployment-for-feature-branches/tug_thumb-450938d93e66fcf9f01448baece6ee86.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tug works well for us because we use feature branches heavily for development. We&amp;#39;re a small team, but it&amp;#39;s not uncommon to have 2 or 3 concurrent branches. The last thing we want to be thinking about is how are we going to get some early feedback from other people in the company. Even as a developer, it&amp;#39;s nice to be able to look at a pull request and then go and try the code out without having to mess around with my local repository.&lt;/p&gt;

&lt;p&gt;What I&amp;#39;m trying to gauge is whether other developers would find this useful in their organisation, or if we have our processes wrong. This idea is not unique to me. We practised this process without the automation at &lt;a href=&quot;http://everydayhero.com&quot;&gt;Everyday Hero&lt;/a&gt; and the guys at &lt;a href=&quot;http://ennova.com.au&quot;&gt;Ennova&lt;/a&gt; shipped &lt;a href=&quot;https://koideploy.com/&quot;&gt;Koi Deploy&lt;/a&gt; for Rails Rumble.&lt;/p&gt;

&lt;h4&gt;Updated 2013-05-20&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://speakerdeck.com/tatey/experimenting-with-continuous-deployment-for-feature-branches&quot;&gt;View the slides&lt;/a&gt; from my lightning talk which I gave at &lt;a href=&quot;http://www.meetup.com/devops-sydney/&quot;&gt;Sydney DevOps&lt;/a&gt; on 16th May, 2013.&lt;/p&gt;

&lt;h4&gt;Updated 2013-10-23&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://tugapp.com&quot;&gt;Tug&lt;/a&gt; is available for you to use!&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Antenna Mate Ships in the United Kingdom</title>
     <link href="http://tatey.com/2013/05/05/antenna-mate-ships-in-the-united-kingdom/"/>
     <updated>2013-05-05T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/05/05/antenna-mate-ships-in-the-united-kingdom</id>
     <content type="html">&lt;p&gt;&lt;a href=&quot;http://antennamate.com&quot;&gt;Antenna Mate&lt;/a&gt; has been for sale on the &lt;a href=&quot;http://appstore.com/antennamate&quot;&gt;Australian App Store&lt;/a&gt; since January 2011. It&amp;#39;s sold over 6,000 copies and has an average rating of 4.5 stars from 48 ratings. It&amp;#39;s appeared in a &lt;a href=&quot;http://www.candm.com.au/magazine&quot;&gt;magazine&lt;/a&gt; and gets recommended by customers on &lt;a href=&quot;http://car.caravanersforum.com/%7Ecaravane/viewtopic.php?f=2&amp;amp;t=32604&quot;&gt;various&lt;/a&gt; &lt;a href=&quot;http://www.candm.com.au/forum/viewtopic.php?f=6&amp;amp;t=8586&amp;amp;p=90562&quot;&gt;caravanning&lt;/a&gt; &lt;a href=&quot;http://www.exploroz.com/Forum/Topic/101815/TV_Reception_iPad_app.aspx&quot;&gt;forums&lt;/a&gt;. Not bad for a little project I started in my final year of university.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve always been interested to know what would happen if these numbers could be replicated in other countries. If Antenna Mate went on sale in the United Kingdom would the total number of sales double?&lt;/p&gt;

&lt;p&gt;Picking the second country for Antenna Mate required some research. I started by looking at existing traffic to the website. The United States seemed like an obvious choice. After Australia, the United States made up 15% of the total traffic. More interestingly Americans were landing on the website through organic searches with keywords like &amp;quot;tv antenna direction app&amp;quot;. Very promising.&lt;/p&gt;

&lt;p&gt;The problem is data. The &lt;a href=&quot;http://www.fcc.gov/&quot;&gt;FCC&lt;/a&gt; publishes terrestrial television data in a pipe delimited text file, but doesn&amp;#39;t provide enough context to turn raw data into meaningful information for an antenna installer or caravaner. Admittedly I don&amp;#39;t know much about terrestrial television in the United States.&lt;/p&gt;

&lt;p&gt;Going back to the website, the next biggest group was from the United Kingdom. They made up 5% of the total traffic and were arriving through similar organic searches. Terrestrial television is culturally popular in the United Kingdom and there are a couple of big &lt;a href=&quot;http://www.caravantalk.co.uk/&quot;&gt;caravanning websites&lt;/a&gt;. More importantly, &lt;a href=&quot;http://www.ofcom.org.uk/&quot;&gt;Ofcom&lt;/a&gt; publishes similar raw data to the &lt;a href=&quot;http://www.acma.gov.au/&quot;&gt;ACMA&lt;/a&gt; in Australia. That meant there would be less changes required to the code and the data could be reliably imported.&lt;/p&gt;

&lt;p&gt;I estimated that it would take about 10-16 hours to write a script to import the data, verify that it worked from inside the United Kingdom, localise the application and update the website. It probably took closer to 20 hours, but I&amp;#39;m happy to say that it&amp;#39;s now on the &lt;a href=&quot;http://appstore.com/antennamate&quot;&gt;App Store&lt;/a&gt;. If I were to fund that 20 hours from revenue at market contracting rates then it costs me about 3 months of revenue. But since it&amp;#39;s more of a fun side project, I don&amp;#39;t.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;re in the United Kingdom give it a try and let me know what you think. If you&amp;#39;re in the United States and could help with data, I&amp;#39;d also be interested to &lt;a href=&quot;mailto:tate@tatey.com&quot;&gt;hear from you&lt;/a&gt;.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Design is an Iterative Process</title>
     <link href="http://tatey.com/2013/04/29/design-is-an-iterative-process/"/>
     <updated>2013-04-29T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/04/29/design-is-an-iterative-process</id>
     <content type="html">&lt;p&gt;I&amp;#39;ve been watching my girlfriend get frustrated at designing her first website. She gets put off after working so hard on something that doesn&amp;#39;t work out the way she thought it would. I keep reminding her that design is an iterative process. The Antenna Mate that thousands of people &lt;a href=&quot;http://www.flickr.com/photos/tatejohnson/8691229793/in/set-72157633377668866/&quot;&gt;use today&lt;/a&gt; is not the same Antenna Mate that &lt;a href=&quot;http://www.flickr.com/photos/tatejohnson/8692347604/in/set-72157633377668866/&quot;&gt;first shipped&lt;/a&gt; on the App Store. In fact, I&amp;#39;m really embarrassed by the earlier versions. But I shipped, and I couldn&amp;#39;t have gotten where I did without iterating. You only need to look at the earlier versions of &lt;a href=&quot;http://blog.directededge.com/wp-content/uploads/2009/03/github.png&quot;&gt;GitHub&lt;/a&gt; and &lt;a href=&quot;http://upload.wikimedia.org/wikipedia/en/d/d8/MacOSX10-0screenshot.png&quot;&gt;Mac OS X&lt;/a&gt; to see the same pattern repeat itself. If your core purpose is solid, then hard work and polish will pay off.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Next Stop is Hopping Off</title>
     <link href="http://tatey.com/2013/04/07/next-stop-is-hopping-off/"/>
     <updated>2013-04-07T00:00:00+10:00</updated>
     <id>http://tatey.com/2013/04/07/next-stop-is-hopping-off</id>
     <content type="html">&lt;p&gt;Today I made the decision to remove Next Stop for sale on the App Store. I posted this message on the &lt;a href=&quot;http://nextstop.me&quot;&gt;Next Stop website&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next Stop is no longer available on the App Store. It was fun to build and made sure I got off at the right stop. The truth is, it hasn&amp;#39;t sold that well and apps like TripGo do the same thing and everything else a commuter could want. At the end of the day, I support any well built piece of software that helps to increase public transport consumption. Everyone wins when someone chooses to catch a bus instead of driving a car. Thank you to everyone who supported Next Stop, especially Jason Weathered, Odin Dutton and Rachael Battle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How well is not well? About 1-3 sales per day. &lt;a href=&quot;http://antennamate.com&quot;&gt;Antenna Mate&lt;/a&gt; sells &lt;em&gt;much&lt;/em&gt; better than that and at for 2.5 times the price. Next Stop was an enormous effort to build. In retrospect, there were a lot of things I could have cut from scope. It took a weekend to build logging with the expectation that people would submit logs so I could help debug Core Location. Number of logs I received? Zero.&lt;/p&gt;

&lt;p&gt;Since building Next Stop I&amp;#39;ve strived to keep focus on the core problem and shipping as early as possible. At the end of the day, you can only commit a finite number of hours to a project and you&amp;#39;ve got to make that project count for something.&lt;/p&gt;

&lt;p&gt;What I&amp;#39;ve always wanted is an app I could tell where I&amp;#39;m going and it figures out the route and tells me where to get off. That&amp;#39;s what &lt;a href=&quot;http://skedgo.com&quot;&gt;TripGo&lt;/a&gt; does. There&amp;#39;s some good people behind it and I wish them all the best. Now I feel free to focus.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m finishing this post off with an experimental design I was contemplating for Next Stop. It was intentionally high contrast to increase visibility for people with vision impairments.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/tatejohnson/8627276780/&quot;&gt;&lt;img src=&quot;http://farm9.staticflickr.com/8532/8627276780_157262c3af_o.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
</feed>
