4elements, Amsterdam, Holland

  1. Getting Started With Phpspec

    In this short, yet comprehensive, tutorial, we'll have a look at behavior driven development (BDD) with phpspec. Mostly, it will be an introduction to the phpspec tool, but as we go, we'll touch on different BDD concepts. BDD is a hot topic these days and phpspec has gained a lot of attention in the PHP community recently.

    SpecBDD & Phpspec

    BDD is all about describing the behavior of software, in order to get the design right. It is often associated with TDD, but whereas TDD focus on testing your application, BDD is more about describing its behavior. Using a BDD approach will force you to constantly consider the actual requirements and desired behavior of the software you're building.

    Two BDD tools have gained a lot of attention in the PHP community recently, Behat and phpspec. Behat helps you describe the external behavior of your application, using the readable Gherkin language. phpspec, on the other hand, helps you describe the internal behavior of your application, by writing small "specs" in the PHP language - hence SpecBDD. These specs are testing that your code has the desired behavior.

    What We Will Do

    In this tutorial, we'll cover everything related to getting started with phpspec. On our way, we'll build the fundament of a todo list application, step-by-step, using a SpecBDD approach. As we go, we'll have phpspec lead the way!

    Note: This is an intermediate article about PHP. I assume you have a good grasp of object-oriented PHP.

    Installation

    For this tutorial, I assume you have the following stuff up and running:

    Installing phpspec through Composer is the easiest way. All you have to do is run the following command in a terminal:

    $ composer require phpspec/phpspec
    Please provide a version constraint for the phpspec/phpspec requirement: 2.0.*@dev

    This will make a composer.json file for you and install phpspec in a vendor/ directory.

    In order to make sure that everything is working, run phpspec and see that you get the following output:

    $ vendor/bin/phpspec run
    
    0 specs
    0 examples 
    0ms

    Configuration

    Before we start, we need to do a little bit of configuration. When phpspec runs, it looks for a YAML file named phpspec.yml. Since we will be putting our code in a namespace, we need to make sure that phpspec knows about this. Also, while we are at it, let's make sure that our specs looks nice and pretty when we run them.

    Go ahead and make the file with the following content:

    formatter.name: pretty
    suites:
        todo_suite:
            namespace: Petersuhm\Todo

    There are many other configuration options available, which you can read about in the documentation.

    Another thing we need to do, is to tell Composer how to autoload our code. phpspec will use Composer's autoloader, so this is required for our specs to run.

    Add an autoload element to the composer.json file that Composer made for you:

    {
        "require": {
            "phpspec/phpspec": "2.0.*@dev"
        },
        "autoload": {
            "psr-0": {
                "Petersuhm\\Todo": "src"
            }
        }
    }

    Running composer dump-autoload will update the autoloader after this change.

    Our First Spec

    Now we are ready to write our first spec. We'll start by describing a class called TaskCollection. We'll have phpspec generate a spec class for us by using the describe command (or alternatively the short version desc) .

    $ vendor/bin/phpspec describe "Petersuhm\Todo\TaskCollection"
    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\TaskCollection` for you? y

    So what happened here? First, we asked phpspec to create a spec for a TaskCollection. Second, we ran our spec suite and then phpspec automagically offered to create the actual TaskCollection class for us. Cool, isn't it?

    Go ahead and run the suite again, and you'll see that we already have one example in our spec (we'll see in a moment what an example is):

    $ vendor/bin/phpspec run
    
          Petersuhm\Todo\TaskCollection
    
      10  ✔ is initializable
    
    
    1 specs
    1 examples (1 passed)
    7ms

    From this output, we can see that the TaskCollection is initializable. What is this about? Take a look at the spec file that phpspec generated, and it should be clearer:

    <?php
    
    namespace spec\Petersuhm\Todo;
    
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    
    class TaskCollectionSpec extends ObjectBehavior
    {
        function it_is_initializable()
        {
            $this->shouldHaveType('Petersuhm\Todo\TaskCollection');
        }
    }

    The phrase 'is initializable' is derived from a function named it_is_initializable() which phpspec has added to a class called TaskCollectionSpec. This function is what we refer to as an example. In this particular example, we have what we refer to as a matcher called shouldHaveType() that checks the type of our TaskCollection. If you change the parameter passed to this function to something else and run the spec again, you will see that it will fail. Before completely understanding this, I think we need to investigate in what the variable $this refers to in our spec.

    What Is $this?

    Of course, $this refers to the instance of the class TaskCollectionSpec, since this is just regular PHP code. But with phpspec, you have to treat $this different from what you normally do, since under the hood, it's actually referring to the object under test, which is in fact the TaskCollection class. This behavior is inherited from the class ObjectBehavior, which makes sure that function calls are proxied to the spec'ed class. This means that SomeClassSpec will proxy method calls to an instance of SomeClass. phpspec will wrap these method calls in order to run their return values against matchers like the one you just saw.

    You don't need a deep understanding of this in order to use phpspec, just remember that as far as you are concerned, $this actually refers to the object under test.

    Building Our Task Collection

    So far, we haven't done anything ourself. But phpspec have made an empty TaskCollection class for us to use. Now is the time to fill in some code and make this class useful. We will add two methods: an add() method, to add tasks, and a count() method, to count the number of tasks in the collection.

    Adding a Task

    Before we write any real code, we should write an example in our spec. In our example, we want to try to add a task to the collection, and then afterwards make sure that the task is in fact added. In order to do this, we need an instance of the (so far non-existing) Task class. If we add this dependency as a parameter to our spec function, phpspec will automatically give us an instance that we can use. Actually, the instance isn't a real instance, but what phpspec refers to as a Collaborator. This object will act as the real object, but phpspec allows us to do more fancy stuff with this, which we'll see soon. Even though the Task class doesn't exist yet, for now, just pretend it does. Open up the TaskCollectionSpec and add a use statement for the Task class and then add the example it_adds_a_task_to_the_collection():

    use Petersuhm\Todo\Task;
    
    ...
    
    function it_adds_a_task_to_the_collection(Task $task)
    {
        $this->add($task);
        $this->tasks[0]->shouldBe($task);
    }

    In our example, we write the code "we wish we had". We call the add() method and then try to give it a $task. Then we check that the task was in fact added to the instance variable $tasks. The matcher shouldBe() is an identity matcher similar to the PHP === comparator. You can use either shouldBe(), shouldBeEqualTo(), shouldEqual() or shouldReturn() - they all do the same.

    Running phpspec will yield some errors, since we don't have a class named Task yet.

    Let's have phpspec fix that for us:

    $ vendor/bin/phpspec describe "Petersuhm\Todo\Task"
    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\Task` for you? y

    Running phpspec again, something interesting happens:

    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\TaskCollection::add()` for you? y

    Perfect! If you take a look at the TaskCollection.php file, you will see that phpspec made an add() function for us to fill out:

    <?php
    
    namespace Petersuhm\Todo;
    
    class TaskCollection
    {
    
        public function add($argument1)
        {
            // TODO: write logic here
        }
    }

    phpspec is still complaining, though. We don't have a $tasks array, so let's make one and add the task to it:

    <?php
    
    namespace Petersuhm\Todo;
    
    class TaskCollection
    {
        public $tasks;
    
        public function add(Task $task)
        {
            $this->tasks[] = $task;
        }
    }

    Now our specs are all nice and green. Note that I made sure to typehint the $task parameter.

    Just to make sure we got it right, let's add another task:

    function it_adds_a_task_to_the_collection(Task $task, Task $anotherTask)
    {
        $this->add($task);
        $this->tasks[0]->shouldBe($task);
    
        $this->add($anotherTask);
        $this->tasks[1]->shouldBe($anotherTask);
    }

    Running phpspec, it looks like we're all good.

    Implementing the Countable Interface

    We want to know how many tasks are in a collection, which is a great reason for using one of the interfaces from the Standard PHP Library (SPL), namely the Countable interface. This interface dictates that a class implementing it must have a count() method.

    Earlier, we used the matcher shouldHaveType(), which is a type matcher. It uses the PHP comparator instanceof to validate that an object is in fact an instance of a given class. There are 4 type matchers, which all does the same. One of them is shouldImplement(), which is perfect for our purpose, so let's go ahead and use that in an example:

    function it_is_countable()
    {
        $this->shouldImplement('Countable');
    }

    See how beautiful that reads? Let's run the example and have phpspec lead the way for us:

    $ vendor/bin/phpspec run
    
            Petersuhm/Todo/TaskCollection
      25  ✘ is countable
            expected an instance of Countable, but got [obj:Petersuhm\Todo\TaskCollection].

    Okay, so our class isn't an instance of Countable since we haven't implemented it yet. Let's update the code for our TaskCollection class:

    class TaskCollection implements \Countable

    Our tests won't run, since the Countable interface has an abstract method, count(), which we have to implement. An empty method will do the trick for now:

    public function count()
    {
        // ...
    }

    And we're back to green. At the moment our count() method doesn't do much, and it's actually pretty useless. Let's write a spec for the behavior that we wish it to have. First, with no tasks, our count function is expected to return zero:

    function it_counts_elements_of_the_collection()
    {
        $this->count()->shouldReturn(0);
    }

    It returns null, not 0. To get a green test, let's fix this the TDD/BDD way:

    public function count()
    {
        return 0;
    }

    We're green and all is good, but this is probably not the behavior we want. Instead, let's expand our spec and add something to the $tasks array:

    function it_counts_elements_of_the_collection()
    {
        $this->count()->shouldReturn(0);
    
        $this->tasks = ['foo'];
        $this->count()->shouldReturn(1);
    }

    Of course, our code is still returning 0, and we have a red step. Fixing this is not too difficult and our TaskCollection class should now look like this:

    <?php
    
    namespace Petersuhm\Todo;
    
    class TaskCollection implements \Countable
    {
        public $tasks;
    
        public function add(Task $task)
        {
            $this->tasks[] = $task;
        }
    
        public function count()
        {
            return count($this->tasks);
        }
    }

    We have a green test and our count() method works. What a day!

    Expectations & Promises

    Remember I told you that phpspec allows you to do cool stuff with instances of the Collaborator class, AKA the instances that are automatically injected by phpspec? If you have been writing unit tests before, you know what mocks and stubs are. If you don't, please don't worry too much about it. It's only jargon. These things refers to "fake" objects that will act as your real objects, but allow you to test in isolation. phpspec will automatically turn these Collaborator instances into mocks and stubs if you need it in your specs. 

    This is really awesome. Under the hood, phpspec uses the Prophecy library, which is a highly opinionated mocking framework that plays well with phpspec (and is build by the same awesome folks). You can set an expectation on a collaborator (mocking), like "this method should be called", and you can add promises (stubbing), like "this method will return this value". With phpspec this is really easy and we'll do both things next.

    Let's make a class, we'll call it TodoList, that can make use of our collection class.

    $ vendor/bin/phpspec desc "Petersuhm\Todo\TodoList"
    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\TodoList` for you? y

    Adding Tasks

    The first example we'll add, is one for adding tasks. We will make an addTask() method, that does nothing more than adding a task to our collection. It simply directs the call to the add() method on the collection, so this is a perfect place to make use of an expectation. We do not want the method to actually call the add() method, we just want to make sure that it tries to do it. Furthermore, we want to make sure that it calls it only once. Take a look at how we can go about this with phpspec:

    <?php
    
    namespace spec\Petersuhm\Todo;
    
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    use Petersuhm\Todo\TaskCollection;
    use Petersuhm\Todo\Task;
    
    class TodoListSpec extends ObjectBehavior
    {
        function it_is_initializable()
        {
            $this->shouldHaveType('Petersuhm\Todo\TodoList');
        }
    
        function it_adds_a_task_to_the_list(TaskCollection $tasks, Task $task)
        {
            $tasks->add($task)->shouldBeCalledTimes(1);
            $this->tasks = $tasks;
    
            $this->addTask($task);
        }
    }

    First, we have phpspec provide us with the two collaborators we need: a task collection and a task. Then we set an expectation on the task collection collaborator that basically says: "the add() method should be called exactly 1 time with the variable $task as a parameter". This is how we prepare our collaborator, which is now a mock, before we assign it to the $tasks property on the TodoList. Finally, we try to actually call the addTask() method.

    Ok, what does phpspec have to say about this:

    $ vendor/bin/phpspec run
    
            Petersuhm/Todo/TodoList
      17  ! adds a task to the list
            property tasks not found.

    The $tasks property is non-existing - easy one:

    <?php
    
    namespace Petersuhm\Todo;
    
    class TodoList
    {
        public $tasks;
    }

    Try again, and have phpspec guide our way:

    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\TodoList::addTask()` for you? y
    $ vendor/bin/phpspec run
    
            Petersuhm/Todo/TodoList
      17  ✘ adds a task to the list
            some predictions failed:
              Double\Petersuhm\Todo\TaskCollection\P4:
                Expected exactly 1 calls that match:
                  Double\Petersuhm\Todo\TaskCollection\P4->add(exact(Double\Petersuhm\Todo\Task\P3:000000002544d76d0000000059fcae53))
                but none were made.

    Okay, now something interesting happened. See the message "Expected exactly 1 calls that match: ..."? This is our failing expectation. This happens because after calling the addTask() method, the add() method on the collection was not called, which we expected it to be.

    In order to get back to green, fill in the following code in the empty addTask() method:

    <?php
    
    namespace Petersuhm\Todo;
    
    class TodoList
    {
        public $tasks;
    
        public function addTask(Task $task)
        {
            $this->tasks->add($task);
        }
    }

    Back to green! It feels good, right?

    Checking for Tasks

    Let's have a look at promises too. We want a method that can tell us if there are any tasks in the collection. For this, we'll simply check the return value of the count() method on the collection. Again, we do not need a real instance with a real count() method. We just need to make sure that our code calls some count() method and do some stuff depending on the return value.

    Take a look at the following example:

    function it_checks_whether_it_has_any_tasks(TaskCollection $tasks)
    {
        $tasks->count()->willReturn(0);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldReturn(false);
    }

    We have a task collection collaborator that has a count() method that will return zero. This is our promise. What this means is that every time someone calls the count() method, it will return zero. We then assign the prepared collaborator to the $tasks property on our object. Finally, we try to call a method, hasTasks(), and make sure it returns false.

    What does phspec have to say about this?

    $ vendor/bin/phpspec run
    Do you want me to create `Petersuhm\Todo\TodoList::hasTasks()` for you? y
    $ vendor/bin/phpspec run
    
            Petersuhm/Todo/TodoList
      25  ✘ checks whether it has any tasks
            expected false, but got null.

    Cool. phpspec made us a hasTasks() method and not surprisingly, it returns null, not false.

    Once again, this is an easy one to fix:

    public function hasTasks()
    {
        return false;
    }

    We are back to green, but this is not quite what we want. Let's check for tasks when there are 20 of them. This should return true:

    function it_checks_whether_it_has_any_tasks(TaskCollection $tasks)
    {
        $tasks->count()->willReturn(0);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldReturn(false);
    
        $tasks->count()->willReturn(20);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldReturn(true);
    }

    Run phspec and we'll get:

    $ vendor/bin/phpspec run
    
            Petersuhm/Todo/TodoList
      25  ✘ checks whether it has any tasks
            expected true, but got false.

    Okay, false is not true, so we need to improve our code. Let's use that count() method to see if there are tasks or not:

    public function hasTasks()
    {
        if ($this->tasks->count() > 0)
            return true;
    
        return false;
    }

    Tah dah! Back to green!

    Building Custom Matchers

    Part of writing good specs is to make them as readable as possible. Our last example can actually be improved a tiny bit, thanks to phpspec's custom matchers. It's easy to implement custom matchers - all we have to do is to overwrite the getMatchers() method that is inherited from ObjectBehavior. By implementing two custom matchers, our spec can be changed to look like this:

    function it_checks_whether_it_has_any_tasks(TaskCollection $tasks)
    {
        $tasks->count()->willReturn(0);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldBeFalse();
    
        $tasks->count()->willReturn(20);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldBeTrue();
    }
    
    function getMatchers()
    {
        return [
            'beTrue' => function($subject) {
                return $subject === true;
            },
            'beFalse' => function($subject) {
                return $subject === false;
            },
        ];
    }

    I think this looks pretty good. Remember, that refactoring your specs is important in order to keep them up to date. Implementing your own custom matchers can clean up your specs and make them more readable.

    Actually, we can use the negation of the matchers as well:

    function it_checks_whether_it_has_any_tasks(TaskCollection $tasks)
    {
        $tasks->count()->willReturn(0);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldNotBeTrue();
    
        $tasks->count()->willReturn(20);
        $this->tasks = $tasks;
    
        $this->hasTasks()->shouldNotBeFalse();
    }

    Yeah. Pretty cool!

    Conclusion

    All our specs are green and look at how nicely they document our code!

          Petersuhm\Todo\TaskCollection
    
      10  ✔ is initializable
      15  ✔ adds a task to the collection
      24  ✔ is countable
      29  ✔ counts elements of the collection
    
          Petersuhm\Todo\Task
    
      10  ✔ is initializable
    
          Petersuhm\Todo\TodoList
    
      11  ✔ is initializable
      16  ✔ adds a task to the list
      24  ✔ checks whether it has any tasks
    
    
    3 specs
    8 examples (8 passed)
    16ms

    We have effectively described and achieved the desired behavior of our code. Not to mention, our code is 100 % covered by our specs, which means that refactoring won't be a fear-inducing experience.

    By following along, I hope you got inspired to give phpspec a try. It is more than a testing tool - it's a design tool. Once you get used to using phpspec (and its awesome code generation tools), you'll have a hard time letting go of it again! People often complain that doing TDD or BDD slows them down. After incorporating phpspec in my work flow, I really feel the opposite way - my productivity is significantly improved. And my code is more solid!

     

    0 Comments

    Leave a comment › Posted in: Daily

    1. Working With Intl

      Internationalization - something you constantly hear developers talking about but rarely actually see people using in practice - is getting a kick in the pants with the new ECMAScript Internationalization API. Currently supported in Chrome 24, Chrome for Android, Firefox 29, IE 11, and Opera 15 (sadly no Safari support), the new Intl namespace provides a set of functionality to add internationalization to your numbers, dates, and sorting. In this article I'll demonstrate the major features of Intl and get you on the path to adopting support for the billions of people on the Internet who live outside your own country!

      Core Features

      The Intl namespace covers three main areas of functionality:

      • Formatting numbers
      • Formatting dates
      • Sorting strings

      Within each of these are various options for controlling both the locales used for formatting as well as formatting options. As an example, the number formatter includes support for handling currency. The date formatter has options for what parts of the date to display.

      Lets take a look at a few examples.

      Our Application

      Our first application is a simple data reporter. It uses AJAX to fetch a set of data containing dates and numbers. First, the HTML:

      Listing 1: test1.html:

      <!DOCTYPE html>
          <html>
              <head>
                  <meta charset="utf-8">
                  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                  <title></title>
                  <meta name="description" content="">
                  <meta name="viewport" content="width=device-width">
              </head>
              <body>
      
                  <h2>Current Stats</h2>
                  <table id="stats">
                      <thead>
                          <tr>
                              <th>Date</th>
                              <th>Visits</th>
                          </tr>
                      </thead>
                      <tbody></tbody>
                  </table>
      
                  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
                  <script src="app1.js"></script>
              </body>
          </html>

      Make note of the empty table. That's where we will be dumping our data. Now let's take a look at the JavaScript.

      Listing 2: app1.js:

      $(document).ready(function() {
      
              //get the table dom
              $table = $("#stats tbody");
              //now, get our data from the api, which is fake btw
              $.getJSON("stats.json").done(function(s) {
                  //iterate over stats and add to table
                  for(var i=0; i < s.length; i++) {
                      $table.append(""+s.date+""+s.views+"");
                  }
              }).fail(function(e) {
                  console.log("we failed");
                  console.dir(e);
              });
          });
      

      All that the code does here, is make an AJAX call to a file and render the result to the data. The data file, stats.json, is simply an array of ten hard coded values. Here is a portion of the file:

      [{"date":"4/1/2013","views":938213},{"date":"4/2/2013","views":238213},
      

      As you can see, the dates are formatted as month/date/year and the numbers are passed, as is. This renders acceptably:

      But note the the numbers are a bit hard to read without formatting. Let's begin by adding some formatting to the numbers.

      Adding Number Formatting

      The following modifications can be seen in app2.js and tested with test2.html. First, I'll modify my code to call a new function, numberFormat:

      $table.append(""+s.date+""+numberFormat(s.views)+"");

      And here is that function:

      function numberFormat(n) {
              //cache the formatter once
              if(window.Intl && !window.numberFormatter) window.numberFormatter = window.Intl.NumberFormat();
      
              if(window.numberFormatter) {
                  return window.numberFormatter.format(n);
              } else {
                  return n;   
              }
          }

      The function begins by checking if Intl exists as part of the window object. If it does, we then check to see if we've made the formatter before. The Intl object creates a formatting object that you can reuse, and since we're formatting a bunch of numbers, we only want to create it one time. Which is exactly what we do as soon as we see that we need too. We don't bother with any options for now, just to keep it simple. Finally, if there was no support for Intl at all, we just return the number as is. The result is a significant improvement, with minimal work:

      Cool! So, how do we test other languages? You may be tempted to check your browser settings. All browsers have a preference for language, but unfortunately, changing the language in the browser is not enough. Changing it does impact how the browser behaves. 

      If you open your dev tools and look at network requests, you can see that a header called "Accept-Lanage" will change based on your settings. If you add French, for example (I'm assuming you aren't a native French speaker), you will see "fr" added to this header. But this does not impact Intl. Instead, you have to change your operating system language and restart the browser. This is not as scary as it sounds. When I tested, I was worried my entire operating system would change immediately. But in my tests, I was able to change the language, restart my browser, and see the change. I quickly changed back. The Intl formatter functions allow you to override the current locale and pass one in instead.

      I modified the application to allow the end user to specify a language via a drop down. Here's the modification made to the HTML. (This modification may be found in test3.html)

      <select id="langDropdown">
              <option value="">None Specified</option>
              <option value="en-US">English (US)</option>
              <option value="fr-FR">French (France)</option>
              <option value="lt">Lithuanian</option>
          </select>

      The languages I picked were pretty arbitrary. Next - I updated my application code to listen to changes to this drop down as well as checking the desired locale when formatting.

      Listing 3: app3.js:

      function numberFormat(n) {
      
              if(window.Intl) {
                  var lang = $("#langDropdown").val();
                  if(lang === "") lang = navigator.language;
                  var formatter = new window.Intl.NumberFormat(lang);
                  return formatter.format(n);
              } else {
                  return n;   
              }
          }
      
          function getStats() {
      
              $.getJSON("stats.json").done(function(s) {
                  //iterate over stats and add to table
                  for(var i=0; i < s.length; i++) {
                      $table.append(""+s.date+""+numberFormat(s.views)+"");
                  }
              }).fail(function(e) {
                  console.log("we failed");
                  console.dir(e);
              });
      
          }
      
          $(document).ready(function() {
      
              //get the table dom
              $table = $("#stats tbody");
      
              //notice changes to drop down
              $("#langDropdown").on("change", function(e) {
                  $table.empty();
                  getStats();
              });
      
              getStats();
          });
      

      Starting at the bottom - note that I've added a simple event handler for changes to the drop down. When a change is detect, the table is emptied out and the function getStats is run. This new function simply abstracts the AJAX code used previously. The real change now is in numberFormat. I check the language selected and if one of them was chosen, we pass that as the locale to the NumberFormat constructor. Note that if something wasn't chosen, we default to navigator.language. This now gives us a way to quickly test different locales and see how they render numbers.

      Adding Date Formatting

      Now is a perfect time to take care of the other column of data - the numbers. I followed the same style as before and added a call to a new function, dateFormat.

      $table.append(""+dateFormat(s.date)+""+numberFormat(s.views)+"");

      And here is dateFormat (You can find the code in app4.js, which is used by test4.html):

      function dateFormat(n) {
      
          //Used for date display
          var opts = {};
          opts.day = "numeric";
          opts.weekday = "long";
          opts.year = "numeric";
          opts.month = "long";
      
          if(window.Intl) {
              var lang = $("#langDropdown").val();
              if(lang === "") lang = navigator.language;
      
              var formatter = new window.Intl.DateTimeFormat(lang, opts);
              n = new Date(n);
              return formatter.format(n);
          } else {
              return n;   
          }
      }
      

      This is very similar to number formatting, except this time we are explicitly passing some options when we create the formatter. The options specify both what fields are visible in the date, as well as how they look. Each part of a date can be shown or not, and each one has different options. The options include:

      • weekday
      • era
      • year
      • month
      • day
      • hour
      • minute
      • second
      • timeZoneName

      For a full list of what values you can use, see the MDN documentation for DateTimeFormat, but as an example, months can be displayed as a number or in different textual forms. So what does this create? Here is the English version:

      And here it is in French:

      You may be wondering - what covers the location of each field? As far as I can tell, you have no control over this. You could, of course, create multiple formatters and then combine them together, but using one formatter the layout of the fields is driven by internal logic. If you turn off the day of the month, for example, here is what you get: April 2013 Monday. Why? Honestly I have no idea.

      Finally - note that you need to pass a date value, not a string, to the formatter. You can see where I use the date constructor in the formatter to parse my string-based date. This is - a bit loose - so keep this in mind when using this functionality.

      Show Me the Money

      Currency formatting isn't a separate object, but rather an optional use of the number formatter. For the next demo, we've created a new data file, stats2.json, and added a "sales" column to our data. Here is a sample:

      {"date":"4/1/2013","views":938213,"sales":3890.21},{"date":"4/2/2013","views":238213,"sales":9890.10}

      The column was added to the HTML (test5.html), added within the JavaScript iterating over the rows of data (see app5.js), and passed to a new function called currencyFormat. Let's look at that.

      function currencyFormat(n) {
      
          var opts = {};
          opts.style = "currency";
          opts.currency = "USD";
      
          if(window.Intl) {
              var lang = $("#langDropdown").val();
              if(lang === "") lang = navigator.language;
              var formatter = new window.Intl.NumberFormat(lang,opts);
              return formatter.format(n);
          } else {
              return n;   
          }
      }
      

      Displaying numbers as currencies requires two optional values. First, a style of "currency", and then the currency type. Other options (like how to display the name of the currency) exists as well. Here comes the part that may trip you up a bit. You must specify the currency type. 

      You may think - how in the heck do I figure out the currency type for all the possible values? The possible values are based on a spec (http://www.currency-iso.org/en/home/tables/table-a1.html) and in theory you could parse their XML, but you don't want to do that. The reason why is pretty obvious but I can honestly say I forgot initially as well. You do not want to just redisplay a particular number in a locale specific currency. Why? Because ten dollars American is certainly not the same as ten dollars in pesos. That's pretty obvious and hopefully I'm the only person to forget that.

      Using the code above, we can see the following results in the French locale. Note how the numbers are formatted right for the locale and the currency symbol is placed after the number.

      Sorting With Collator

      For our final example, we'll look at the Collator constructor. Collators allow you to handle text sorting. While some languages follow a simple A to Z ordering system other languages have different rules. And of course, things get even more interesting when you start adding accents. Can you say, for certain, if ä comes after a? I know I can't. The collator constructor takes a number of arguments to help it specify exactly how it should sort, but the default will probably work well for you.

      For this example, we've built an entirely new demo, but one similar to the previous examples. In test6.html, you can see a new table, for Students. Our new code will load up a JSON packet of students and then sort them on the client. The JSON data is simply an array of names so I'll skip showing an excerpt. Let's look at the application logic.

      Listing 4: app6.js:

      function sorter(x,y) {
      
              if(window.Intl) {
                  var lang = $("#langDropdown").val();
                  if(lang === "") lang = navigator.language;      
                  return window.Intl.Collator(lang).compare(x,y);
              } else {
                  return x.localeCompare(y);  
              }
          }
      
          function getStudents() {
      
              $.getJSON("students.json").done(function(s) {
                  //iterate over stats and add to table
                  s.sort(sorter);
                  for(var i=0; i < s.length; i++) {
                      $table.append(""+s+"");
                  }
              }).fail(function(e) {
                  console.log("we failed");
                  console.dir(e);
              });
      
          }
      
          $(document).ready(function() {
      
              //get the table dom
              $table = $("#students tbody");
      
              //notice changes to drop down
              $("#langDropdown").on("change", function(e) {
                  $table.empty();
                  getStudents();
              });
      
              getStudents();
          });
      

      As I said, this code is pretty similar to the previous examples, so focus on getStudents first. The crucial line here is: s.sort(sorter). We're using the built in function for arrays to do sorting via a custom function. That function will be passed two things to compare and must return -1, 0, or 1 to represent how the two items should be sorted. Now let's look at sorter.

      If we have an Intl object, we create a new Collator (and again, we're allowing you to pass in a locale) and then we run the compare function. That's it. As I said, there are options to modify how things are sorted, but we can use the defaults. The fallback is localeCompare, which will also attempt to use locale specific formatting, but has (in this form) slightly better support. We could check for that support as well and add one more fallback for really good support, but I'll leave that for you, as an exercise.

      We've also modified the front end to use Swedish as a language. I did this because the excellent MDN documentation showed that it was a good way to see the sorting in action. Here's the English sort of our student names:

      And here it is in Swedish:

      Note how ätest is sorted differently. (Sorry, I couldn't think of a name that began with ä.)

      Wrap Up

      All in all, the Intl class provides some very simple ways to add locale specific formatting to your code. This is certainly something you can find now, probably in a few thousand different JavaScript libraries, but it is great to see the browser manufacturers adding in support directly within the language itself. The lack of iOS support is a bummer, but hopefully it will be added soon.

      Thanks goes to the excellent Mozilla Developer Network for its great Intl documentation.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Working With Controllers in Symfony 2

      Today we'll take a quick look at controllers from within Symfony 2. The easiest way to get started learning, is to just dive right in, see some code examples and I'll explain everything as we proceed.  If you're ready to begin, you can press play on the video below:


      I hope this video has shown you how easy and fun controllers are to work with in Symfony 2. We can use the console to generate them and link everything up so that it all works seamlessly. 

      In the next video, we'll move on to the Twig templating engine.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Refactoring Legacy Code: Part 4 - Our First Unit Tests

      Old code. Ugly code. Complicated code. Spaghetti code. Gibberish nonsense. In two words, Legacy Code. This is a series that will help you work and deal with it.

      One of the key moments of refactoring a totally legacy code is when we start extracting small pieces from it and we start writing targeted unit tests for those small pieces. But this can be quite difficult, especially when you have code that is written so that it would be hard to compile or run if pieces of it are missing. We can't safely do large surgeries on a code we still barely understand and only a golden master test keeps us breaking it totally. Fortunately there are some techniques that can help us.

      What Is a Unit Test?

      Throughout the history of automated testing, the past twenty or so years, the term Unit Test was defined in many ways. Initially it was about the scope of the code exercised inside a test. A unit test was a test that tested the smallest possible unit of a particular programming language.

      In this sense, for our PHP code, a unit test is a test that exercises a single function or method. When we are programming in an object oriented style, our functions are organized in classes. All the tests associated with a single class are usually called a Test Case.

      There are about 25 other definitions for the term of Unit Test, so we will not go into each one. While these definitions are quite different, all of them has two things in common. This leads us to the probably most accepted definition.

      A Unit Test is a test that runs in milliseconds and tests a piece of code in isolation.

      We must note two key words in the definition: milliseconds - our tests must run fast, very fast; and isolation - we must test our code as isolated as possible. These two key words go hand-in-hand, because in order to make tests faster we must reduce their scope. Databases, network communications, user interfaces, they are just too slow to be tested this way. We need to find and isolate a small enough chunk of code, so that we can compile (if needed) and run that code in the order of milliseconds, that is, in less than ten milliseconds, because that would be a centisecond. Our test framework will add a slight overhead over the pure run time of the code, but that is negligible.

      Identifying Code to be Unit Tested

      Finding Isolated Methods

      If the structure of the code permits, it is recommended to start by writing tests for whatever code we actually can test. This will help us start to build up coverage and it will also force us to concentrate and understand small pieces of code. Remember, we are refactoring, we do not want to change behavior. In fact, at this initial step we do not want to change our production code at all if possible.

      We need to analyze our three files, to see what we can test and what not.

      GameRunner.php has basically no logic. We created it to be just a delegation. Could we test it? Sure we could. Should we test it? No, we shouldn't. Even though some methods can, in a technical sense, be tested, if there is no logic in them we probably don't want to test them.

      RunnerFunctions.php is a different story. There are two functions in there. run() is a big function, doing a whole run of the system. This is not something we can easily test. And it has no return value either, it just outputs to the screen, so we would need to capture output and compare strings. This is not very typical for Unit Testing. On the other hand isCurrentAnswerCorrect() returns a simple true or false based on some conditions. Can we test that?

      function isCurrentAnswerCorrect() {
      	$minAnswerId = 0;
      	$maxAnswerId = 9;
      	$wrongAnswerId = 7;
      	return rand($minAnswerId, $maxAnswerId) != $wrongAnswerId;
      }

      We already understand that this code generates a random number and compares it to the ID of the wrong number.

      Step 1 - go to the GoldenMasterTest.php and mark all tests as skipped. We do not want to run them for the time being. As we start building unit tests, we will run our golden master more rarely. As we write new tests and we do not modify the production code, fast feedback is more important.

      Step 2 - create a new test RunnerFunctionsTest.php in our Test directory, alongside GoldenMasterTest.php. Now think about the simplest possible test code that you can write. What is the bare minimum to get it running? Well, it is something like this:

      require_once __DIR__ . '/../trivia/php/RunnerFunctions.php';
      
      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      
      	}
      
      }

      We require the RunnerFunctions.php file, so we test that it can be included and does not produce an error. The rest of the code is pure boilerplate, just a skeleton class and an empty test function. But, now what? What do we do next? Do you know how can we trick rand() to return what we want? I do not know, yet. So let's investigate how it is working right now.

      We know how to seed the random generator, so what if we try to seed it with some numbers, would that work? We can write code in our test to figure out how something works.

      function testItCanFindCorrectAnswer() {
      
      	srand(0);
      	var_dump(rand(0,9));
      	srand(1);
      	var_dump(rand(0,9));
      	srand(2);
      	var_dump(rand(0,9));
      	srand(3);
      	var_dump(rand(0,9));
      	srand(4);
      	var_dump(rand(0,9));
      
      }

      We also know that our question IDs are between zero and nine. This produces the output below.

      int(8)
      int(8)
      int(7)
      int(5)
      int(9)

      Well, that doesn't look very obvious. In fact I can see no logic on how could we determine the values the rand() function will produce. We will need to modify our production code, so that we can inject the values we need.

      Dependencies and Dependency Injection

      When most people are talking about "dependency" they think about connections between classes. This is the most common case, especially in object oriented programming. But what if we generalize the term a little bit. Forget about classes, forget about objects, concentrate only on the meaning of "dependency". What does our rand(min,max) method depend on? It depends on two values. A minimum and a maximum.

      Can we control rand() by those two parameters? Doesn't rand() predictably return the same number if min and max are the same? Let's see.

      function testItCanFindCorrectAnswer() {
      
      	var_dump(rand(0,0));
      	var_dump(rand(1,1));
      	var_dump(rand(2,2));
      	var_dump(rand(3,3));
      	var_dump(rand(4,4));
      
      }

      If we are right, each line should dump a number from zero to four in a predictable way.

      int(0)
      int(1)
      int(2)
      int(3)
      int(4)

      That looks pretty predictable to me. By sending the same number for min and max to rand() we can be sure we generate the expected number. Now, how do we do this for our function? It has no parameters!

      Probably the most common way to inject dependencies into a method is to use parameters with default values. This will preserve the function's current functionality, but will allow us to control its flow when we test it.

      function isCurrentAnswerCorrect($minAnswerId = 0, $maxAnswerId = 9) {
      	$wrongAnswerId = 7;
      	return rand($minAnswerId, $maxAnswerId) != $wrongAnswerId;
      }

      Modifying the isCurrentAnswerCorrect() this way will preserve its current behavior and allow us to test it in the same time. You can re-enable your golden master and run it now. The production code was changed, we need to be sure we didn't break it.

      As our isCurrentAnswerCorrect() looks now, testing it is just a matter of sending in ten values for each possible number returned by rand().

      function testItCanFindCorrectAnswer() {
      
      	$this->assertTrue(isCurrentAnswerCorrect(0,0));
      	$this->assertTrue(isCurrentAnswerCorrect(1,1));
      	$this->assertTrue(isCurrentAnswerCorrect(2,2));
      	$this->assertTrue(isCurrentAnswerCorrect(3,3));
      	$this->assertTrue(isCurrentAnswerCorrect(4,4));
      	$this->assertTrue(isCurrentAnswerCorrect(5,5));
      	$this->assertTrue(isCurrentAnswerCorrect(6,6));
      	$this->assertFalse(isCurrentAnswerCorrect(7,7));
      	$this->assertTrue(isCurrentAnswerCorrect(8,8));
      	$this->assertTrue(isCurrentAnswerCorrect(9,9));
      
      }

      That test function was built by running our tests after each line. Now that our tests are very fast, we can run them almost continuously. There are actually tools to run tests as soon as a file changes and I've heard about programmers who are running their tests continuously and they just glimpse at the test status bar at the end of each command. As you program you know what to expect, if the test doesn't turn green when you thought it should, you did something wrong. Their feedback look is so tight, it is almost a certainty that something went wrong in the last line or command they wrote.

      Even though that may sound extreme test driven development, I imagine it is useful especially when you develop algorithms. I personally prefer to run my tests by pressing a shortcut, a single key shortcut. And as tests are helping me develop my programs, my shortcut for running tests is F1.

      Let's get back to our business. That test, with ten assertions, runs in 66 ms, about 6.6 ms per assertion. Each assertion calls and executes a piece of our code. This seems to be as we defined unit tests at the beginning of this tutorial.

      Did you spot the assertFalse() for the number seven? I bet half of you missed it. It is buried deep inside a bunch of other assertions. Hard to spot. I think it deserves its own test, so we make explicit the single wrong answer case.

      function testItCanFindCorrectAnswer() {
      	$this->assertTrue(isCurrentAnswerCorrect(0, 0));
      	$this->assertTrue(isCurrentAnswerCorrect(1, 1));
      	$this->assertTrue(isCurrentAnswerCorrect(2, 2));
      	$this->assertTrue(isCurrentAnswerCorrect(3, 3));
      	$this->assertTrue(isCurrentAnswerCorrect(4, 4));
      	$this->assertTrue(isCurrentAnswerCorrect(5, 5));
      	$this->assertTrue(isCurrentAnswerCorrect(6, 6));
      	$this->assertTrue(isCurrentAnswerCorrect(8, 8));
      	$this->assertTrue(isCurrentAnswerCorrect(9, 9));
      }
      
      function testItCanFindWrongAnser() {
      	$this->assertFalse(isCurrentAnswerCorrect(7, 7));
      }

      Refactoring Tests

      As we are in a quest of refactoring, making code better, easier to understand, we must not forget about our tests. They are just as important as our production code. We need to keep our tests clean and easy to understand also. We need to refactor our tests and we should do it as soon as we observe something is wrong with them and only when they are passing. In this way, the production code can verify our tests. If we have a green test, we refactor it and it turns red, we broke the test. We can just undo a few steps and try again.

      We could extract the correct answer numbers into an array and use that to generate correct answers.

      function testItCanFindCorrectAnswer() {
      	$correctAnserIDs = [0, 1, 2, 3, 4, 5, 6, 8, 9];
      	foreach ($correctAnserIDs as $id) {
      		$this->assertTrue(isCurrentAnswerCorrect($id, $id));
      	}
      }

      That passes, but also introduces some logic. Maybe we could extract it in a custom assertion. This may be a little bit extreme for such a simple test, but it is a good opportunity to understand the concept.

      function testItCanFindCorrectAnswer() {
      	$correctAnserIDs = [0, 1, 2, 3, 4, 5, 6, 8, 9];
      	$this->assertAnswersAreCorrectFor($correctAnserIDs);
      }
      
      function testItCanFindWrongAnser() {
      	$this->assertFalse(isCurrentAnswerCorrect(7, 7));
      }
      
      private function assertAnswersAreCorrectFor($correctAnserIDs) {
      	foreach ($correctAnserIDs as $id) {
      		$this->assertTrue(isCurrentAnswerCorrect($id, $id));
      	}
      }

      Now, this helped us in two ways. First, we moved the logic about going over each element of the array an verifying it into a private method. As we usually keep our private methods at the end of the class, out of sight, out of the way of the higher level logic in the public methods, we managed to rise the abstraction of our test. In the test method we don't care about how the answers are verified for correctness. We care about the IDs that should represent correct answers. The second advantage is the breaking of the implementation from the preparation. Keeping the correct answer IDs in the test helped us separate the details of implementation from the premise we need to test.

      Test to Production Code Dependencies

      One of the most common mistakes any of us commits when writing test is to repeat what it is in the production code. This is a case of both code duplication and a hidden dependency, usually, on some values or constants. In our case the dependency is on the answer ID that represents the wrong answer.

      But how to prove this dependency? At first sight it seems only a simple duplication of a single value. To answer your dilemma ask yourself this question: "Should my tests fail if I decide to change the wrong answer's ID?". Of course the answer is no. Changing a simple constant in the production code will not affect behavior, or logic. Thus, the tests should not fail.

      That sounds great! But how to do it? Well, the simplest way is just to expose the desired variable as a public class variable, preferable static or constant. In our case, as we have no class, we can just make it a global variable or constant.

      include_once __DIR__ . '/Game.php';
      
      const WRONG_ANSWER_ID = 7;
      
      function isCurrentAnswerCorrect($minAnswerId = 0, $maxAnswerId = 9) {
      	return rand($minAnswerId, $maxAnswerId) != WRONG_ANSWER_ID;
      }
      
      function run() {
      	// ... //
      }

      First modify the RunnerFunctions.php file so that isCurrentAnswerCorrect() will use a constant instead of a local variable. Then run your unit tests. This ensures us that the change we made to the production code did not break anything. Now it's time for the test.

      	function testItCanFindWrongAnswer() {
      		$this->assertFalse(isCurrentAnswerCorrect(WRONG_ANSWER_ID, WRONG_ANSWER_ID));
      	}
      

      Modify testItCanFindWrongAnswer() to use the same constant. As the file RunnerFunctions.php is included at the beginning of the test file, the declared constant will be accessible to the the test.

      Refactoring Tests (Again)

      Now, that we rely on the WRONG_ANSWER_ID for our testItCanFindWrongAnswer(), shouldn't we refactor our test so that testItCanFindCorrectAnswer() also relies on the same constant? Well we should. It will not only make our test easier to understand, it will also make it more robust. Yes, because if we would to select a wrong answer ID that is already in the list of correct answers defined in the test, that particular case would fail the test even though the production code would still be correct.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      		$correctAnserIDs = $this->getGoodAnswerIDs();
      		$this->assertAnswersAreCorrectFor($correctAnserIDs);
      	}
      
      	private function getGoodAnswerIDs() {
      		return [0, 1, 2, 3, 4, 5, 6, 8, 9];
      	}
      
      }

      While having the numbers for the correct answers in the test function itself was a good idea at some point, as we change our test to rely more and more on the values provided by the production code, we also want to hide the details about the numbers. The first step is to apply an Extract Method refactoring and get it in its own method.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      		$correctAnserIDs = $this->getGoodAnswerIDs();
      		$this->assertAnswersAreCorrectFor($correctAnserIDs);
      	}
      
      	private function getGoodAnswerIDs() {
      		return array_diff(range(0,9), [WRONG_ANSWER_ID]);
      	}
      
      }

      We changed getGoodAnswerIDs() significantly. First of all we generate the list with range() instead of typing all possible IDs by hand. Then we subtract from the array the element containing WRONG_ANSWER_ID. Now the list of correct answer IDs is also independent from the value set in the wrong answer's ID. But is that enough? What about the minimum and maximum IDs? Can't we extract them also in a similar manner? Well, let's see.

      include_once __DIR__ . '/Game.php';
      
      const WRONG_ANSWER_ID = 7;
      const MIN_ANSWER_ID = 0;
      const MAX_ANSWER_ID = 9;
      
      function isCurrentAnswerCorrect($minAnswerId = MIN_ANSWER_ID, $maxAnswerId = MAX_ANSWER_ID) {
      	return rand($minAnswerId, $maxAnswerId) != WRONG_ANSWER_ID;
      }
      
      function run() {
      	// ... //
      }

      This looks pretty nice. The constants were only used as default values for parameters of the function isCurrentAnswerCorrect(). This still allows us to inject the required values when testing and it also makes quite clear what those parameters mean. As a nice side effect, a small block of constants at the top of the file started to highlight the key values our RunnerFunctions.php file uses. Nice!

      Just don't forget to re-enable from the golden master test the testOutputMatchesGoldenMaster() test function. The constants we introduced are used only in the golden master test. Our unit tests actually shortcut those values always.

      Now we need to update our unit test to use the constants.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      		$correctAnserIDs = $this->getGoodAnswerIDs();
      		$this->assertAnswersAreCorrectFor($correctAnserIDs);
      	}
      
      	private function getGoodAnswerIDs() {
      		return array_diff(range(MIN_ANSWER_ID,MAX_ANSWER_ID), [WRONG_ANSWER_ID]);
      	}
      
      }

      It was simple and easy. We just had to change the parameters to the range() method.

      The last step we can do with our test, is to clean up the mess we left behind in our testItCanFindCorrectAnswer() method.

      function testItCanFindCorrectAnswer() {
      	$correctAnserIDs = $this->getGoodAnswerIDs();
      	$this->assertAnswersAreCorrectFor($correctAnserIDs);
      }

      We can observe two major problems with this code. First an inconsistency in naming. Once we called answers correct and then we called them good. We must decide on one of the two. Correct seems to be grammatically more fitting. As correct is the opposite of wrong, while good is the opposite of bad.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      		$correctAnserIDs = $this->getCorrectAnswerIDs();
      		$this->assertAnswersAreCorrectFor($correctAnserIDs);
      	}
      
      	private function getCorrectAnswerIDs() {
      		return array_diff(range(MIN_ANSWER_ID,MAX_ANSWER_ID), [WRONG_ANSWER_ID]);
      	}
      
      }

      We renamed our private method according to the reasoning above. But that is not enough. We need to solve another problem. We assign the return value of a private method to a variable just to use that same variable on the next line. And this is the only use case for the variable. In our case the variable was there because it provided extra clarification about what an array of number meant. It had its use and scope. But now that we have a method with almost the same name, expressing the same concept, the variable outlived its usefulness. This is an unnecessary assignment.

      We can use the inline variable refactoring to remove the variable and call the method directly instead of using the variable on the next line.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	function testItCanFindCorrectAnswer() {
      		$this->assertAnswersAreCorrectFor($this->getCorrectAnswerIDs());
      	}
      
      	private function getCorrectAnswerIDs() {
      		return array_diff(range(MIN_ANSWER_ID,MAX_ANSWER_ID), [WRONG_ANSWER_ID]);
      	}
      
      }

      Now, what is really cool here is that we started with only two lines of code that was not that clear and it was polluted by duplication and a hidden dependency. After a few steps of changes we ended up with two lines of code also, but we broke the dependency on the numerical ID numbers. Is that cool or what?

      Breaking the Run

      Are we finished with the RunnerFunctions.php? Well if I see an if() that means logic. If I see logic that means a unit test is needed to verify it. And we have an if() in our run() method's do-while() loop. It's time to use our IDE's refactoring tool to extract a method and then test it.

      But what piece of code should we extract? At first glance taking just the conditional statement seems a good idea. This leads to the code below.

      function run() {
      	$notAWinner;
      
      	$aGame = new Game();
      
      	$aGame->add("Chet");
      	$aGame->add("Pat");
      	$aGame->add("Sue");
      
      	do {
      		$dice = rand(0, 5) + 1;
      		$aGame->roll($dice);
      
      		$notAWinner = getNotWinner($aGame);
      
      	} while ($notAWinner);
      }
      
      function getNotWinner($aGame) {
      	if (isCurrentAnswerCorrect()) {
      		$notAWinner = $aGame->wasCorrectlyAnswered();
      		return $notAWinner;
      	} else {
      		$notAWinner = $aGame->wrongAnswer();
      		return $notAWinner;
      	}
      }

      While this looks pretty decent and it was generated by just selecting the right menu item from our IDE, there is a problem that bothers me. The aGame object is used both in the do-while loop and both in the extracted method. What about this?

      function run() {
      	$notAWinner;
      
      	$aGame = new Game();
      
      	$aGame->add("Chet");
      	$aGame->add("Pat");
      	$aGame->add("Sue");
      
      	do {
      		$dice = rand(0, 5) + 1;
      		$notAWinner = getNotWinner($aGame, $dice);
      
      	} while ($notAWinner);
      }
      
      function getNotWinner($aGame, $dice) {
      	$aGame->roll($dice);
      
      	if (isCurrentAnswerCorrect()) {
      		$notAWinner = $aGame->wasCorrectlyAnswered();
      		return $notAWinner;
      	} else {
      		$notAWinner = $aGame->wrongAnswer();
      		return $notAWinner;
      	}
      }
      

      This solution removes the aGame object from the loop. However it introduces other type of problems. Our parameter count increases. Now we need to send in $dice. While the sheer number of parameters, two, is low enough to not rise any concerns we must also think about how those parameters are used in the method itself. $dice is only used when the roll() method is called on aGame. While the roll() method has a great significance in the Game class, it is not the one that decides if we have a winner or not. By analyzing the code in Game, we can conclude that a winner state can be true only by calling wasCorrectlyAnswered(). This is strange and it highlights some serious naming issues in the Game class we will address in an upcoming lesson.

      Based on all the above observations, it is most probably better to go with the first version of our extracted method.

      function getNotWinner($aGame) {
      	if (isCurrentAnswerCorrect()) {
      		$notAWinner = $aGame->wasCorrectlyAnswered();
      		return $notAWinner;
      	} else {
      		$notAWinner = $aGame->wrongAnswer();
      		return $notAWinner;
      	}
      }

      We can believe in our IDE and by just looking at the code we can be pretty sure nothing has broken. If you feel uncertain, just run your golden master tests. Now let's focus on creating some tests for this nice method.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {}

      I came up with this name by transforming what I want to test into the test method's name. It is very important to name your tests about what behavior they should test and not about what they will do. This will help others or yourself six months from now, to understand what that small piece of code should actually do.

      But we have a problem. Our tested method needs an object. We need to run it like this:

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$aGame = ???
      	getNotWinner($aGame);
      }

      We need an $aGame object of type Game. But we are doing a unit test, we do not want to use the real, complex and badly understood, Game class. This leads us to a new chapter in testing we will talk about in an another lesson: Mocking, Stubbing and Faking. These are all techniques to create and test object by using other objects that behave in a predefined manner. While using a framework or even PHPUnit's own built-in capabilities can be of help, for our current knowledge for our very simple test we can do a thing many people forget.

      We can just create a class similar to Game inside our test file and define on it the only two methods we are interested in. It is very simple.

      class RunnerFunctionsTest extends PHPUnit_Framework_TestCase {
      
      	// ... //
      
      	function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      		$aGame = new FakeGame();
      		getNotWinner($aGame);
      	}
      
      	// ... //
      
      }
      
      class FakeGame {
      
      	function wasCorrectlyAnswered() {
      
      	}
      
      	function wrongAnswer() {
      
      	}
      }
      

      This makes our tests pass and we are still in the millisecond zone. Note that the two skipped tests are the ones from the golden master.

      Time: 43 ms, Memory: 3.00Mb
      
      OK, but incomplete or skipped tests!
      Tests: 5, Assertions: 10, Skipped: 2.

      Even though we had to name our class differently from Game because we can't declare the same class twice, the code is pretty simple. We just defined the two methods we are interested in. The next step is to actually return something and test for it. But this may be more difficult than we expected because of this line of code:

      if (isCurrentAnswerCorrect())

      Our method calls isCurrentAnswerCorrect() without any parameters. This is bad for us. We can't control its output. It will just generate random numbers. We need to refactor our code a little bit before we can continue. We need to move the call to this method into the loop and pass its result as a parameter to getNotWinner(). This will allow us to control the result of the expression in the above if statement, thus controlling the path on which our code will go down. For our first test we need it to enter the if and call wasCorrectlyAnswered().

      function run() {
      
      	// ... //
      
      	do {
      		$dice = rand(0, 5) + 1;
      		$aGame->roll($dice);
      
      		$notAWinner = getNotWinner($aGame, isCurrentAnswerCorrect());
      
      	} while ($notAWinner);
      }
      
      function getNotWinner($aGame, $isCurrentAnswerCorrect) {
      	if ($isCurrentAnswerCorrect) {
      		$notAWinner = $aGame->wasCorrectlyAnswered();
      		return $notAWinner;
      	} else {
      		$notAWinner = $aGame->wrongAnswer();
      		return $notAWinner;
      	}
      }

      Now we have control, all dependencies broken. It's time for testing.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$aGame = new FakeGame();
      	$isCurrentAnswerCorrect = true;
      	$this->assertTrue(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }

      This is a passing test, pretty nice. We returned true from our overridden method, of course.

      function wasCorrectlyAnswered() {
      	return true;
      }

      We need to test the other path through the if() also.

      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$aGame = new FakeGame();
      	$isCurrentAnswerCorrect = false;
      	$this->assertFalse(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }

      We just chose to test false this time, so we differentiate between the two cases easier.

      class FakeGame {
      
      	function wasCorrectlyAnswered() {
      		return true;
      	}
      
      	function wrongAnswer() {
      		return false;
      	}
      }

      And our FakeGame was modified accordingly.

      Final Cleanup

      Refactoring the Extracted Method

      We are almost done. Sorry for getting this tutorial so long, I hope you liked it and didn't fall asleep. Final changes before concluding the RunnerFunctions.php file and its tests.

      function getNotWinner($aGame, $isCurrentAnswerCorrect) {
      	if ($isCurrentAnswerCorrect) {
      		$notAWinner = $aGame->wasCorrectlyAnswered();
      		return $notAWinner;
      	} else {
      		$notAWinner = $aGame->wrongAnswer();
      		return $notAWinner;
      	}
      }

      There are some unnecessary assignments in our method, we should clean it up. Our unit tests will make this change very safe.

      function getNotWinner($aGame, $isCurrentAnswerCorrect) {
      	if ($isCurrentAnswerCorrect) {
      		return $aGame->wasCorrectlyAnswered();
      	} else {
      		return $aGame->wrongAnswer();
      	}
      }

      We applied the same inline variable refactoring and it led to its disappearance. Tests still passing and we are still under 100 ms for all the unit tests together. I say this is pretty nice.

      Refactoring Tests (Again, Again)

      Yes, yes, we can make our test a little bit better also. Since we only have a few lines of code, our refactorings will be easy. The problem is in the code below.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$aGame = new FakeGame();
      	$isCurrentAnswerCorrect = true;
      	$this->assertTrue(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }
      
      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$aGame = new FakeGame();
      	$isCurrentAnswerCorrect = false;
      	$this->assertFalse(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }

      We have duplicate code by calling new FakeGame() in each method. Time for an extract method.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$aGame = $this->aFakeGame();
      	$isCurrentAnswerCorrect = true;
      	$this->assertTrue(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }
      
      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$aGame = $this->aFakeGame();
      	$isCurrentAnswerCorrect = false;
      	$this->assertFalse(getNotWinner($aGame, $isCurrentAnswerCorrect));
      }

      Now, this makes the $aGame variable pretty useless. Time for inline variable.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$isCurrentAnswerCorrect = true;
      	$this->assertTrue(getNotWinner($this->aFakeGame(), $isCurrentAnswerCorrect));
      }
      
      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$isCurrentAnswerCorrect = false;
      	$this->assertFalse(getNotWinner($this->aFakeGame(), $isCurrentAnswerCorrect));
      }

      This made our code shorter and more expressive on the same time. When we read an assertion it reads like a prose. Assert that we receive true whe we call try to get the not winner using our fake class with correct answer provided. What I still don't like is that we use the same variable and assign to it true or false depending on the test. I think there should be a more expressive way to do it.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$this->assertTrue(getNotWinner($this->aFakeGame(), $this->aCorrectAnswer()));
      }
      
      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$this->assertFalse(getNotWinner($this->aFakeGame(), $this->aWrongAnswer()));
      }

      Wow! Our tests became single liners and they are truly expressing what we are testing. All the details are hidden in private methods, at the end of the test. 99% of the cases you will not care about their implementation and when you do, you can simply CTRL+click on the method's name and the IDE will jump to the implementation.

      Back to the Production Code

      If we look at our loop, we can see that there is a variable we can get rid of in a blink of an eye.

      function run() {
      	$notAWinner;
      
      	$aGame = new Game();
      
      	$aGame->add("Chet");
      	$aGame->add("Pat");
      	$aGame->add("Sue");
      
      	do {
      		$dice = rand(0, 5) + 1;
      		$aGame->roll($dice);
      
      		$notAWinner = getNotWinner($aGame, isCurrentAnswerCorrect());
      
      	} while ($notAWinner);
      }

      That will turn into this:

      function run() {
      
      	$aGame = new Game();
      
      	$aGame->add("Chet");
      	$aGame->add("Pat");
      	$aGame->add("Sue");
      
      	do {
      		$dice = rand(0, 5) + 1;
      		$aGame->roll($dice);
      
      	} while (getNotWinner($aGame, isCurrentAnswerCorrect()));
      }

      Bye, bye $notAWinner variable. But our method's name is horrible. We know we should always prefer positive naming and behavior and negate it where needed in conditionals. What about this naming?

      do {
      	$dice = rand(0, 5) + 1;
      	$aGame->roll($dice);
      
      } while (didSomebodyWin($aGame, isCurrentAnswerCorrect()));

      But with that name, we need to negate it in the while() and change its behavior also. We start by changing our tests.

      class FakeGame {
      
      	function wasCorrectlyAnswered() {
      		return false;
      	}
      
      	function wrongAnswer() {
      		return true;
      	}
      }

      Actually changing only our fake game is better. It keeps the tests really readable, with the new method names.

      function testItCanTellIfThereIsNoWinnerWhenACorrectAnswerIsProvided() {
      	$this->assertTrue(didSomebodyWin($this->aFakeGame(), $this->aCorrectAnswer()));
      }
      
      function testItCanTellIfThereIsNoWinnerWhenAWrongAnswerIsProvided() {
      	$this->assertFalse(didSomebodyWin($this->aFakeGame(), $this->aWrongAnswer()));
      }

      Getting the Tests to Pass

      Of course the tests are failing now. We have to change the method's implementation.

      function didSomebodyWin($aGame, $isCurrentAnswerCorrect) {
      	if ($isCurrentAnswerCorrect) {
      		return ! $aGame->wasCorrectlyAnswered();
      	} else {
      		return ! $aGame->wrongAnswer();
      	}
      }

      Fixing the Golden Master

      Unit tests are passing, but running our golden master will break. We need to negate the login in the while statement.

      do {
      	$dice = rand(0, 5) + 1;
      	$aGame->roll($dice);
      
      } while (!didSomebodyWin($aGame, isCurrentAnswerCorrect()));

      Done!

      Now that makes the golden master pass again and our do-while reads like well written prose also. Now it is really time to stop. Thank you for reading.

       

      0 Comments

      Leave a comment › Posted in: Daily

    1. Migrating From 960 Grid System to ZURB Foundation

      960gs was great!  When the majority of the visitors to your site used desktops with monitors at least as wide as 1024 pixels, 960gs made it dead simple to design a site in code.  However, with the advent of device proliferation and media query prevalence, fixed width sites are decidedly less effective than responsive layouts.

      In this document I will describe how to take your fixed width 960gs site and move it to ZURB's Foundation framework. Without digressing too much, I want to be fair to 960gs and mention adapt.js, that framework's response to responsive web design.  Now, this article will cover the basics of the Foundation grid, how it compares to 960gs' grid and some extra options with Foundation's Sass.  For this tutorial, I'm assuming you are already familiar with 960gs and looking at Foundation as a way to achieve a responsive design.

      The Grid

      To get started, you'll need to understand the basic concepts of rows and columns in Foundation. 960gs' convention was to use one mega container and rely on each combination of DIVs to make a row. Like so:

      <div class="container_12"> 
          <div class="grid_6"></div> 
          <div class="grid_6"></div> 
          <div class="grid_6"></div> 
          <div class="grid_6"></div> 
      </div>

      You might have a <div class="clear"></div> thrown in between grid DIVs that add up to 12, but that's optional. This layout, would in effect, produce two rows with two columns that equally divided the available width. If you add alpha and omega classes, it will respectively strip the extra margin-left and margin-right.

      In Foundation's predefined HTML classes, this same layout would be accomplished by the following snippet:

      <div class="row"> 
          <div class="medium-6 columns"></div> 
          <div class="medium-6 columns"></div> 
      </div> 
      <div class="row"> 
          <div class="medium-6 columns"></div>
          <div class="medium-6 columns"></div> 
      </div>

      There is no mega container for Foundation, instead there are rows and rows contain columns, and columns must total 12.  Each column is defined by adding the columns class accompanied by at least one class to dictate the width of that column.

      To go on a short tangent, for what it's worth, Foundation's grid is similar to Twitter Bootstrap's rows and spans, except Foundation gives you the power to define column widths at multiple breakpoints.

      You'll notice the notation medium-6. That means at the medium breakpoint (however that's defined, the default is 641px), you'll see six columns worth of width, or half of the available width. Another class may be added to indicate how many columns worth of width the div should take up at other breakpoints, including small and large. Here's how that would look:

      <div class="row"> 
          <div class="medium-6 small-6 columns"></div> 
          <div class="medium-6 small-6 columns"></div> 
      </div> 
      <div class="row"> 
          <div class="medium-6 small-3 columns"></div> 
          <div class="medium-6 small-9 columns"></div> 
      </div>

      Foundation is mobile-first. Code for small screens first, and larger devices will inherit those styles. Customize for larger screens as necessary. source

      By default, Foundation is designed in a mobile first concept. What this means for grids is that the small class can be used alone to define the width of a column at the small breakpoint and all breakpoints above will inherit from that as long as a medium or large class is not present. On the flip side, if you just use a medium class, then the default small breakpoint layout will transform the DIVs into stacked single-column rows (equivalent to small-12) which is the default applied to columns in the small breakpoint.

      960 Grid "Equivalents"

      With all that in mind, the basics of changing your markup is as follows: First, the div with the container class can be deleted. Next, around your grid_# DIVs that make up "rows", you'll need to create a div with the class row. The individual DIVs containing grid classes can be changed to medium-#.

      This will give you something that looks an awful lot like your old 960gs layout for viewports above 640 pixels and below that width, you'll just have full-width stacks of rows, meaning that each column div will change to 100% width.

      Here are some other 960gs concepts translated into Foundation parlance:

      Nesting

      In 960gs, nesting could be accomplished by adding alpha to the first column in your row and omega to your last, effectively removing horizontal margins.  When using this approach, your nested rows had to be a sum of the column's width that the nested columns lived within.

      In Foundation, nesting is done for you, you just have to insert one row inside of a column.  No extra classes required.  The other main difference is that every nest row assumes a fresh 12 columns within the available nest space.  So a row inside a medium-6 will allow you to divide those six columns into 12.

      Creating Gaps

      960gs' prefix and suffix classes were excellent utility classes for creating empty space in your layout and provided a means for centering.  Foundation has the same capabilities, with Offsets.

      Source Ordering

      This is actually pretty much the same in both frameworks.  Source ordering allows you to create your columns in any order you want in your actual HTML, but have it appear in a different left-to-right order.  For this, you can use push and pull classes.

      Read More

      Foundation covers all of 960gs' capabilities and much more. See the docs to learn about everything else it can do.

      Foundation Breakpoints

      Well, this is the main reason you move into something like Foundation: the responsiveness.  You know about large,  medium and small breakpoints, but there are also xlarge and xxlarge. Here's what these breakpoint classes relate to:

      Breakpoint Viewport Width
      small < 40em (640px)
      medium 40.063em (641px) < 64em (1024px)
      large 64.063em (1025px) < 90em (1440px)
      xlarge 90.063em (1441px) > 120em (1920px)
      xxlarge > 120.063em (1921px)

      Note that only the small, medium and large breakpoints can be used in your HTML. If you need to use xlarge or xxlarge, or you'd like to customize these breakpoints, you can use work with Sass to tailor Foundation to fit your needs.

      Sass Options

      Foundation is built to work with Compass and Sass. If Sass is something your comfortable with, it can make development easier, read more about getting started with Sass and Foundation.

      The key pro for using Sass is that instead of adding Foundation-specific classes to your HTML, you can just extend Foundation attributes based on existing markup. For example, that existing div with the class news can be made to mimic a grid-6 columns div.

      Here's a full example of how this might look, let's say you have this HTML:

      <div class="main"> 
          <div class="news"></div> 
          <div class="events"></div> 
      </div>

      To achieve a 50/50 split of .news and .events, your Sass would look like this:

      .main { 
          @include grid-row; 
      
          .news { 
              @include grid-column(6); 
          } 
      
          .events { 
              @include grid-colmn(6); 
          } 
      }

      This is the equivalent of changing the markup to this:

      <div class="row">
      	<div class="small-6 columns"></div>
      	<div class="small-6 columns"></div>
      </div>

      Including Additional Breakpoints

      If you wanted to include other breakpoints in your SCSS, you would just use this technique:

      .main {
      	@include grid-row;
      	
      	.news {
      		@include grid-column(8);
      		@media #{$large-up} {
      			grid-column(6)
      		}
      	}
      	.events {
      		@include grid-colmn(4);
      		@media #{$large-up} {
      			grid-column(6)
      		}
      	}
      }

      Which is the same as:

      <div class="row">
      	<div class="small-8 large-6 columns"></div>
      	<div class="small-4 large-6 columns"></div>
      </div>

      The SCSS technique is nice because it keeps your classes uncluttered in your HTML, and allows you to be more semantic.

      Avoid Duplicated Styles

      There's one more important thing to understand about this method. If you are compiling your CSS to a separate, additional stylesheet, but you want to make use of the Foundation mixins, you'll need to import what you need, but prevent duplicating Foundation styles. To avoid redundant styles being added to your output CSS, you need to specify the $include-html-classes variable as false, here's what it looks like:

      @import "foundation/settings";
      $include-html-classes: false;
      @import "foundation";

      Note that the paths may differ based on your own setup. This will allow you to use all the mixins, functions and settings in Foundation, without having to duplicate all the CSS. This is handy if you are already including the Foundation CSS on the page you are working on. This method could, for example, be used as a place to store all of your overrides for a special page or subset of pages.

      In Conclusion

      This is just the tip of the iceberg: Foundation and Sass both have much more to offer and both have large followings of developers that continue to make them both more advanced, and well, better.  

       

      0 Comments

      Leave a comment › Posted in: Daily

  • Page 3 of 21 pages  < 1 2 3 4 5 >  Last ›
  • Browse the Blog

    Syndicate

    governing-bruise