Curl Global Community
TDD with Curl (part 2) - Printable Version

+- Curl Global Community (https://communities.curl.com)
+-- Forum: Blogs (https://communities.curl.com/forumdisplay.php?fid=17)
+--- Forum: Tech blog (https://communities.curl.com/forumdisplay.php?fid=18)
+---- Forum: Robert blog (https://communities.curl.com/forumdisplay.php?fid=20)
+---- Thread: TDD with Curl (part 2) (/showthread.php?tid=325)



TDD with Curl (part 2) - RobertShiplett - 10-26-2011


One thing we might consider is how we already know that a 'geo-links-widget' would be named GeoFrame. We can address this by first instantiating our test widget as type Frame.

We will not want to start with a GeoFrame class as merely inheriting from Graphic, because that requires implementing an abstract method immediately for get-height-preference with a LayoutContext. We will not want BaseFrame because our widget likely will have multiple children (at least in the most common use-case.)

What I propose is to add the following to our start.curl test runner. Place it immediately before the testing {include }.

|| later we will test importing a new package; for now, we just use an include

{include "code/geoframe.scurl"}

Our source code file is simply this:

{curl-file-attributes character-encoding = "utf8"}

|| first TDD iteration code goes below:

Leave that source code file otherwise empty for now.


Now we need to write our first test.

We will start with a failing test for the property name not being empty for our Frame.

Curl provides a macro for creating SimpleTestCase instances, so here we go:

{def model:Graphic = {Frame} }

{test-case
"geo-links-widget.has-name",
{TestCondition.assert ( not {model.name.equal? "" } ) )
}

Place the above in our ./test-cases/test-geoframe.scurl and run our applet. Our first test does not run Green.

We make this change to our test def

{def model:Graphic = {Frame name = "test-class-geo-links-widget"} }

Run tests: Our first test runs Green.

Now to fail that test with one teeny-tiny change ( as Kent Beck or Ward Cunningham might say.) This test will be to change Frame to GeoLinksWidget in our test def.


{def model:Graphic = {GeoLinksWidget name = "test-class-geo-links-widget"} }

We get the "Red" in the Curl Eclipse environment and get that "test" running with our first minimalist source code:

{define-class public GeoLinksWidget {inherits Frame}

}

Now Eclipse gives us Red in the test file for lack of a constructor in our class which will accept that name parameter. ONLY for that reason do we add this minimalist constructor to our source:

{constructor {default ... }

{construct-super ... }

}

The Eclipse CDE has no Red. Run the test-runner. Our tests are Green. (Yes, we ran the test-runner; we ALWAYS run our tests as soon as the development environment will permit.)

What have we achieved? We have written the test before we have written the source code.

Whatever class we go on to develop through successive iterations will come to replace GeoLinksWidget; we might use the Sonntag framework or the Advanced-UI or develop a macro {geo-links set-of-directional-links}. But. If we are doing TDD, we will write the test first and only then write minimalist -even (and often) ugly -code to get the tests to run Green. We will not look too far ahead, we will not build out anything not needed to get our tests to run. We will not ask, "But what if there are two links that both lie north-east of our geo site?!?" Our requirement is to generate a visual equivalent to the geo-links widget found in
the External Links section of Dawson Creek.

Here is our current test suite:

{def model:Graphic = {GeoLinksWidget name = "test-class-geo-links-widget"}}

{let public test-suite:TestSuite = {TestSuite "GeoFrame",
{test-case "geo-links-widget.has-name",
{TestCondition.assert (not {model.name.equal? ""})}
} } }

Here is our current source code:

{define-class public GeoLinksWidget {inherits Frame}
{constructor {default ...}
{construct-super ...}
}

In the next installment we will introduce redundancy and then refactor to reduce that
redundancy.