Page 12 of 15

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 6:02 am
by Chris Corbyn
matthijs wrote:What would be the easiest step up? ArrayStorageModel? We basically already have that isn't it?
Well, the ArrayStorageModel would need to be able to actually "write" PHP code to a file in order to be persistent. The idea is that a user can come along and edit the file by hand but our DataStore will know that the user changed thing when it's next loaded. The perfect example is an application configuration. ArrayStorageModel will likely be the easiest to write, but they'll all be *relatively* easy I'd say.

I'm not fussy which we do. They'll all warrant a little discussion before we begin :)

I've attached the latest files since I'd consider our current position to be a bit like hitting an atomic milestone. I added our @author names. Sorry, I don't know your real names so just edit them yourself. If we produce something really flexible we can always release it ;)

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 6:22 am
by matthijs
Ok cool. thanks for packaging it up.

Let's go with the ArrayStorageModel then. What that class should do is, and please correct me if I'm wrong:

Code: Select all

 
$storage = new StorageModel($somefile); // needs the file in the constructor?
$storage->load(); // reads the file and returns array
$storage->save($somefile); // writes the data as an array to the file or optionally to other file?
 
Or should the load method contain the input file?

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 6:29 am
by Chris Corbyn
matthijs wrote:Ok cool. thanks for packaging it up.

Let's go with the ArrayStorageModel then. What that class should do is, and please correct me if I'm wrong:

Code: Select all

 
$storage = new StorageModel($somefile); // needs the file in the constructor?
$storage->load(); // reads the file and returns array
$storage->save($somefile); // writes the data as an array to the file or optionally to other file?
 
Or should the load method contain the input file?
I think we'll use the constructor for any model-specific configuration :) If we specify the file using the load() method then DataStore will need to know where the file is when it calls load(). We'd also need to modify our interface to support it.

The information our ArrayStorageModel will need includes a filename indeed :) Can you think of something else it will need before it can find the array?

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 6:34 am
by matthijs
The name of the array?

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 6:39 am
by Chris Corbyn
matthijs wrote:The name of the array?
Yay! I'm sure we could do some magic tricks with get_defined_vars() to determine its name but hmmm, yeah, feels a bit over-engineered ;) If we have the filename and the name of a the array then I think we'd be good to go!

So we agree it's going to look something like this? This isn't what a "user" would be doing by the way. This is what DataStore will be doing -- as our previous tests have shown. The only bit the user will use is the constructor.

Code: Select all

$arrayModel = new ArrayStorageModel('file.php', 'config');
 
//Load existing "saved" data like this
$existingData = $arrayModel->load();
 
if ($arrayModel->save(array('some' => 'new data'))) {
  //Data in the file is now changed!
}

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:06 am
by matthijs
Ok I set up the files like this:

Code: Select all

<?php
// file ArrayStorageModelTest.php
require_once dirname(__FILE__) . '/../configure.php';
require_once CLASS_BASE . '/ArrayStorageModel.php';
require_once CLASS_BASE . '/StorageModel.php';
 
class ArrayStorageModelTest extends UnitTestCase {
    
}
 

Code: Select all

<?php
// file ArrayStorageModel.php
require_once dirname(__FILE__) . '/StorageModel.php';
 
class ArrayStorageModel implements StorageModel {
    private $file;
    private $array;
    public function __construct($file, $arrayname){
      $this->file = $file;
      $this->array = $arrayname;
    }
    public function load(){}
    public function save($data){}
}
 

Code: Select all

<?php
// file StorageModel.php
interface StorageModel {
  public function save($data);
  public function load();
}
 
So let's start with testing the load method. Maybe

testLoadReturnsArrayAfterReadingFile{}
testLoadReturnsEmptyArrayAfterReadingEmptyFile{}

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:34 am
by Chris Corbyn
Good good. You shouldn't really have added that implementation code yet though (copying values to properties).

(You've also swapped conventions again and dropped the private member underscores :P)

I usually start like this:

Code: Select all

<?php
 
require_once dirname(__FILE__) . '/../configure.php';
require_once CLASS_BASE . '/ArrayStorageModel.php';
require_once CLASS_BASE . '/StorageModel.php';
 
class ArrayStorageModelTest extends UnitTestCase {
  public function testNothing() {
    $this->assertFalse(true, 'Just a failing nothing test');
  }
}

Code: Select all

<?php
 
require_once dirname(__FILE__) . '/StorageModel.php';
 
class ArrayStorageModel implements StorageModel {
 
  public function __construct($filename, $arrayName) {
  }
  
  public function load() {
  }
  
  public function save($data) {
  }
 
}
As minimal as possible, and always with a failing "nothing test".

Did you add it to the AllTests.php file too? :)

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:39 am
by Chris Corbyn
Well... I think we should maybe discuss this test before we start writing it. How would you anticipate we set up a test environment for this test? :) We're going to be reading and writing to a file. Can see any potential issues with this?

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:42 am
by matthijs
(You've also swapped conventions again and dropped the private member underscores :P)
Glad you're not in one team with me isn't it :)
You're right, I forgot about them.

About the tests: should we have setup and teardown methods to create and destroy a clean testfile for each test method?

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:56 am
by Chris Corbyn
matthijs wrote:
(You've also swapped conventions again and dropped the private member underscores :P)
Glad you're not in one team with me isn't it :)
You're right, I forgot about them.
I think we just both follow different conventions in our own work. It's hard to adopt somebody else's conventions for a project until you've done it several times over. Then it's weird... you just "switch" from one convention to another depending on the project you're adding code to at the time :P
matthijs wrote:About the tests: should we have setup and teardown methods to create and destroy a clean testfile for each test method?
Sounds like a plan! :) I say we create a directory called at tests/tmp/ and we all make sure we have write access to it. Running the tests on command line would mean this will work "out of the box". If you're running in a web browser then you'll need to change the access permissions on the directory.

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 8:02 am
by matthijs
I don't have any conventions yet. I'm still a clean slate in that sense :)

Code: Select all

 
  function setUp() {
    @unlink(TEST_BASE .'/tmp/test.php');
  }
  
  function tearDown() {
    @unlink(TEST_BASE .'/tmp/test.php');
  }
    
  private function createtestFile(){}
 

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 8:25 am
by Chris Corbyn
No need to have the same code in setUp() and tearDown(). Also a very bad idea to surpress errors in a test case ;) If the file cannot be removed we *need* to know about it otherwise we're going to run into all kinds of confusing test failures ;)

I think we'll pick this up tomorrow ;) Sorry, it's 11:30pm and I'm falling asleep. You've got the right idea with this test I think so we'll more than like steam through its implementation tomorrow and be onto the next class in no time!

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 10:25 am
by sike
wow, 11 pages? a lot to read (:
but one thing upfront and wiothout reading the whole thing : you are talking too much for my taste. just start writing the tests using mocks and don't fear refactoring. i hope that doesn't sound too rude or is totally out of context but i am going to read most of the thread tonight and will try to contribute as far as time permits.

cheers
Chris

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 10:50 am
by matthijs
chris, you're welcome to jump in.

The main reason we talk so much is that the goal of the thread is to teach how to TDD. So for each little step we discuss things, someone might ask a question if something is not clear, etc. Even if there are just a few of us actually taking part in this exercise, I think it will be an excellent read for anyone who wants to get into TDD.

So the main goal is not to write a nice piece of code, that's only a pleasant side effect.

So far this has been an excellent learning experience for me.

Re: TDD workshop. Anybody welcome; Data storage abstraction.

Posted: Mon Apr 28, 2008 7:17 pm
by Chris Corbyn
Yes, most of the lengthy discussions are to clear up confusion and the spend time explaining things so they're absorbed. This is supposed to be a learning experience for those involved, not just a "jump in and write some code" exercise :) Feel free to join in. You've actually come at a good opportunity since we're starting a brand new class now.