プロローグ
読者の方で、
- 「いちばん重要な財産はコードであり、
万一コードを失ってしまったら、 元と同じ品質のコードをもう一度書くのはとても大変だ」
筆者も長年このように思っていました。では、
「いちばん重要な財産はテストであり、
今までとずいぶん違う考え方ですね。いろんな声が聞こえてきそうです。
- 「コメントはどうするんだ」
- 「テストが複雑すぎて保守できなくなったらどうするんだ」
ごもっともです。テスト駆動開発は万能ではありません。うまく適用できない場面もあり、
でも、
ブックレット作成プログラム
では最初に、

このテストで使うのは、
リスト1 テスト実行スクリプト
#! /usr/local/bin/php
<?php
function asserteq($expected, $found) {
if ($expected === $found) {
printf(".");
return;
}
printf("\nexpected: \"%s\"\nfound: \"%s\"\n----\ntest failed.\n", $expected, $found);
die();
}
require("target.php");
foreach (get_declared_classes() as $classname) {
foreach (get_class_methods($classname) as $methodname) {
if (!ereg("^test", $methodname))
continue;
$obj =& new $classname();
$obj->$methodname();
}
}
print"\ntest successed.\n";
?>
asserteq()というのは、
run.
一方、
- 最初のページ順は "a b c d e f g h"
- ブックレット順に並び替え
- ページ順が"h a b g f c d e"になっているかテスト
そうすると、
そして、
<?php
class dummy_pdfpage {
var $name = "";
function dummy_pdfpage($name = "none") {
$this->name = $name;
}
}
class dummy_pdf {
var $pages;
function dummy_pdf() {
$this->pages = array();
}
function &newPage() {
$page =& new dummy_pdfpage("@");
return $page;
}
function pagelist() {
$array = array();
foreach ($this->pages as $key => $dummy)
$array[] = $this->pages[$key]->name;
return implode(" ", $array);
}
}
?>
さっそくページの並べ替えのテストをしたいところですが、
では、
- pdfオブジェクトを生成。
- リストが""であることをテスト。
- 「a」
というページを追加。 - リストが"a"であることをテスト。
- 「b」
というページを追加。 - リストが"a b"であることをテスト。
- newPage()を呼び出して、
空のページを追加。 - リストが"a b @"であることをテスト。
- もう一度newPage()を呼び出して、
空のページを追加。 - リストが"a b @ @"であることをテスト。
これでうまくいけば、
class dummy_pdf {
....
function test1() {
$pdf =& new dummy_pdf();
asserteq("", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("a");
asserteq("a", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("b");
asserteq("a b", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b @", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b @ @", $pdf->pagelist());
}
}
では、
$ php ..... test successed. $
asserteq()が呼ばれて成功すると
まずテストを書く
さて、
そこでテスト駆動開発では、
練習として、
class dummy_pdf {
....
function test2() {
$pdf =& new dummy_pdf("a b c");
asserteq("a b c", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("d");
asserteq("a b c d", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b c d @", $pdf->pagelist());
}
}
実行してみましょう。
$ php run.php ..... Expected: "a b c" Found: "" ---- test failed. $
しっかりエラーになりました。期待通り、
あとは、
class dummy_pdf {
var $pages;
function dummy_pdf($s = "") {
$this->pages = array();
foreach (explode(" ", $s) as $name)
$this->pages[] =& new dummy_pdfpage($name);
}
....
}
実行すると、
$ php run.php . Expected: "a" Found: " a" ---- test failed. $
"a"と比較しているテストは1ヵ所だけですから、
class dummy_pdf {
var $pages;
function dummy_pdf($s = "") {
$this->pages = array();
if ($s != "")
foreach (explode(" ", $s) as $name)
$this->pages[] =& new dummy_pdfpage($name);
}
....
}
もう一度実行すると、
$ php run.php ........ test successed. $
ページ順の編集
では、
class pdfpages {
function pdfpages(&$pdf) {
}
function makebooklet() {
}
}
class pdfpages_test {
function test1() {
$pdf =& new dummy_pdf("a b c d");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("d a b c", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b @ @ c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b @ f c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f g");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b g f c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f g h");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("h a b g f c d e", $pdf->pagelist());
}
}
注意点ですが、
ちなみにPHP5以降では、
実行すると、
$ php run.php ........ Expected: "dabc" Fonud: "abcd" ---- test failed. $
では、
class pdfpages {
var $pdf = null;
function pdfpages(&$pdf) {
$this->pdf =& $pdf;
}
function &newblankpage() {
$page =& $this->pdf->newPage();
return $page;
}
function makebooklet() {
while ((count($this->pdf->pages) % 4))
$this->pdf->pages[] =& $this->newblankpage();
$newpages = array();
$left = count($this->pdf->pages) - 1;
$right = 0;
while ($right < $left) {
$newpages[] =& $this->pdf->pages[$left--];
$newpages[] =& $this->pdf->pages[$right++];
$newpages[] =& $this->pdf->pages[$right++];
$newpages[] =& $this->pdf->pages[$left--];
}
$this->pdf->pages = $newpages;
}
}
実行すると、
$ php run.php ............. test successed. $
あとは、
- Zend Framework
- URL:http://
framework. zend. com/
run.
<?php
class dummy_pdfpage {
var $name = "";
function dummy_pdfpage($name = "none") {
$this->name = $name;
}
function getWidth() {
return 1;
}
function getHeight() {
return 1;
}
function drawLine() {
}
}
class dummy_pdf {
var $pages;
function dummy_pdf($s = "") {
$this->pages = array();
if ($s != "")
foreach (explode(" ", $s) as $name)
$this->pages[] =& new dummy_pdfpage($name);
}
function &newPage() {
$page =& new dummy_pdfpage("@");
return $page;
}
function pagelist() {
$array = array();
foreach ($this->pages as $key => $dummy)
$array[] = $this->pages[$key]->name;
return implode(" ", $array);
}
function test1() {
$pdf =& new dummy_pdf();
asserteq("", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("a");
asserteq("a", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("b");
asserteq("a b", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b @", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b @ @", $pdf->pagelist());
}
function test2() {
$pdf =& new dummy_pdf("a b c");
asserteq("a b c", $pdf->pagelist());
$pdf->pages[] =& new dummy_pdfpage("d");
asserteq("a b c d", $pdf->pagelist());
$pdf->pages[] =& $pdf->newPage();
asserteq("a b c d @", $pdf->pagelist());
}
}
class pdfpages {
var $pdf = null;
function pdfpages(&$pdf) {
$this->pdf =& $pdf;
}
function &newblankpage() {
if (count($this->pdf->pages) <= 0)
die("no page.\n");
$p =& $this->pdf->pages[0];
$page =& $this->pdf->newPage($p->getWidth().":".$p->getHeight());
$page->drawLine(0, 0, 0, 0); # avoid PDF error.
return $page;
}
function makebooklet() {
while ((count($this->pdf->pages) % 4))
$this->pdf->pages[] =& $this->newblankpage();
$newpages = array();
$left = count($this->pdf->pages) - 1;
$right = 0;
while ($right < $left) {
$newpages[] =& $this->pdf->pages[$left--];
$newpages[] =& $this->pdf->pages[$right++];
$newpages[] =& $this->pdf->pages[$right++];
$newpages[] =& $this->pdf->pages[$left--];
}
$this->pdf->pages = $newpages;
}
}
class pdfpages_test {
function test1() {
$pdf =& new dummy_pdf("a b c d");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("d a b c", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b @ @ c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b @ f c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f g");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("@ a b g f c d e", $pdf->pagelist());
$pdf =& new dummy_pdf("a b c d e f g h");
$p =& new pdfpages($pdf);
$p->makebooklet();
asserteq("h a b g f c d e", $pdf->pagelist());
}
}
if (!function_exists("asserteq")) {
set_include_path(get_include_path().PATH_SEPARATOR."/download/ZendFramework-1.11.6/library/");
require_once('Zend/Loader/Autoloader.php');
Zend_Loader_Autoloader::getInstance();
ini_set("max_execution_time", "300");
ini_set("memory_limit", "1024M");
$pdf =& Zend_Pdf::load("input.pdf");
$p =& new pdfpages($pdf);
$p->makebooklet();
$pdf->save("output.pdf");
}
?>
また、
今回はユーザインターフェースについては相当手を抜いたので、
エピローグ
いかがでしたでしょうか。実は、