Plans for the year [2019]

11th January, 2019

I've learnt a lot in 2018, but unfortunately I didn't document anything to this blog. Could be something to do with the sleep deprivation of having a 1 year old to deal with, or just that it's been such a full on productive work year?

I don't really have a great excuse, so I thought I'd share a few notes at the start of the year then hopefully this will motivate me to do some more learning and writing.

Things that look cool

Siler

On the back end, and in PHP world I've only just found Siler though it dates back at least to 2017. It's a very small, functional framework for PHP. You define your routes, with a regex, a method (HTTP verb) and then return a handler (callable, closure or anonymous function), or even a file name. It is a change from a typical Model View Controller mentality (not originally intended for the web) and away from using objects for everything. It doesn't mean you can't use objects elsewhere in your domain code, in fact the author encourages using OO in your domain.

GraphQL

This looks pretty neat, though I've only just touched the surface. One I've struggled with before now is having a consistent, query-able API. GraphQL lets you query deeply nested relational data in a predictable, scalable fashion. It also lets you run pre-defined mutations. It also acts as a type system between your API server and clients - this is really nice for consumers as they can easily see what type of data is available, how it is related and what they can do with it, all without having to make multiple http requests. It's a bit like HATEOS but preloaded upfront.

Elm

On the front end, I'm still really interested in Elm. After spending time with the compiler I can attest to the home page slogan that it is a "delightful language for reliable webapps". I wonder if I will have more opportunity to do more front end this year? I do have to work with React from time to time but I must confess I do often find it a less that pleasurable experience, but that could be down to how I'm using it and my limited exposure and understanding of it, rather than the tool itself which is obviously loved by many!

Glitch

This is a fantastic online IDE and back-end server all in one. This is how easy programming should be, focus on your creative software building - where you can add value - and let the machines take care of installing dependencies, building assets and serving those in near real time. The collaborative editor works pretty well, not quite as smooth as a desktop IDE like VS Code or the Intellij products, but you get live collaboration which is neat. It doesn't seem take itself too seriously, with playful artwork, fun friendly messages, with a large helping of emoji everywhere. This is a seriously cool problem to work on (DevOps with no barriers). With some services like Amazon and Google offering server-less architecture, but from my experience there is still a lot of config and steps to follow to get these working. Glitch is an ideal place for rapid application development and prototyping. There are restrictions - the app goes to sleep after 5 minutes of no requests, so it is slightly slower to spin up the next request. Also you can only make 40000 requests an hour. But it is easy to download the project as a zip file or export it to GitHub, so you can then run your code wherever you fancy.

Tagged: php functional programming js devops


Code Kata - Gilded Rose

11th January, 2019

The Gilded Rose Kata is a refactoring based kata. It is available from this GitHub in many languages. I tried to solve it in PHP and also Haskell.

I started by writing test cases that matched the requirements in the description, and yet ran with the existing code.

Once I felt I had the test cases sufficiently covered, I began to refactor the code - the interesting part.

The first thing I refactored was pushing the behaviour of updating an Item onto the Item itself, so the GildedRose was just looping over all the items in its inventory and calling update on them.

updateQuality :: GildedRose -> GildedRose
updateQuality = map updateItem

updateItem :: Item -> Item
updateItem (Item name sellIn quality) = ...

The code was full of conditionals, switching on the item name or type.

This was easy to extract behaviour based on the item name in Haskell thanks to pattern matching:

updateItem :: Item -> Item
updateItem (Item "Aged Brie" sellIn quality) = ...
updateItem (Item "Backstage passes to a TAFKAL80ETC concert" sellIn quality) = ...
updateItem (Item "Sulfuras, Hand of Ragnaros" sellIn quality) = ...
updateItem (Item "Sulfuras, Hand of Ragnaros" sellIn quality) = ...
updateItem (Item name sellIn quality) = ...

Once I had the different edge cases handled, I could extract conditionals out from the most general case at the bottom.

This is my final solution:

module GildedRose where

type GildedRose = [Item]

data Item = Item { name :: String, sellIn :: Int, quality :: Int } deriving (Eq)

instance Show Item where
  show (Item name sellIn quality) =
    name ++ ", " ++ show sellIn ++ ", " ++ show quality

updateQuality :: GildedRose -> GildedRose
updateQuality = map updateItem

restrictQuality :: Int -> Int
restrictQuality = min 50 . max 0

updateItem :: Item -> Item
updateItem (Item "Aged Brie" sellIn quality) =
  Item "Aged Brie" sellIn' quality'
    where sellIn'   = sellIn - 1
          quality'  = restrictQuality $ if sellIn > 0
                                        then quality + 1
                                        else quality + 2

updateItem (Item "Backstage passes to a TAFKAL80ETC concert" sellIn quality) =
  Item "Backstage passes to a TAFKAL80ETC concert" sellIn' (restrictQuality quality')
    where sellIn' = sellIn - 1
          quality'
            | sellIn < 1  = 0
            | sellIn < 6  =  quality + 3
            | sellIn < 11 =  quality + 2
            | otherwise   =  quality + 1

updateItem (Item "Sulfuras, Hand of Ragnaros" sellIn _) =
  Item "Sulfuras, Hand of Ragnaros" sellIn 80

updateItem (Item "Conjured Mana Cake" sellIn quality) =
  Item "Conjured Mana Cake" sellIn' quality'
    where sellIn'  = sellIn - 1
          quality' = restrictQuality $ if sellIn > 0
                                       then quality - 2
                                       else quality - 4

updateItem (Item name sellIn quality) =
  Item name sellIn' quality'
    where sellIn'  = sellIn - 1
          quality' = restrictQuality $ if sellIn > 0
                                       then quality - 1
                                       else quality - 2

You can see when I got round to adding the Conjured item it was just a case of adding an extra case to the pattern matching.

Tagged: kata haskell php phunkie tdd


PHP Testing your privates

11th January, 2019

I was recently writing some tests for a PHP object that had some internal state I wanted to check.

As I was building the class with TDD it was natural for me to test the state by adding getters to the object, so I could assemble my object, run the methods I wanted to test, then assert the resulting state of the object.

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  function test_it_does_something_internally()
  {
    $foo = new Foo;
    $foo->doSomething();

    $this->assertEquals('modified', $foo->getProperty());
  }
}

class Foo
{
  private $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }

  public function getProperty()
  {
    return $this->property;
  }
}

This all looked good, but once I had finished writing my tests and code I realised that my tests were the only places I was using the getProperty() method. I had methods in my object that were only being used in my test. This didn't feel quite right. I particularly didn't want clients of this object to be able to get at the private property (which was a reference to another object in this case) and manipulate that directly, I wanted other developers to interact with that object through this Façade class. But how did I communicate that intent?

A few options, some better than others, came to mind:

1) Drop the public getter method on the class, and use reflection in the test to check the property.

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  function test_it_does_something_internally()
  {
    $foo = new Foo;
    $foo->doSomething();

    $property = (new ReflectionObject($foo))->getProperty('property');
    $property->setAccessible('true');

    $this->assertEquals('modified', $property->getValue($foo));
  }
}

class Foo
{
  private $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }
}

It does clean up the source code by removing the method, but now the test seems a bit clunky.

2) Don't have the public getter in the class we are testing, but make a test class (or anonymous class if using PHP7!) that extends the base class and add the getter method in there.

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  function test_it_does_something_internally()
  {
    $foo = new Class extends Foo
    {
      public function getProperty()
      {
        return $this->property;
      }
    };

    $foo->doSomething();

    $this->assertEquals('modified', $foo->getProperty());
  }
}

class Foo
{
  protected $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }
}

Note that in order for the child test class to be able to access the property I would have to declare the visibility as protected and not private. Also this would not work if the class I was testing was declared as final, as I would not be able to extend it.

3) Leave the getter method there, but mark it as @internal - so if other developers tried to use it in the future, and if they are using an IDE like PHPStorm then it would be displayed with a ~~strikethrough~~.

This is a bit unconventional, and the other developers could still use the method as it is part of the classes public API, but if everyone on the team knew not to use @internal methods then this could be the easiest option.

4) Use an integration test, stop unit testing this bit. The reason there were no other needs to use the getter in the rest of the code base was because the private property was mapped by an ORM (Doctrine in this case) to the database. I could have made my test more of an integration test like so:

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  // the entity manager would have to be constructed or passed somewhere else
  private $em;

  function test_it_does_something_internally()
  {
    $foo = new Foo;
    $foo->doSomething();

    $this->em->save($foo);

    $dbResult = // insert SQL query here: SELECT `property` FROM `table` WHERE

    $this->assertEquals('modified', $dbResult['property']);
  }
}

class Foo
{
  private $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }
}

The plus side of this is I'm testing something closer to the real code, but that's about the only benefit. The cons are that it requires a database connection to run, so it will be a little bit slower, and there is that ugly, brittle SQL query in there to fetch the data too. I guess I could use an interface for the repository saving the element, and just save it to memory, but then I'd still need to add a public getter to view the property or reflection again, so I've not really gained anything!

5) Then last week I read this great blog post from Mark Baker. He explains that you can bind closures to another object, and grant them the scope of that object - meaning you can access private properties/methods once your closure is bound to a particular class. It deserves a demonstration:

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  function test_it_does_something_internally()
  {
    $foo = new Foo;
    $foo->doSomething();

    $getProperty = function()
    {
      return $this->property;
    };

    $getPropertyOfFoo = $getProperty->bindTo($foo, $foo);

    $this->assertEquals('modified', $getPropertyOfFoo());
  }
}

class Foo
{
  private $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }
}

To anyone who's not bound a closure to another object before this may look a little strange at first. We have effectively moved the public getter from our tested class, into a closure $getProperty. We then bindTo($foo, $foo) which effectively means that $this refers to our instance of $foo in the closure. We then call the closure in $getPropertyOfFoo(). I think this does muddle the test a little bit so I extracted it out into a private method, which meant I could call it multiple times in my test case too if I needed.

<?php

class FooTest extends PHPUnit\Framework\TestCase
{
  function test_it_does_something_internally()
  {
    $foo = new Foo;
    $foo->doSomething();

    $this->assertEquals('modified', $this->getPropertyOf($foo));
  }

  private function getPropertyOf($obj)
  {
    return (function() {
      return $this->property;
    })->bindTo($obj, $obj)();
  }
}

class Foo
{
  private $property;

  public function doSomething()
  {
    // Some other code...
    $this->property = 'modified';
  }
}

I don't think this should be used everywhere as generally I prefer tests that test behaviour rather than state, but this pattern could come in handy when you feel your test behaviour leaking into your domain model.

Have you ever been in a similar scenario as I describe? How did you solve that? I'd be interested to hear!

Tagged: php tdd