Diffs
Maple4_DocTest/tags/0.2.0-alpha/Maple4/Utils/Array.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+/**
+ * 配列関連のユーティリティークラス
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_Utils_Array
+{
+ /**
+ * @var array 各要素のデフォルト値
+ */
+ private $defaults = array();
+
+ /**
+ * @var array 処理する配列
+ */
+ private $array = array();
+
+ /**
+ * コンストラクタ
+ *
+ * @params array $array 処理する配列
+ */
+ public function __construct($array = array())
+ {
+ $this->array = $array;
+ }
+
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @params array $array 処理する配列
+ * @return object このオブジェクト自身
+ */
+ static public function create($array = array())
+ {
+ return new self($array);
+ }
+
+ /**
+ * 配列から安全に値を取得する
+ *
+ * @param string $key 配列要素
+ * @param mixed $default 値がなかった場合のデフォルト値
+ * @return mixed 取得した値
+ * @access public
+ */
+ public function get($key, $default = null)
+ {
+ if (is_array($this->array) && isset($this->array[$key])) {
+ $result = $this->array[$key];
+ } else {
+ $result = $default;
+ }
+
+ return $result;
+ }
+
+ /**
+ * 配列に値をセットする
+ *
+ * @param string $key 配列要素
+ * @param mixed $value 要素に対する値
+ * @return object このオブジェクト自身
+ * @access public
+ */
+ public function set($key, $value = null)
+ {
+ $this->array[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * 配列ということを隠蔽したアクセス
+ *
+ * @param mixed $key 配列要素
+ * @return mixed 要素に対する値
+ */
+ public function __get($key)
+ {
+ $default = null;
+ if (isset($this->default[$key])) {
+ $default = $this->default[$key];
+ }
+
+ return $this->get($key, $default);
+ }
+
+ /**
+ * 配列ということを隠蔽したアクセス
+ *
+ * @param mixed $key 配列要素
+ * @param mixed $value 要素に対する値
+ */
+ public function __set($key, $value)
+ {
+ $this->set($key, $value);
+ }
+
+ /**
+ * 要素に対してデフォルト値をセット
+ *
+ * @param mixed $key 配列要素
+ * @param mixed $default 要素に対するデフォルト値
+ * @return object このオブジェクト自身
+ */
+ public function setDefault($key, $default = null)
+ {
+ $this->array[$key] = $default;
+
+ return $this;
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/Utils/File.php
@@ -0,0 +1,464 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.1.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/Exception.php');
+
+/**
+ * ファイル関連のユーティリティークラス
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @author Kazunobu Ichihashi <bobchin@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.1.0
+ */
+class Maple4_Utils_File
+{
+ const MARKER_FILENAME = '__BASEDIR__';
+
+ /**
+ * @var array 処理対象外パターンを保持する
+ * @access private
+ */
+ private $ignore = array();
+
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * ディレクトリ区切り文字をOSのものに統一する
+ *
+ * @param string $pathname ディレクトリ文字列
+ * @return string 置き換え後のディレクトリ文字列
+ * @access public
+ */
+ public function fixDirectorySeparator($pathname)
+ {
+ return str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $pathname);
+ }
+
+ /**
+ * 末尾のディレクトリ区切り文字を削除する
+ *
+ * @param string $pathname ディレクトリ文字列
+ * @return string 削除後のディレクトリ文字列
+ * @access public
+ */
+ public function removeTailSlash($pathname)
+ {
+ return rtrim($this->fixDirectorySeparator($pathname), DIRECTORY_SEPARATOR);
+ }
+
+ /**
+ * 末尾にディレクトリ区切り文字を追加する
+ *
+ * @param string $pathname ディレクトリ文字列
+ * @return string 追加後のディレクトリ文字列
+ * @access public
+ */
+ public function addTailSlash($pathname)
+ {
+ return $this->removeTailSlash($pathname) . DIRECTORY_SEPARATOR;
+ }
+
+ /**
+ * 先頭のディレクトリ区切り文字を削除する
+ *
+ * @param string $pathname ディレクトリ文字列
+ * @return string 削除後のディレクトリ文字列
+ * @access public
+ */
+ public function removeHeadSlash($pathname)
+ {
+ return ltrim($this->fixDirectorySeparator($pathname), DIRECTORY_SEPARATOR);
+ }
+
+ /**
+ * 先頭にディレクトリ区切り文字を追加する
+ *
+ * @param string $pathname ディレクトリ文字列
+ * @return string 追加後のディレクトリ文字列
+ * @access public
+ */
+ public function addHeadSlash($pathname)
+ {
+ return DIRECTORY_SEPARATOR . $this->removeHeadSlash($pathname);
+ }
+
+ /**
+ * 指定した文字列を処理対象外とする
+ *
+ * @param mixed $str 処理対象外とする文字列
+ * @access public
+ */
+ public function setIgnore($path)
+ {
+ if (is_array($path)) {
+ $this->ignore = array_merge($this->ignore, $path);
+ } else {
+ $this->ignore[] = $path;
+ }
+ }
+
+ /**
+ * 処理対象外リストをクリアする
+ *
+ * @access public
+ */
+ public function clearIgnore()
+ {
+ $this->ignore = array();
+ }
+
+ /**
+ * 処理対象外かどうか?
+ *
+ * @param string $pathname ディレクトリ名
+ * @return boolean 処理対象外かどうか
+ * @access public
+ */
+ public function isIgnore($pathname)
+ {
+ $match = false;
+ foreach ($this->ignore as $ignore) {
+ if (preg_match("|{$ignore}|", $pathname)) {
+ $match = true;
+ break;
+ }
+ }
+
+ return $match;
+ }
+
+ /**
+ * 基準ディレクトリを返却
+ *
+ * 基準となるディレクトリに設置されているマーカーファイルを探す
+ *
+ * @param string $pathname ディレクトリ名もしくはファイル
+ * @return string 基準となるディレクトリ
+ * @access public
+ */
+ public function searchBasePathname($pathname)
+ {
+ if (is_dir($pathname)) {
+ $path = $pathname;
+ } else {
+ $path = dirname($pathname);
+ }
+
+ while (!$this->isTopDir($path)) {
+ $marker = $this->addTailSlash($path) . self::MARKER_FILENAME;
+ if (file_exists($marker)) {
+ break;
+ }
+ $path = dirname($path);
+ }
+
+ return $this->removeTailSlash($path);
+ }
+
+ /**
+ * トップディレクトリか?
+ *
+ * @param $pathname ディレクトリ名
+ * @return boolean トップディレクトリかどうか
+ * @access private
+ */
+ private function isTopDir($pathname)
+ {
+ if (strstr(PHP_OS, "WIN")) {
+ $result = preg_match('|^[A-Za-z]+:\\\\$|', $pathname);
+ } else {
+ $result = ($this->removeHeadSlash($pathname) === '');
+ }
+
+ return $result;
+ }
+
+ /**
+ * ディレクトリとファイルのリストを取得する
+ *
+ * @param string $pathname ディレクトリ名
+ * @return array ディレクトリとファイルの配列
+ * @access public
+ */
+ public function ls($pathname)
+ {
+ $dirs = array();
+ $files = array();
+
+ if (!is_dir($pathname) || (!$dh = opendir($pathname))) {
+ return array($dirs, $files);
+ }
+
+ while (($filename = readdir($dh)) !== false) {
+ if (preg_match("/^[.]{1,2}$/", $filename)) {
+ continue;
+ }
+
+ $realpath = $this->addTailSlash($pathname) . $filename;
+
+ if ($this->isIgnore($realpath)) {
+ continue;
+ }
+
+ if (is_dir($realpath)) {
+ $dirs[] = $realpath;
+ } else {
+ $files[] = $realpath;
+ }
+ }
+
+ closedir($dh);
+
+ sort($dirs);
+ sort($files);
+
+ return array($dirs, $files);
+ }
+
+ /**
+ * 指定したディレクトリのファイルリストを取得する
+ *
+ * @param string $pathname ディレクトリ名
+ * @param string $regex 取得するファイル名の正規表現
+ * @param function $callback コールバック
+ * @return array ファイルの配列
+ * @access public
+ */
+ public function find($pathname, $regex = null, $callback = null)
+ {
+ list (, $files) = $this->ls($pathname);
+
+ if (is_null($regex)) {
+ if (is_callable($callback)) {
+ $files = array_map($callback, $files);
+ }
+ return $files;
+ }
+
+ $result = array();
+ foreach ($files as $filename) {
+ if (preg_match($regex, $filename)) {
+ if (is_callable($callback)) {
+ $filename = call_user_func($callback, $filename);
+ }
+ $result[] = $filename;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * 指定したディレクトリ以下のファイルリストを取得する
+ *
+ * サブディレクトリがある場合は再帰的に取得する
+ *
+ * @param string $pathname ディレクトリ名
+ * @param string $regex 取得するファイル名の正規表現
+ * @param function $callback コールバック
+ * @return array ファイルの配列
+ * @access public
+ */
+ public function findRecursive($pathname, $regex = null, $callback = null)
+ {
+ list ($dirs,) = $this->ls($pathname);
+
+ $found = $this->find($pathname, $regex, $callback);
+
+ foreach ($dirs as $dir) {
+ $found = array_merge($found, $this->findRecursive($dir, $regex, $callback));
+ }
+
+ sort($found);
+ reset($found);
+
+ return $found;
+ }
+
+ /**
+ * ファイルを削除する
+ *
+ * @param string $filename ファイル名
+ * @return boolean 処理結果
+ * @access public
+ */
+ public function unlink($filename)
+ {
+ $result = true;
+ if (file_exists($filename)) {
+ $result = unlink($filename);
+ }
+
+ return $result;
+ }
+
+ /**
+ * ディレクトリを作成する。
+ *
+ * 複数階層のディレクトリを指定した場合に、
+ * 途中のディレクトリも自動的に作成する。
+ *
+ * @param string $pathname 作成するディレクトリ名
+ * @param int $mode 権限
+ * @param int $umask umaskの値
+ * @return boolean 処理結果
+ * @access public
+ */
+ public function makeDir($pathname, $mode = 0777, $umask = 0)
+ {
+ umask($umask);
+
+ $result = true;
+ if (!file_exists($pathname)) {
+ $result = mkdir($pathname, $mode, true);
+ }
+
+ return $result;
+ }
+
+ /**
+ * ディレクトリを削除する
+ *
+ * 指定したディレクトリより下のディレクトリ・ファイルも
+ * 自動的に削除する。
+ *
+ * @param string $pathname 削除するディレクトリ名
+ * @return boolean 処理結果
+ * @access public
+ */
+ public function removeDir($pathname)
+ {
+ list ($dirs, $files) = $this->ls($pathname);
+
+ array_map(array($this, 'unlink'), $files);
+ array_map(array($this, 'removeDir'), $dirs);
+
+ $result = true;
+ if (file_exists($pathname)) {
+ $result = rmdir($pathname);
+ }
+
+ return $result;
+ }
+
+ /**
+ * ファイルを読み込む
+ *
+ * @param string $filename ファイル名
+ * @return string ファイルの内容
+ * @access public
+ */
+ public function read($filename)
+ {
+ $result = null;
+
+ if (!file_exists($filename)) {
+ throw new Maple4_Exception("file not found({$filename})");
+ }
+
+ if (!is_readable($filename)) {
+ throw new Maple4_Exception("file not readable({$filename})");
+ }
+
+ if (version_compare('6.0.0', phpversion(), '<=')) {
+ $result = @file_get_contents($filename, FILE_USE_INCLUDE_PATH);
+ } else {
+ $result = @file_get_contents($filename, true);
+ }
+
+ if ($result === false) {
+ $result = null;
+ }
+
+ return $result;
+ }
+
+ /**
+ * ファイルに書き込む
+ *
+ * 指定した内容をファイルに上書きで書き込む。
+ * 途中のフォルダが存在しない場合は自動的に作成する。
+ *
+ * @param string $filename ファイル名
+ * @param string $buf 書き込む内容
+ * @param string $mode 書き込みモード
+ * @return boolean
+ * @access public
+ */
+ public function write($filename, $buf, $mode = "wb")
+ {
+ if (file_exists($filename) && !is_writable($filename)) {
+ throw new Maple4_Exception("file not writable({$filename})");
+ }
+
+ $this->makeDir(dirname($filename));
+
+ if (!($fh = fopen($filename, $mode))) {
+ return false;
+ }
+
+ if (!fwrite($fh, $buf)) {
+ return false;
+ }
+
+ if (!fclose($fh)) {
+ return false;
+ }
+
+ return true;
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/Utils/Class.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.1.0
+ */
+
+/**
+ * クラス関連のユーティリティークラス
+ *
+ * @category Utils
+ * @package Maple4_Utils
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.1.0
+ */
+class Maple4_Utils_Class
+{
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * 指定されたファイル名に対するクラス名を返却
+ *
+ * 返却されるクラス名は小文字に変換後返却される
+ *
+ * オプション
+ * ucfirst: クラス名の各パートの先頭を大文字にするか
+ * namespace: 変換時に使用する擬似名前空間
+ *
+ * @param string $filename クラス名に変換したいファイル名
+ * @param array $options 変換時に使用するオプション
+ * @return string クラス名
+ * @access public
+ */
+ public function toClassname($filename, $options = array())
+ {
+ $doUcfirst = true;
+ if (isset($options['ucfirst']) &&
+ !is_null($options['ucfirst'])) {
+ $doUcfirst = $options['ucfirst'];
+ }
+
+ $namespace = '';
+ if (isset($options['namespace']) &&
+ !is_null($options['namespace'])) {
+ $namespace = $options['namespace'];
+ }
+
+ $result = null;
+ if (!preg_match('|\.php|', $filename)) {
+ return $result;
+ }
+
+ if ($namespace) {
+ $pathname = join('/', preg_split('|_|', $namespace));
+ $filename = "{$pathname}/{$filename}";
+ }
+
+ $filename = preg_replace('|\.php|', '', $filename);
+ $parts = preg_split('|[\\\\/]|', $filename);
+
+ if ($doUcfirst) {
+ $result = join('_', array_map('ucfirst', $parts));
+ } else {
+ $result = strtolower(join('_', $parts));
+ }
+
+ return $result;
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/Exception.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Exception
+ * @package Maple4_Exception
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.1.0
+ */
+
+/**
+ * Maple4の例外のベースとなる例外
+ *
+ * @category Exception
+ * @package Maple4_Exception
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.1.0
+ */
+class Maple4_Exception extends Exception
+{
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Runner.php
@@ -0,0 +1,284 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once('PHPUnit/Framework.php');
+require_once('PHPUnit/TextUI/TestRunner.php');
+require_once(dirname(dirname(__FILE__)) . '/Utils/File.php');
+require_once(dirname(dirname(__FILE__)) . '/Utils/Class.php');
+require_once(dirname(dirname(__FILE__)) . '/Utils/Array.php');
+
+/**
+ * テストケースを実行する
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_Runner
+{
+ /**
+ * @var object Maple4_Utils_Fileのインスタンス
+ * @access private
+ */
+ private $fileUtils;
+
+ /**
+ * @var object Maple4_Utils_Classのインスタンス
+ * @access private
+ */
+ private $classUtils;
+
+ /**
+ * コンストラクタ
+ */
+ public function __construct()
+ {
+ $this->fileUtils = new Maple4_Utils_File();
+ $this->classUtils = new Maple4_Utils_Class();
+ }
+
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * テストを実行する
+ *
+ * @param array $options DocTestの動作オプション
+ * @param string $pathname テスト対象となるディレクトリ
+ * @param array $testcases 実行するファイルリスト
+ * @return string 実行結果
+ * @access public
+ */
+ public function run($options, $pathname, $testcases)
+ {
+ // ファイル単体で指定された場合のための対策
+ if (preg_match('|\.php$|', $pathname)) {
+ $testcases = $this->filterTestCases($pathname, $testcases);
+ }
+
+ $suite = new PHPUnit_Framework_TestSuite();
+
+ foreach ($testcases as $realpath => $path) {
+ if (is_null($realpath) || is_null($path) ||
+ !file_exists($realpath)) {
+ continue;
+ }
+
+ require_once($realpath);
+
+ $classname = $this->classUtils->toClassname($path);
+
+ if (!is_null($classname)) {
+ $suite->addTestSuite($classname);
+ }
+ }
+
+ $parameters = array();
+
+ $options = new Maple4_Utils_Array($options);
+
+ if (!strstr(PHP_OS, "WIN") && $options->color) {
+ include_once(dirname(__FILE__) . '/Runner/ResultPrinter.php');
+ $parameters['printer'] = new Maple4_DocTest_Runner_ResultPrinter();
+ }
+
+ if (!is_null($options->report) &&
+ is_dir($options->report) &&
+ file_exists($options->report)) {
+ $parameters['reportDirectory'] = $options->report;
+ }
+
+ ob_start();
+ PHPUnit_TextUI_TestRunner::run($suite, $parameters);
+ $output = ob_get_contents();
+ ob_end_clean();
+
+ echo $output;
+
+ if ($options->notify) {
+ $notify = new Maple4_Utils_Array($options->notify);
+ if ($notify->type === 'growl') {
+ $this->growlNotify($notify, $output);
+ }
+ }
+ }
+
+ /**
+ * ファイル単体で指定された場合はテストケースを絞る
+ *
+ * @param string $pathname テスト対象となるディレクトリ
+ * @param array $testcases 実行するファイルリスト
+ * @return array 絞り込んだテストケース
+ * @access private
+ */
+ private function filterTestCases($pathname, $testcases)
+ {
+ $pathname = $this->fileUtils->fixDirectorySeparator($pathname);
+
+ foreach ($testcases as $realpath => $path) {
+ $original = $this->makeOriginalFilename($path);
+ if (strstr($pathname, $original)) {
+ $testcases = array($realpath => $path);
+ break;
+ }
+ }
+
+ return $testcases;
+ }
+
+ /**
+ * テストケースファイルから元のPHPファイル名を生成する
+ *
+ * @param string $pathname テストケースのファイル名
+ * @return string 元のPHPファイル名
+ * @access private
+ */
+ private function makeOriginalFilename($pathname)
+ {
+ $result = preg_replace('|^Maple4_DocTest_|', '', $pathname);
+ $result = preg_replace('|Test\.php$|', '', $result);
+ $result = $this->fileUtils->removeHeadSlash($result) . '.php';
+
+ $parts = preg_split('|_|', $this->classUtils->toClassname($result));
+
+ $result = $this->fileUtils->fixDirectorySeparator(join('/', $parts) . '.php');
+
+ return $result;
+ }
+
+ /**
+ * Growlを利用する
+ *
+ * @param array $options DocTestの動作オプション(Notify部分)
+ * @param string $output テスト結果
+ * @access private
+ */
+ private function growlNotify($notify, $output)
+ {
+ @include_once 'Net/Growl.php';
+ if (!class_exists('Net_Growl', false)) {
+ return;
+ }
+
+ $appName = 'Maple4_DocTest';
+ $notifications = array('Green', 'Red');
+
+ $greenPriority = $notify->get('greePriority', 0);
+ $greenSticky = $notify->get('greeStickey', false);
+ $redPriority = $notify->get('redPriority', 2);
+ $redSticky = $notify->get('redSticky', false);
+
+ $status = 'Red';
+ $title = $notify->get('title', 'Test Results');
+ $description = 'No output';
+ $notifyOptions = array(
+ 'priority' => $redPriority,
+ 'sticky' => $redSticky,
+ );
+
+ $output = preg_replace('|\033\[[\d;]+m|', '', $output);
+
+ if (preg_match("|(OK \(\d+ test[s]{0,1}\))|m", $output, $matches)) {
+ $status = 'Green';
+ $description = $matches[1];
+ $notifyOptions = array(
+ 'priority' => $greenPriority,
+ 'sticky' => $greenSticky,
+ );
+ } else if (preg_match("|(OK, but incomplete or skipped tests!\s*\nTests: .+\.)|m", $output, $matches)) {
+ $status = 'Red';
+ $description = $matches[1];
+ $notifyOptions = array(
+ 'priority' => $redPriority,
+ 'sticky' => $redSticky,
+ );
+ } else if (preg_match("|(FAILURES!\s*\nTests: .+\.)|m", $output, $matches)) {
+ $status = 'Red';
+ $description = $matches[1];
+ $notifyOptions = array(
+ 'priority' => $redPriority,
+ 'sticky' => $redSticky,
+ );
+ }
+
+ set_error_handler(array($this, 'handler'));
+
+ $application = new Net_Growl_Application($appName, $notifications, $notify->password);
+ $growl = new Net_Growl($application);
+ $growl->notify($status, $title, $description, $notifyOptions);
+ }
+
+ /**
+ * Net_GrowlのStrict Errorだけを封じ込める
+ *
+ * 本当はこんなことしたくないのだが・・・
+ * しかしUnitTestは E_ALL | E_STRICT で実行されるべき
+ *
+ * @param integer $errno エラーレベル
+ * @param string $errstr エラーメッセージ
+ * @param string $errfile エラーが発生したファイル名
+ * @param string $errline エラーが発生した行数
+ * @access public
+ */
+ public function handler($errno, $errstr, $errfile, $errline)
+ {
+ if (($errno === E_STRICT) &&
+ preg_match('|Non-static method PEAR::getStaticProperty\(\) should not be called statically|', $errstr)) {
+ return true;
+ }
+
+ return false;
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Parser.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/Utils/Class.php');
+
+/**
+ * PHPファイルからDocTestコメントを抜き出す
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_Parser
+{
+ /**
+ * PHPファイルからDocTestコメントを抜き出す
+ *
+ * @param string $realpath 対象となるPHPファイル(フルパス)
+ * @param string $path 対象となるPHPファイル
+ * @return string 抜き出した文字列
+ * @access public
+ */
+ public function parse($realpath, $path)
+ {
+ $result = array();
+
+ if (!file_exists($realpath)) {
+ return $result;
+ }
+
+ include_once($realpath);
+
+ $classname = Maple4_Utils_Class::create()->toClassname($path);
+
+ $docComments = $this->getDocComments($classname);
+
+ foreach ($docComments as $methodname => $methodComment) {
+ $this->getTestData($result, $methodComment, $methodname);
+ }
+
+ return $result;
+ }
+
+ /**
+ * クラスおよびメソッドに対するDocコメントを取得
+ *
+ * 返却値はクラスおよび各メソッドに対するDocコメント
+ *
+ * @param string $classname クラス名
+ * @return array Docコメントの配列
+ * @access private
+ */
+ private function getDocComments($classname)
+ {
+ $refClass = new ReflectionClass($classname);
+
+ $result = array();
+
+ if ($comment = $refClass->getDocComment()) {
+ $result[''] = $this->removeCommentStr($comment);
+ }
+
+ // 親クラスのコメントは削除する
+ $method_comments = $this->getDocCommentsOfMethods($refClass);
+
+ while($refClass = $refClass->getParentClass()) {
+ $parent_comments = $this->getDocCommentsOfMethods($refClass);
+ foreach ($parent_comments as $method => $comment) {
+ if (isset($method_comments[$method]) &&
+ $method_comments[$method] == $comment) {
+ unset($method_comments[$method]);
+ }
+ }
+ }
+
+ $result = array_merge($result, $method_comments);
+
+ return $result;
+ }
+
+ /**
+ * 文字列からコメント文字列を除去
+ *
+ * 正規表現があまりいけてないような気がするので
+ * 後で直す・・・
+ *
+ * @param string $str 元の文字列
+ * @return string コメント文字列を除去した文字列
+ * @access private
+ */
+ private function removeCommentStr($str)
+ {
+ $str = preg_replace('|^\s*/\*\*|m', '', $str);
+ $str = preg_replace('|^\s*\*/|m', '', $str);
+ $str = preg_replace('|^\s*\*[ ]{1}|m', '', $str);
+ $str = preg_replace('|^\s*\*[ ]{0}|m', '', $str);
+
+ return trim($str);
+ }
+
+ /**
+ * メソッドのDocコメントを取得する
+ *
+ * @param object $refClass リフレクションクラスのインスタンス
+ * @return array メソッドに対するコメントの配列
+ * @access private
+ */
+ private function getDocCommentsOfMethods($refClass)
+ {
+ $result = array();
+ foreach ($refClass->getMethods() as $refMethod) {
+ if ($comment = $refMethod->getDocComment()) {
+ $result[$refMethod->getName()]
+ = $this->removeCommentStr($comment);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * 指定した文字列からテストに関する情報のみを抜き出す
+ *
+ * 第1引数で結果を組み立てていく
+ *
+ * @param array &$result テスト情報の配列
+ * @param string $str Docコメント文字列
+ * @param string $methodname メソッド名
+ * @access private
+ */
+ private function getTestData(&$result, $str, $methodname = null)
+ {
+ $methodname = strtolower($methodname);
+
+ if (preg_match_all('|(#test (.*?))?<code>(.*?)</code>|s', $str, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $userdefine = trim($match[2]);
+ if (($methodname === '') && ($userdefine === '')) {
+ throw new Maple4_Exception('missing testname');
+ break;
+ }
+
+ $testname = $this->createTestName($methodname, $userdefine);
+ $body = trim($match[3]);
+
+ if (preg_match('|#f\(|', $body)) {
+ if (!$methodname) {
+ throw new Maple4_Exception('missing testname');
+ break;
+ }
+
+ $body = preg_replace('|#f\(|', "\$this->obj->{$methodname}(", $body);
+ }
+
+ if (isset($result[$testname])) {
+ $result[$testname]['body'] .= "\n\n" . $body;
+ } else {
+ $result[$testname] = array(
+ 'method' => $methodname,
+ 'userdefine' => $userdefine,
+ 'body' => $body,
+ );
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * テスト名を生成する
+ *
+ * @param string $methodname テスト対象のメソッド
+ * @param string $userdefine ユーザが記述したテスト名
+ * @return string 生成されたテスト名
+ * @access private
+ */
+ private function createTestName($methodname, $userdefine)
+ {
+ $specialKeys = array('__noop', '__setup', '__teardown');
+ if (in_array(strtolower($userdefine), $specialKeys)) {
+ $testname = strtolower($userdefine);
+ } else {
+ $testname = $methodname;
+ if ($userdefine) {
+ $testname .= '_' . $userdefine;
+ }
+ }
+
+ return $testname;
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/PHPFinder.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/DocTest/Finder.php');
+
+/**
+ * PHPファイルをサーチしてリスト生成するクラス
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_PHPFinder
+{
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * 引数で指定されたディレクトリ(もしくはファイル)に対して
+ * ファイルリストを返却
+ *
+ * @param array $options DocTestの動作オプション
+ * @param string $pathname ディレクトリ名もしくはファイル
+ * @param string $basePathname 基準となるディレクトリ
+ * @return array ファイルリスト
+ * @access publicp
+ */
+ public function find($options, $pathname, $basePathname = null)
+ {
+ $regex = '|.+\.php$|';
+
+ $finder = new Maple4_DocTest_Finder();
+ return $finder->find($options, $regex, $pathname, $basePathname);
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Builder/specialMethod.tpl
@@ -0,0 +1,11 @@
+private $obj;
+
+public function setUp()
+{
+ $this->obj = new #class;
+}
+
+public function tearDown()
+{
+ $this->obj = null;
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Builder/class.tpl
@@ -0,0 +1,4 @@
+class Maple4_DocTest_%sTest extends PHPUnit_Framework_TestCase
+{
+%s
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Builder/file.tpl
@@ -0,0 +1,4 @@
+<?php
+require_once('%s');
+
+%s
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Builder/method.tpl
@@ -0,0 +1,4 @@
+ public function %s()
+ {
+%s
+ }
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Runner/ResultPrinter.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once 'PHPUnit/TextUI/ResultPrinter.php';
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * PHPUnit3の出力結果に色をつけるためのクラス
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_Runner_ResultPrinter extends PHPUnit_TextUI_ResultPrinter
+{
+ const LINE_WIDTH = 80;
+
+ const STYLE_BOLD = 1;
+ const FG_WHITE = 37;
+ const BG_RED = 41;
+ const BG_GREEN = 42;
+ const BG_MAGENTA = 45;
+
+ /**
+ * PHPUnitの出力部分にフックする
+ *
+ * @param array $defects
+ * @param integer $count
+ * @param string $type
+ */
+ protected function printDefects(array $defects, $count, $type)
+ {
+ if ($count == 0) {
+ return;
+ }
+
+ if (($type == 'error') || ($type == 'failure')) {
+ $bgColor = self::BG_RED;
+ } else {
+ $bgColor = self::BG_MAGENTA;
+ }
+
+ $str = sprintf(
+ "There %s %d %s%s:\n",
+
+ ($count == 1) ? 'was' : 'were',
+ $count,
+ $type,
+ ($count == 1) ? '' : 's'
+ );
+
+ $this->write($this->convert($bgColor, $str));
+
+ $i = 1;
+
+ foreach ($defects as $defect) {
+ $this->printDefect($defect, $i++);
+ }
+ }
+
+ /**
+ * PHPUnitの出力部分にフックする
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printFooter(PHPUnit_Framework_TestResult $result)
+ {
+ if ($result->wasSuccessful() &&
+ $result->allCompletlyImplemented() &&
+ $result->noneSkipped()) {
+ $str = sprintf(
+ "OK (%d test%s)\n",
+
+ count($result),
+ (count($result) == 1) ? '' : 's'
+ );
+
+ $this->write($this->convert(self::BG_GREEN, $str));
+ } else if ((!$result->allCompletlyImplemented() ||
+ !$result->noneSkipped()) &&
+ $result->wasSuccessful()) {
+ $str = sprintf(
+ "OK, but incomplete or skipped tests!\n" .
+ "Tests: %d%s%s.\n",
+
+ count($result),
+ $this->getCountString($result->notImplementedCount(), 'Incomplete'),
+ $this->getCountString($result->skippedCount(), 'Skipped')
+ );
+
+ $this->write("\n" . $this->convert(self::BG_MAGENTA, $str));
+ } else {
+ $str = sprintf(
+ "FAILURES!\n" .
+ "Tests: %d%s%s%s%s.\n",
+
+ count($result),
+ $this->getCountString($result->failureCount(), 'Failures'),
+ $this->getCountString($result->errorCount(), 'Errors'),
+ $this->getCountString($result->notImplementedCount(), 'Incomplete'),
+ $this->getCountString($result->skippedCount(), 'Skipped')
+ );
+
+ $this->write("\n" . $this->convert(self::BG_RED, $str));
+ }
+ }
+
+ /**
+ * 指定された色コードに対するエスケープシーケンスを発行
+ *
+ * @param integer $code 色コード
+ * @param string $str 表示文字列
+ * @return string 装飾済みの文字列
+ * @access private
+ */
+ private function convert($code, $str)
+ {
+ $lines = preg_split("|\n|", rtrim($str));
+
+ $result = null;
+
+ foreach ($lines as $line) {
+ if (strlen($line) < self::LINE_WIDTH) {
+ $line = $line . str_repeat(' ', self::LINE_WIDTH - strlen($line));
+ }
+
+ $codes = array();
+ $codes[] = self::STYLE_BOLD;
+ $codes[] = self::FG_WHITE;
+ $codes[] = $code;
+
+ $result .= sprintf("\033[%sm%s\033[0m\n", implode(';', $codes), $line);
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/TestCaseFinder.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/DocTest/Finder.php');
+
+/**
+ * テストケースファイルをサーチしてリスト生成するクラス
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_TestCaseFinder
+{
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * 引数で指定されたディレクトリ(もしくはファイル)に対して
+ * ファイルリストを返却
+ *
+ * @param array $options DocTestの動作オプション
+ * @param string $pathname ディレクトリ名もしくはファイル
+ * @param string $basePathname 基準となるディレクトリ
+ * @return array ファイルリスト
+ * @access public
+ */
+ public function find($options, $pathname, $basePathname = null)
+ {
+ $regex = '|.+Test\.php$|';
+
+ $finder = new Maple4_DocTest_Finder();
+ return $finder->find($options, $regex, $pathname, $basePathname);
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Builder.php
@@ -0,0 +1,313 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/Utils/Class.php');
+require_once(dirname(dirname(__FILE__)) . '/Utils/File.php');
+
+/**
+ * DocTestコメントから生成された文字列からテストケースを生成する
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_Builder
+{
+ /**
+ * @var object Maple4_Utils_Fileのインスタンス
+ * @access private
+ */
+ private $fileUtils = null;
+
+ /**
+ * @static string インデントで使用する空白の数
+ * @access private
+ */
+ static private $indentWidth = 4;
+
+ /**
+ * コンストラクタ
+ */
+ public function __construct()
+ {
+ $this->fileUtils = new Maple4_Utils_File();
+ }
+
+ /**
+ * DocTestコメントから抜き出された文字列からテストケースを生成
+ *
+ * @param string $realpath 対象となるPHPファイル(フルパス)
+ * @param string $path 対象となるPHPファイル
+ * @param array $comments DocTestコメントから抜き出された
+ * 文字列の配列
+ * @return string 生成したテストケース
+ * @access public
+ */
+ public function build($realpath, $path, $comments)
+ {
+ if (is_null($realpath) || is_null($path) ||
+ !is_array($comments)) {
+ return null;
+ }
+
+ $definition = $this->createTestClassDefinition($realpath, $path, $comments);
+ if (is_null($definition)) {
+ return null;
+ }
+
+ $template = $this->getFileTemplate();
+ return rtrim(sprintf($template, $realpath, rtrim($definition)));
+ }
+
+ /**
+ * テストで使用するクラス定義を生成する
+ *
+ * @param string $realpath 対象となるPHPファイル(フルパス)
+ * @param string $path 対象となるPHPファイル
+ * @param array $comments DocTestコメントから抜き出された
+ * 文字列の配列
+ * @return string 生成されたクラス定義
+ * @access private
+ */
+ private function createTestClassDefinition($realpath, $path, $comments)
+ {
+ $definition = null;
+ $existsSetUp = false;
+ $existsTearDown = false;
+
+ foreach ($comments as $testname => $commentData) {
+ $body = $commentData['body'];
+ $method = $commentData['method'];
+
+ if ($testname === '__noop') {
+ $definition .= $this->concatIndent($body, self::$indentWidth) . "\n\n";
+ } else {
+ $definition .= $this->createMethodDefinition($testname, $commentData);
+ }
+
+ if ($testname === '__setup') {
+ $existsSetUp = true;
+ } else if ($testname === '__teardown') {
+ $existsTearDown = true;
+ }
+ }
+
+ if (is_null($definition)) {
+ return null;
+ }
+
+ if (!$existsSetUp && !$existsTearDown) {
+ $body = $this->getSpecialMethodTemplate();
+ $definition = $this->concatIndent($body, self::$indentWidth) . "\n\n" . $definition;
+ }
+
+ $replaceStrings = $this->getReplaceStrings();
+
+ $classname = Maple4_Utils_Class::create()->toClassname($path);
+ $replaceStrings['class'] = "{$classname}()";
+
+ foreach ($replaceStrings as $from => $to) {
+ $definition = preg_replace("|#{$from}|", $to, $definition);
+ }
+
+ $template = $this->getClassTemplate();
+ return rtrim(sprintf($template, $classname, rtrim($definition)));
+ }
+
+ /**
+ * 文字列の各行の先頭にインデントを挿入
+ *
+ * 文字列の各行に引数で指定された数だけのインデントを挿入
+ *
+ * @param string $str 元の文字列
+ * @param integer $indent インデントの数
+ * @return string インデント挿入後の文字列
+ * @access private
+ */
+ private function concatIndent($str, $indent = null)
+ {
+ if ($indent === null) {
+ $indent = self::$indentWidth * 2;
+ }
+
+ $lines = preg_split("|\n|", $str);
+ $lines = array_map('rtrim', $lines);
+
+ $hereDocumentString = null;
+ $quoteString = null;
+
+ foreach ($lines as $key => $line) {
+ if ($hereDocumentString || $quoteString) {
+ $lines[$key] = rtrim($line);
+
+ if ($hereDocumentString &&
+ preg_match("|^{$hereDocumentString}[;,]*|", $line)) {
+ $hereDocumentString = null;
+ }
+
+ if ((($quoteString == "'") &&
+ preg_match('/(^\'|[^\\\\]?\')/', $line)) ||
+ (($quoteString == '"') &&
+ preg_match('/(^"|[^\\\\]?")/', $line))) {
+ $quoteString = null;
+ }
+ } else {
+ $lines[$key] = rtrim(str_repeat(chr(32), $indent) . $line);
+
+ if (preg_match('|<<<(.+)|', $line, $matches)) {
+ $hereDocumentString = $matches[1];
+ } else if (preg_match_all('/(^\'|[^\\\\]?\')/', $line, $matches, PREG_SET_ORDER) &&
+ (count($matches) == 1)) {
+ $quoteString = "'";
+ } else if (preg_match_all('/(^"|[^\\\\]?")/', $line, $matches, PREG_SET_ORDER) &&
+ (count($matches) == 1)) {
+ $quoteString = '"';
+ }
+ }
+ }
+
+ return rtrim(join("\n", $lines));
+ }
+
+ /**
+ * 文字列からメソッドを生成する
+ *
+ * @param string $testname テスト名
+ * @param array $commentData コメント情報
+ * @return string メソッド定義
+ * @access private
+ */
+ private function createMethodDefinition($testname, $commentData)
+ {
+ $specialKeys = array(
+ '__setup' => 'setUp',
+ '__teardown' => 'tearDown',
+ );
+
+ $methodname = $commentData['method'];
+ $userdefine = $commentData['userdefine'];
+ $header = ($userdefine) ? ($userdefine) : $methodname;
+ $body = sprintf("// %s\n%s", $header, $commentData['body']);
+
+ if (in_array(strtolower($userdefine), array_keys($specialKeys))) {
+ $methodname = $specialKeys[strtolower($userdefine)];
+ } else {
+ $methodname = sprintf('test%s', ucfirst($testname));
+ }
+
+ $body = $this->concatIndent($body, self::$indentWidth * 2);
+
+ $template = $this->getMethodTemplate();
+ return rtrim(sprintf($template, $methodname, $body)) ."\n\n";
+ }
+
+ /**
+ * メソッドのテンプレートを返却
+ *
+ * @return string メソッドのテンプレート
+ * @access private
+ */
+ private function getMethodTemplate()
+ {
+ $filename = dirname(__FILE__) . '/Builder/method.tpl';
+ return $this->fileUtils->read($filename);
+ }
+
+ /**
+ * スペシャルメソッド(setUp/TearDown)のテンプレートを返却
+ *
+ * @return string スペシャルメソッドのテンプレート
+ * @access private
+ */
+ private function getSpecialMethodTemplate()
+ {
+ $filename = dirname(__FILE__) . '/Builder/specialMethod.tpl';
+ return $this->fileUtils->read($filename);
+ }
+
+ /**
+ * クラスのテンプレートを返却
+ *
+ * @return string クラスのテンプレート
+ * @access public
+ */
+ public function getClassTemplate()
+ {
+ $filename = dirname(__FILE__) . '/Builder/class.tpl';
+ return $this->fileUtils->read($filename);
+ }
+
+ /**
+ * テストケースファイルのテンプレートを返却
+ *
+ * @return string テストケースクラスのテンプレート
+ * @access public
+ */
+ public function getFileTemplate()
+ {
+ $filename = dirname(__FILE__) . '/Builder/file.tpl';
+ return $this->fileUtils->read($filename);
+ }
+
+ /**
+ * メソッドの省略可能文字列を返却
+ *
+ * @return string 省略文字列の配列
+ * @access public
+ */
+ public function getReplaceStrings()
+ {
+ return array(
+ 'eq\(' => '$this->assertEquals(',
+ 'ne\(' => '$this->assertNotEquals(',
+ 'true\(' => '$this->assertTrue(',
+ 'false\(' => '$this->assertFalse(',
+ 'null\(' => '$this->assertNull(',
+ 'notnull\(' => '$this->assertNotNull(',
+ );
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/Finder.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/Utils/File.php');
+
+/**
+ * PHPファイルをサーチしてリスト生成するクラス
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_Finder
+{
+ /**
+ * 引数で指定されたディレクトリ(もしくはファイル)に対して
+ * ファイルリストを返却
+ *
+ * @param array $options DocTestの動作オプション
+ * @param string $regex ファイルリストに含めたい正規表現パターン
+ * @param string $pathname ディレクトリ名もしくはファイル
+ * @param string $basePathname 基準となるディレクトリ
+ * @return array ファイルリスト
+ * @access public
+ */
+ public function find($options, $regex, $pathname, $basePathname = null)
+ {
+ $fileUtils = new Maple4_Utils_File();
+
+ if (isset($options['ignore'])) {
+ $fileUtils->setIgnore($options['ignore']);
+ }
+
+ $pathname = $fileUtils->fixDirectorySeparator($pathname);
+
+ $files = array();
+
+ if (is_dir($pathname)) {
+ $files = $fileUtils->findRecursive($pathname, $regex);
+ } else if (file_exists($pathname) &&
+ preg_match($regex, $pathname)) {
+ $files = array($fileUtils->fixDirectorySeparator($pathname));
+ }
+
+ $result = array();
+
+ if (!is_array($files) || (count($files) < 1)) {
+ return $result;
+ }
+
+ if (is_null($basePathname)) {
+ $basePathname = $fileUtils->searchBasePathname($pathname);
+ } else {
+ $basePathname = $fileUtils->fixDirectorySeparator($basePathname);
+ }
+
+ foreach ($files as $filename) {
+ $path = str_replace($basePathname, '', $filename);
+ $result[$filename] = $fileUtils->removeHeadSlash($path);
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest/UpdateChecker.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.2.0
+ */
+
+require_once(dirname(dirname(__FILE__)) . '/Utils/File.php');
+
+/**
+ * ファイルの更新状況をチェックする
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.2.0
+ */
+class Maple4_DocTest_UpdateChecker
+{
+ /**
+ * @var object Maple4_Utils_Fileのインスタンス
+ * @access private
+ */
+ private $fileUtils = null;
+
+ /**
+ * コンストラクタ
+ */
+ public function __construct()
+ {
+ $this->fileUtils = new Maple4_Utils_File();
+ }
+
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * 引数で指定されたファイルリストに対して、更新状況をチェックする
+ *
+ * @param array $options DocTestの動作オプション
+ * @param string $pathname ディレクトリ名もしくはファイル
+ * @param array $files ファイルリスト
+ * @return array 更新状況
+ * @access public
+ */
+ public function check($options, $pathname, $files)
+ {
+ $result = array(
+ 'delete' => array(),
+ 'new' => array(),
+ 'update' => array(),
+ );
+
+ $options = new Maple4_Utils_Array($options);
+ $compileDir = $options->compileDir;
+ if (is_null($compileDir)) {
+ return $result;
+ }
+
+ $forceCompile = $options->forceCompile;
+ if (is_null($forceCompile)) {
+ $forceCompile = false;
+ }
+
+ $filename = $this->makeStatusFilename($compileDir, $pathname);
+
+ $lines = array();
+ if ($forceCompile === true) {
+ $this->fileUtils->unlink($filename);
+ } else if (file_exists($filename)) {
+ $buf = $this->fileUtils->read($filename);
+ if (!is_null($buf)) {
+ $lines = preg_split('|\n|', trim($buf));
+ }
+ }
+
+ if (!is_array($lines)) {
+ $lines = array();
+ }
+
+ $basePathname = $this->fileUtils->addTailSlash($this->fileUtils->searchBasePathname($pathname));
+
+ $checkList = array();
+ foreach ($lines as $line) {
+ if (strlen(trim($line)) < 1) {
+ continue;
+ }
+
+ list ($realpath, $mtime) = preg_split('|\t|', trim($line));
+ $checkList[$realpath] = $realpath;
+ $path = str_replace($basePathname, '', $realpath);
+
+ if (!isset($files[$realpath])) {
+ $result['delete'][$realpath] = $path;
+ } else if (filemtime($realpath) > $mtime) {
+ $result['update'][$realpath] = $path;
+ }
+ }
+
+ $saveLines = null;
+ foreach ($files as $realpath => $path) {
+ if (!isset($checkList[$realpath])) {
+ $result['new'][$realpath] = $path;
+ }
+
+ $saveLines .= sprintf("%s\t%s\n", $realpath, filemtime($realpath));
+ }
+
+ $this->fileUtils->write($filename, $saveLines);
+
+ return $result;
+ }
+
+ /**
+ * 更新状況を保存しているファイル名の生成
+ *
+ * @param string $compileDir コンパイルディレクトリ
+ * @param string $pathname チェックしたいディレクトリ
+ * もしくはファイル名
+ * @return string ファイル名
+ * @access private
+ */
+ private function makeStatusFilename($compileDir, $pathname)
+ {
+ return sprintf("%s/%s.txt", $this->fileUtils->removeTailSlash($compileDir), sha1($pathname));
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/Maple4/DocTest.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * PHP versions 5
+ *
+ * Copyright (c) 2008 Maple Project, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @since File available since Release 0.1.0
+ */
+
+require_once('PHPUnit/Framework.php');
+require_once('PHPUnit/TextUI/TestRunner.php');
+require_once(dirname(__FILE__) . '/Utils/File.php');
+require_once(dirname(__FILE__) . '/Utils/Class.php');
+require_once(dirname(__FILE__) . '/Utils/Array.php');
+require_once(dirname(__FILE__) . '/DocTest/PHPFinder.php');
+require_once(dirname(__FILE__) . '/DocTest/UpdateChecker.php');
+require_once(dirname(__FILE__) . '/DocTest/Parser.php');
+require_once(dirname(__FILE__) . '/DocTest/Builder.php');
+require_once(dirname(__FILE__) . '/DocTest/TestCaseFinder.php');
+require_once(dirname(__FILE__) . '/DocTest/Runner.php');
+
+/**
+ * 指定されたディレクトリにあるPHPファイルに対するテストを実行
+ *
+ * @category Testing
+ * @package Maple4_DocTest
+ * @author TAKAHASHI Kunihiko <kunit@maple-project.com>
+ * @copyright 2008 Maple Project
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @since Class available since Release 0.1.0
+ */
+class Maple4_DocTest
+{
+ /**
+ * @var object Maple4_Utils_Fileのインスタンス
+ * @access private
+ */
+ private $fileUtils;
+
+ /**
+ * @var object Maple4_Utils_Classのインスタンス
+ * @access private
+ */
+ private $classUtils;
+
+ /**
+ * コンストラクタ
+ */
+ public function __construct()
+ {
+ $this->fileUtils = new Maple4_Utils_File();
+ $this->classUtils = new Maple4_Utils_Class();
+ }
+
+ /**
+ * fluent interface(流れるようなインタフェースで使用するための
+ * スタティックコンストラクタ
+ *
+ * @return object このオブジェクト自身
+ */
+ static public function create()
+ {
+ return new self();
+ }
+
+ /**
+ * 指定されたディレクトリにあるPHPファイルに対するテストを実行
+ *
+ * @param string $pathname テスト対象となるディレクトリ
+ * @param array $options テストで使用するオプション
+ * @return string 実行結果
+ * @access public
+ */
+ public function run($pathname, $options)
+ {
+ if (!isset($options['compileDir'])) {
+ throw new Maple4_Exception('compileDir not set');
+ }
+
+ $phpFiles = Maple4_DocTest_PHPFinder::create()->find($options, $pathname);
+ $updateFiles = Maple4_DocTest_UpdateChecker::create()->check($options, $pathname, $phpFiles);
+ $this->updateTestCases($options, $updateFiles);
+
+ if ($this->isUpdated($options, $updateFiles)) {
+ $testcases = $this->findTestCases($options, $pathname, $phpFiles);
+ } else {
+ $testcases = array();
+ }
+
+ if (count($testcases) > 0) {
+ Maple4_DocTest_Runner::create()->run($options, $pathname, $testcases);
+ }
+ }
+
+ /**
+ * テストケースファイルの更新を行う
+ *
+ * @param array $options テストで使用するオプション
+ * @param array $updateFiles 更新ファイルリスト
+ * @access private
+ */
+ private function updateTestcases($options, $updateFiles)
+ {
+ $compileDir = $options['compileDir'];
+ $this->fileUtils->makeDir($compileDir);
+
+ if (isset($updateFiles['delete']) &&
+ (count($updateFiles['delete'] > 0))) {
+ foreach ($updateFiles['delete'] as $realpath => $path) {
+ $filename = $this->toTestCase($options, $path);
+ $this->fileUtils->unlink($filename);
+ }
+ }
+
+ $parser = new Maple4_DocTest_Parser();
+ $builder = new Maple4_DocTest_Builder();
+
+ foreach (array('new', 'update') as $key) {
+ if (!isset($updateFiles[$key])) {
+ continue;
+ }
+
+ foreach ($updateFiles[$key] as $realpath => $path) {
+ $comments = $parser->parse($realpath, $path);
+ $data = $builder->build($realpath, $path, $comments);
+ if (is_null($data)) {
+ continue;
+ }
+
+ $filename = $this->toTestCase($options, $path);
+ $this->fileUtils->write($filename, $data);
+ }
+ }
+ }
+
+ /**
+ * テストケースのファイルリストを取得する
+ *
+ * @param array $options テストで使用するオプション
+ * @param string $pathname PHPファイル名
+ * @param array $files PHPFinderが検索したファイルリスト
+ * @return array テストケースのファイルリスト
+ * @access private
+ */
+ private function findTestCases($options, $pathname, $files)
+ {
+ // ファイル単体で指定された場合のための対策
+ // 余計なファイル探索が走らないように
+ if (preg_match('|\.php$|', $pathname)) {
+ $testcases = Maple4_DocTest_TestCaseFinder::create()->find($options, $this->convertTestCase($options, $pathname, $files));
+ } else {
+ $list = Maple4_DocTest_TestCaseFinder::create()->find($options, $options['compileDir']);
+
+ $pickup = array();
+ foreach ($files as $realpath => $path) {
+ $filename = $this->toTestCase($options, $path);
+ if (isset($list[$filename])) {
+ $pickup[$filename] = $list[$filename];
+ }
+ }
+
+ $testcases = $pickup;
+ }
+
+ return $testcases;
+ }
+
+ /**
+ * 指定されたPHPファイルからテストケースファイル名を生成する
+ *
+ * @param array $options テストで使用するオプション
+ * @param string $pathname PHPファイル名
+ * @param array $files PHPFinderが検索したファイルリスト
+ * @return string テストケースのファイル名
+ * @access private
+ */
+ private function convertTestCase($options, $pathname, $files)
+ {
+ $pathname = $this->fileUtils->fixDirectorySeparator($pathname);
+
+ $result = null;
+ foreach ($files as $realpath => $path) {
+ $realpath = $this->fileUtils->fixDirectorySeparator($realpath);
+ if ($pathname === $realpath) {
+ $result = $this->toTestCase($options, $path);
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * PHPファイル名からテストケースファイル名を生成する
+ *
+ * @param array $options テストで使用するオプション
+ * @param string $pathname PHPファイル名
+ * @return string テストケースのファイル名
+ * @access private
+ */
+ private function toTestCase($options, $pathname)
+ {
+ $compileDir = $options['compileDir'];
+ $classname = $this->classUtils->toClassname($pathname);
+ $filename = "{$compileDir}/Maple4_DocTest_{$classname}Test.php";
+
+ return $this->fileUtils->fixDirectorySeparator($filename);
+ }
+
+ /**
+ * 更新されたファイルがあるか?
+ *
+ * @param array $options テストで使用するオプション
+ * @param array $files UpdateCheckerが生成したファイルリスト
+ * @return boolean 更新されたファイルがあるか?
+ * @access private
+ */
+ private function isUpdated($options, $files)
+ {
+ if (!isset($options['forceRun']) || $options['forceRun']) {
+ return true;
+ }
+
+ $files = new Maple4_Utils_Array($files);
+
+ if (!is_array($files->new) ||
+ !is_array($files->update) ||
+ !is_array($files->delete)) {
+ return false;
+ }
+
+ return ((count($files->new) > 0) ||
+ (count($files->update) > 0) ||
+ (count($files->delete) > 0));
+ }
+}
Maple4_DocTest/tags/0.2.0-alpha/package.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.7.2" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Maple4_DocTest</name>
+ <channel>__uri</channel>
+ <summary>TDD/BDD Tool for PHPUnit3</summary>
+ <description>TDD/BDD Tool for PHPUnit3</description>
+ <lead>
+ <name>TAKAHASHI Kunihiko</name>
+ <user>kunit</user>
+ <email>kunit@maple-project.com</email>
+ <active>yes</active>
+ </lead>
+ <date>2008-08-20</date>
+ <time>20:56:28</time>
+ <version>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD License</license>
+ <notes>TDD/BDD Tool for PHPUnit3</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <dir name="Maple4">
+ <dir name="DocTest">
+ <dir name="Builder">
+ <file name="class.tpl" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="file.tpl" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="method.tpl" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="specialMethod.tpl" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- //Maple4/DocTest/Builder -->
+ <dir name="Runner">
+ <file name="ResultPrinter.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- //Maple4/DocTest/Runner -->
+ <file name="Builder.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="Finder.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="Parser.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="PHPFinder.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="Runner.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="TestCaseFinder.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="UpdateChecker.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- //Maple4/DocTest -->
+ <dir name="Utils">
+ <file name="Array.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="Class.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="File.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- //Maple4/Utils -->
+ <file name="DocTest.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ <file name="Exception.php" role="php">
+ <tasks:replace from="@package_version@" to="version" type="package-info" />
+ </file>
+ </dir> <!-- //Maple4 -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.1.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.4.3</min>
+ </pearinstaller>
+ <package>
+ <name>PEAR</name>
+ <channel>pear.php.net</channel>
+ <min>1.4.3</min>
+ </package>
+ <package>
+ <name>PHPUnit</name>
+ <channel>pear.phpunit.de</channel>
+ <min>3.2.21</min>
+ </package>
+ </required>
+ <optional>
+ <package>
+ <name>Net_Growl</name>
+ <channel>pear.php.net</channel>
+ <min>0.7.0</min>
+ </package>
+ </optional>
+ </dependencies>
+ <phprelease />
+ <changelog>
+ <release>
+ <version>
+ <release>0.2.0</release>
+ <api>0.2.0</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2008-08-20</date>
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD License</license>
+ <notes>TDD/BDD Tool for PHPUnit3</notes>
+ </release>
+ </changelog>
+</package>