diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100755 index 0000000..648d1e4 --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,48 @@ +------------------------------------------------------------------------------- + + Sabel 1.2 Beta2 - Rapid Web Application Development Framework + + The New BSD License + + Copyright (c) 2004-2009 + Mori Reo All rights reserved. + +------------------------------------------------------------------------------- + + Authors: + + Mori Reo + Ebine Yutaka + Hamanaka Kazuhiro + Hosokawa Yasuko + +------------------------------------------------------------------------------- + + 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. + + 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. + +------------------------------------------------------------------------------- + + For more information on the Sabel project, + please see + +------------------------------------------------------------------------------- diff --git a/Sabel.php b/Sabel.php new file mode 100755 index 0000000..71e66bd --- /dev/null +++ b/Sabel.php @@ -0,0 +1,204 @@ + + * @author Ebine Yutaka + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +final class Sabel +{ + /** + * @var array + */ + private static $readableFiles = array(); + + /** + * @var int + */ + private static $readableFilesNum = 0; + + /** + * @var array + */ + private static $required = array(); + + /** + * @var array + */ + private static $fileUsing = array(); + + public static function getPath() + { + return dirname(__FILE__); + } + + public static function using($className) + { + if (class_exists($className, false)) { + return true; + } else { + return self::autoload($className); + } + } + + public static function autoload($className) + { + if (isset(self::$required[$className])) return true; + + if (isset(self::$readableFiles[$className])) { + require (self::$readableFiles[$className]); + self::$required[$className] = 1; + return true; + } elseif ($path = self::getFilePath($className)) { + require ($path); + + self::$required[$className] = 1; + self::$readableFiles[$className] = $path; + return true; + } else { + return false; + } + } + + public static function fileUsing($path, $once = false) + { + if ($once && isset(self::$fileUsing[$path])) return true; + + if (isset(self::$readableFiles[$path])) { + $readable = true; + } elseif (is_readable($path)) { + $readable = true; + self::$readableFiles[$path] = $path; + } else { + $readable = false; + } + + if ($readable) { + ($once) ? require_once ($path) : require ($path); + self::$fileUsing[$path] = 1; + return true; + } + + return false; + } + + private static function getFilePath($className) + { + static $includePath = null; + static $paths = null; + + $exp = explode("_", $className); + + if (count($exp) === 1) { + $path = $exp[0] . ".php"; + } else { + $class = array_pop($exp); + $prePath = implode("/", array_map("lcfirst", $exp)); + $path = $prePath . DIRECTORY_SEPARATOR . $class . ".php"; + } + + if ($includePath === null) { + $includePath = get_include_path(); + } elseif (($incPath = get_include_path()) !== $includePath) { + $includePath = $incPath; + $paths = null; + } + + if ($paths === null) { + $paths = explode(PATH_SEPARATOR, $includePath); + } + + foreach ($paths as $p) { + $fullPath = $p . DIRECTORY_SEPARATOR . $path; + if (is_readable($fullPath)) return $fullPath; + } + + return false; + } + + public static function main() + { + $SABEL = "sabel" . DIRECTORY_SEPARATOR; + + require ($SABEL . "Object.php"); + require ($SABEL . "Logger.php"); + require ($SABEL . "Bus.php"); + require ($SABEL . "Config.php"); + require ($SABEL . "Context.php"); + require ($SABEL . "Request.php"); + require ($SABEL . "Session.php"); + require ($SABEL . "Response.php"); + require ($SABEL . "View.php"); + + require ($SABEL . "functions" . DIRECTORY_SEPARATOR . "core.php"); + require ($SABEL . "functions" . DIRECTORY_SEPARATOR . "db.php"); + + $BUS = $SABEL . "bus" . DIRECTORY_SEPARATOR; + $MAP = $SABEL . "map" . DIRECTORY_SEPARATOR; + $CTRL = $SABEL . "controller" . DIRECTORY_SEPARATOR; + $RESP = $SABEL . "response" . DIRECTORY_SEPARATOR; + $SESSION = $SABEL . "session" . DIRECTORY_SEPARATOR; + $VIEW = $SABEL . "view" . DIRECTORY_SEPARATOR; + $UTIL = $SABEL . "util" . DIRECTORY_SEPARATOR; + + require ($BUS . "Config.php"); + require ($BUS . "Processor.php"); + + require ($MAP . "Configurator.php"); + require ($MAP . "Candidate.php"); + require ($MAP . "Destination.php"); + require ($MAP . "config" . DIRECTORY_SEPARATOR . "Route.php"); + + require ($RESP . "Object.php"); + require ($RESP . "Status.php"); + require ($RESP . "Redirector.php"); + require ($RESP . "Header.php"); + + require ($SESSION . "Abstract.php"); + require ($SESSION . "PHP.php"); + + require ($VIEW . "Renderer.php"); + require ($VIEW . "Object.php"); + require ($VIEW . "Location.php"); + require ($VIEW . "location" . DIRECTORY_SEPARATOR . "File.php"); + + require ($UTIL . "HashList.php"); + require ($UTIL . "VariableCache.php"); + + require ($SABEL . "request" . DIRECTORY_SEPARATOR . "Object.php"); + require ($SABEL . "controller" . DIRECTORY_SEPARATOR . "Page.php"); + require ($SABEL . "exception" . DIRECTORY_SEPARATOR . "Runtime.php"); + require ($SABEL . "logger" . DIRECTORY_SEPARATOR . "Interface.php"); + } + + public static function init() + { + $path = "sabel" . DIRECTORY_SEPARATOR . "Sabel"; + $cache = Sabel_Util_VariableCache::create($path); + + if ($files = $cache->read("readableFiles")) { + self::$readableFiles = $files; + self::$readableFilesNum = count($files); + } + } + + public static function shutdown() + { + if (self::$readableFilesNum !== count(self::$readableFiles)) { + $path = "sabel" . DIRECTORY_SEPARATOR . "Sabel"; + $cache = Sabel_Util_VariableCache::create($path); + $cache->write("readableFiles", self::$readableFiles); + $cache->save(); + } + } +} + +/* register autoload method */ +spl_autoload_register(array("Sabel", "autoload")); + +Sabel::main(); diff --git a/SabelAllTests.php b/SabelAllTests.php new file mode 100755 index 0000000..fdd6cae --- /dev/null +++ b/SabelAllTests.php @@ -0,0 +1,139 @@ +addTest(Test_DB_Statement_Tests::suite()); + $suite->addTest(Test_DB_Storage_Tests::suite()); + $suite->addTest(Test_DB_Tests::suite()); + return $suite; + } + + $suite->addTest(Test_Object::suite()); + $suite->addTest(Test_ValueObject::suite()); + $suite->addTest(Test_Console::suite()); + $suite->addTest(Test_Bus_Tests::suite()); + $suite->addTest(Test_Map_Tests::suite()); + $suite->addTest(Test_Request_Tests::suite()); + $suite->addTest(Test_Response_Tests::suite()); + $suite->addTest(Test_Controller_Tests::suite()); + $suite->addTest(Test_Util_Tests::suite()); + $suite->addTest(Test_View_Tests::suite()); + $suite->addTest(Test_Cache_Tests::suite()); + $suite->addTest(Test_Session_Tests::suite()); + $suite->addTest(Test_Processor_Tests::suite()); + + $suite->addTest(Test_Annotation::suite()); + $suite->addTest(Test_Reflection::suite()); + $suite->addTest(Test_Container::suite()); + //$suite->addTest(Test_Aspect_Tests::suite()); + $suite->addTest(Test_Exception::suite()); + + $suite->addTest(Test_I18n_Gettext::suite()); + $suite->addTest(Test_Cookie_Tests::suite()); + $suite->addTest(Test_Mail_Tests::suite()); + $suite->addTest(Test_XML_Tests::suite()); + + $suite->addTest(Test_Application::suite()); + + return $suite; + } +} diff --git a/Test/Annotation.php b/Test/Annotation.php new file mode 100755 index 0000000..86342d5 --- /dev/null +++ b/Test/Annotation.php @@ -0,0 +1,116 @@ + + */ +class Test_Annotation extends SabelTestCase +{ + private $reader = null; + + public static function suite() + { + return self::createSuite("Test_Annotation"); + } + + public function setUp() + { + $this->reader = Sabel_Annotation_Reader::create(); + } + + public function testClassAnnotation() + { + $annotations = $this->reader->readClassAnnotation("TestAnnotation"); + $this->assertEquals("class", $annotations["annotation"][0][0]); + } + + public function testBasic() + { + $annotation = $this->reader->readMethodAnnotation("TestAnnotation", "testMethod"); + $this->assertEquals("value", $annotation["param"][0][0]); + } + + public function testMultipleValue() + { + $annotation = $this->reader->readMethodAnnotation("TestAnnotation", "testMethod"); + $this->assertEquals("hoge", $annotation["array"][0][0]); + $this->assertEquals("fuga", $annotation["array"][0][1]); + } + + public function testIgnoreSpace() + { + $annotation = $this->reader->readMethodAnnotation("TestAnnotation", "testMethod2"); + $this->assertEquals("value", $annotation["ignoreSpace"][0][0]); + } + + public function testQuotedValue() + { + $annotation = $this->reader->readMethodAnnotation("TestAnnotation", "testMethod2"); + + $this->assertEquals("hoge", $annotation["array"][0][0]); + $this->assertEquals(' test"a" ', $annotation["array"][0][1]); + $this->assertEquals("a: index", $annotation["array"][0][2]); + $this->assertEquals("fuga", $annotation["array"][1][0]); + $this->assertEquals(" test'a' ", $annotation["array"][1][1]); + $this->assertEquals("c: index, a: index", $annotation["array"][1][2]); + } + + public function testEmptyValue() + { + $annotation = $this->reader->readMethodAnnotation("TestAnnotation", "testMethod3"); + $this->assertTrue(isset($annotation["emptyValue"])); + $this->assertNull($annotation["emptyValue"][0]); + } + + public function testPropertyAnnotation() + { + $annotations = $this->reader->readPropertyAnnotation("TestAnnotation", "var"); + $this->assertEquals("int", $annotations["var"][0][0]); + } +} + +/** + * class annotation + * + * @annotation class + */ +class TestAnnotation +{ + /** + * @var int + */ + protected $var = 10; + + /** + * this is annotation test + * + * @param value + * @array hoge fuga + */ + public function testMethod($test, $test = null) + { + + } + + /** + * this is annotation test + * + * @ignoreSpace value + * @array hoge ' test"a" ' "a: index" + * @array fuga " test'a' " 'c: index, a: index' + */ + public function testMethod2() + { + + } + + /** + * @emptyValue + */ + public function testMethod3() + { + + } +} diff --git a/Test/Application.php b/Test/Application.php new file mode 100755 index 0000000..b273050 --- /dev/null +++ b/Test/Application.php @@ -0,0 +1,230 @@ + + */ +class Test_Application extends SabelTestCase +{ + private static $setup = false; + + public static function suite() + { + return self::createSuite("Test_Application"); + } + + public function setUp() + { + if (self::$setup) return; + + $dir = TEST_APP_DIR . DS . LIB_DIR_NAME . DS . "processor" . DS; + + Sabel::fileUsing($dir . "Addon.php", true); + Sabel::fileUsing($dir . "Session.php", true); + Sabel::fileUsing($dir . "Executer.php", true); + Sabel::fileUsing($dir . "Helper.php", true); + Sabel::fileUsing($dir . "Initializer.php", true); + Sabel::fileUsing($dir . "Controller.php", true); + Sabel::fileUsing($dir . "Response.php", true); + Sabel::fileUsing($dir . "Request.php", true); + Sabel::fileUsing($dir . "Router.php", true); + Sabel::fileUsing($dir . "View.php", true); + + unshift_include_paths(array(MODULES_DIR_NAME, + LIB_DIR_NAME, + MODULES_DIR_NAME . DS . "models", + ADDON_DIR_NAME), TEST_APP_DIR . DS); + + self::$setup = true; + } + + public function testResponses() + { + $bus = $this->getBus("index/index"); + $bus->run(new AppBusConfig()); + + $responses = $bus->get("response")->getResponses(); + $this->assertEquals("10", $responses["hoge"]); + $this->assertEquals("20", $responses["fuga"]); + $this->assertFalse(isset($responses["foo"])); + } + + public function testHtml() + { + $bus = $this->getBus("index/hoge"); + $bus->run(new AppBusConfig()); + + $lines = $this->toHtmlLines($bus->get("result")); + + $this->assertEquals("", $lines[0]); + $this->assertEquals("", $lines[1]); + $this->assertEquals("

yamada

", $lines[2]); + $this->assertEquals("", $lines[3]); + $this->assertEquals("", $lines[4]); + } + + public function testInstanceOfController() + { + $bus = $this->getBus(""); + $bus->run(new AppBusConfig()); + $this->assertTrue($bus->get("controller") instanceof Index_Controllers_Index); + + $bus = $this->getBus("main"); + $bus->run(new AppBusConfig()); + $this->assertTrue($bus->get("controller") instanceof Index_Controllers_Main); + + $bus = $this->getBus("manage/login/prepare"); + $bus->run(new AppBusConfig()); + $this->assertTrue($bus->get("controller") instanceof Manage_Controllers_Login); + } + + public function testUriParameters() + { + $bus = $this->getBus("manage/index/index/1/2"); + $bus->run(new AppBusConfig()); + $lines = $this->toHtmlLines($bus->get("result")); + + $this->assertEquals("", $lines[0]); + $this->assertEquals("", $lines[1]); + $this->assertEquals("

manage

", $lines[2]); + $this->assertEquals("

param1: 1

", $lines[3]); + $this->assertEquals("

param2: 2

", $lines[4]); + $this->assertEquals("", $lines[5]); + $this->assertEquals("", $lines[6]); + + $bus = $this->getBus("manage/index/index/100/200"); + $bus->run(new AppBusConfig()); + $lines = $this->toHtmlLines($bus->get("result")); + + $this->assertEquals("

param1: 100

", $lines[3]); + $this->assertEquals("

param2: 200

", $lines[4]); + } + + public function testRedirect() + { + $bus = $this->getBus("manage/index/index/abcde/2"); + $bus->run(new AppBusConfig()); + + $controller = $bus->get("controller"); + $this->assertTrue($controller->isRedirected()); + $this->assertEquals("/manage/login/prepare", $controller->getResponse()->getRedirector()->getUri()); + } + + public function testNotFound() + { + $bus = $this->getBus("manage/hoge/fuga"); + $bus->run(new AppBusConfig()); + + $response = $bus->get("response"); + $this->assertEquals(Sabel_Response::NOT_FOUND, $response->getStatus()->getCode()); + $headers = $response->outputHeader(); + $this->assertEquals("HTTP/1.0 404 Not Found", $headers[0]); + } + + public function testServerError() + { + $bus = $this->getBus("manage/index/refuse"); + $bus->run(new AppBusConfig()); + + $response = $bus->get("response"); + $this->assertEquals(Sabel_Response::INTERNAL_SERVER_ERROR, $response->getStatus()->getCode()); + $headers = $response->outputHeader(); + $this->assertEquals("HTTP/1.0 500 Internal Server Error", $headers[0]); + } + + public function testInternalRequest() + { + $bus = $this->getBus("main/foo"); + $bus->run(new AppBusConfig()); + $this->assertEquals("foo bar", $bus->get("response")->getResponse("bar")); + } + + protected function toHtmlLines($result) + { + $html = str_replace(array("\r\n", "\r"), "\n", trim($result)); + return array_map("trim", explode("\n", $html)); + } + + protected function getBus($uri) + { + $bus = new Sabel_Bus(); + $bus->set("request", new Sabel_Request_Object($uri)); + $bus->set("session", Sabel_Session_InMemory::create()); + return $bus; + } +} + +class AppBusConfig extends Sabel_Bus_Config +{ + protected $processors = array("addon" => "TestProcessor_Addon", + "request" => "TestProcessor_Request", + "response" => "TestProcessor_Response", + "router" => "TestProcessor_Router", + "session" => "TestProcessor_Session", + "controller" => "TestProcessor_Controller", + "helper" => "TestProcessor_Helper", + "initializer" => "TestProcessor_Initializer", + "executer" => "TestProcessor_Executer", + "view" => "TestProcessor_View"); + + protected $configs = array("map" => "AppTestMapConfig", + "addon" => "AppTestAddonConfig", + "database" => "AppTestDbConfig"); +} + +class AppTestMapConfig extends Sabel_Map_Configurator +{ + public function configure() + { + $this->route("manage") + ->uri("manage/:controller/:action/:param1/:param2") + ->module("manage") + ->defaults(array(":controller" => "index", + ":action" => "index", + ":param1" => null, + ":param2" => null)); + + $this->route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array(":controller" => "index", + ":action" => "index")); + } +} + +class AppBusConfig2 extends AppBusConfig +{ + protected $configs = array("map" => "AppTestMapConfig2", + "addon" => "AppTestAddonConfig", + "database" => "AppTestDbConfig"); +} + +class AppTestMapConfig2 extends Sabel_Map_Configurator +{ + public function configure() + { + $this->route("all") + ->uri(":uri[]") + ->module("index") + ->controller("index") + ->action("index") + ->defaults(array(":uri" => array())); + } +} + +class AppTestAddonConfig implements Sabel_Config +{ + public function configure() { return array(); } +} + +class AppTestDbConfig implements Sabel_Config +{ + public function configure() { return array(); } +} diff --git a/Test/Aspect/Config.php b/Test/Aspect/Config.php new file mode 100755 index 0000000..1f20c01 --- /dev/null +++ b/Test/Aspect/Config.php @@ -0,0 +1,23 @@ +configure(); + } +} + +class Sabel_Test_Aspect_Config extends Sabel_Aspect_Config implements Sabel_Config +{ + public function configure() + { + $this->aspect("default"); + } +} \ No newline at end of file diff --git a/Test/Aspect/Introduction.php b/Test/Aspect/Introduction.php new file mode 100755 index 0000000..94bac4c --- /dev/null +++ b/Test/Aspect/Introduction.php @@ -0,0 +1,147 @@ + + */ +class Test_Aspect_Introduction extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Aspect_Introduction"); + } + + private $weaver = null; + + public function setUp() + { + $this->weaver = new Sabel_Aspect_Weaver("Sabel_Test_Aspect_Person"); + } + + public function testIntroduceLockable() + { + $mixin = new Sabel_Test_Aspect_LockMixin(); + + $this->weaver->addAdvisor(new Sabel_Test_Aspect_LockMixinAdvisor($mixin)); + + $person = $this->weaver->getProxy(); + $person->__checkTargetMethod(false); + + $person->lock(); + + try { + $person->setAge(28); + $this->assertFalse(true); + } catch (Sabel_Test_Aspect_LockedException $e) { + $this->assertEquals("locked", $e->getMessage()); + } + + $person->unlock(); + $person->setAge(29); + $this->assertEquals(29, $person->getAge()); + } +} + +/** + * target class + */ +class Sabel_Test_Aspect_Person +{ + private $age = 0; + + public function setAge($age) + { + $this->age = $age; + } + + public function getAge() + { + return $this->age; + } +} + +/** + * lockable interface + */ +interface Sabel_Test_Aspect_Lockable +{ + public function lock(); + public function unlock(); + public function locked(); +} + +class Sabel_Test_Aspect_LockMixin extends Sabel_Aspect_Introduction_DelegatingInterceptor + implements Sabel_Test_Aspect_Lockable +{ + private $locked = false; + + public function lock() + { + $this->locked = true; + } + + public function unlock() + { + $this->locked = false; + } + + public function locked() + { + return $this->locked; + } + + public function invoke(Sabel_Aspect_MethodInvocation $invocation) + { + $method = $invocation->getMethod()->getName(); + + if (in_array($method, get_class_methods($this))) { + $this->$method(); + } + + if (preg_match("/set+/", $invocation->getMethod()->getName())) { + if ($this->locked()) { + throw new Sabel_Test_Aspect_LockedException("locked"); + } + } + + return parent::invoke($invocation); + } +} + +class Sabel_Test_Aspect_LockedException extends Sabel_Exception_Runtime {} + + +class Sabel_Test_Aspect_LockMixinAdvisor extends Sabel_Aspect_Introduction_DefaultAdvisor +{ +} + + +class TrueClassMatcher implements Sabel_Aspect_Matcher_Class +{ + public function matches($class) + { + return true; + } +} + +class TrueMethodMatcher implements Sabel_Aspect_Matcher_Method +{ + public function matches($method, $class) + { + return true; + } +} + +class TrueMatchPointcut implements Sabel_Aspect_Pointcut +{ + public function getClassMatcher() + { + return new TrueClassMatcher(); + } + + public function getMethodMatcher() + { + return new TrueMethodMatcher(); + } +} diff --git a/Test/Aspect/Matcher.php b/Test/Aspect/Matcher.php new file mode 100755 index 0000000..9b7f930 --- /dev/null +++ b/Test/Aspect/Matcher.php @@ -0,0 +1,31 @@ + + */ +class Test_Aspect_Matcher extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Aspect_Matcher"); + } + + public function testRegexMethodMatcher() + { + $matcher = new Sabel_Aspect_Matcher_RegexMethod(); + $matcher->setPattern("/set+/"); + $this->assertTrue($matcher->matches("setX", "")); + } + + public function testRegexClassMatcher() + { + $matcher = new Sabel_Aspect_Matcher_RegexClass(); + $matcher->setPattern("/Sabel_+/"); + $this->assertTrue($matcher->matches("Sabel_Test", "")); + + $matcher->setPattern("/Sabel_+/"); + $this->assertFalse($matcher->matches("Test_Test", "")); + } +} \ No newline at end of file diff --git a/Test/Aspect/Pointcuts.php b/Test/Aspect/Pointcuts.php new file mode 100755 index 0000000..b402d29 --- /dev/null +++ b/Test/Aspect/Pointcuts.php @@ -0,0 +1,50 @@ + + */ +class Test_Aspect_Pointcuts extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Aspect_Pointcuts"); + } + + protected $target = null; + protected $pointcuts = null; + + public function setUp() + { + $this->target = new Sabel_Tests_Aspect_TargetClass(); + $this->pointcuts = new Sabel_Aspect_DefaultPointcuts(); + } + + public function testPointcuts() + { + $match = $this->pointcuts->matches(new StaticPointcut(), "setX", $this->target); + + $this->assertTrue($match); + } + + public function testRegexMatcherPointcuts() + { + $pointcuts = $this->pointcuts; + $target = $this->target; + + + $pointcut = new Sabel_Aspect_Pointcut_DefaultRegex(); + $pointcut->setClassMatchPattern("/Sabel+/"); + $pointcut->setMethodMatchPattern("/set+/"); + + $match = $pointcuts->matches($pointcut, "setX", $target); + $this->assertTrue($match); + + $match = $pointcuts->matches($pointcut, "setY", $target); + $this->assertTrue($match); + + $match = $pointcuts->matches($pointcut, "getY", $target); + $this->assertFalse($match); + } +} \ No newline at end of file diff --git a/Test/Aspect/Proxy.php b/Test/Aspect/Proxy.php new file mode 100755 index 0000000..4be5b33 --- /dev/null +++ b/Test/Aspect/Proxy.php @@ -0,0 +1,416 @@ + + */ +class Test_Aspect_Proxy extends SabelTestCase +{ + protected $weaver = null; + + public static function suite() + { + return self::createSuite("Test_Aspect_Proxy"); + } + + public function setUp() + { + $this->weaver = new Sabel_Aspect_Weaver("Sabel_Tests_Aspect_TargetClass"); + } + + public function testRegexMethodMatcher() + { + $matcher = new Sabel_Aspect_Matcher_RegexMethod(); + $matcher->setPattern("/set+/"); + $this->assertTrue($matcher->matches("setX", "")); + } + + public function testRegexClassMatcher() + { + $matcher = new Sabel_Aspect_Matcher_RegexClass(); + $matcher->setPattern("/Sabel_+/"); + $this->assertTrue($matcher->matches("Sabel_Test", "")); + + $matcher->setPattern("/Sabel_+/"); + $this->assertFalse($matcher->matches("Test_Test", "")); + } + + public function testNonExistTargetClass() + { + try { + $this->weaver->setTarget("Non_Exist_Target_Class"); + } catch (Sabel_Exception_Runtime $e) { + $this->assertTrue(true); + return; + } + + $this->fail(); + } + + public function testWeaverWithInterceptor() + { + $weaver = $this->weaver; + + $interceptor = new Sabel_Aspect_Interceptor_Debug(); + $advisor = new MyStaticMethodMatcherPointcutAdvisor(); + $advisor->setAdvice($interceptor); + + $weaver->addAdvisor($advisor); + + $interceptor = new Sabel_Aspect_Interceptor_SimpleTrace(); + $advisor = new MyStaticMethodMatcherPointcutAdvisor(); + $advisor->setAdvice($interceptor); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $result = $target->getX("arg", "arg2"); + $this->assertEquals("X", $result); + + $result = $target->getY("arg", "arg2"); + $this->assertEquals("Y", $result); + } + + public function testAopWeaverWithoutInterceptors() + { + $weaver = $this->weaver; + + $target = $weaver->getProxy(); + + $result = $target->getX("arg", "arg2"); + $this->assertEquals("X", $result); + + $result = $target->getY("arg", "arg2"); + $this->assertEquals("Y", $result); + } + + public function testMultipleAdvice() + { + defineClass("ResultInterceptor", ' + class %s implements Sabel_Aspect_MethodInterceptor + { + public function invoke(Sabel_Aspect_MethodInvocation $invocation) + { + return "adviced " . $invocation->proceed(); + } + } + '); + + $weaver = $this->weaver; + + $weaver->setTarget("Sabel_Tests_Aspect_TargetClass"); + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/get+/"); + + $advisor->addAdvice(new ResultInterceptor()); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $this->assertEquals("adviced X", $target->getX()); + $this->assertEquals("adviced Y", $target->getY()); + + $advisor->addAdvice(new ResultInterceptor()); + + $this->assertEquals("adviced adviced X", $weaver->getProxy()->getX()); + $this->assertEquals("adviced adviced Y", $weaver->getProxy()->getY()); + + $advisor->addAdvice(new ResultInterceptor()); + + $this->assertEquals("adviced adviced adviced X", $weaver->getProxy()->getX()); + $this->assertEquals("adviced adviced adviced Y", $weaver->getProxy()->getY()); + } + + public function testTargetMethodExistance() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/get+/"); + + $beforeAdvice = new Sabel_Tests_Aspect_SimpleBeforeAdvice(); + $advisor->addAdvice(new Sabel_Tests_Aspect_SimpleAfterReturningAdvice()); + $advisor->addAdvice(new Sabel_Aspect_Interceptor_SimpleTrace()); + $advisor->addAdvice($beforeAdvice); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + try { + $target->invalidMethod(); + $this->assertTrue(false); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testSimpleBeforeAdvice() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/get+/"); + + $beforeAdvice = new Sabel_Tests_Aspect_SimpleBeforeAdvice(); + $advisor->addAdvice(new Sabel_Tests_Aspect_SimpleAfterReturningAdvice()); + $advisor->addAdvice(new Sabel_Aspect_Interceptor_SimpleTrace()); + $advisor->addAdvice($beforeAdvice); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $target->getX(); + $target->getY(); + + $this->assertEquals(array("getX", "getY"), $beforeAdvice->getCalledMethods()); + } + + public function testSimpleAfterAdvice() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/get+/"); + + $advice = new Sabel_Tests_Aspect_SimpleAfterReturningAdvice(); + $advisor->addAdvice($advice); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $target->getX(); + $target->getY(); + + $this->assertEquals(array("X", "Y"), $advice->getResults()); + } + + public function testSimpleThrowsAdvice() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/willThrowException/"); + + $advice = new Sabel_Tests_Aspect_SimpleThrowsAdvice(); + $advisor->addAdvice($advice); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $this->assertEquals("", $advice->getThrowsMessage()); + + try { + $target->willThrowException(); + } catch (Exception $e) { + $this->assertEquals("throws", $advice->getThrowsMessage()); + } + } + + public function testSimpleThrowsAndReturnAdvice() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/U"); + $advisor->setMethodMatchPattern("/.+/"); + + $throwsAdvice = new Sabel_Tests_Aspect_SimpleThrowsAdvice(); + $beforeAdvice = new Sabel_Tests_Aspect_SimpleBeforeAdvice(); + $returningAdvice = new Sabel_Tests_Aspect_SimpleAfterReturningAdvice(); + + $advisor->addAdvice($throwsAdvice); + $advisor->addAdvice($returningAdvice); + $advisor->addAdvice($beforeAdvice); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $this->assertEquals("", $throwsAdvice->getThrowsMessage()); + + try { + $target->willThrowException(); + } catch (Exception $e) { + $this->assertEquals("throws", $throwsAdvice->getThrowsMessage()); + $this->assertEquals(array(), $returningAdvice->getResults()); + $this->assertEquals(array("willThrowException"), $beforeAdvice->getCalledMethods()); + } + } + + public function testAdvices() + { + $advices = new Sabel_Aspect_Advices(); + $advices->addAdvice(new Sabel_Aspect_Interceptor_SimpleTrace()); + $advices->addAdvice(new Sabel_Tests_Aspect_SimpleBeforeAdvice()); + $advices->addAdvice(new Sabel_Tests_Aspect_SimpleAfterReturningAdvice()); + + foreach ($advices->toArray() as $advice) { + $this->assertTrue($advice instanceof Sabel_Aspect_Advice); + } + } + + public function testPlainObjectAdvice() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/"); + $advisor->setMethodMatchPattern("/get+/"); + + $throwAdvisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $throwAdvisor->setClassMatchPattern("/.+/"); + $throwAdvisor->setMethodMatchPattern("/will+/"); + + $poAdvice = new Sabel_Tests_Aspect_PlainObject_Advice(); + $plainObjectInterceptor = new Sabel_Aspect_Interceptor_PlainObjectAdvice($poAdvice); + $plainObjectInterceptor->setBeforeAdviceMethod("before"); + $plainObjectInterceptor->setAfterAdviceMethod("after"); + $plainObjectInterceptor->setAroundAdviceMethod("around"); + $plainObjectInterceptor->setThrowsAdviceMethod("throws"); + + $advisor->addAdvice($plainObjectInterceptor); + $throwAdvisor->addAdvice($plainObjectInterceptor); + + $weaver->addAdvisor($advisor); + $weaver->addAdvisor($throwAdvisor); + + $target = $weaver->getProxy(); + + $target->getX(); + + $this->assertEquals("getX", $poAdvice->before); + $this->assertEquals("X", $poAdvice->after); + + $target->willThrowException(); + $this->assertEquals("throws", $poAdvice->throws); + } + + public function testPlainObjectPreventBefore() + { + $weaver = $this->weaver; + + $advisor = new Sabel_Aspect_Advisor_RegexMatcherPointcut(); + $advisor->setClassMatchPattern("/.+/"); + $advisor->setMethodMatchPattern("/get+/"); + + $poAdvice = new Sabel_Tests_Aspect_PlainObject_PreventBeforeAdvice(); + $plainObjectInterceptor = new Sabel_Aspect_Interceptor_PlainObjectAdvice($poAdvice); + $plainObjectInterceptor->setBeforeAdviceMethod("before"); + + $advisor->addAdvice($plainObjectInterceptor); + + $weaver->addAdvisor($advisor); + + $target = $weaver->getProxy(); + + $result = $target->getX(); + + $this->assertEquals("Y", $result); + } + + public function testAnnotationPlainObjectAdvice() + { + $weaver = new Sabel_Aspect_Weaver(); + $weaver->build("Sabel_Tests_Aspect_TargetClass", + "Sabel_Tests_Aspect_PlainObject_Advice"); + + $advice = $weaver->getAdvice(); + + $target = $weaver->getProxy(); + + $target->getX(); + $this->assertEquals("getX", $advice->before); + + $target->setX("x"); + $this->assertEquals("setX", $advice->before); + } + + public function testGetClassName() + { + $weaver = $this->weaver; + + $weaver->setTarget("Sabel_Tests_Aspect_TargetClass"); + $target = $weaver->getProxy(); + + $this->assertEquals($target->__getClassName(), "Sabel_Tests_Aspect_TargetClass"); + } + + public function testTargetClass() + { + $weaver = $this->weaver; + + $weaver->setTarget("Sabel_Tests_Aspect_TargetClass"); + $target = $weaver->getProxy(); + + $this->assertEquals(get_class($target), "Sabel_Aspect_Proxy"); + } +} + +/** + * @classMatch Sabel+ + * + * @advisor Sabel_Aspect_Advisor_RegexMatcherPointcut + * @interceptor Sabel_Aspect_Interceptor_PlainObjectAdvice + */ +class Sabel_Tests_Aspect_PlainObject_Advice +{ + public + $before, + $after, + $throws = ""; + + /** + * @before get+ + */ + public function before($method, $arguments, $target) + { + $this->before = $method->getName(); + } + + /** + * @before set+ + */ + public function beforeSet($method, $arguments, $target) + { + $this->before = $method->getName(); + } + + public function after($method, $arguments, $target, $result) + { + $this->after = $result; + } + + public function around($invocation) + { + $result = $invocation->proceed(); + return $result; + } + + public function throws($method, $arguments, $target, $exception) + { + $this->throws = $exception->getMessage(); + } +} + +class Sabel_Tests_Aspect_PlainObject_PreventBeforeAdvice +{ + public function before($method, $arguments, $target) + { + return "Y"; + } +} \ No newline at end of file diff --git a/Test/Aspect/SimpleUsage.php b/Test/Aspect/SimpleUsage.php new file mode 100755 index 0000000..1899aa3 --- /dev/null +++ b/Test/Aspect/SimpleUsage.php @@ -0,0 +1,66 @@ + + */ +class Test_Aspect_SimpleUsage extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Aspect_SimpleUsage"); + } + + public function setUp() + { + } + + public function testUsageConfig() + { + $updatable = load("Sabel_Test_Aspect_SimpleUsage_Person", new Sabel_Test_Aspect_ConfigSimple()); + + $this->assertTrue($updatable instanceof Sabel_Aspect_Proxy); + $updatable->updateState(); + } +} + +class Sabel_Test_Aspect_ConfigSimple extends Sabel_Container_Injection +{ + public function configure() + { + $this->aspect("Sabel_Test_Aspect_Updatable")->advice("Sabel_Test_Aspect_UpdatableAdvice"); + } +} + +interface Sabel_Test_Aspect_Updatable +{ + public function updateState(); +} + +class Sabel_Test_Aspect_SimpleUsage_Person implements Sabel_Test_Aspect_Updatable +{ + public function updateState() + { + // update state + } +} + +class Sabel_Test_Aspect_UpdatableAdvice +{ + /** + * @before update.+ + */ + public function before($method, $arguments, $target) + { + // before + } + + /** + * @around update.+ + */ + public function around($invocation) + { + // around + } +} \ No newline at end of file diff --git a/Test/Aspect/Tests.php b/Test/Aspect/Tests.php new file mode 100755 index 0000000..98cf1c1 --- /dev/null +++ b/Test/Aspect/Tests.php @@ -0,0 +1,41 @@ + + */ +class Test_Aspect_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + $suite->addTest(Test_Aspect_Proxy::suite()); + $suite->addTest(Test_Aspect_Pointcuts::suite()); + $suite->addTest(Test_Aspect_Matcher::suite()); + $suite->addTest(Test_Aspect_Introduction::suite()); + $suite->addTest(Test_Aspect_SimpleUsage::suite()); + + // @todo remove this before commit. + $suite->addTest(Test_Aspect_Exp::suite()); + + return $suite; + } +} \ No newline at end of file diff --git a/Test/Aspect/classes/All.php b/Test/Aspect/classes/All.php new file mode 100755 index 0000000..c076b1f --- /dev/null +++ b/Test/Aspect/classes/All.php @@ -0,0 +1,130 @@ +getName() === "Sabel_Tests_Aspect_TargetClass"); + } +} + +class MyMethodMatcher extends Sabel_Aspect_Matcher_StaticMethod +{ + public function matches($method, $class) + { + return ($method === "setX"); + } +} + +class MyStaticMethodMatcherPointcutAdvisor extends Sabel_Aspect_Advisor_StaticMethodMatcherPointcut +{ + public function __construct() + { + defineClass("MyClassMatcher", ' + class %s implements Sabel_Aspect_Matcher_Class + { + public function matches($class) + { + return true; + } + } + '); + + $this->setClassMatcher(new MyClassMatcher()); + } + + public function matches($method, $class) + { + return preg_match("/get+/", $method); + } +} + +class MyRegexMethodMatcherPointcutAdvisor extends Sabel_Aspect_Advisor_StaticMethodMatcherPointcut +{ + private $pattern; + + public function __construct() + { + defineClass("MyClassMatcher", ' + class %s implements Sabel_Aspect_Matcher_Class + { + public function matches($class) + { + return true; + } + } + '); + + $this->setClassMatcher(new MyClassMatcher()); + } + + public function setPattern($pattern) + { + $this->pattern = $pattern; + } + + public function matches($method, $class) + { + return preg_match($this->pattern, $method); + } +} + +function defineClass($className, $class) +{ + if (!class_exists($className)) { + eval(sprintf($class, $className)); + } +} diff --git a/Test/Aspect/classes/Interceptors.php b/Test/Aspect/classes/Interceptors.php new file mode 100755 index 0000000..45d36a9 --- /dev/null +++ b/Test/Aspect/classes/Interceptors.php @@ -0,0 +1,46 @@ +calledMethods[] = $method->getName(); + } + + public function getCalledMethods() + { + return $this->calledMethods; + } +} + +class Sabel_Tests_Aspect_SimpleAfterReturningAdvice implements Sabel_Aspect_Advice_MethodAfterReturning +{ + private $results = array(); + + public function after($method, $arguments, $target, $returnValue) + { + $this->results[] = $returnValue; + } + + public function getResults() + { + return $this->results; + } +} + +class Sabel_Tests_Aspect_SimpleThrowsAdvice implements Sabel_Aspect_Advice_MethodThrows +{ + private $throwsMessage = ""; + + public function throws($method, $arguments, $target, $exception) + { + $this->throwsMessage = $exception->getMessage(); + } + + public function getThrowsMessage() + { + return $this->throwsMessage; + } +} \ No newline at end of file diff --git a/Test/Bus/Runner.php b/Test/Bus/Runner.php new file mode 100755 index 0000000..bc9ac82 --- /dev/null +++ b/Test/Bus/Runner.php @@ -0,0 +1,184 @@ + + */ +class Test_Bus_Runner extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Bus_Runner"); + } + + public function testEmptyNameProcessor() + { + try { + $bus = Sabel_Bus::create(); + $bus->addProcessor(new HogeProcessor("")); + } catch (Sabel_Exception_InvalidArgument $e) { + return; + } + + $this->fail(); + } + + public function testProcessorList() + { + $bus = Sabel_Bus::create(); + $bus->addProcessor(new HogeProcessor("hoge")); + $bus->addProcessor(new FugaProcessor("fuga")); + $bus->addProcessor(new FooProcessor("foo")); + + $ins = $bus->getProcessor("hoge"); + $this->assertTrue($ins instanceof HogeProcessor); + $this->assertNull($bus->getProcessor("test")); + + $list = $bus->getProcessorList(); + $this->assertTrue($list->has("hoge")); + $this->assertTrue($list->has("fuga")); + $this->assertTrue($list->has("foo")); + $this->assertFalse($list->has("bar")); + } + + public function testConfigs() + { + $bus = Sabel_Bus::create(); + eval ("class TemporaryConfig implements Sabel_Config + { + public function configure() {} + }"); + + $bus->setConfig("tmp", new TemporaryConfig()); + $this->assertTrue($bus->getConfig("tmp") instanceof Sabel_Config); + $this->assertNull($bus->getConfig("hoge")); + } + + public function testBusInit() + { + $bus = Sabel_Bus::create(array("null" => null, + "int" => 10, + "string" => "test", + "bool" => false)); + + $this->assertEquals(null, $bus->get("null")); + $this->assertEquals(10, $bus->get("int")); + $this->assertEquals("test", $bus->get("string")); + $this->assertEquals(false, $bus->get("bool")); + } + + public function testRun() + { + $bus = Sabel_Bus::create(); + $bus->run(new TestBusConfig()); + + $this->assertEquals("10", $bus->get("a")); + $this->assertEquals("20", $bus->get("b")); + $this->assertEquals(null, $bus->get("c")); + } + + public function testAttatchExecuteBeforeEvent() + { + $bus = Sabel_Bus::create(); + $bus->attachExecuteBeforeEvent("foo", new TestEvent(), "beforeMethod"); + $bus->run(new TestBusConfig()); + + $this->assertEquals("before: fuga_result", $bus->get("beforeResult")); + } + + public function testAttatchExecuteAfterEvent() + { + $bus = Sabel_Bus::create(); + $bus->attachExecuteAfterEvent("hoge", new TestEvent(), "afterMethod"); + $bus->run(new TestBusConfig()); + + $this->assertEquals("after: hoge_result", $bus->get("afterResult")); + } + + public function testAttatchExecuteAfterEvent2() + { + $bus = Sabel_Bus::create(); + $bus->attachExecuteAfterEvent("hoge", new TestEvent(), "afterMethod"); + $bus->attachExecuteAfterEvent("hoge", new TestEvent2(), "afterMethod"); + $bus->run(new TestBusConfig()); + + $this->assertEquals("after: hoge_result", $bus->get("afterResult")); + $this->assertEquals("after: hoge_result", $bus->get("afterResult2")); + } + + public function testHas() + { + $bus = Sabel_Bus::create(); + $bus->set("a", "10"); + $bus->set("b", "20"); + $bus->set("c", "30"); + + $this->assertTrue($bus->has("a")); + $this->assertFalse($bus->has("d")); + + $this->assertTrue($bus->has(array("a", "b", "c"))); + $this->assertFalse($bus->has(array("a", "d", "c"))); + } +} + +class TestEvent +{ + public function beforeMethod($bus) + { + $bus->set("beforeResult", "before: " . $bus->get("result")); + } + + public function afterMethod($bus) + { + $bus->set("afterResult", "after: " . $bus->get("result")); + } +} + +class TestEvent2 +{ + public function afterMethod($bus) + { + $bus->set("afterResult2", "after: " . $bus->get("result")); + } +} + +class TestBusConfig extends Sabel_Bus_Config +{ + protected $processors = array("hoge" => "HogeProcessor", + "fuga" => "FugaProcessor", + "foo" => "FooProcessor"); +} + +class HogeProcessor extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $bus->set("a", "10"); + $bus->set("result", "hoge_result"); + } +} + +class FugaProcessor extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $bus->set("b", "20"); + $bus->set("result", "fuga_result"); + } +} + +class FooProcessor extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $this->a = $bus->get("a"); + $this->b = $bus->get("b"); + + if ($this->a !== "10") throw new Exception("test error"); + if ($this->b !== "20") throw new Exception("test error"); + + $bus->set("result", "foo_result"); + } +} diff --git a/Test/Bus/Tests.php b/Test/Bus/Tests.php new file mode 100755 index 0000000..aa010cc --- /dev/null +++ b/Test/Bus/Tests.php @@ -0,0 +1,14 @@ +addTest(Test_Bus_Runner::suite()); + + return $suite; + } +} diff --git a/Test/Cache/Apc.php b/Test/Cache/Apc.php new file mode 100755 index 0000000..8bf5679 --- /dev/null +++ b/Test/Cache/Apc.php @@ -0,0 +1,23 @@ + + */ +class Test_Cache_Apc extends Test_Cache_Test +{ + public static function suite() + { + if (ini_get("apc.enable_cli") === "1") { + return self::createSuite("Test_Cache_Apc"); + } else { + throw new Exception("must enable 'apc.enable_cli' in your php.ini"); + } + } + + public function setUp() + { + $this->cache = Sabel_Cache_Apc::create(); + $this->cache->delete("hoge"); + } +} diff --git a/Test/Cache/File.php b/Test/Cache/File.php new file mode 100755 index 0000000..613f045 --- /dev/null +++ b/Test/Cache/File.php @@ -0,0 +1,23 @@ + + */ +class Test_Cache_File extends Test_Cache_Test +{ + public static function suite() + { + $dir = SABEL_BASE . DIRECTORY_SEPARATOR . "Test" . DIRECTORY_SEPARATOR + . "data" . DIRECTORY_SEPARATOR . "application" . DIRECTORY_SEPARATOR . "cache"; + + define("CACHE_DIR_PATH", $dir); + return self::createSuite("Test_Cache_File"); + } + + public function setUp() + { + $this->cache = Sabel_Cache_File::create(); + $this->cache->delete("hoge"); + } +} diff --git a/Test/Cache/Memcache.php b/Test/Cache/Memcache.php new file mode 100755 index 0000000..6253a77 --- /dev/null +++ b/Test/Cache/Memcache.php @@ -0,0 +1,19 @@ + + */ +class Test_Cache_Memcache extends Test_Cache_Test +{ + public static function suite() + { + return self::createSuite("Test_Cache_Memcache"); + } + + public function setUp() + { + $this->cache = Sabel_Cache_Memcache::create(); + $this->cache->delete("hoge"); + } +} diff --git a/Test/Cache/Null.php b/Test/Cache/Null.php new file mode 100755 index 0000000..2c3155b --- /dev/null +++ b/Test/Cache/Null.php @@ -0,0 +1,39 @@ + + */ +class Test_Cache_Null extends SabelTestCase +{ + protected $cache = null; + + public static function suite() + { + return self::createSuite("Test_Cache_Null"); + } + + public function setUp() + { + $this->cache = Sabel_Cache_Null::create(); + } + + public function testRead() + { + $this->assertNull($this->cache->read("hoge")); + } + + public function testWrite() + { + $this->cache->write("hoge", "value"); + $this->assertNull($this->cache->read("hoge")); + } + + public function testDelete() + { + $this->cache->delete("hoge"); + $this->assertNull($this->cache->read("hoge")); + } +} diff --git a/Test/Cache/Test.php b/Test/Cache/Test.php new file mode 100755 index 0000000..d2bd8b1 --- /dev/null +++ b/Test/Cache/Test.php @@ -0,0 +1,56 @@ + + */ +class Test_Cache_Test extends SabelTestCase +{ + protected $cache = null; + + public function testRead() + { + $this->assertNull($this->cache->read("hoge")); + } + + public function testWrite() + { + $this->cache->write("hoge", "value"); + $this->assertEquals("value", $this->cache->read("hoge")); + } + + public function testDelete() + { + $this->cache->write("hoge", "value"); + $this->assertEquals("value", $this->cache->read("hoge")); + $this->cache->delete("hoge"); + $this->assertNull($this->cache->read("hoge")); + } + + public function testArray() + { + $this->cache->write("hoge", array("k1" => "value", "k2" => 10, "k3" => true)); + $array = $this->cache->read("hoge"); + $this->assertTrue(is_array($array)); + $this->assertEquals("value", $array["k1"]); + $this->assertEquals(10, $array["k2"]); + $this->assertEquals(true, $array["k3"]); + } + + public function testObject() + { + $obj = new stdClass(); + $obj->k1 = "value"; + $obj->k2 = 10; + $obj->k3 = true; + + $this->cache->write("hoge", $obj); + $object = $this->cache->read("hoge"); + $this->assertTrue(is_object($object)); + $this->assertEquals("value", $object->k1); + $this->assertEquals(10, $object->k2); + $this->assertEquals(true, $object->k3); + } +} diff --git a/Test/Cache/Tests.php b/Test/Cache/Tests.php new file mode 100755 index 0000000..b6f30d6 --- /dev/null +++ b/Test/Cache/Tests.php @@ -0,0 +1,37 @@ + + */ +class Test_Cache_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + //if (extension_loaded("apc")) { + // $suite->addTest(Test_Cache_Apc::suite()); + //} + + if (extension_loaded("memcache")) { + $suite->addTest(Test_Cache_Memcache::suite()); + } + + $suite->addTest(Test_Cache_File::suite()); + $suite->addTest(Test_Cache_Null::suite()); + + return $suite; + } +} diff --git a/Test/Console.php b/Test/Console.php new file mode 100755 index 0000000..14a83ab --- /dev/null +++ b/Test/Console.php @@ -0,0 +1,89 @@ + + */ +class Test_Console extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Console"); + } + + public function testMessage() + { + $_SERVER["IS_WINDOWS"] = true; + + ob_start(); + Sabel_Console::success("success"); + $result = ob_get_clean(); + $this->assertEquals("[SUCCESS] success", rtrim($result)); + + ob_start(); + Sabel_Console::warning("warning"); + $result = ob_get_clean(); + $this->assertEquals("[WARNING] warning", rtrim($result)); + + ob_start(); + Sabel_Console::error("failure"); + $result = ob_get_clean(); + $this->assertEquals("[FAILURE] failure", rtrim($result)); + + ob_start(); + Sabel_Console::message("message"); + $result = ob_get_clean(); + $this->assertEquals("[MESSAGE] message", rtrim($result)); + } + + public function testHasOption() + { + $args = array("rm", "-r"); + $this->assertTrue(Sabel_Console::hasOption("r", $args)); + + $args = array("rm", "-r", "-f"); + $this->assertTrue(Sabel_Console::hasOption("r", $args)); + $this->assertTrue(Sabel_Console::hasOption("f", $args)); + + $args = array("rm", "-rf"); + $this->assertTrue(Sabel_Console::hasOption("r", $args)); + $this->assertTrue(Sabel_Console::hasOption("f", $args)); + } + + public function testHasOption2() + { + $args = array("cmd", "--foo"); + $this->assertTrue(Sabel_Console::hasOption("foo", $args)); + + $args = array("cmd", "--foo=bar"); + $this->assertTrue(Sabel_Console::hasOption("foo", $args)); + } + + public function testGetOption() + { + $args = array("cmd", "-d", "/var/tmp", "-f", "/tmp/test.txt"); + $this->assertTrue(Sabel_Console::hasOption("d", $args)); + $this->assertTrue(Sabel_Console::hasOption("f", $args)); + + $args = array("cmd", "-d", "/var/tmp", "-f", "/tmp/test.txt"); + $this->assertEquals("/var/tmp", Sabel_Console::getOption("d", $args)); + $this->assertEquals(array("cmd", "-f", "/tmp/test.txt"), $args); + + $args = array("cmd", "-d", "/var/tmp", "-f", "/tmp/test.txt"); + $this->assertEquals("/tmp/test.txt", Sabel_Console::getOption("f", $args)); + $this->assertEquals(array("cmd", "-d", "/var/tmp"), $args); + } + + public function testGetOption2() + { + $args = array("cmd", "--dir=/var/tmp", "--file=/tmp/test.txt"); + $this->assertEquals("/var/tmp", Sabel_Console::getOption("dir", $args)); + $this->assertEquals(array("cmd", "--file=/tmp/test.txt"), $args); + + $args = array("cmd", "--dir=/var/tmp", "--file=/tmp/test.txt"); + $this->assertEquals("/tmp/test.txt", Sabel_Console::getOption("file", $args)); + $this->assertEquals(array("cmd", "--dir=/var/tmp"), $args); + } +} diff --git a/Test/Container.php b/Test/Container.php new file mode 100755 index 0000000..6a03194 --- /dev/null +++ b/Test/Container.php @@ -0,0 +1,566 @@ + + */ +class Test_Container extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Container"); + } + + /** + * setUp + * + * @access public + * @return void + */ + public function setUp() + { + } + + /** + * @test + */ + public function createContainer() + { + $container = Sabel_Container::create(new Sabel_CTest_Config()); + } + + /** + * @test + */ + public function createContainerWithInvalidConfiguration() + { + try { + $container = Sabel_Container::create(new StdClass()); + } catch (Sabel_Exception_InvalidArgument $e) { + $this->assertTrue(true); + return; + } + + $this->fail(); + } + + /** + * @test + */ + public function instanciateUndefinedClass() + { + $container = Sabel_Container::create(new Sabel_CTest_Config()); + + try { + $controller = $container->newInstance("Sabel_CTest_WillNotFoundClass"); + } catch (Sabel_Container_Exception_UndefinedClass $une) { + $this->assertTrue(true); + return; + } catch (Exception $e) { + echo $e->getMessage(); + $this->fail(); + } + + $this->fail(); + } + + /** + * @test + */ + public function injectionWithoutSetterConfig() + { + } + + public function injectionNestedDependency() + { + } + + /** + * @test + */ + public function injectionWithConstructor() + { + $container = Sabel_Container::create(new Sabel_CTest_Config_Construct()); + $controller = $container->newInstance("Sabel_CTest_Controller_WithConstruct"); + $this->assertTrue($controller->model instanceof Sabel_CTest_Model); + } + + /** + * @test + */ + public function SetterInjection() + { + $container = Sabel_Container::create(new Sabel_CTest_Config()); + $controller = $container->newInstance("Sabel_CTest_Controller"); + $this->assertTrue($controller->model instanceof Sabel_CTest_Model); + } + + /** + * @test + */ + public function constructorWithBind() + { + $container = Sabel_Container::create(new Sabel_CTest_Config_Construct()); + $controller = $container->newInstance("Sabel_CTest_Controller_WithConstruct"); + $this->assertTrue($controller->model instanceof Sabel_CTest_Model); + } + + /** + * simple injection + * + * @test + */ + public function injection() + { + $injector = Sabel_Container::create(new Config()); + $person = $injector->newInstance("Person"); + + $this->assertEquals(10, $person->calc()); + } + + public function testConstructorInjection() + { + $injector = Sabel_Container::create(new ConstructConfig()); + $car = $injector->newInstance("Car"); + $this->assertTrue(is_object($car->getEngine())); + } + + public function testStrLiteralConstructorInjection() + { + $injector = Sabel_Container::create(new StrLiteralConstructConfig()); + $car = $injector->newInstance("Car"); + $this->assertEquals("this is engine", $car->getEngine()); + } + + public function testNumLiteralConstructorInjection() + { + $injector = Sabel_Container::create(new NumLiteralConstructConfig()); + $car = $injector->newInstance("Car"); + $this->assertEquals(123, $car->getEngine()); + } + + public function testBoolLiteralConstructorInjection() + { + $injector = Sabel_Container::create(new BoolLiteralConstructConfig()); + $car = $injector->newInstance("Car"); + $this->assertTrue($car->getEngine()); + } + + public function testWrongInjectionConfig() + { + $injector = Sabel_Container::create(new WrongClassNameConfig()); + + try { + $person = $injector->newInstance("Person"); + $this->fail(); + } catch (Exception $e) { + $this->assertEquals("WrongCalculator does't exist", $e->getMessage()); + } + } + + public function testMultipleConstructerInjection() + { + $injector = Sabel_Container::create(new MultipleConstructConfig()); + + $oil = new EngineOil("normal"); + $engine = new MultiEngine($oil); + $car = new MultiCar($engine, "multiple"); + + $injCar = $injector->newInstance("MultiCar"); + + $this->assertEquals($car, $injCar); + } + + public function testSpecificSetter() + { + $injector = Sabel_Container::create(new SpecificSetterConfig()); + $instance = $injector->newInstance("SpecificSetter"); + + $engineOil = new EngineOil("specific"); + $specific = new SpecificSetter(); + $specific->setSpecificSetter($engineOil); + + $this->assertEquals($instance, $specific); + } +} + +/** test classes **/ + +interface Sabel_CTest_Controller_Interface +{ +} +class Sabel_CTest_Controller implements Sabel_CTest_Controller_Interface +{ + public $model = null; + + public function setModel(Sabel_CTest_Model $model) + { + $this->model = $model; + } +} +class Sabel_CTest_Controller_WithConstruct +{ + public $model = null; + + public function __construct(Sabel_CTest_Model $model) + { + $this->model = $model; + } +} +interface Sabel_CTest_Model +{ + public function getData(); +} +interface Sabel_CTest_Result +{ +} +class Sabel_CTest_Result_Implement implements Sabel_CTest_Result +{ +} +class Sabel_CTest_Model_Implement implements Sabel_CTest_Model +{ + // @inject Sabel_CTest_Model + public function getData() + { + } +} +class Person +{ + protected $age = null; + protected $calc = null; + + public function __construct(Age $age) + { + $this->age = $age; + } + + public function howOldAreYou() + { + return $this->age->getAge(); + } + + public function setCalculator(Calculator $c) + { + $this->calc = $c; + } + + public function getCalculator() + { + if (!is_object($this->calc)) { + throw new Exception(var_export($this->calc, 1)); + } + + return $this->calc; + } + + public function calc() + { + return $this->calc->calc($this); + } +} +class Integer +{ + private $self = 0; + + public function set($num) + { + $this->self = $num; + } + + public function add($num) + { + return $this->self + $num; + } +} +interface Calculator +{ + public function calc($obj); +} +class FrastrationCalculator implements Calculator +{ + private $int = null; + + public function __construct(Integer $int) + { + $this->int = $int; + } + + public function calc($obj) + { + $this->int->set(5); + $this->int->add(5); + return 10; + } +} +class Age +{ + protected $age = 15; + + public function __construct() + { + } + + public function getAge() + { + return $this->age; + } + + public function setAge($age = 0) + { + $this->age = $age; + } +} +class SpecificSetter +{ + private $oil = null; + public function setSpecificSetter(Oil $oil) + { + $this->oil = $oil; + } +} +class MultiCar +{ + private $engine = null; + private $shaft = null; + + public function __construct($engine, $shaft) + { + $this->engine = $engine; + $this->shaft = $shaft; + } +} +class MultiEngine +{ + private $oil = null; + + public function __construct($oil) + { + $this->oil = $oil; + } +} +interface Oil +{ +} +class EngineOil implements Oil +{ + private $type = ""; + public function __construct($type) + { + $this->type = $type; + } +} +class Car +{ + private $engine = null; + + public function __construct($engine) + { + $this->engine = $engine; + } + + public function getEngine() + { + return $this->engine; + } +} +class Engine +{ + public function run(){} +} + +class AspectConfig extends Sabel_Container_Injection +{ + private $trace = null; + + public function __construct($trace) + { + $this->trace = $trace; + } + + public function configure() + { + $this->aspect("AspectTarget")->apply($this->trace)->to("run"); + } + + public function getTrace() + { + return $this->trace; + } +} + +class MultipleAspectConfig extends Sabel_Container_Injection +{ + public function configure() + { + $trace = new Trace(); + $this->aspect("AspectTarget")->apply($trace)->to("run"); + $this->aspect("AspectTarget")->apply($trace)->to("run"); + } +} + +class AspectTarget +{ + public function run($parameter) + { + return $parameter; + } + + public function runrun($parameter) + { + return $parameter; + } +} + +class BaseAspect +{ + public function after($joinpoint){} + public function before($joinpoint){} +} + +class Trace extends BaseAspect +{ + private $argument = ""; + + public function after($joinpoint) + { + $this->argument = $joinpoint->getArgument(0); + } + + public function getArgument() + { + return $this->argument; + } +} + +class Config extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Calculator")->to("FrastrationCalculator"); + } +} +class WrongClassNameConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Calculator")->to("WrongCalculator"); + } +} +class AspectToMethod extends Sabel_Container_Injection +{ + public function configure() + { + $this->aspect("AspectTarget")->apply("Trace")->to("run"); + } +} +class AspectToEveryMethods extends Sabel_Container_Injection +{ + public function configure() + { + $this->aspect("AspectTarget")->apply("Trace")->toEveryMethods(); + } +} +class AspectToMethodRegex extends Sabel_Container_Injection +{ + public function configure() + { + $this->aspect("AspectTarget")->apply("Trace")->toMethodRegex("run.+"); + } +} +class ConstructConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Car")->with("Engine"); + } +} +class StrLiteralConstructConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Car")->with("this is engine"); + } +} +class NumLiteralConstructConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Car")->with(123); + } +} +class BoolLiteralConstructConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Car")->with(true); + } +} +class SpecificSetterConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("EngineOil")->with("specific"); + $this->bind("Oil")->to("EngineOil")->setter("setSpecificSetter"); + } +} +class MultipleConstructConfig extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("MultiCar")->with("MultiEngine") + ->with("multiple"); + + $this->construct("MultiEngine")->with("Oil"); + $this->construct("EngineOil")->with("normal"); + + $this->bind("Oil")->to("EngineOil"); + } +} +class Sabel_CTest_Config extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Sabel_CTest_Model") + ->to("Sabel_CTest_Model_Implement")->setter("setModel"); + } +} +class Sabel_CTest_Config_WithoutSetter extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Sabel_CTest_Model") + ->to("Sabel_CTest_Model_Implement"); + } +} +class Sabel_CTest_Config_Construct extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Sabel_CTest_Controller_WithConstruct")->with("Sabel_CTest_Model_Implement"); + } +} +class Sabel_CTest_Config_ConstructWithBind extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Sabel_CTest_Model")->to("Sabel_CTest_Model_Implement"); + $this->construct("Sabel_CTest_Controller_WithConstruct")->with("Sabel_CTest_Model"); + } +} +class Sabel_CTest_Config_ConstructWithInvalidImplement extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Sabel_CTest_Controller")->with("Sabel_CTest_Model"); + } +} +class Sabel_CTest_Config_ConstructWithInterface extends Sabel_Container_Injection +{ + public function configure() + { + $this->construct("Sabel_CTest_Controller")->with("Sabel_CTest_Model"); + } +} diff --git a/Test/Controller/Page.php b/Test/Controller/Page.php new file mode 100755 index 0000000..dea2080 --- /dev/null +++ b/Test/Controller/Page.php @@ -0,0 +1,158 @@ + + */ +class Test_Controller_Page extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Controller_Page"); + } + + public function testSetInvalidAction() + { + $c = $this->createController(); + try { + $c->setAction(10000); + } catch (Sabel_Exception_InvalidArgument $e) { + return; + } + + $this->fail(); + } + + public function testIndexAction() + { + $c = $this->createController(); + $c->initialize(); + $c->setAction("index"); + $c->execute(); + + $this->assertTrue($c->isExecuted()); + $this->assertEquals("index", $c->getAction()); + $this->assertEquals("index", $c->getAttribute("actionResult")); + } + + public function testFugaAction() + { + $c = $this->createController(); + $c->initialize(); + $c->execute("fuga", array("10", "20", "30")); + + $this->assertEquals("10 20 30", $c->getAttribute("actionResult")); + } + + public function testReservedAction() + { + $c = $this->createController(); + $c->setAction("getRequest"); + $c->execute(); + + $this->assertFalse($c->isExecuted()); + $this->assertEquals(Sabel_Response::NOT_FOUND, $c->getResponse()->getStatus()->getCode()); + } + + public function testHiddenAction() + { + $c = $this->createController(); + $c->setAction("hiddenAction"); + $c->execute(); + + $this->assertFalse($c->isExecuted()); + $this->assertEquals(Sabel_Response::NOT_FOUND, $c->getResponse()->getStatus()->getCode()); + } + + public function testProtectedAction() + { + $c = $this->createController(); + $c->setAction("hoge"); + $c->execute(); + + $this->assertFalse($c->isExecuted()); + } + + public function testAttributesAndResponses() + { + $c = $this->createController(); + $c->setAttribute("a", "10"); + $c->setAttribute("b", "20"); + $c->assign("c", "30"); + + $this->assertEquals("10", $c->getAttribute("a")); + $this->assertEquals("20", $c->getAttribute("b")); + $this->assertEquals(null, $c->getAttribute("c")); + $this->assertEquals("30", $c->getResponse()->getResponse("c")); + } + + public function testAttributes() + { + $c = $this->createController(); + $c->setAttributes(array("a" => "10", "b" => "20")); + $this->assertEquals("10", $c->getAttribute("a")); + $this->assertEquals("20", $c->getAttribute("b")); + $this->assertEquals(null, $c->getAttribute("c")); + + $expected = array("a" => "10", "b" => "20"); + $this->assertEquals($expected, $c->getAttributes()); + } + + public function testIsAttributeSet() + { + $c = $this->createController(); + $c->setAttribute("a", "10"); + $this->assertTrue($c->isAttributeSet("a")); + $c->setAttribute("b", null); + $this->assertFalse($c->isAttributeSet("b")); + } + + public function testHasAttribute() + { + $c = $this->createController(); + $c->setAttribute("a", "10"); + $this->assertTrue($c->hasAttribute("a")); + $c->setAttribute("b", null); + $this->assertTrue($c->hasAttribute("b")); + } + + public function testMagickMethods() + { + $c = $this->createController(); + $c->a = "10"; + $c->b = "20"; + $this->assertEquals("10", $c->a); + $this->assertEquals("20", $c->b); + $this->assertEquals(null, $c->c); + $this->assertEquals("10", $c->getAttribute("a")); + $this->assertEquals("20", $c->getAttribute("b")); + } + + protected function createController() + { + $c = new TestController; + $c->setResponse(new Sabel_Response_Object()); + + return $c; + } +} + +class TestController extends Sabel_Controller_Page +{ + protected $hidden = array("hiddenAction"); + + public function index() + { + $this->actionResult = "index"; + } + + public function fuga($a, $b, $c) + { + $this->actionResult = "$a $b $c"; + } + + public function hiddenAction() {} + protected function hoge() {} +} diff --git a/Test/Controller/Tests.php b/Test/Controller/Tests.php new file mode 100755 index 0000000..77dd9b2 --- /dev/null +++ b/Test/Controller/Tests.php @@ -0,0 +1,14 @@ +addTest(Test_Controller_Page::suite()); + + return $suite; + } +} diff --git a/Test/Cookie/InMemory.php b/Test/Cookie/InMemory.php new file mode 100755 index 0000000..4482d5b --- /dev/null +++ b/Test/Cookie/InMemory.php @@ -0,0 +1,77 @@ + + */ +class Test_Cookie_InMemory extends SabelTestCase +{ + private $cookie = null; + + public static function suite() + { + return self::createSuite("Test_Cookie_InMemory"); + } + + public function setUp() + { + $this->cookie = Sabel_Cookie_InMemory::create(); + } + + public function testSimple() + { + $this->cookie->set("foo", "10"); + $this->assertEquals("10", $this->cookie->get("foo")); + $this->assertEquals(null, $this->cookie->get("bar")); + } + + public function testPath() + { + $this->setUri("/"); + $this->cookie->set("bar", "20", array("path" => "/bar")); + $this->assertEquals(null, $this->cookie->get("bar")); + + # request: http://localhost/foo + $this->setUri("/foo"); + $this->assertEquals(null, $this->cookie->get("bar")); + + # request: http://localhost/bar + $this->setUri("/bar"); + $this->assertEquals("20", $this->cookie->get("bar")); + + # request: http://localhost/bar/baz + $this->setUri("/bar/baz"); + $this->assertEquals("20", $this->cookie->get("bar")); + } + + public function testExpire() + { + $this->setUri("/"); + $this->cookie->set("hoge", "30"); + $this->assertEquals("30", $this->cookie->get("hoge")); + + $this->cookie->set("hoge", "30", array("expire" => time() - 3600)); + $this->assertEquals(null, $this->cookie->get("hoge")); + } + + public function testDelete() + { + $this->setUri("/"); + $this->assertNotNull($this->cookie->get("foo")); + + $this->cookie->delete("foo"); + $this->assertNull($this->cookie->get("foo")); + } + + protected function setUri($uri) + { + $bus = Sabel_Context::getContext()->getBus(); + if (is_object($bus) && ($request = $bus->get("request"))) { + $request->setUri($uri); + } + + $_SERVER["REQUEST_URI"] = $uri; + } +} diff --git a/Test/Cookie/Tests.php b/Test/Cookie/Tests.php new file mode 100755 index 0000000..7c8b8e0 --- /dev/null +++ b/Test/Cookie/Tests.php @@ -0,0 +1,14 @@ +addTest(Test_Cookie_InMemory::suite()); + + return $suite; + } +} diff --git a/Test/DB/Config.php b/Test/DB/Config.php new file mode 100755 index 0000000..2446fb8 --- /dev/null +++ b/Test/DB/Config.php @@ -0,0 +1,115 @@ + + */ +class Test_DB_Config extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_Config"); + } + + public function testInitialize() + { + Sabel_Db_Config::initialize(new TestDatabaseConfig()); + $config = Sabel_Db_Config::get("configtest"); + $this->assertEquals("localhost", $config["host"]); + $this->assertEquals("mydb", $config["database"]); + } + + public function testDefaultSchemaName() + { + $params = array("package" => "sabel.db.mysql", + "database" => "mydb"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("mydb", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.pgsql", + "database" => "mydb"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("public", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.pdo.pgsql", + "database" => "mydb"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("public", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.oci", + "database" => "mydb", "user" => "webuser"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("WEBUSER", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.pdo.oci", + "database" => "mydb", "user" => "webuser"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("WEBUSER", Sabel_Db_Config::getSchemaName("configtest")); + } + + public function testSchemaNameSet() + { + $params = array("package" => "sabel.db.mysql", + "database" => "mydb", "schema" => "hoge"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("hoge", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.pgsql", + "database" => "mydb", "schema" => "hoge"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("hoge", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "sabel.db.oci", + "database" => "mydb", "schema" => "HOGE"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("HOGE", Sabel_Db_Config::getSchemaName("configtest")); + } + + public function testSchemaNameOfCustomPackage() + { + $params = array("package" => "my.db.org", + "database" => "mydb", "schema" => "hoge"); + + Sabel_Db_Config::add("configtest", $params); + $this->assertEquals("hoge", Sabel_Db_Config::getSchemaName("configtest")); + + $params = array("package" => "my.db.org", + "database" => "mydb"); + + Sabel_Db_Config::add("configtest", $params); + + try { + Sabel_Db_Config::getSchemaName("configtest"); + } catch (Sabel_Db_Exception $e) { + return; + } + + $this->fail(); + } +} + +class TestDatabaseConfig implements Sabel_Config +{ + public function configure() + { + $params = array("configtest" => array( + "package" => "sabel.db.mysql", + "host" => "localhost", + "database" => "mydb", + "user" => "root", + "password" => "") + ); + + return $params; + } +} diff --git a/Test/DB/Ibase.php b/Test/DB/Ibase.php new file mode 100755 index 0000000..7e7b20e --- /dev/null +++ b/Test/DB/Ibase.php @@ -0,0 +1,50 @@ + + */ +class Test_DB_Ibase extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Ibase"); + } + + public function testConnectionRefused() + { + $params = array("package" => "sabel.db.ibase", + "host" => "localhost", + "user" => "hogehoge", + "password" => "fugafuga", + "database" => "/home/firebird/sdb_test.fdb"); + + Sabel_Db_Config::add("conrefused", $params); + $driver = new Sabel_Db_Ibase_Driver("conrefused"); + + try { + $c = error_reporting(0); + $resource = Sabel_Db_Connection::connect($driver); + error_reporting($c); + } catch (Sabel_Db_Exception_Connection $e) { + return; + } + + $this->fail(); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getIbaseConfig()); + Test_DB_Test::$db = "IBASE"; + } + + public function testDefinedValue() + { + $this->assertEquals(8, IBASE_COMMITTED); + $this->assertEquals(32, IBASE_REC_NO_VERSION); + $this->assertEquals(40, IBASE_COMMITTED|IBASE_REC_NO_VERSION); + } +} diff --git a/Test/DB/Mssql.php b/Test/DB/Mssql.php new file mode 100755 index 0000000..ab8bd97 --- /dev/null +++ b/Test/DB/Mssql.php @@ -0,0 +1,21 @@ + + */ +class Test_DB_Mssql extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Mssql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMssqlConfig()); + Test_DB_Test::$db = "MSSQL"; + } +} diff --git a/Test/DB/Mysql.php b/Test/DB/Mysql.php new file mode 100755 index 0000000..2a973e6 --- /dev/null +++ b/Test/DB/Mysql.php @@ -0,0 +1,43 @@ + + */ +class Test_DB_Mysql extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Mysql"); + } + + public function testConnectionRefused() + { + $params = array("package" => "sabel.db.mysql", + "host" => "127.0.0.1", + "user" => "hogehoge", + "password" => "fugafuga", + "database" => "sdb_test"); + + Sabel_Db_Config::add("conrefused", $params); + $driver = new Sabel_Db_Mysql_Driver("conrefused"); + + try { + $c = error_reporting(0); + $resource = Sabel_Db_Connection::connect($driver); + error_reporting($c); + } catch (Sabel_Db_Exception_Connection $e) { + return; + } + + $this->fail(); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMysqlConfig()); + Test_DB_Test::$db = "MYSQL"; + } +} diff --git a/Test/DB/Mysqli.php b/Test/DB/Mysqli.php new file mode 100755 index 0000000..0e20ab6 --- /dev/null +++ b/Test/DB/Mysqli.php @@ -0,0 +1,43 @@ + + */ +class Test_DB_Mysqli extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Mysqli"); + } + + public function testConnectionRefused() + { + $params = array("package" => "sabel.db.mysqli", + "host" => "127.0.0.1", + "user" => "hogehoge", + "password" => "fugafuga", + "database" => "sdb_test"); + + Sabel_Db_Config::add("conrefused", $params); + $driver = new Sabel_Db_Mysqli_Driver("conrefused"); + + try { + $c = error_reporting(0); + $resource = Sabel_Db_Connection::connect($driver); + error_reporting($c); + } catch (Sabel_Db_Exception_Connection $e) { + return; + } + + $this->fail(); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMysqliConfig()); + Test_DB_Test::$db = "MYSQL"; + } +} diff --git a/Test/DB/Oci.php b/Test/DB/Oci.php new file mode 100755 index 0000000..d21d8b9 --- /dev/null +++ b/Test/DB/Oci.php @@ -0,0 +1,44 @@ + + */ +class Test_DB_Oci extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Oci"); + } + + public function testConnectionRefused() + { + $params = array("package" => "sabel.db.oci", + "host" => "127.0.0.1", + "user" => "hogehoge", + "password" => "fugafuga", + "database" => "XE", + "charset" => "UTF-8"); + + Sabel_Db_Config::add("conrefused", $params); + $driver = new Sabel_Db_Oci_Driver("conrefused"); + + try { + $c = error_reporting(0); + $resource = Sabel_Db_Connection::connect($driver); + error_reporting($c); + } catch (Sabel_Db_Exception_Connection $e) { + return; + } + + $this->fail(); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getOciConfig()); + Test_DB_Test::$db = "ORACLE"; + } +} diff --git a/Test/DB/PdoMysql.php b/Test/DB/PdoMysql.php new file mode 100755 index 0000000..a73dcae --- /dev/null +++ b/Test/DB/PdoMysql.php @@ -0,0 +1,15 @@ + "sabel.db.pdo.oci", + "host" => "127.0.0.1", + "user" => "develop", + "password" => "develop", + "database" => "xe"); + + public static function main() + { + require_once "PHPUnit/TextUI/TestRunner.php"; + + $suite = new PHPUnit_Framework_TestSuite("Test_DB_PdoOci"); + $result = PHPUnit_TextUI_TestRunner::run($suite); + } + + public static function suite() + { + return self::createSuite("Test_DB_PdoOci"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", self::$params1); + Test_DB_Test::$db = "PDO_ORACLE"; + } +} diff --git a/Test/DB/PdoPgsql.php b/Test/DB/PdoPgsql.php new file mode 100755 index 0000000..c140c38 --- /dev/null +++ b/Test/DB/PdoPgsql.php @@ -0,0 +1,15 @@ + + */ +class Test_DB_Pgsql extends Test_DB_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Pgsql"); + } + + public function testConnectionRefused() + { + return; + $params = array("package" => "sabel.db.pgsql", + "host" => "localhost", + "user" => "hogehoge", + "password" => "fugafuga", + "database" => "sdb_test"); + + Sabel_Db_Config::add("conrefused", $params); + $driver = new Sabel_Db_Pgsql_Driver("conrefused"); + + try { + $c = error_reporting(0); + $resource = Sabel_Db_Connection::connect($driver); + error_reporting($c); + } catch (Sabel_Db_Exception_Connection $e) { + return; + } + + $this->fail(); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPgsqlConfig()); + Test_DB_Test::$db = "PGSQL"; + } +} diff --git a/Test/DB/SQLite.php b/Test/DB/SQLite.php new file mode 100755 index 0000000..f4c41ba --- /dev/null +++ b/Test/DB/SQLite.php @@ -0,0 +1,15 @@ + + */ +class Test_DB_SchemaColumn extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_SchemaColumn"); + } + + public function testIntegerCast() + { + $ts = MODEL("TestSchema"); + + $ts->intcol = "0"; + $this->assertEquals(0, $ts->intcol); + + $ts->intcol = "10"; + $this->assertEquals(10, $ts->intcol); + + $ts->intcol = "100.000"; + $this->assertEquals(100, $ts->intcol); + + $ts->intcol = "100.000.000"; + $this->assertEquals("100.000.000", $ts->intcol); + + $ts->intcol = 10000000000; + $this->assertEquals(10000000000, $ts->intcol); + $this->assertTrue(is_float($ts->intcol)); + + $ts->intcol = 1000000000.0; + $this->assertEquals(1000000000, $ts->intcol); + $this->assertTrue(is_int($ts->intcol)); + + $ts->intcol = false; + $this->assertEquals(false, $ts->intcol); + + $ts->intcol = true; + $this->assertEquals(true, $ts->intcol); + } + + public function testSmallIntegerCast() + { + $ts = MODEL("TestSchema"); + + $ts->sintcol = "0"; + $this->assertEquals(0, $ts->sintcol); + + $ts->sintcol = "10"; + $this->assertEquals(10, $ts->sintcol); + + $ts->sintcol = "100.000"; + $this->assertEquals(100, $ts->sintcol); + + $ts->sintcol = "100.000.000"; + $this->assertEquals("100.000.000", $ts->sintcol); + + $ts->sintcol = 10000000000; + $this->assertEquals(10000000000, $ts->sintcol); + $this->assertTrue(is_float($ts->sintcol)); + + $ts->sintcol = 10000.0; + $this->assertEquals(10000, $ts->sintcol); + $this->assertTrue(is_int($ts->sintcol)); + + $ts->sintcol = false; + $this->assertEquals(false, $ts->sintcol); + + $ts->sintcol = true; + $this->assertEquals(true, $ts->sintcol); + } + + public function testBooleanCast() + { + $ts = MODEL("TestSchema"); + + $ts->boolcol = 1; + $this->assertTrue($ts->boolcol); + + $ts->boolcol = "1"; + $this->assertTrue($ts->boolcol); + + $ts->boolcol = "t"; + $this->assertTrue($ts->boolcol); + + $ts->boolcol = "true"; + $this->assertTrue($ts->boolcol); + + $ts->boolcol = 0; + $this->assertFalse($ts->boolcol); + + $ts->boolcol = "0"; + $this->assertFalse($ts->boolcol); + + $ts->boolcol = "f"; + $this->assertFalse($ts->boolcol); + + $ts->boolcol = "false"; + $this->assertFalse($ts->boolcol); + + $ts->boolcol = 10; + $this->assertEquals(10, $ts->boolcol); + + $ts->boolcol = "abc"; + $this->assertEquals("abc", $ts->boolcol); + } + + public function testFloatCast() + { + $ts = MODEL("TestSchema"); + + $ts->floatcol = 1; + $this->assertTrue(is_float($ts->floatcol)); + $this->assertEquals(1, $ts->floatcol); + + $ts->floatcol = "1"; + $this->assertTrue(is_float($ts->floatcol)); + $this->assertEquals(1, $ts->floatcol); + + $ts->floatcol = "0.123"; + $this->assertTrue(is_float($ts->floatcol)); + $this->assertEquals(0.123, $ts->floatcol); + + $ts->floatcol = "0.123.456"; + $this->assertFalse(is_float($ts->floatcol)); + $this->assertEquals("0.123.456", $ts->floatcol); + + $ts->floatcol = true; + $this->assertFalse(is_float($ts->floatcol)); + $this->assertEquals(true, $ts->floatcol); + } +} + +class Schema_TestSchema +{ + public static function get() + { + $cols = array(); + + $cols['intcol'] = array('type' => Sabel_Db_Type::INT, + 'max' => PHP_INT_MAX, + 'min' => -PHP_INT_MAX - 1, + 'increment' => false, + 'nullable' => true, + 'primary' => false, + 'default' => null); + + $cols['sintcol'] = array('type' => Sabel_Db_Type::SMALLINT, + 'max' => 32767, + 'min' => -32768, + 'increment' => false, + 'nullable' => true, + 'primary' => false, + 'default' => null); + + $cols['boolcol'] = array('type' => Sabel_Db_Type::BOOL, + 'increment' => false, + 'nullable' => true, + 'primary' => false, + 'default' => null); + + $cols['floatcol'] = array('type' => Sabel_Db_Type::FLOAT, + 'min' => -3.4028235E+38, + 'max' => 3.4028235E+38, + 'increment' => false, + 'nullable' => true, + 'primary' => false, + 'default' => null); + + return $cols; + } + + public function getProperty() + { + $property = array(); + + $property["tableEngine"] = null; + $property["uniques"] = null; + $property["fkeys"] = null; + + return $property; + } +} diff --git a/Test/DB/Statement/Ibase.php b/Test/DB/Statement/Ibase.php new file mode 100755 index 0000000..6896ad1 --- /dev/null +++ b/Test/DB/Statement/Ibase.php @@ -0,0 +1,52 @@ + + */ +class Test_DB_Statement_Ibase extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_Statement_Ibase"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getIbaseConfig()); + } + + public function testQuoteIdentifier() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals('"FOO"', $stmt->quoteIdentifier("foo")); + $this->assertEquals('"BAR"', $stmt->quoteIdentifier("bar")); + } + + public function testBuildSelectQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT"'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectWhereQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->where('WHERE "ID" = 1'); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT" WHERE "ID" = 1'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testClose() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } +} diff --git a/Test/DB/Statement/Mysql.php b/Test/DB/Statement/Mysql.php new file mode 100755 index 0000000..363a1a5 --- /dev/null +++ b/Test/DB/Statement/Mysql.php @@ -0,0 +1,78 @@ + + */ +class Test_DB_Statement_Mysql extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_Statement_Mysql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMysqlConfig()); + } + + public function testQuoteIdentifier() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals("`foo`", $stmt->quoteIdentifier("foo")); + $this->assertEquals("`bar`", $stmt->quoteIdentifier("bar")); + } + + public function testBuildSelectQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $expected = "SELECT `id`, `name` FROM `student`"; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectWhereQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->where("WHERE `id` = 1"); + $expected = "SELECT `id`, `name` FROM `student` WHERE `id` = 1"; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => array("mode" => "DESC", "nulls" => "LAST")))); + $expected = "SELECT `id`, `name` FROM `student` ORDER BY `id` IS NULL, `id` DESC"; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery2() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => array("mode" => "DESC", "nulls" => "LAST"), "name" => array("mode" => "ASC", "nulls" => "LAST")))); + $expected = "SELECT `id`, `name` FROM `student` ORDER BY `id` IS NULL, `id` DESC, `name` IS NULL, `name` ASC"; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testEscapeString() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals(array("'a\'b\\\\z'"), $stmt->escape(array("a'b\z"))); + } + + public function testClose() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } +} diff --git a/Test/DB/Statement/Oci.php b/Test/DB/Statement/Oci.php new file mode 100755 index 0000000..54f3029 --- /dev/null +++ b/Test/DB/Statement/Oci.php @@ -0,0 +1,72 @@ + + */ +class Test_DB_Statement_Oci extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_Statement_Oci"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getOciConfig()); + } + + public function testQuoteIdentifier() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals('"FOO"', $stmt->quoteIdentifier("foo")); + $this->assertEquals('"BAR"', $stmt->quoteIdentifier("bar")); + } + + public function testBuildSelectQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT"'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectWhereQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->where('WHERE "ID" = 1'); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT" WHERE "ID" = 1'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => "DESC"))); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT" ORDER BY "ID" DESC'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery2() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => "DESC", "name" => "ASC"))); + $expected = 'SELECT "ID", "NAME" FROM "STUDENT" ORDER BY "ID" DESC, "NAME" ASC'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testClose() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } +} diff --git a/Test/DB/Statement/Pgsql.php b/Test/DB/Statement/Pgsql.php new file mode 100755 index 0000000..8b7ceff --- /dev/null +++ b/Test/DB/Statement/Pgsql.php @@ -0,0 +1,78 @@ + + */ +class Test_DB_Statement_Pgsql extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_DB_Statement_Pgsql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPgsqlConfig()); + } + + public function testQuoteIdentifier() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals('"foo"', $stmt->quoteIdentifier("foo")); + $this->assertEquals('"bar"', $stmt->quoteIdentifier("bar")); + } + + public function testBuildSelectQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $expected = 'SELECT "id", "name" FROM "student"'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectWhereQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->where('WHERE "id" = 1'); + $expected = 'SELECT "id", "name" FROM "student" WHERE "id" = 1'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => "DESC"))); + $expected = 'SELECT "id", "name" FROM "student" ORDER BY "id" DESC'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testBuildSelectOrderByQuery2() + { + $stmt = Sabel_Db::createStatement("default"); + $stmt->type(Sabel_Db_Statement::SELECT); + $stmt->setMetadata(Sabel_Db_Metadata::getTableInfo("student")); + $stmt->constraints(array("order" => array("id" => "DESC", "name" => "ASC"))); + $expected = 'SELECT "id", "name" FROM "student" ORDER BY "id" DESC, "name" ASC'; + $this->assertEquals($expected, $stmt->getQuery()); + } + + public function testEscapeString() + { + $stmt = Sabel_Db::createStatement("default"); + $this->assertEquals(array("'a''b\\\\z'"), $stmt->escape(array("a'b\z"))); + } + + public function testClose() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } +} diff --git a/Test/DB/Statement/Tests.php b/Test/DB/Statement/Tests.php new file mode 100755 index 0000000..cdbad0b --- /dev/null +++ b/Test/DB/Statement/Tests.php @@ -0,0 +1,43 @@ + + */ +class Test_DB_Statement_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + if (extension_loaded("mysql")) { + $suite->addTest(Test_DB_Statement_Mysql::suite()); + } + + if (extension_loaded("pgsql")) { + $suite->addTest(Test_DB_Statement_Pgsql::suite()); + } + + if (extension_loaded("oci8")) { + $suite->addTest(Test_DB_Statement_Oci::suite()); + } + + if (extension_loaded("interbase")) { + $suite->addTest(Test_DB_Statement_Ibase::suite()); + } + + return $suite; + } +} diff --git a/Test/DB/Storage/Ibase.php b/Test/DB/Storage/Ibase.php new file mode 100755 index 0000000..bc8e1bf --- /dev/null +++ b/Test/DB/Storage/Ibase.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_Ibase extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_Ibase"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getIbaseConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/Mysql.php b/Test/DB/Storage/Mysql.php new file mode 100755 index 0000000..6b34584 --- /dev/null +++ b/Test/DB/Storage/Mysql.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_Mysql extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_Mysql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMysqlConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/Mysqli.php b/Test/DB/Storage/Mysqli.php new file mode 100755 index 0000000..9cf3c6f --- /dev/null +++ b/Test/DB/Storage/Mysqli.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_Mysqli extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_Mysqli"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getMysqliConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/Oci.php b/Test/DB/Storage/Oci.php new file mode 100755 index 0000000..3599f24 --- /dev/null +++ b/Test/DB/Storage/Oci.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_Oci extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_Oci"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getOciConfig()); + MODEL("Sblkvs")->delete(); + } +} diff --git a/Test/DB/Storage/PdoMysql.php b/Test/DB/Storage/PdoMysql.php new file mode 100755 index 0000000..ccb843a --- /dev/null +++ b/Test/DB/Storage/PdoMysql.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_PdoMysql extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_PdoMysql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPdoMysqlConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/PdoOci.php b/Test/DB/Storage/PdoOci.php new file mode 100755 index 0000000..4505478 --- /dev/null +++ b/Test/DB/Storage/PdoOci.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_PdoOci extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_PdoOci"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPdoOciConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/PdoPgsql.php b/Test/DB/Storage/PdoPgsql.php new file mode 100755 index 0000000..fb1c4db --- /dev/null +++ b/Test/DB/Storage/PdoPgsql.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_PdoPgsql extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_PdoPgsql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPdoPgsqlConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/PdoSqlite.php b/Test/DB/Storage/PdoSqlite.php new file mode 100755 index 0000000..b1b016e --- /dev/null +++ b/Test/DB/Storage/PdoSqlite.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_PdoSqlite extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_PdoSqlite"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPdoSqliteConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/Pgsql.php b/Test/DB/Storage/Pgsql.php new file mode 100755 index 0000000..194eea5 --- /dev/null +++ b/Test/DB/Storage/Pgsql.php @@ -0,0 +1,19 @@ + + */ +class Test_DB_Storage_Pgsql extends Test_DB_Storage_Test +{ + public static function suite() + { + return self::createSuite("Test_DB_Storage_Pgsql"); + } + + public function testInit() + { + Sabel_Db_Config::add("default", Test_DB_TestConfig::getPgsqlConfig()); + MODEL("SblKvs")->delete(); + } +} diff --git a/Test/DB/Storage/Test.php b/Test/DB/Storage/Test.php new file mode 100755 index 0000000..0326f20 --- /dev/null +++ b/Test/DB/Storage/Test.php @@ -0,0 +1,58 @@ + + */ +class Test_DB_Storage_Test extends SabelTestCase +{ + public function testStore() + { + $obj = new SblStorageTestObj(); + $obj->hoge = array("int" => 10, "bool" => true); + + $stdClass = new stdClass(); + $stdClass->int = 20; + $stdClass->bool = false; + $obj->fuga = $stdClass; + + $storage = Sabel_Kvs_Database::create(); + $storage->write("hashkey", $obj, 60); + } + + public function testFetch() + { + $storage = Sabel_Kvs_Database::create(); + $obj = $storage->read("hashkey"); + + $hoge = $obj->hoge; + $fuga = $obj->fuga; + + $this->assertEquals(10, $hoge["int"]); + $this->assertEquals(true, $hoge["bool"]); + $this->assertEquals(20, $fuga->int); + $this->assertEquals(false, $fuga->bool); + } + + public function testClose() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } +} + +class SblStorageTestObj extends Sabel_Object +{ + const FOO = "FOO"; + + private $foo = null; + protected $bar = 0; + public $baz = false; + + public $hoge = null; + public $fuga = null; + + private function foo() {} + protected function bar() {} + public function baz() {} +} diff --git a/Test/DB/Storage/Tests.php b/Test/DB/Storage/Tests.php new file mode 100755 index 0000000..9769b98 --- /dev/null +++ b/Test/DB/Storage/Tests.php @@ -0,0 +1,69 @@ + + */ +class Test_DB_Storage_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + if (extension_loaded("mysql")) { + $suite->addTest(Test_DB_Storage_Mysql::suite()); + } + + if (extension_loaded("mysqli")) { + $suite->addTest(Test_DB_Storage_Mysqli::suite()); + } + + if (extension_loaded("pgsql")) { + $suite->addTest(Test_DB_Storage_Pgsql::suite()); + } + + if (extension_loaded("oci8")) { + $suite->addTest(Test_DB_Storage_Oci::suite()); + } + + if (extension_loaded("interbase")) { + $suite->addTest(Test_DB_Storage_Ibase::suite()); + } + + if (extension_loaded("pdo_sqlite")) { + $suite->addTest(Test_DB_Storage_PdoSqlite::suite()); + } + + if (extension_loaded("pdo_mysql")) { + $suite->addTest(Test_DB_Storage_PdoMysql::suite()); + } + + if (extension_loaded("pdo_pgsql")) { + $suite->addTest(Test_DB_Storage_PdoPgsql::suite()); + } + + if (extension_loaded("pdo_oci")) { + $suite->addTest(Test_DB_Storage_PdoOci::suite()); + } + + return $suite; + } +} diff --git a/Test/DB/Test.php b/Test/DB/Test.php new file mode 100755 index 0000000..b2a14b2 --- /dev/null +++ b/Test/DB/Test.php @@ -0,0 +1,614 @@ + + */ +class Test_DB_Test extends SabelTestCase +{ + public static $db = ""; + public static $tables = array("schema_test", "grandchildren", "children", + "parents", "grandparents", "student_course", "student", "course"); + + protected static $lastStId = null; + + public function testClean() + { + $tables = self::$tables; + $driver = Sabel_Db::createDriver("default"); + + foreach ($tables as $table) { + $driver->execute("DELETE FROM $table"); + } + } + + public function testInsert() + { + $st = MODEL("SchemaTest"); + $generatedId = $st->insert(array("email" => "test1@example.com", "bl" => true)); + $this->assertTrue(is_numeric($generatedId)); + } + + public function testInsertBySave() + { + $st = MODEL("SchemaTest"); + $st->email = "test2@example.com"; + $st->bl = false; + + $st->save(); + + // default values. + $this->assertEquals("default name", $st->name); + $this->assertEquals("90000000000", $st->bint); + $this->assertEquals(30000, $st->sint); + $this->assertEquals(10.234, $st->ft); + $this->assertEquals(10.23456, $st->dbl); + + self::$lastStId = $st->id; + } + + public function testSelectOne() + { + $st = MODEL("SchemaTest"); + $st = $st->selectOne(self::$lastStId); + + $this->assertTrue($st->isSelected()); + $this->assertEquals("test2@example.com", $st->email); + $this->assertEquals(false, $st->bl); + } + + public function testInitSelect() + { + $st = MODEL("SchemaTest", self::$lastStId); + $this->assertTrue($st->isSelected()); + $this->assertEquals("test2@example.com", $st->email); + $this->assertEquals(false, $st->bl); + } + + public function testUpdate() + { + $st = MODEL("SchemaTest"); + $st->setCondition(self::$lastStId); + $st->update(array("bl" => true)); + + $st = MODEL("SchemaTest", self::$lastStId); + $this->assertEquals("test2@example.com", $st->email); + $this->assertEquals(true, $st->bl); + } + + public function testUpdateBySave() + { + $st = MODEL("SchemaTest", self::$lastStId); + $st->email = "test2@updated.com"; + $st->bl = false; + $affectedRows = $st->save(); # update + + $this->assertEquals(1, $affectedRows); + + $st = MODEL("SchemaTest", self::$lastStId); + $this->assertEquals("test2@updated.com", $st->email); + $this->assertEquals(false, $st->bl); + } + + public function testCount() + { + $st = MODEL("SchemaTest"); + $this->assertEquals(2, $st->getCount()); + + $st->setCondition(self::$lastStId); + $this->assertEquals(1, $st->getCount()); + + $this->assertEquals(1, $st->getCount("email", "test2@updated.com")); + } + + public function testDelete() + { + $st = MODEL("SchemaTest"); + $st->setCondition(self::$lastStId); + $st->delete(); + + $this->assertEquals(1, $st->getCount()); + $affectedRows = $st->delete("email", "test1@example.com"); + $this->assertEquals(1, $affectedRows); + $this->assertEquals(0, $st->getCount()); + $this->insertTestData(); + } + + public function testJoin1() + { + $this->insertJoinTableData(); + $join = new Sabel_Db_Join("Grandchildren"); + $join->setOrderBy("Grandchildren.id"); + $results = $join->add("Children")->select(); + + $this->assertEquals(2, count($results)); + $this->assertEquals("grandchildren1", $results[0]->value); + $this->assertEquals("grandchildren2", $results[1]->value); + $this->assertEquals("children2", $results[0]->Children->value); + $this->assertEquals("children1", $results[1]->Children->value); + } + + public function testJoin2() + { + $join = new Sabel_Db_Join("Grandchildren"); + $join->setOrderBy("Grandchildren.id"); + $chilren = new Sabel_Db_Join_Relation("Children"); + $results = $join->add($chilren->add("Parents"))->select(); + + $this->assertEquals(2, count($results)); + $this->assertEquals("children2", $results[0]->Children->value); + $this->assertEquals("children1", $results[1]->Children->value); + $this->assertEquals("parents1", $results[0]->Children->Parents->value); + $this->assertEquals("parents2", $results[1]->Children->Parents->value); + } + + public function testJoin3() + { + $join = new Sabel_Db_Join("Grandchildren"); + $join->setOrderBy("Grandchildren.id"); + $children = new Sabel_Db_Join_Relation("Children"); + $parents = new Sabel_Db_Join_Relation("Parents"); + $results = $join->add($children->add($parents->add("Grandparents")))->select(); + + $this->assertEquals(2, count($results)); + $this->assertEquals("children2", $results[0]->Children->value); + $this->assertEquals("children1", $results[1]->Children->value); + $this->assertEquals("parents1", $results[0]->Children->Parents->value); + $this->assertEquals("parents2", $results[1]->Children->Parents->value); + $this->assertEquals("grandparents2", $results[0]->Children->Parents->Grandparents->value); + $this->assertEquals("grandparents1", $results[1]->Children->Parents->Grandparents->value); + } + + public function testJoinCondition() + { + $join = new Sabel_Db_Join("Grandchildren"); + $join->setCondition("Grandparents.value", "grandparents2"); + $children = new Sabel_Db_Join_Relation("Children"); + $parents = new Sabel_Db_Join_Relation("Parents"); + + $results = $join->add($children->add($parents->add("Grandparents")))->select(); + $this->assertEquals(1, count($results)); + $this->assertEquals("children2", $results[0]->Children->value); + $this->assertEquals("parents1", $results[0]->Children->Parents->value); + $this->assertEquals("grandparents2", $results[0]->Children->Parents->Grandparents->value); + } + + public function testEqualCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select("sint", 200); + $this->assertEquals(2, count($results)); + + $results = $st->select(Condition::create(EQUAL, "sint", 200)); + $this->assertEquals(2, count($results)); + + $st->setCondition("sint", 100); + $st->setCondition("name", "name2"); + $results = $st->select(); + $this->assertEquals(1, count($results)); + $this->assertEquals("test2@example.com", $results[0]->email); + + $st->setCondition("sint", 100); + $st->setCondition("name", "name5"); + $this->assertEquals(0, count($st->select())); + } + + public function testBetweenCondition() + { + $st = MODEL("SchemaTest"); + $between = array("2008-01-06", "2008-01-10"); + $results = $st->select(Condition::create(BETWEEN, "dt", $between)); + $this->assertEquals(5, count($results)); + + $st->setCondition("bl", true); + $st->setCondition(Condition::create(BETWEEN, "dt", $between)); + $this->assertEquals(4, count($st->select())); + } + + public function testGreaterCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select(Condition::create(GREATER_THAN, "sint", 300)); + $this->assertEquals(4, count($results)); + + $results = $st->select(Condition::create(GREATER_EQUAL, "sint", 300)); + $this->assertEquals(6, count($results)); + + $st->setCondition(Condition::create(GREATER_EQUAL, "sint", 300)); + $st->setCondition("bl", false); + $this->assertEquals(1, count($st->select())); + } + + public function testLessCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select(Condition::create(LESS_THAN, "sint", 300)); + $this->assertEquals(4, count($results)); + + $results = $st->select(Condition::create(LESS_EQUAL, "sint", 300)); + $this->assertEquals(6, count($results)); + + $st->setCondition(Condition::create(LESS_EQUAL, "sint", 300)); + $st->setCondition("bl", false); + $this->assertEquals(3, count($st->select())); + } + + public function testIsNullCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select(Condition::create(ISNULL, "txt")); + $this->assertEquals(8, count($results)); + + $this->assertEquals(4, count($st->select("bl", false))); + + $st->setCondition(Condition::create(ISNULL, "txt")); + $st->setCondition("bl", false); + $this->assertEquals(3, count($st->select())); + } + + public function testIsNotNullCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select(Condition::create(ISNOTNULL, "txt")); + $this->assertEquals(2, count($results)); + } + + public function testLikeCondition() + { + $st = MODEL("SchemaTest"); + $results = $st->select(Condition::create(LIKE, "name", "name")); + $this->assertEquals(10, count($results)); + + $like = Condition::create(LIKE, "name", "0")->type(LIKE_ENDS_WITH); + $this->assertEquals(1, count($st->select($like))); + + $like = Condition::create(LIKE, "name", "a")->type(LIKE_ENDS_WITH); + $this->assertEquals(0, count($st->select($like))); + } + + public function testInCondition() + { + // Segfault... + if (self::$db === "PDO_ORACLE") return; + + $st = MODEL("SchemaTest"); + $st->setCondition(Condition::create(IN, "name", array("name1", "name3", "name5"))); + $st->setOrderBy("id"); + $results = $st->select(); + + $this->assertEquals(3, count($results)); + $this->assertEquals("name1", $results[0]->name); + $this->assertEquals("name3", $results[1]->name); + $this->assertEquals("name5", $results[2]->name); + } + + public function testOrCondition() + { + $st = MODEL("SchemaTest"); + $or = new Sabel_Db_Condition_Or(); + $or->add(Condition::create(EQUAL, "sint", 200)); + $or->add(Condition::create(EQUAL, "email", "test9@example.com")); + $st->setOrderBy("id"); + $results = $st->select($or); + + $this->assertEquals(3, count($results)); + $this->assertEquals("test3@example.com", $results[0]->email); + $this->assertEquals("test4@example.com", $results[1]->email); + $this->assertEquals("test9@example.com", $results[2]->email); + } + + public function testOrCondition2() + { + $st = MODEL("SchemaTest"); + $or = new Sabel_Db_Condition_Or(); + $or->add(Condition::create(EQUAL, "sint", 100)); + $or->add(Condition::create(BETWEEN, "dt", array("2008-01-07", "2008-01-09"))); + $st->setOrderBy("id"); + $results = $st->select($or); + + $this->assertEquals(5, count($results)); + $this->assertEquals("test1@example.com", $results[0]->email); + $this->assertEquals("test2@example.com", $results[1]->email); + $this->assertEquals("test7@example.com", $results[2]->email); + $this->assertEquals("test8@example.com", $results[3]->email); + $this->assertEquals("test9@example.com", $results[4]->email); + } + + public function testOrAndOrCondition() + { + $st = MODEL("SchemaTest"); + $or1 = new Sabel_Db_Condition_Or(); + $or1->add(Condition::create(EQUAL, "sint", 100)); + $or1->add(Condition::create(EQUAL, "sint", 300)); + $or2 = new Sabel_Db_Condition_Or(); + $or2->add(Condition::create(EQUAL, "sint", 300)); + $or2->add(Condition::create(EQUAL, "sint", 500)); + $st->setOrderBy("id"); + + $st->setCondition($or1); + $st->setCondition($or2); + + $results = $st->select(); + + $this->assertEquals(2, count($results)); + $this->assertEquals("test5@example.com", $results[0]->email); + $this->assertEquals("test6@example.com", $results[1]->email); + } + + public function testOrderBy() + { + if (self::$db === "MSSQL") return; // @todo SQL Server 2008 + + $st = MODEL("SchemaTest"); + $results = $st->setOrderBy("dt")->select(); + $this->assertEquals("2008-01-01", $results[0]->dt); + $this->assertEquals("2008-01-10", $results[9]->dt); + + $results = $st->setOrderBy("dt", "desc")->select(); + $this->assertEquals("2008-01-10", $results[0]->dt); + $this->assertEquals("2008-01-01", $results[9]->dt); + + $results = $st->setOrderBy("SchemaTest.dt", "desc")->select(); + $this->assertEquals("2008-01-10", $results[0]->dt); + $this->assertEquals("2008-01-01", $results[9]->dt); + } + + public function testLimitation() + { + $st = MODEL("SchemaTest"); + $st->setLimit(2)->setOrderBy("id", "desc"); + $results = $st->select(); + $this->assertEquals(2, count($results)); + $this->assertEquals("name10", $results[0]->name); + $this->assertEquals("name_", $results[1]->name); + + $st->setLimit(2)->setOffset(2)->setOrderBy("id", "desc"); + $results = $st->select(); + $this->assertEquals(2, count($results)); + $this->assertEquals("name8", $results[0]->name); + $this->assertEquals("name7", $results[1]->name); + + $st->setLimit(2)->setOffset(4)->setOrderBy("id", "desc"); + $results = $st->select(); + $this->assertEquals(2, count($results)); + $this->assertEquals("name6", $results[0]->name); + $this->assertEquals("name5", $results[1]->name); + } + + public function testModelCondition() + { + $child = MODEL("Children")->selectOne(1); + $gChildren = MODEL("Grandchildren")->select($child); + $this->assertEquals(1, count($gChildren)); + + $gc = $gChildren[0]; + $this->assertEquals(2, $gc->id); + $this->assertEquals(1, $gc->children_id); + $this->assertEquals("grandchildren2", $gc->value); + } + + public function testRollback() + { + Sabel_Db_Transaction::activate(); + + $gp = MODEL("Grandparents"); + $gp->insert(array("id" => 3, "value" => "grandparents3")); + $gp->insert(array("id" => 4, "value" => "grandparents4")); + + Sabel_Db_Transaction::rollback(); + $this->assertEquals(2, $gp->getCount()); + } + + public function testCommit() + { + Sabel_Db_Transaction::activate(Sabel_Db_Transaction::SERIALIZABLE); + + $gp = MODEL("Grandparents"); + $gp->insert(array("id" => 3, "value" => "grandparents3")); + $gp->insert(array("id" => 4, "value" => "grandparents4")); + + Sabel_Db_Transaction::commit(); + $this->assertEquals(4, $gp->getCount()); + } + + public function testBridge() + { + $join = new Sabel_Db_Join("StudentCourse"); + $join->setOrderBy("StudentCourse.student_id")->setOrderBy("StudentCourse.course_id"); + $r = $join->add("Student")->add("Course")->select(); + + $this->assertEquals(7, count($r)); + $this->assertEquals("yamada", $r[0]->Student->name); + $this->assertEquals("Mathematics", $r[0]->Course->name); + $this->assertEquals("yamada", $r[1]->Student->name); + $this->assertEquals("Physics", $r[1]->Course->name); + $this->assertEquals("tanaka", $r[2]->Student->name); + $this->assertEquals("Mathematics", $r[2]->Course->name); + $this->assertEquals("tanaka", $r[3]->Student->name); + $this->assertEquals("Science", $r[3]->Course->name); + $this->assertEquals("suzuki", $r[4]->Student->name); + $this->assertEquals("Mathematics", $r[4]->Course->name); + $this->assertEquals("suzuki", $r[5]->Student->name); + $this->assertEquals("Physics", $r[5]->Course->name); + $this->assertEquals("suzuki", $r[6]->Student->name); + $this->assertEquals("Science", $r[6]->Course->name); + } + + public function testBridgeWithCondition() + { + $join = new Sabel_Db_Join("StudentCourse"); + $join->setOrderBy("StudentCourse.student_id")->setOrderBy("StudentCourse.course_id"); + $join->setCondition("Student.id", 1); + $r = $join->add("Student")->add("Course")->select(); + + $this->assertEquals(2, count($r)); + $this->assertEquals("yamada", $r[0]->Student->name); + $this->assertEquals("Mathematics", $r[0]->Course->name); + $this->assertEquals("yamada", $r[1]->Student->name); + $this->assertEquals("Physics", $r[1]->Course->name); + } + + public function testBridgeCount() + { + $join = new Sabel_Db_Join("StudentCourse"); + $join->setCondition("Student.id", 3); + $this->assertEquals(3, $join->add("Student")->add("Course")->getCount()); + } + + public function testBinaryData() + { + $image = file_get_contents(SABEL_BASE . DS . "Test" . DS . "data" . DS . "php.gif"); + $st = MODEL("SchemaTest"); + $st->email = "test@example.com"; + $st->idata = $image; + $st->save(); + + if (self::$db === "IBASE") return; + $s = MODEL("SchemaTest", $st->id); + $this->assertEquals(0, strcmp($image, $s->idata)); + } + + /** + * information(schema) of table + */ + public function testTableInfo() + { + $schema = MODEL("SchemaTest")->getMetadata(); + $this->assertEquals("schema_test", $schema->getTableName()); + $this->assertEquals("id", $schema->getPrimaryKey()); + $this->assertEquals("id", $schema->getSequenceColumn()); + + $this->assertTrue($schema->id->isInt(true)); + $this->assertTrue($schema->id->primary); + $this->assertTrue($schema->id->increment); + $this->assertFalse($schema->name->primary); + $this->assertFalse($schema->name->increment); + + $this->assertTrue($schema->bint->isBigint()); + $this->assertTrue($schema->sint->isSmallint()); + $this->assertTrue($schema->bint->isInt()); + $this->assertTrue($schema->sint->isInt()); + $this->assertFalse($schema->bint->isInt(true)); // strict mode + $this->assertFalse($schema->sint->isInt(true)); // strict mode + + $this->assertTrue($schema->name->isString()); + $this->assertEquals(128, $schema->name->max); + $this->assertTrue($schema->email->isString()); + $this->assertEquals(255, $schema->email->max); + + $this->assertTrue($schema->bl->isBool()); + $this->assertEquals(false, $schema->bl->default); + $this->assertTrue($schema->ft->isFloat()); + $this->assertEquals(10.234, $schema->ft->default); + $this->assertTrue($schema->dbl->isDouble()); + $this->assertEquals(10.23456, $schema->dbl->default); + $this->assertTrue($schema->txt->isText()); + + if (self::$db !== "MSSQL") { // @todo SQL-Server 2008 + $this->assertTrue($schema->dt->isDate()); + } + + $uniques = $schema->getUniques(); + $this->assertTrue(is_array($uniques)); + $this->assertEquals(1, count($uniques)); + $this->assertEquals(1, count($uniques[0])); + $this->assertEquals("email", $uniques[0][0]); + $this->assertTrue($schema->isUnique("email")); + } + + public function testForeignKeyInfo() + { + if (self::$db === "SQLITE") return; + + $schema = MODEL("Children")->getMetadata(); + $fkey = $schema->getForeignKey(); + $this->assertFalse($fkey->has("foo")); + $this->assertTrue($fkey->has("parents_id")); + + $this->assertEquals("parents", $fkey->parents_id->table); + $this->assertEquals("id", $fkey->parents_id->column); + } + + // @todo more tests + + public function testClear() + { + Sabel_Db_Metadata::clear(); + Sabel_Db_Connection::closeAll(); + } + + protected function insertTestData() + { + $data = array(); + $data[] = array("name" => "name1", "email" => "test1@example.com", "sint" => 100, "bl" => false, "ft" => 1.234, "dt" => "2008-01-01"); + $data[] = array("name" => "name2", "email" => "test2@example.com", "sint" => 100, "bl" => false, "ft" => 2.234, "dt" => "2008-01-02"); + $data[] = array("name" => "name3", "email" => "test3@example.com", "sint" => 200, "bl" => true, "ft" => 3.234, "dt" => "2008-01-03"); + $data[] = array("name" => "name4", "email" => "test4@example.com", "sint" => 200, "bl" => false, "ft" => 4.234, "txt" => "body", "dt" => "2008-01-04"); + $data[] = array("name" => "name5", "email" => "test5@example.com", "sint" => 300, "bl" => true, "ft" => 5.234, "dt" => "2008-01-05"); + $data[] = array("name" => "name6", "email" => "test6@example.com", "sint" => 300, "bl" => true, "ft" => 6.234, "txt" => "body", "dt" => "2008-01-06"); + $data[] = array("name" => "name7", "email" => "test7@example.com", "sint" => 400, "bl" => false, "ft" => 7.234, "dt" => "2008-01-07"); + $data[] = array("name" => "name8", "email" => "test8@example.com", "sint" => 400, "bl" => true, "ft" => 8.234, "dt" => "2008-01-08"); + $data[] = array("name" => "name_", "email" => "test9@example.com", "sint" => 500, "bl" => true, "ft" => 9.234, "dt" => "2008-01-09"); + $data[] = array("name" => "name10", "email" => "test10@example.com", "sint" => 500, "bl" => true, "ft" => 10.234, "dt" => "2008-01-10"); + + $st = MODEL("SchemaTest"); + foreach ($data as $values) $st->insert($values); + + $data = array(); + $data[] = array("id" => 1, "name" => "yamada"); + $data[] = array("id" => 2, "name" => "tanaka"); + $data[] = array("id" => 3, "name" => "suzuki"); + + $student = MODEL("Student"); + foreach ($data as $values) $student->insert($values); + + $data = array(); + $data[] = array("id" => 1, "name" => "Mathematics"); + $data[] = array("id" => 2, "name" => "Physics"); + $data[] = array("id" => 3, "name" => "Science"); + + $course = MODEL("Course"); + foreach ($data as $values) $course->insert($values); + + $data = array(); + $data[] = array("student_id" => 1, "course_id" => 1,"val" => "val1"); + $data[] = array("student_id" => 1, "course_id" => 2,"val" => "val2"); + $data[] = array("student_id" => 2, "course_id" => 1,"val" => "val3"); + $data[] = array("student_id" => 2, "course_id" => 3,"val" => "val4"); + $data[] = array("student_id" => 3, "course_id" => 1,"val" => "val5"); + $data[] = array("student_id" => 3, "course_id" => 2,"val" => "val6"); + $data[] = array("student_id" => 3, "course_id" => 3,"val" => "val7"); + + $sc = MODEL("StudentCourse"); + foreach ($data as $values) $sc->insert($values); + } + + protected function insertJoinTableData() + { + $data = array(); + $data[] = array("id" => 1, "value" => "grandparents1"); + $data[] = array("id" => 2, "value" => "grandparents2"); + $gp = MODEL("Grandparents"); + foreach ($data as $values) $gp->insert($values); + + $data = array(); + $data[] = array("id" => 1, "grandparents_id" => 2, "value" => "parents1"); + $data[] = array("id" => 2, "grandparents_id" => 1, "value" => "parents2"); + $p = MODEL("Parents"); + foreach ($data as $values) $p->insert($values); + + $data = array(); + $data[] = array("id" => 1, "parents_id" => 2, "value" => "children1"); + $data[] = array("id" => 2, "parents_id" => 1, "value" => "children2"); + $c = MODEL("Children"); + foreach ($data as $values) $c->insert($values); + + $data = array(); + $data[] = array("id" => 1, "children_id" => 2, "value" => "grandchildren1"); + $data[] = array("id" => 2, "children_id" => 1, "value" => "grandchildren2"); + $gc = MODEL("Grandchildren"); + foreach ($data as $values) $gc->insert($values); + } +} diff --git a/Test/DB/TestConfig.php b/Test/DB/TestConfig.php new file mode 100755 index 0000000..7a6db14 --- /dev/null +++ b/Test/DB/TestConfig.php @@ -0,0 +1,93 @@ + "sabel.db.mysql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } + + public static function getMysqliConfig() + { + return array("package" => "sabel.db.mysqli", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } + + public static function getPgsqlConfig() + { + return array("package" => "sabel.db.pgsql", + "host" => "127.0.0.1", + "user" => "pgsql", + "password" => "pgsql", + "database" => "sdb_test"); + } + + public static function getIbaseConfig() + { + return array("package" => "sabel.db.ibase", + "host" => "localhost", + "user" => "develop", + "password" => "develop", + "database" => "/home/firebird/sdb_test.fdb"); + } + + public static function getOciConfig() + { + return array("package" => "sabel.db.oci", + "host" => "127.0.0.1", + "user" => "develop", + "password" => "develop", + "database" => "XE", + "charset" => "UTF8"); + } + + public static function getMssqlConfig() + { + return array("package" => "sabel.db.mssql", + "host" => ".\\SQLEXPRESS", + "user" => "develop", + "password" => "develop", + "database" => "sdb_test"); + } + + public static function getPdoMysqlConfig() + { + return array("package" => "sabel.db.pdo.mysql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } + + public static function getPdoPgsqlConfig() + { + return array("package" => "sabel.db.pdo.pgsql", + "host" => "127.0.0.1", + "user" => "pgsql", + "password" => "pgsql", + "database" => "sdb_test"); + } + + public static function getPdoSqliteConfig() + { + return array("package" => "sabel.db.pdo.sqlite", + "database" => SABEL_BASE . "/Test/data/sdb_test.sq3"); + } + + public static function getPdoOciConfig() + { + return array("package" => "sabel.db.pdo.oci", + "host" => "127.0.0.1", + "user" => "develop", + "password" => "develop", + "database" => "XE", + "charset" => "UTF8"); + } +} diff --git a/Test/DB/Tests.php b/Test/DB/Tests.php new file mode 100755 index 0000000..98b9740 --- /dev/null +++ b/Test/DB/Tests.php @@ -0,0 +1,99 @@ + + */ +class Test_DB_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + if (extension_loaded("mysql")) { + $suite->addTest(Test_DB_Mysql::suite()); + } + + if (extension_loaded("mysqli")) { + $suite->addTest(Test_DB_Mysqli::suite()); + } + + if (extension_loaded("pgsql")) { + $suite->addTest(Test_DB_Pgsql::suite()); + } + + if (extension_loaded("pdo_mysql")) { + $suite->addTest(Test_DB_PdoMysql::suite()); + } + + if (extension_loaded("pdo_pgsql")) { + $suite->addTest(Test_DB_PdoPgsql::suite()); + } + + if (extension_loaded("interbase")) { + $suite->addTest(Test_DB_Ibase::suite()); + } + + //if (extension_loaded("mssql")) { + // $suite->addTest(Test_DB_Mssql::suite()); + //} + + if (extension_loaded("oci8")) { + $suite->addTest(Test_DB_Oci::suite()); + } + + if (extension_loaded("pdo_sqlite")) { + $suite->addTest(Test_DB_SQLite::suite()); + } + + if (extension_loaded("pdo_oci")) { + $suite->addTest(Test_DB_PdoOci::suite()); + } + + $suite->addTest(Test_DB_SchemaColumn::suite()); + $suite->addTest(Test_DB_Config::suite()); + + return $suite; + } +} diff --git a/Test/DB/migration/10_Grandchildren_create.php b/Test/DB/migration/10_Grandchildren_create.php new file mode 100755 index 0000000..e985c19 --- /dev/null +++ b/Test/DB/migration/10_Grandchildren_create.php @@ -0,0 +1,7 @@ +column("id")->type(_INT)->primary(true); +$create->column("children_id")->type(_INT)->nullable(false); +$create->column("value")->type(_STRING)->nullable(false); +$create->fkey("children_id"); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/1_SchemaTest_create.php b/Test/DB/migration/1_SchemaTest_create.php new file mode 100755 index 0000000..63040db --- /dev/null +++ b/Test/DB/migration/1_SchemaTest_create.php @@ -0,0 +1,14 @@ +column("id")->type(_INT)->primary(true)->increment(true); +$create->column("name")->type(_STRING)->length(128)->nullable(false)->value("default name"); +$create->column("email")->type(_STRING)->nullable(false); +$create->column("bint")->type(_BIGINT)->value("90000000000"); +$create->column("sint")->type(_SMALLINT)->value(30000); +$create->column("txt")->type(_TEXT); +$create->column("bl")->type(_BOOL); +$create->column("ft")->type(_FLOAT)->value(10.234); +$create->column("dbl")->type(_DOUBLE)->value(10.23456); +$create->column("dt")->type(_DATE); +$create->column("idata")->type(_BINARY); +$create->unique("email"); diff --git a/Test/DB/migration/2_Student_create.php b/Test/DB/migration/2_Student_create.php new file mode 100755 index 0000000..f57c4fe --- /dev/null +++ b/Test/DB/migration/2_Student_create.php @@ -0,0 +1,9 @@ +column("id")->type(_INT) + ->primary(true); + +$create->column("name")->type(_STRING) + ->nullable(false); + +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/3_Course_create.php b/Test/DB/migration/3_Course_create.php new file mode 100755 index 0000000..f57c4fe --- /dev/null +++ b/Test/DB/migration/3_Course_create.php @@ -0,0 +1,9 @@ +column("id")->type(_INT) + ->primary(true); + +$create->column("name")->type(_STRING) + ->nullable(false); + +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/4_StudentCourse_create.php b/Test/DB/migration/4_StudentCourse_create.php new file mode 100755 index 0000000..966784d --- /dev/null +++ b/Test/DB/migration/4_StudentCourse_create.php @@ -0,0 +1,13 @@ +column("student_id")->type(_INT) + ->nullable(false); + +$create->column("course_id")->type(_INT) + ->nullable(false); + +$create->column("val")->type(_STRING) + ->nullable(false); + +$create->primary(array("student_id", "course_id")); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/5_Session_create.php b/Test/DB/migration/5_Session_create.php new file mode 100755 index 0000000..58c3fe8 --- /dev/null +++ b/Test/DB/migration/5_Session_create.php @@ -0,0 +1,10 @@ +column("sid")->type(_STRING) + ->length(64) + ->primary(true); + +$create->column("sdata")->type(_TEXT); + +$create->column("timeout")->type(_INT) + ->value(0); diff --git a/Test/DB/migration/6_SblStorage_create.php b/Test/DB/migration/6_SblStorage_create.php new file mode 100755 index 0000000..db365ab --- /dev/null +++ b/Test/DB/migration/6_SblStorage_create.php @@ -0,0 +1,10 @@ +column("id")->type(_STRING) + ->length(64) # client_id(32) + key(32) + ->primary(true); + +$create->column("data")->type(_TEXT); + +$create->column("timeout")->type(_INT) + ->value(0); diff --git a/Test/DB/migration/7_Grandparents_create.php b/Test/DB/migration/7_Grandparents_create.php new file mode 100755 index 0000000..171b486 --- /dev/null +++ b/Test/DB/migration/7_Grandparents_create.php @@ -0,0 +1,5 @@ +column("id")->type(_INT)->primary(true); +$create->column("value")->type(_STRING)->nullable(false); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/8_Parents_create.php b/Test/DB/migration/8_Parents_create.php new file mode 100755 index 0000000..3409388 --- /dev/null +++ b/Test/DB/migration/8_Parents_create.php @@ -0,0 +1,7 @@ +column("id")->type(_INT)->primary(true); +$create->column("grandparents_id")->type(_INT)->nullable(false); +$create->column("value")->type(_STRING)->nullable(false); +$create->fkey("grandparents_id"); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migration/9_Children_create.php b/Test/DB/migration/9_Children_create.php new file mode 100755 index 0000000..1522bda --- /dev/null +++ b/Test/DB/migration/9_Children_create.php @@ -0,0 +1,7 @@ +column("id")->type(_INT)->primary(true); +$create->column("parents_id")->type(_INT)->nullable(false); +$create->column("value")->type(_STRING)->nullable(false); +$create->fkey("parents_id"); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migtests/exec.php b/Test/DB/migtests/exec.php new file mode 100755 index 0000000..3d77d0b --- /dev/null +++ b/Test/DB/migtests/exec.php @@ -0,0 +1,53 @@ + array( + "package" => "sabel.db.pdo.sqlite", + "database" => "/home/ebine/test.sq3"), + "mysql" => array( + "package" => "sabel.db.mysql", + "host" => "127.0.0.1", + "database" => "sdb_test", + "port" => "3306", + "user" => "root", + "password" => ""), + "pgsql" => array( + "package" => "sabel.db.pgsql", + "host" => "127.0.0.1", + "database" => "sdb_test", + "user" => "pgsql", + "password" => "pgsql"), + "oci" => array( + "package" => "sabel.db.oci", + "host" => "127.0.0.1", + "database" => "XE", + "schema" => "DEVELOP", + "user" => "DEVELOP", + "password" => "DEVELOP") + ); + +foreach ($configs as $key => $param) { + Sabel_Db_Config::add($key, $param); +} + +$args = $_SERVER["argv"]; +$path = $args[1]; +$conName = $args[2]; +$type = $args[3]; + +$schema = Sabel_Db::createMetadata($conName); +$stmt = Sabel_Db::createStatement($conName); + +Sabel_Db_Migration_Manager::setSchema($schema); +Sabel_Db_Migration_Manager::setStatement($stmt); +Sabel_Db_Migration_Manager::setDirectory(RUN_BASE . "/migration/tmp"); +Sabel_Db_Migration_Manager::setApplyMode($type); + +$dirs = explode(".", Sabel_Db_Config::getPackage($conName)); +$className = implode("_", array_map("ucfirst", $dirs)) . "_Migration"; +$mig = new $className(); +$mig->execute($path); diff --git a/Test/DB/migtests/files/1_Hoge_create.php b/Test/DB/migtests/files/1_Hoge_create.php new file mode 100755 index 0000000..67c439d --- /dev/null +++ b/Test/DB/migtests/files/1_Hoge_create.php @@ -0,0 +1,20 @@ +column("id")->type(_INT) + ->primary(true) + ->increment(true); + +$create->column("name")->type(_STRING) + ->length(128) + ->value("default name"); + +$create->column("test")->type(_STRING) + ->nullable(true); + +$create->column("body")->type(_TEXT) + ->nullable(false); + +$create->column("bool")->type(_BOOL) + ->value(false); + +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migtests/files/2_Hoge_addColumn.php b/Test/DB/migtests/files/2_Hoge_addColumn.php new file mode 100755 index 0000000..228712f --- /dev/null +++ b/Test/DB/migtests/files/2_Hoge_addColumn.php @@ -0,0 +1,15 @@ +column("ft")->type(_FLOAT) + ->value(1.333); + +$add->column("dbl")->type(_DOUBLE) + ->nullable(false) + ->value(1.23456); + +$add->column("sint")->type(_SMALLINT) + ->value(30000); + +$add->column("bint")->type(_BIGINT) + ->value(400000000); + diff --git a/Test/DB/migtests/files/3_Hoge_dropColumn.php b/Test/DB/migtests/files/3_Hoge_dropColumn.php new file mode 100755 index 0000000..8c3cce7 --- /dev/null +++ b/Test/DB/migtests/files/3_Hoge_dropColumn.php @@ -0,0 +1,5 @@ +column("dbl"); +$drop->column("sint"); + diff --git a/Test/DB/migtests/files/4_Hoge_changeColumn.php b/Test/DB/migtests/files/4_Hoge_changeColumn.php new file mode 100755 index 0000000..4914bfa --- /dev/null +++ b/Test/DB/migtests/files/4_Hoge_changeColumn.php @@ -0,0 +1,5 @@ +column("name")->value(_NULL); +$change->column("test")->nullable(false); +$change->column("ft")->type(_DOUBLE)->value(1.33333); diff --git a/Test/DB/migtests/files/5_Huga_create.php b/Test/DB/migtests/files/5_Huga_create.php new file mode 100755 index 0000000..55759ad --- /dev/null +++ b/Test/DB/migtests/files/5_Huga_create.php @@ -0,0 +1,11 @@ +column("id")->type(_INT) + ->primary(true); + +$create->column("email")->type(_STRING) + ->length(255) + ->nullable(false); + +$create->unique("email"); +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migtests/files/6_Foo_create.php b/Test/DB/migtests/files/6_Foo_create.php new file mode 100755 index 0000000..4cae9f0 --- /dev/null +++ b/Test/DB/migtests/files/6_Foo_create.php @@ -0,0 +1,6 @@ +column("id")->type(_INT) + ->primary(true); + +$create->options("engine", "InnoDB"); diff --git a/Test/DB/migtests/files/7_Hoge_drop.php b/Test/DB/migtests/files/7_Hoge_drop.php new file mode 100755 index 0000000..e69de29 diff --git a/Test/DB/migtests/files/8_Bar_create.php b/Test/DB/migtests/files/8_Bar_create.php new file mode 100755 index 0000000..ade53e3 --- /dev/null +++ b/Test/DB/migtests/files/8_Bar_create.php @@ -0,0 +1,15 @@ +column("id")->type(_INT) + ->primary(true); + +$create->column("huga_id")->type(_INT) + ->nullable(false); + +$create->column("foo_id")->type(_INT) + ->nullable(false); + +$create->fkey("huga_id"); +$create->fkey("foo_id")->onDelete("CASCADE"); +$create->options("engine", "InnoDB"); + diff --git a/Test/DB/migtests/run.php b/Test/DB/migtests/run.php new file mode 100755 index 0000000..467252e --- /dev/null +++ b/Test/DB/migtests/run.php @@ -0,0 +1,6 @@ + array( + "package" => "sabel.db.pdo.sqlite", + "database" => "/home/ebine/test.sq3"), + "mysql" => array( + "package" => "sabel.db.mysql", + "host" => "127.0.0.1", + "database" => "sdb_test", + "port" => "3306", + "user" => "root", + "password" => ""), + "pgsql" => array( + "package" => "sabel.db.pgsql", + "host" => "127.0.0.1", + "database" => "sdb_test", + "user" => "pgsql", + "password" => "pgsql"), + "oci" => array( + "package" => "sabel.db.oci", + "host" => "127.0.0.1", + "database" => "XE", + "schema" => "DEVELOP", + "user" => "DEVELOP", + "password" => "DEVELOP") + ); + +foreach ($configs as $key => $param) { + Sabel_Db_Config::add($key, $param); +} + +echo "[ " . CONNAME . " ]\n"; + +$path = RUN_BASE . "/migration/tmp/1_Hoge_create.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/2_Hoge_addColumn.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$ft = $hoge->ft; +$dbl = $hoge->dbl; +$sint = $hoge->sint; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isFloat()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.333); +isTrue($ft->nullable); + +isTrue($dbl->isDouble()); +isFalse($dbl->primary); +isFalse($dbl->increment); +equals($dbl->default, 1.23456); +isFalse($dbl->nullable); + +isTrue($sint->isSmallint()); +isFalse($sint->primary); +isFalse($sint->increment); +equals($sint->default, 30000); +isTrue($sint->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/3_Hoge_dropColumn.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isFloat()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.333); +isTrue($ft->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +isNull($hoge->dbl); +isNull($hoge->sint); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/4_Hoge_changeColumn.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$ft = $hoge->ft; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +isNull($name->default); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isFalse($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isDouble()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.33333); +isTrue($ft->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +isNull($hoge->dbl); +isNull($hoge->sint); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/5_Huga_create.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$huga = $accessor->getTable("huga"); +$id = $huga->id; +$email = $huga->email; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isFalse($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($email->isString()); +isFalse($email->primary); +isFalse($email->increment); +isNull($email->default); +isFalse($email->nullable); +equals($email->max, 255); +isTrue($huga->isUnique("email")); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/6_Foo_create.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$foo = $accessor->getTable("foo"); +$id = $foo->id; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isFalse($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/7_Hoge_drop.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$tables = $accessor->getTableList(); +isFalse(in_array("hoge", $tables)); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/8_Bar_create.php"; +system("php exec.php $path " . CONNAME . " upgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$bar = $accessor->getTable("bar"); +$id = $bar->id; +$huga_id = $bar->huga_id; +$foo_id = $bar->foo_id; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isFalse($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($huga_id->isInt(true)); +isFalse($huga_id->primary); +isFalse($huga_id->increment); +isNull($huga_id->default); +isFalse($huga_id->nullable); +equals($huga_id->max, PHP_INT_MAX); + +isTrue($foo_id->isInt(true)); +isFalse($foo_id->primary); +isFalse($foo_id->increment); +isNull($foo_id->default); +isFalse($foo_id->nullable); +equals($foo_id->max, PHP_INT_MAX); + +if (CONNAME !== "sqlite") { + $fkey = $bar->getForeignKey(); + isTrue($fkey->has("huga_id")); + isTrue($fkey->has("foo_id")); + $hugaId = $fkey->huga_id; + $fooId = $fkey->foo_id; + equals($hugaId->table, "huga"); + equals($fooId->table, "foo"); + equals($hugaId->column, "id"); + equals($fooId->column, "id"); + equals($hugaId->onDelete, "NO ACTION"); + equals($fooId->onDelete, "CASCADE"); + equals($hugaId->onUpdate, "NO ACTION"); + equals($fooId->onUpdate, "NO ACTION"); +} + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/8_Bar_create.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$tables = $accessor->getTableList(); +isFalse(in_array("bar", $tables)); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/7_Hoge_drop.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$ft = $hoge->ft; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +isNull($name->default); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isFalse($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isDouble()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.33333); +isTrue($ft->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +isNull($hoge->dbl); +isNull($hoge->sint); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/6_Foo_create.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$tables = $accessor->getTableList(); +isFalse(in_array("foo", $tables)); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/5_Huga_create.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$tables = $accessor->getTableList(); +isFalse(in_array("huga", $tables)); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/4_Hoge_changeColumn.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$ft = $hoge->ft; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isFloat()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.333); +isTrue($ft->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +isNull($hoge->dbl); +isNull($hoge->sint); + +$tables = $accessor->getTableList(); +isFalse(in_array("huga", $tables)); +isFalse(in_array("foo", $tables)); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/3_Hoge_dropColumn.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$ft = $hoge->ft; +$dbl = $hoge->dbl; +$sint = $hoge->sint; +$bint = $hoge->bint; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($ft->isFloat()); +isFalse($ft->primary); +isFalse($ft->increment); +equals($ft->default, 1.333); +isTrue($ft->nullable); + +isTrue($dbl->isDouble()); +isFalse($dbl->primary); +isFalse($dbl->increment); +equals($dbl->default, 1.23456); +isFalse($dbl->nullable); + +isTrue($sint->isSmallint()); +isFalse($sint->primary); +isFalse($sint->increment); +equals($sint->default, 30000); +isTrue($sint->nullable); + +isTrue($bint->isBigint()); +isFalse($bint->primary); +isFalse($bint->increment); +equals($bint->default, "400000000"); +isTrue($bint->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/2_Hoge_addColumn.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$hoge = $accessor->getTable("hoge"); +$id = $hoge->id; +$name = $hoge->name; +$test = $hoge->test; +$body = $hoge->body; +$bool = $hoge->bool; + +isTrue($id->isInt(true)); +isTrue($id->primary); +isTrue($id->increment); +isNull($id->default); +isFalse($id->nullable); +equals($id->max, PHP_INT_MAX); + +isTrue($name->isString()); +isFalse($name->primary); +isFalse($name->increment); +equals($name->default, "default name"); +isTrue($name->nullable); +equals($name->max, 128); + +isTrue($test->isString()); +isFalse($test->primary); +isFalse($test->increment); +isNull($test->default); +isTrue($test->nullable); +equals($test->max, 255); + +isTrue($body->isText()); +isFalse($body->primary); +isFalse($body->increment); +isNull($body->default); +isFalse($body->nullable); + +isTrue($bool->isBool()); +isFalse($bool->primary); +isFalse($bool->increment); +isFalse($bool->default); +isTrue($bool->nullable); + +isNull($hoge->ft); +isNull($hoge->dbl); +isNull($hoge->sint); +isNull($hoge->bint); + +Sabel_Db_Connection::closeAll(); + +$path = RUN_BASE . "/migration/tmp/1_Hoge_create.php"; +system("php exec.php $path " . CONNAME . " downgrade"); + +$accessor = Sabel_Db::createMetadata(CONNAME); +$tables = $accessor->getTableList(); +isFalse(in_array("hoge", $tables)); + +Sabel_Db_Connection::closeAll(); + +echo "\n"; diff --git a/Test/Exception.php b/Test/Exception.php new file mode 100755 index 0000000..fe4c1ae --- /dev/null +++ b/Test/Exception.php @@ -0,0 +1,60 @@ + + */ +class Test_Exception extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Exception"); + } + + public function testInvalidArgument() + { + try { + $this->throwInvalidArgumentException(); + } catch (Sabel_Exception_InvalidArgument $e) { + $this->assertTrue($e instanceof InvalidArgumentException); // SPL + $this->assertEquals("invalid argument.", $e->getMessage()); + return; + } + + $this->fail(); + } + + public function testRuntime() + { + try { + $this->throwRuntimeException(); + } catch (Sabel_Exception_Runtime $e) { + $message = <<writeSyslog($message); + $this->assertEquals(3, count($messageLines)); + $this->assertEquals("throw", $messageLines[0]); + $this->assertEquals("runtime", $messageLines[1]); + $this->assertEquals("exception", $messageLines[2]); + return; + } + + $this->fail(); + } + + protected function throwInvalidArgumentException() + { + throw new Sabel_Exception_InvalidArgument("invalid argument."); + } + + protected function throwRuntimeException() + { + throw new Sabel_Exception_Runtime(""); + } +} diff --git a/Test/Experimental.php b/Test/Experimental.php new file mode 100755 index 0000000..71e4d1e --- /dev/null +++ b/Test/Experimental.php @@ -0,0 +1,23 @@ + + */ +class Test_Experimental extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Experimental"); + } + + public function setUp() + { + } + + public function testExperimental() + { + } +} diff --git a/Test/I18n/Gettext.php b/Test/I18n/Gettext.php new file mode 100755 index 0000000..c0a9a90 --- /dev/null +++ b/Test/I18n/Gettext.php @@ -0,0 +1,51 @@ + + */ +class Test_I18n_Gettext extends SabelTestCase +{ + public static function suite() + { + ini_set("mbstring.internal_encoding", "UTF-8"); + define("LOCALE_DIR_PATH", dirname(__FILE__) . DIRECTORY_SEPARATOR . "locale"); + return self::createSuite("Test_I18n_Gettext"); + } + + public function testI18n() + { + $gettext = Sabel_I18n_Gettext::getInstance(); + $gettext->setMessagesFileName("messages.php"); + $gettext->init("ja,en-us;q=0.7,en;q=0.3"); + + $this->assertTrue($gettext->isInitialized()); + + $this->assertEquals("名前", __("name")); + $this->assertEquals("住所", __("address")); + } + + public function testMessagesFileName() + { + $this->assertEquals("名前", __("name")); + $this->assertEquals("住所", __("address")); + + Sabel_I18n_Gettext::getInstance()->setMessagesFileName("hiragana.php"); + $this->assertEquals("なまえ", __("name")); + $this->assertEquals("じゅうしょ", __("address")); + } + + public function testCodeSet() + { + $gettext = Sabel_I18n_Gettext::getInstance(); + $gettext->setCodeSet("EUC-JP"); + + $this->assertEquals(mb_convert_encoding("なまえ", "EUC-JP", "UTF-8"), __("name")); + $this->assertEquals(mb_convert_encoding("じゅうしょ", "EUC-JP", "UTF-8"), __("address")); + } +} + +function __($msgid) +{ + return Sabel_I18n_Sabel_Gettext::_($msgid); +} diff --git a/Test/I18n/locale/ja/hiragana.php b/Test/I18n/locale/ja/hiragana.php new file mode 100755 index 0000000..72dbe45 --- /dev/null +++ b/Test/I18n/locale/ja/hiragana.php @@ -0,0 +1,6 @@ + "なまえ", + "address" => "じゅうしょ", +); diff --git a/Test/I18n/locale/ja/messages.php b/Test/I18n/locale/ja/messages.php new file mode 100755 index 0000000..31336de --- /dev/null +++ b/Test/I18n/locale/ja/messages.php @@ -0,0 +1,6 @@ + "名前", + "address" => "住所", +); diff --git a/Test/Mail/MimeDecode.php b/Test/Mail/MimeDecode.php new file mode 100755 index 0000000..18666e7 --- /dev/null +++ b/Test/Mail/MimeDecode.php @@ -0,0 +1,375 @@ + + */ +class Test_Mail_MimeDecode extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Mail_MimeDecode"); + } + + /** + * @test + */ + public function plain() + { + $decoded = $this->decode("plain"); + + $this->assertEquals("text/plain", $decoded->content->getType()); + $this->assertEquals("ISO-2022-JP", $decoded->content->getCharset()); + + $this->assertEquals('"from1" ', $decoded->getHeader("From")); + $this->assertEquals('from1', $decoded->getFromName()); + $this->assertEquals('from1@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to1@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + + $this->assertNull($decoded->html); + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function html() + { + $decoded = $this->decode("html"); + + $this->assertEquals("text/html", $decoded->content->getType()); + $this->assertEquals("ISO-2022-JP", $decoded->content->getCharset()); + + $this->assertEquals('"from2" ', $decoded->getHeader("From")); + $this->assertEquals('from2', $decoded->getFromName()); + $this->assertEquals('from2@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to2@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $this->assertNull($decoded->body); + $this->assertEquals(array(), $decoded->html->getImages()); + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function plain_html() + { + $decoded = $this->decode("plain_html"); + + $this->assertEquals("multipart/alternative", $decoded->content->getType()); + + $this->assertEquals('"from3" ', $decoded->getHeader("From")); + $this->assertEquals('from3', $decoded->getFromName()); + $this->assertEquals('from3@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to3@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $this->assertEquals(array(), $decoded->html->getImages()); + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function htmlimg() + { + $decoded = $this->decode("htmlimg"); + + $this->assertEquals("multipart/related", $decoded->content->getType()); + + $this->assertEquals('"from4" ', $decoded->getHeader("From")); + $this->assertEquals('from4', $decoded->getFromName()); + $this->assertEquals('from4@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to4@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $this->assertNull($decoded->body); + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function plain_attachment() + { + $decoded = $this->decode("plain_attachment"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from5" ', $decoded->getHeader("From")); + $this->assertEquals('from5', $decoded->getFromName()); + $this->assertEquals('from5@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to5@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + + $this->assertNull($decoded->html); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function plain_html_attachment() + { + $decoded = $this->decode("plain_html_attachment"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from6" ', $decoded->getHeader("From")); + $this->assertEquals('from6', $decoded->getFromName()); + $this->assertEquals('from6@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to6@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + $this->assertEquals(array(), $decoded->html->getImages()); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function html_attachment() + { + $decoded = $this->decode("html_attachment"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from7" ', $decoded->getHeader("From")); + $this->assertEquals('from7', $decoded->getFromName()); + $this->assertEquals('from7@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to7@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $this->assertNull($decoded->body); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function htmlimg_attachment() + { + $decoded = $this->decode("htmlimg_attachment"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from8" ', $decoded->getHeader("From")); + $this->assertEquals('from8', $decoded->getFromName()); + $this->assertEquals('from8@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to8@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $this->assertNull($decoded->body); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function plain_htmlimg() // thunderbird + { + $decoded = $this->decode("plain_htmlimg"); + + $this->assertEquals("multipart/alternative", $decoded->content->getType()); + + $this->assertEquals('"from9" ', $decoded->getHeader("From")); + $this->assertEquals('from9', $decoded->getFromName()); + $this->assertEquals('from9@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to9@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function plain_htmlimg2() // outlook express + { + $decoded = $this->decode("plain_htmlimg2"); + + $this->assertEquals("multipart/related", $decoded->content->getType()); + + $this->assertEquals('"from10" ', $decoded->getHeader("From")); + $this->assertEquals('from10', $decoded->getFromName()); + $this->assertEquals('from10@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to10@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $this->assertEquals(array(), $decoded->attachments); + } + + /** + * @test + */ + public function plain_htmlimg_attachment() // thunderbird + { + $decoded = $this->decode("plain_htmlimg_attachment"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from11" ', $decoded->getHeader("From")); + $this->assertEquals('from11', $decoded->getFromName()); + $this->assertEquals('from11@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to11@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function plain_htmlimg_attachment2() // outlook express + { + $decoded = $this->decode("plain_htmlimg_attachment2"); + + $this->assertEquals("multipart/mixed", $decoded->content->getType()); + + $this->assertEquals('"from12" ', $decoded->getHeader("From")); + $this->assertEquals('from12', $decoded->getFromName()); + $this->assertEquals('from12@example.com', $decoded->getFromAddr()); + + $this->assertEquals('to12@example.com', $decoded->getToAddr()); + + $this->assertEquals("件名", $decoded->getHeader("Subject")); + $this->assertNotEquals(false, strpos($decoded->body->getContent(), "本文")); + $this->assertNotEquals(false, stripos($decoded->html->getContent(), "")); + + $images = $decoded->html->getImages(); + $this->assertEquals(2, count($images)); + $this->assertEquals("image/png", $images[0]["mimetype"]); + $this->assertEquals("image/png", $images[1]["mimetype"]); + $this->assertTrue($images[0]["data"] !== $images[1]["data"]); + + $attachments = $decoded->attachments; + $this->assertEquals(2, count($attachments)); + $this->assertEquals("image/png", $attachments[0]->getType()); + $this->assertEquals("image/png", $attachments[1]->getType()); + $this->assertTrue($attachments[0]->getContent() !== $attachments[1]->getContent()); + } + + /** + * @test + */ + public function jpattachment() // thunderbird (RFC2231) + { + $decoded = $this->decode("jpattachment"); + + $attachment = $decoded->attachments[0]; + $this->assertEquals("日本語日本語日本語日本語日本語日本語.png", $attachment->getName()); + } + + /** + * @test + */ + public function jpattachment2() // outlook express (mime encoding) + { + $decoded = $this->decode("jpattachment2"); + + $attachment = $decoded->attachments[0]; + $this->assertEquals("日本語日本語日本語日本語日本語日本語.png", $attachment->getName()); + } + + protected function decode($name) + { + $decoder = new Sabel_Mail_MimeDecode(); + return $decoder->decode(file_get_contents(dirname(__FILE__) . DS . "mails" . DS . $name . ".eml")); + } +} diff --git a/Test/Mail/Tests.php b/Test/Mail/Tests.php new file mode 100755 index 0000000..acbf45f --- /dev/null +++ b/Test/Mail/Tests.php @@ -0,0 +1,14 @@ +addTest(Test_Mail_MimeDecode::suite()); + + return $suite; + } +} diff --git a/Test/Mail/mails/html.eml b/Test/Mail/mails/html.eml new file mode 100755 index 0000000..7d7178d --- /dev/null +++ b/Test/Mail/mails/html.eml @@ -0,0 +1,20 @@ +Return-Path: +X-Original-To: to2@example.com +Delivered-To: to2@example.com +Message-ID: <484F2B3B.9000304@sabel.jp> +Date: Wed, 11 Jun 2008 10:32:43 +0900 +From: "from2" +MIME-Version: 1.0 +To: to2@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B + + diff --git a/Test/Mail/mails/html_attachment.eml b/Test/Mail/mails/html_attachment.eml new file mode 100755 index 0000000..4b5e941 --- /dev/null +++ b/Test/Mail/mails/html_attachment.eml @@ -0,0 +1,108 @@ +Return-Path: +X-Original-To: to7@example.com +Delivered-To: to7@example.com +Message-ID: <484F2DE9.6040208@sabel.jp> +Date: Wed, 11 Jun 2008 10:44:09 +0900 +From: "from7" +MIME-Version: 1.0 +To: to7@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------090708090103020604030603" + +This is a multi-part message in MIME format. +--------------090708090103020604030603 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B + + + +--------------090708090103020604030603 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------090708090103020604030603 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------090708090103020604030603-- diff --git a/Test/Mail/mails/htmlimg.eml b/Test/Mail/mails/htmlimg.eml new file mode 100755 index 0000000..8a20dba --- /dev/null +++ b/Test/Mail/mails/htmlimg.eml @@ -0,0 +1,114 @@ +Return-Path: +X-Original-To: to4@example.com +Delivered-To: to4@example.com +Message-ID: <484F2C54.3000704@sabel.jp> +Date: Wed, 11 Jun 2008 10:37:24 +0900 +From: "from4" +MIME-Version: 1.0 +To: to4@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/related; + boundary="------------020704060607050404030000" + +This is a multi-part message in MIME format. +--------------020704060607050404030000 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B
+
+
+ + + +--------------020704060607050404030000 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------020704060607050404030000 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="check_all_32.png" + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9i +ZSBJbWFnZVJlYWR5ccllPAAABvpJREFUeNrEVwlsFFUY/mZmj570YhdaCrSlLQQoJNxVQNSA +SBAkgAmYgBeIEUgIGEUTFEwwBhETY0hARWwwgkdiYhGEIJcK5aYItbZlW3YLpV1Kt8teszPP +f449BnYL0Rin+/e9efPmfd///f87hmOM4f+8uAiBi+/lVVKxmazyP8b8nWz1iLVupYQp0spk +9mVBf19p7vB5GrP0YsCSd//hpOADoTJPrVreuvRtZeu1tF1ULTEQkGWU5hA4Aw/Zdw3s9nmA +TyGzxkrBqt9biCEZb6aShuD4+0udUgQu4IKC4WzeWxxpjylAkWA+F+RQF1jghgbCiwRKxocJ +g0pZq2sm6RYhoQzFJVcg1E3OWcH7HIhPu5gCEoPsdZL3LhU8dbaLXoj0ZCpDFvaA+W/QYB1E +tgWy+wSY2KUrEiEj9CCDVcOQWAICMoXT06R5wTO14Bink+C0nzmLHO1F9+VglLNC/2fAuhsg +tR2E3HlGG4RX1FCIJFZDwZDlXokIEJSkeyuFYqARAaJeaPHiwGnUMstgyiiF3FWLsGMXqXOb +GiNETPeGQtKwIhdvCIHyULc43fQfF3evWeRPqfPZFTBXbACfM5pC5ScLakaqMIaoaeMnCQGL +Az66PhZLjmKbkT8KppRs5JZOQ++hc2HJ7KerES0o/FaYS5dQ4mYi7Nqv5YQgEz+TVo8qkCwJ +4wiM6B8nGxMREE9C8prQfeIwnIffQXrxVBQ/ug5ptmH6iqb3JTbmkgU0mzyQbhxTXWZxSXq3 +AoYQKOwSGYhxCgmSLoTRJz2EclsQWbf24coXU+A4tF6V+e6wWMtfpIWsN+WEj4xCIgYAJSTJ +CEhx8e/ZSCkxhDQ+iOIcP8Taj3B5z7PU5ovlhx42a8UqyGGR1LhDBHxU+tQxFCzuIKeaIQQs +HJO993ItHrK/HbLnKkTnLwi17IfoOhKhrEqTa5HhbduLK7sXYdjCb8glProemTKLYB4wG6H6 +r8AoPzhSUMFIrICMhLOAT7XB1GccUke/jqw5h5A19zgEe2WcGqKqRlrbPjTuX6fPFi6qhqVk +DvWTIAe9mkkaVpJpGLNklzm/Ejnzj6iEov3DkkoicOYDeFrPES4XJSLQzGkdMBFvW/7E+0Id +2jnWQxKSPBHreWcRkDlxI9LHvGF4J88aRnP1m4a1o6arBptM9bho68KBHCc25TF0mkgCBSMc +Nw2lu6T/abnGTbBmIHfQRAycshK2odMNPDInb0SorRaBhuqYQq0/o6u5BlkDx6H6ZjWeOjkT +T+fb8HC/sXB3nEVNXx/aBhNyCDbq3p50Glb01WxIthcZ1/ehbvsM1H23huQOGUk8toX+W6Lv +ZZBLHef2oKq5CrOPzcSCfoUYbCvDzZsX4Qv4MJx2dtcQIhDEK2TJl+JoMpJaaTTowGzAd+JD +1FYtUfu3B9qxoXYDPnMfgLVsjuGdHTd246VfF2FxWRkKcwrR4jwLj9eDIHFXTFZ8CEJQCCRd +ilOKHkHOjC1qvXPvKgQcR5CXSvXLVbhy9gl87D+Omls74b7jw7m0aXhLf3crbXSfpLbihYrh +SLFYUN94hsIrRset95AzlwX8UShtNZwJd8+zsnGDYx0LX3PAnD1ArYu3W+DcVKQdqUizTX0L +ERxpRnlBPi7Vncap1iDmdFD8aaiv7WYsfKgCYQpVk+MyORabc010dJhwHZh0wYxllSKXZDvW +k5IJMMfVI892UZDtjxcg4O9GzfkaAhJRmkHtXiA3MxWLJ4+Eu7MDjY4GQ6600C49qQ1Y4efQ +RKsy/Al2Q4utBMG2JvW+ducyjHh+u3Zi3rEEebojN++IFIIrtLd4DADD7FZMHj8Kjc3NaHE5 +Dc+udwIjm4HlJg797CVokFsSEIibBeoDmloHVhRo4ciidovWviDAYeYFD/rn0wxIj4cJ4ujJ +c/De8RnA228BUyk8y2lN6B1GbDPyJTiUmnrZaeJbEHDWIYP0Hxx3Kme6AuVkn4Y5LHUw5NOW +bbHG+viDRvDbbuBJIvAqT+DKZLUXqRiMNScMQcPVUydLi8aMh6VPCX0SFFIS2hMuhLOVZLzW +iLV/nUUe5aZw78kLXvJ6XuogrBk7FDl+D0JuJ0xZdhAGYfFXIwSis2DbNNNkgcNmIjvmQT9x +fkxj+CFXRmax8QwaIPAJLRxm+XhkycZ3KNdPUwRWv9xHOmogwHHqEEriU04jV1nk1CWup8O+ +ck3HSqEAC6z6CUpsJ3Pge1zA53DBrZ/WlKWnWxFOEUfphvnaOTeeQGRzUkBpyYESXeG+BDQS +7/L5eE4JqHwNVWjCFtSjPfZRoR4egvrkC2EW5Hs+TrmYhnyccQ8UCzsRHYmlSqKTf9vwG9ru +Po1rizrZdMgJv47/8ef1VO5fvf+3AAMAoXePQvnneewAAAAASUVORK5CYII= +--------------020704060607050404030000-- diff --git a/Test/Mail/mails/htmlimg_attachment.eml b/Test/Mail/mails/htmlimg_attachment.eml new file mode 100755 index 0000000..7b3bbb1 --- /dev/null +++ b/Test/Mail/mails/htmlimg_attachment.eml @@ -0,0 +1,202 @@ +Return-Path: +X-Original-To: to8@example.com +Delivered-To: to8@example.com +Message-ID: <484F2EA3.6070303@sabel.jp> +Date: Wed, 11 Jun 2008 10:47:15 +0900 +From: "from8" +MIME-Version: 1.0 +To: to8@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------020908030104060509010004" + +This is a multi-part message in MIME format. +--------------020908030104060509010004 +Content-Type: multipart/related; + boundary="------------080902090709030608060706" + + +--------------080902090709030608060706 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B
+
+
+ + + +--------------080902090709030608060706 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------080902090709030608060706 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------080902090709030608060706-- + +--------------020908030104060509010004 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="comment_rss_32.png" + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9i +ZSBJbWFnZVJlYWR5ccllPAAABjdJREFUeNrEV1tsFFUY/mZmZ3d72d5rW2yrLRRoI5iIEpOS +NKg8eCEYiYmJIZFLovGBxEA0PkiMPigkPphQE0rA+KAQn4yi8crVlFBKQQoFWopt0/tl2+5u +9zI7M8f/zJy9DN1VKzGc7J+zZ86c83/n+7//nDMSYwz3s7gSf65+VNpC1QGy9f+zzw6yt9e+ +O3PGAYCZ7PhDjzxQ6Vu+CVJuPZiSA0jULSnUq9h1mjHrmSz6JWH/UOIzCPceW//n+fbj1Kpy +AmCoLGjYDGPiJ7DIV4DsIXOL2ksYvOJ/ok21lHhHFWC5ZQcieSqQu2obWHt75aIQmCaBgAxz +7rpwYsDzwgg9S2iEamaAhfrA9BBYeABs7grMhTsCBJlk2GA4OxkKi0xA8a22fC0CQCGgiYNU +czQaTcQsViUmCRCSRbdEE0hcuEXrwJa9BDk6BXPsO5jT56hfp3E0gcyZUDOGhRkxy1eiyA4G +NBuADUYTTiX6kSXjLCVptp56y6HU7YC0eh/gqaJxYbKYcKTz0DoM9DwjAyZ3qgVgGqlOvf8w +poOwxOZSffCWNsBbVA/F7UsuThKLcfnqwJr2IXqzFXLgUiosFEqLDUkWDEQtXxk1YMYCdghE +iV54A/7phIJk63XN9CKndhNKVm1FWePLNhAm8Cgqcpp2I3TjEFz+s9S2nUuJsJA+mB7NwoBB +DMSCXGeOUlOcfIOMwiKZJMATWLjwMwauH0JZ837kV61LsUE6yW98HbMXhuGN9dqC5kCESJke +sXxl1IARDVoh+FvTKa5xDblKDCWxi4j8uhn+nq9T2rA0o8D36B5ENBeFdYE0HSaL2KunRWZl +wIwtOBjwbemw+yh9zLke6GNnEB/+yUpHGJq1IjePcSetmFKzeO0OES5AzSmFa+Wb0K99AMUV +JxYIuOKmSMw7GHCKMBp2AFDKbGqtrK55Dp41e6EHhxDr+hDaraNc0nZoKMZS1x6Ei1cit2aD +YAMofLgFg911xFSvBYBvXkyac4gwFQJrUVEH3RkPD18t8loOQ33qG5osx2YuHif2woid3UUD +446ULWh6FQuhEPXbZkRmHXPLjhBocYuBhOmTlxAcIRu9sghI/orNUJ+hDYi57fd1k8LUj/C1 +NiEHe+8oqmvBbMhlOWccRGQ+swgNnoZ8kjQG/MfW42or2cF16DxQh9GLXzhA+Oo2IrLiLRh6 +aky069O0DYscUPoplRughWn1UQIQDVi+MjNgijrNlpfZVu0ahHF6OwZP7HaAqN74HmaMiuT7 +8dk70CYTjNlZUVDzBALzYTsEnIWMaWg9VB0hgJIPb+NrUJe1WG2uWPeNg/B3tqUmUHOgNmyD +pqXGxYd/d4arcg0CQQJAIgfXi5FFhIyO1/QQlGz9AUXPHkXpK6cgrdqZfK6df592zJSSCuua +4Q+lxun+fgcAT+EyhEJ0BlgiN7KIkFJDUnIdDLjK1yRfjOQ1YiYoxBkYR3yyO9nnLa7FQiQ1 +jlPtyBxvITFE+uI0UVJnPguIFlnNc+wD87+8A9/T+xHxD2HwVCtyY+TAY/dNtD2G21MELG63 +c1Qkx4YuHcHQuSMYmUu7jEh2v0wXmywbEW956NZSACMcsJ4FLrZh4Ewbxqmp0m5UXOLcH+pL +nKmZ3ldEQIsq7r4RFVg+sm3FI1ODkw9WNNCFw+VOCYislh94dD/QZsehTQ3BW7UcanHVkm+j +fI6Jvn7LVyYGdnX3BD7v7rlceffAiiIT9dUu5Dc1U5hy6YR1o+f0eUzOyYgbS8YxTrYryUri +u0ByXiYdjS9fVAeeXF9eW1Czgu6mebhx8iQGxszbUR3NO0/Ep5ZCQuoSzJwMpDlWRHZYID7e +6KpRZdTmllZa1Pf++C36R8zpyQW2Ze9v+jzfGpbg3BQnGFsUAuGQt73CVAsIY8/nexk85TUY +7erAtZvz0auTbPsnHQZXavm/dM4d83yJCtMTIFwZVk9fJCgW+nOpkrSpwGsiNDqM9tO3zM4x +tq/1ssEvatVLWDl3yDeHWQHEyAQgQZGeOujpwHHj8b4xGX3f/4GBefYZOT/3Hz7HEtTr4j/L +JkJZxJSz4BGMSLi3woTzGN9Q7YslneIJvxmyQE6ze3V+N7sJwyIA96v8JcAAbf9pxPL6PpQA +AAAASUVORK5CYII= +--------------020908030104060509010004 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------020908030104060509010004-- diff --git a/Test/Mail/mails/jpattachment.eml b/Test/Mail/mails/jpattachment.eml new file mode 100755 index 0000000..a2ec3b6 --- /dev/null +++ b/Test/Mail/mails/jpattachment.eml @@ -0,0 +1,61 @@ +Return-Path: +X-Original-To: to@example.com +Delivered-To: to@example.com +Message-ID: <484F31D8.50807@sabel.jp> +Date: Wed, 11 Jun 2008 11:00:56 +0900 +From: "jpattach1" +MIME-Version: 1.0 +To: to@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------060205050506040602050305" + +This is a multi-part message in MIME format. +--------------060205050506040602050305 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +$BK\J8(B + +--------------060205050506040602050305 +Content-Type: image/png; + name="=?ISO-2022-JP?B?GyRCRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsGyhCLg==?==?ISO-2022-JP?B?cG5n?=" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename*0*=ISO-2022-JP''%1B%24%42%46%7C%4B%5C%38%6C%46%7C%4B%5C%38%6C%46; + filename*1*=%7C%4B%5C%38%6C%46%7C%4B%5C%38%6C%46%7C%4B%5C%38%6C%46%7C%4B; + filename*2*=%5C%38%6C%1B%28%42%2E%70%6E%67 + +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 +AAAASUVORK5CYII= +--------------060205050506040602050305-- diff --git a/Test/Mail/mails/jpattachment2.eml b/Test/Mail/mails/jpattachment2.eml new file mode 100755 index 0000000..9cb0bff --- /dev/null +++ b/Test/Mail/mails/jpattachment2.eml @@ -0,0 +1,85 @@ +Return-Path: +X-Original-To: to@example.com +Delivered-To: to@example.com +Message-ID: <001801c8cb67$ec49f900$c401000a@YOURC6937191ED> +From: "jpattach2" +To: to@example.com +Subject: =?iso-2022-jp?B?GyRCN29MPhsoQg==?= +Date: Wed, 11 Jun 2008 11:02:05 +0900 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_000B_01C8CBB2.95B84D80" + +This is a multi-part message in MIME format. + +------=_NextPart_000_000B_01C8CBB2.95B84D80 +Content-Type: multipart/alternative; + boundary="----=_NextPart_001_000C_01C8CBB2.95B84D80" + + +------=_NextPart_001_000C_01C8CBB2.95B84D80 +Content-Type: text/plain; + charset="iso-2022-jp" +Content-Transfer-Encoding: 7bit + +$BK\J8(B +------=_NextPart_001_000C_01C8CBB2.95B84D80 +Content-Type: text/html; + charset="iso-2022-jp" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
=1B$BK\J8=1B(B
+ +------=_NextPart_001_000C_01C8CBB2.95B84D80-- + +------=_NextPart_000_000B_01C8CBB2.95B84D80 +Content-Type: image/png; + name="=?iso-2022-jp?B?GyRCRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsGyhC?= + =?iso-2022-jp?B?LnBuZw==?=" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="=?iso-2022-jp?B?GyRCRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsRnxLXDhsGyhC?= + =?iso-2022-jp?B?LnBuZw==?=" + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ +bWFnZVJlYWR5ccllPAAABjdJREFUeNrEV1tsFFUY/mZmZ3d72d5rW2yrLRRoI5iIEpOSNKg8eCEY +iYmJIZFLovGBxEA0PkiMPigkPphQE0rA+KAQn4yi8crVlFBKQQoFWopt0/tl2+5u9zI7M8f/zJy9 +DN1VKzGc7J+zZ86c83/n+7//nDMSYwz3s7gSf65+VNpC1QGy9f+zzw6yt9e+O3PGAYCZ7PhDjzxQ +6Vu+CVJuPZiSA0jULSnUq9h1mjHrmSz6JWH/UOIzCPceW//n+fbj1KpyAmCoLGjYDGPiJ7DIV4Ds +IXOL2ksYvOJ/ok21lHhHFWC5ZQcieSqQu2obWHt75aIQmCaBgAxz7rpwYsDzwgg9S2iEamaAhfrA +9BBYeABs7grMhTsCBJlk2GA4OxkKi0xA8a22fC0CQCGgiYNUczQaTcQsViUmCRCSRbdEE0hcuEXr +wJa9BDk6BXPsO5jT56hfp3E0gcyZUDOGhRkxy1eiyA4GNBuADUYTTiX6kSXjLCVptp56y6HU7YC0 +eh/gqaJxYbKYcKTz0DoM9DwjAyZ3qgVgGqlOvf8wpoOwxOZSffCWNsBbVA/F7UsuThKLcfnqwJr2 +IXqzFXLgUiosFEqLDUkWDEQtXxk1YMYCdghEiV54A/7phIJk63XN9CKndhNKVm1FWePLNhAm8Cgq +cpp2I3TjEFz+s9S2nUuJsJA+mB7NwoBBDMSCXGeOUlOcfIOMwiKZJMATWLjwMwauH0JZ837kV61L +sUE6yW98HbMXhuGN9dqC5kCESJkesXxl1IARDVoh+FvTKa5xDblKDCWxi4j8uhn+nq9T2rA0o8D3 +6B5ENBeFdYE0HSaL2KunRWZlwIwtOBjwbemw+yh9zLke6GNnEB/+yUpHGJq1IjePcSetmFKzeO0O +ES5AzSmFa+Wb0K99AMUVJxYIuOKmSMw7GHCKMBp2AFDKbGqtrK55Dp41e6EHhxDr+hDaraNc0nZo +KMZS1x6Ei1cit2aDYAMofLgFg911xFSvBYBvXkyac4gwFQJrUVEH3RkPD18t8loOQ33qG5osx2Yu +Hif2woid3UUD446ULWh6FQuhEPXbZkRmHXPLjhBocYuBhOmTlxAcIRu9sghI/orNUJ+hDYi57fd1 +k8LUj/C1NiEHe+8oqmvBbMhlOWccRGQ+swgNnoZ8kjQG/MfW42or2cF16DxQh9GLXzhA+Oo2IrLi +LRh6aky069O0DYscUPoplRughWn1UQIQDVi+MjNgijrNlpfZVu0ahHF6OwZP7HaAqN74HmaMiuT7 +8dk70CYTjNlZUVDzBALzYTsEnIWMaWg9VB0hgJIPb+NrUJe1WG2uWPeNg/B3tqUmUHOgNmyDpqXG +xYd/d4arcg0CQQJAIgfXi5FFhIyO1/QQlGz9AUXPHkXpK6cgrdqZfK6df592zJSSCuua4Q+lxun+ +fgcAT+EyhEJ0BlgiN7KIkFJDUnIdDLjK1yRfjOQ1YiYoxBkYR3yyO9nnLa7FQiQ1jlPtyBxvITFE ++uI0UVJnPguIFlnNc+wD87+8A9/T+xHxD2HwVCtyY+TAY/dNtD2G21MELG63c1Qkx4YuHcHQuSMY +mUu7jEh2v0wXmywbEW956NZSACMcsJ4FLrZh4Ewbxqmp0m5UXOLcH+pLnKmZ3ldEQIsq7r4RFVg+ +sm3FI1ODkw9WNNCFw+VOCYislh94dD/QZsehTQ3BW7UcanHVkm+jfI6Jvn7LVyYGdnX3BD7v7rlc +effAiiIT9dUu5Dc1U5hy6YR1o+f0eUzOyYgbS8YxTrYryUriu0ByXiYdjS9fVAeeXF9eW1Czgu6m +ebhx8iQGxszbUR3NO0/Ep5ZCQuoSzJwMpDlWRHZYID7e6KpRZdTmllZa1Pf++C36R8zpyQW2Ze9v ++jzfGpbg3BQnGFsUAuGQt73CVAsIY8/nexk85TUY7erAtZvz0auTbPsnHQZXavm/dM4d83yJCtMT +IFwZVk9fJCgW+nOpkrSpwGsiNDqM9tO3zM4xtq/1ssEvatVLWDl3yDeHWQHEyAQgQZGeOujpwHHj +8b4xGX3f/4GBefYZOT/3Hz7HEtTr4j/LJkJZxJSz4BGMSLi3woTzGN9Q7YslneIJvxmyQE6ze3V+ +N7sJwyIA96v8JcAAbf9pxPL6PpQAAAAASUVORK5CYII= + +------=_NextPart_000_000B_01C8CBB2.95B84D80-- + diff --git a/Test/Mail/mails/plain.eml b/Test/Mail/mails/plain.eml new file mode 100755 index 0000000..28111c1 --- /dev/null +++ b/Test/Mail/mails/plain.eml @@ -0,0 +1,13 @@ +Return-Path: +X-Original-To: to1@example.com +Delivered-To: to1@example.com +Message-ID: <484F2A46.1050504@sabel.jp> +Date: Wed, 11 Jun 2008 10:28:38 +0900 +From: "from1" +MIME-Version: 1.0 +To: to1@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +$BK\J8(B diff --git a/Test/Mail/mails/plain_attachment.eml b/Test/Mail/mails/plain_attachment.eml new file mode 100755 index 0000000..f07c1fb --- /dev/null +++ b/Test/Mail/mails/plain_attachment.eml @@ -0,0 +1,101 @@ +Return-Path: +X-Original-To: to5@example.com +Delivered-To: to5@example.com +Message-ID: <484F2D49.2030501@sabel.jp> +Date: Wed, 11 Jun 2008 10:41:29 +0900 +From: "from5" +MIME-Version: 1.0 +To: to5@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------060004050807000209060302" + +This is a multi-part message in MIME format. +--------------060004050807000209060302 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +$BK\J8(B + +--------------060004050807000209060302 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------060004050807000209060302 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="check_all_32.png" + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9i +ZSBJbWFnZVJlYWR5ccllPAAABvpJREFUeNrEVwlsFFUY/mZmj570YhdaCrSlLQQoJNxVQNSA +SBAkgAmYgBeIEUgIGEUTFEwwBhETY0hARWwwgkdiYhGEIJcK5aYItbZlW3YLpV1Kt8teszPP +f449BnYL0Rin+/e9efPmfd///f87hmOM4f+8uAiBi+/lVVKxmazyP8b8nWz1iLVupYQp0spk +9mVBf19p7vB5GrP0YsCSd//hpOADoTJPrVreuvRtZeu1tF1ULTEQkGWU5hA4Aw/Zdw3s9nmA +TyGzxkrBqt9biCEZb6aShuD4+0udUgQu4IKC4WzeWxxpjylAkWA+F+RQF1jghgbCiwRKxocJ +g0pZq2sm6RYhoQzFJVcg1E3OWcH7HIhPu5gCEoPsdZL3LhU8dbaLXoj0ZCpDFvaA+W/QYB1E +tgWy+wSY2KUrEiEj9CCDVcOQWAICMoXT06R5wTO14Bink+C0nzmLHO1F9+VglLNC/2fAuhsg +tR2E3HlGG4RX1FCIJFZDwZDlXokIEJSkeyuFYqARAaJeaPHiwGnUMstgyiiF3FWLsGMXqXOb +GiNETPeGQtKwIhdvCIHyULc43fQfF3evWeRPqfPZFTBXbACfM5pC5ScLakaqMIaoaeMnCQGL +Az66PhZLjmKbkT8KppRs5JZOQ++hc2HJ7KerES0o/FaYS5dQ4mYi7Nqv5YQgEz+TVo8qkCwJ +4wiM6B8nGxMREE9C8prQfeIwnIffQXrxVBQ/ug5ptmH6iqb3JTbmkgU0mzyQbhxTXWZxSXq3 +AoYQKOwSGYhxCgmSLoTRJz2EclsQWbf24coXU+A4tF6V+e6wWMtfpIWsN+WEj4xCIgYAJSTJ +CEhx8e/ZSCkxhDQ+iOIcP8Taj3B5z7PU5ovlhx42a8UqyGGR1LhDBHxU+tQxFCzuIKeaIQQs +HJO993ItHrK/HbLnKkTnLwi17IfoOhKhrEqTa5HhbduLK7sXYdjCb8glProemTKLYB4wG6H6 +r8AoPzhSUMFIrICMhLOAT7XB1GccUke/jqw5h5A19zgEe2WcGqKqRlrbPjTuX6fPFi6qhqVk +DvWTIAe9mkkaVpJpGLNklzm/Ejnzj6iEov3DkkoicOYDeFrPES4XJSLQzGkdMBFvW/7E+0Id +2jnWQxKSPBHreWcRkDlxI9LHvGF4J88aRnP1m4a1o6arBptM9bho68KBHCc25TF0mkgCBSMc +Nw2lu6T/abnGTbBmIHfQRAycshK2odMNPDInb0SorRaBhuqYQq0/o6u5BlkDx6H6ZjWeOjkT +T+fb8HC/sXB3nEVNXx/aBhNyCDbq3p50Glb01WxIthcZ1/ehbvsM1H23huQOGUk8toX+W6Lv +ZZBLHef2oKq5CrOPzcSCfoUYbCvDzZsX4Qv4MJx2dtcQIhDEK2TJl+JoMpJaaTTowGzAd+JD +1FYtUfu3B9qxoXYDPnMfgLVsjuGdHTd246VfF2FxWRkKcwrR4jwLj9eDIHFXTFZ8CEJQCCRd +ilOKHkHOjC1qvXPvKgQcR5CXSvXLVbhy9gl87D+Omls74b7jw7m0aXhLf3crbXSfpLbihYrh +SLFYUN94hsIrRset95AzlwX8UShtNZwJd8+zsnGDYx0LX3PAnD1ArYu3W+DcVKQdqUizTX0L +ERxpRnlBPi7Vncap1iDmdFD8aaiv7WYsfKgCYQpVk+MyORabc010dJhwHZh0wYxllSKXZDvW +k5IJMMfVI892UZDtjxcg4O9GzfkaAhJRmkHtXiA3MxWLJ4+Eu7MDjY4GQ6600C49qQ1Y4efQ +RKsy/Al2Q4utBMG2JvW+ducyjHh+u3Zi3rEEebojN++IFIIrtLd4DADD7FZMHj8Kjc3NaHE5 +Dc+udwIjm4HlJg797CVokFsSEIibBeoDmloHVhRo4ciidovWviDAYeYFD/rn0wxIj4cJ4ujJ +c/De8RnA228BUyk8y2lN6B1GbDPyJTiUmnrZaeJbEHDWIYP0Hxx3Kme6AuVkn4Y5LHUw5NOW +bbHG+viDRvDbbuBJIvAqT+DKZLUXqRiMNScMQcPVUydLi8aMh6VPCX0SFFIS2hMuhLOVZLzW +iLV/nUUe5aZw78kLXvJ6XuogrBk7FDl+D0JuJ0xZdhAGYfFXIwSis2DbNNNkgcNmIjvmQT9x +fkxj+CFXRmax8QwaIPAJLRxm+XhkycZ3KNdPUwRWv9xHOmogwHHqEEriU04jV1nk1CWup8O+ +ck3HSqEAC6z6CUpsJ3Pge1zA53DBrZ/WlKWnWxFOEUfphvnaOTeeQGRzUkBpyYESXeG+BDQS +7/L5eE4JqHwNVWjCFtSjPfZRoR4egvrkC2EW5Hs+TrmYhnyccQ8UCzsRHYmlSqKTf9vwG9ru +Po1rizrZdMgJv47/8ef1VO5fvf+3AAMAoXePQvnneewAAAAASUVORK5CYII= +--------------060004050807000209060302-- diff --git a/Test/Mail/mails/plain_html.eml b/Test/Mail/mails/plain_html.eml new file mode 100755 index 0000000..4e1c9f6 --- /dev/null +++ b/Test/Mail/mails/plain_html.eml @@ -0,0 +1,33 @@ +Return-Path: +X-Original-To: to3@example.com +Delivered-To: to3@example.com +Message-ID: <484F2B24.5000108@sabel.jp> +Date: Wed, 11 Jun 2008 10:32:20 +0900 +From: "from3" +MIME-Version: 1.0 +To: to3@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/alternative; + boundary="------------090105030302000205020906" + +This is a multi-part message in MIME format. +--------------090105030302000205020906 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +*$BK\J8(B* + +--------------090105030302000205020906 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B + + + +--------------090105030302000205020906-- diff --git a/Test/Mail/mails/plain_html_attachment.eml b/Test/Mail/mails/plain_html_attachment.eml new file mode 100755 index 0000000..8dc907b --- /dev/null +++ b/Test/Mail/mails/plain_html_attachment.eml @@ -0,0 +1,121 @@ +Return-Path: +X-Original-To: to6@example.com +Delivered-To: to6@example.com +Message-ID: <484F2E2F.4080707@sabel.jp> +Date: Wed, 11 Jun 2008 10:45:19 +0900 +From: "from6" +MIME-Version: 1.0 +To: to6@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------050700040003030904080909" + +This is a multi-part message in MIME format. +--------------050700040003030904080909 +Content-Type: multipart/alternative; + boundary="------------090708010308090509060302" + + +--------------090708010308090509060302 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +*$BK\J8(B* + +--------------090708010308090509060302 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B + + + +--------------090708010308090509060302-- + +--------------050700040003030904080909 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------050700040003030904080909 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------050700040003030904080909-- diff --git a/Test/Mail/mails/plain_htmlimg.eml b/Test/Mail/mails/plain_htmlimg.eml new file mode 100755 index 0000000..50d789c --- /dev/null +++ b/Test/Mail/mails/plain_htmlimg.eml @@ -0,0 +1,129 @@ +Return-Path: +X-Original-To: to9@example.com +Delivered-To: to9@example.com +Message-ID: <484F2D00.4040309@sabel.jp> +Date: Wed, 11 Jun 2008 10:40:16 +0900 +From: "from9" +MIME-Version: 1.0 +To: to9@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/alternative; + boundary="------------070605040107080804030704" + +This is a multi-part message in MIME format. +--------------070605040107080804030704 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +$BK\J8(B + + + +--------------070605040107080804030704 +Content-Type: multipart/related; + boundary="------------050006090903040902020905" + + +--------------050006090903040902020905 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B
+
+
+ + + +--------------050006090903040902020905 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------050006090903040902020905 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------050006090903040902020905-- + +--------------070605040107080804030704-- diff --git a/Test/Mail/mails/plain_htmlimg2.eml b/Test/Mail/mails/plain_htmlimg2.eml new file mode 100755 index 0000000..032fa44 --- /dev/null +++ b/Test/Mail/mails/plain_htmlimg2.eml @@ -0,0 +1,132 @@ +Return-Path: +X-Original-To: to10@example.com +Delivered-To: to10@example.com +Message-ID: <001801c8cb65$9646fff0$c401000a@YOURC6937191ED> +From: "from10" +To: +Subject: =?iso-2022-jp?B?GyRCN29MPhsoQg==?= +Date: Wed, 11 Jun 2008 10:50:55 +0900 +MIME-Version: 1.0 +Content-Type: multipart/related; + type="multipart/alternative"; + boundary="----=_NextPart_000_0013_01C8CBB1.06146930" + +This is a multi-part message in MIME format. + +------=_NextPart_000_0013_01C8CBB1.06146930 +Content-Type: multipart/alternative; + boundary="----=_NextPart_001_0014_01C8CBB1.06146930" + + +------=_NextPart_001_0014_01C8CBB1.06146930 +Content-Type: text/plain; + charset="iso-2022-jp" +Content-Transfer-Encoding: 7bit + +$BK\J8(B + + +------=_NextPart_001_0014_01C8CBB1.06146930 +Content-Type: text/html; + charset="iso-2022-jp" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
=1B$BK\J8=1B(B
+
3D""
+
3D""
+ +------=_NextPart_001_0014_01C8CBB1.06146930-- + +------=_NextPart_000_0013_01C8CBB1.06146930 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: <001101c8cb65$962cc130$c401000a@YOURC6937191ED> + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ +bWFnZVJlYWR5ccllPAAABjdJREFUeNrEV1tsFFUY/mZmZ3d72d5rW2yrLRRoI5iIEpOSNKg8eCEY +iYmJIZFLovGBxEA0PkiMPigkPphQE0rA+KAQn4yi8crVlFBKQQoFWopt0/tl2+5u9zI7M8f/zJy9 +DN1VKzGc7J+zZ86c83/n+7//nDMSYwz3s7gSf65+VNpC1QGy9f+zzw6yt9e+O3PGAYCZ7PhDjzxQ +6Vu+CVJuPZiSA0jULSnUq9h1mjHrmSz6JWH/UOIzCPceW//n+fbj1KpyAmCoLGjYDGPiJ7DIV4Ds +IXOL2ksYvOJ/ok21lHhHFWC5ZQcieSqQu2obWHt75aIQmCaBgAxz7rpwYsDzwgg9S2iEamaAhfrA +9BBYeABs7grMhTsCBJlk2GA4OxkKi0xA8a22fC0CQCGgiYNUczQaTcQsViUmCRCSRbdEE0hcuEXr +wJa9BDk6BXPsO5jT56hfp3E0gcyZUDOGhRkxy1eiyA4GNBuADUYTTiX6kSXjLCVptp56y6HU7YC0 +eh/gqaJxYbKYcKTz0DoM9DwjAyZ3qgVgGqlOvf8wpoOwxOZSffCWNsBbVA/F7UsuThKLcfnqwJr2 +IXqzFXLgUiosFEqLDUkWDEQtXxk1YMYCdghEiV54A/7phIJk63XN9CKndhNKVm1FWePLNhAm8Cgq +cpp2I3TjEFz+s9S2nUuJsJA+mB7NwoBBDMSCXGeOUlOcfIOMwiKZJMATWLjwMwauH0JZ837kV61L +sUE6yW98HbMXhuGN9dqC5kCESJkesXxl1IARDVoh+FvTKa5xDblKDCWxi4j8uhn+nq9T2rA0o8D3 +6B5ENBeFdYE0HSaL2KunRWZlwIwtOBjwbemw+yh9zLke6GNnEB/+yUpHGJq1IjePcSetmFKzeO0O +ES5AzSmFa+Wb0K99AMUVJxYIuOKmSMw7GHCKMBp2AFDKbGqtrK55Dp41e6EHhxDr+hDaraNc0nZo +KMZS1x6Ei1cit2aDYAMofLgFg911xFSvBYBvXkyac4gwFQJrUVEH3RkPD18t8loOQ33qG5osx2Yu +Hif2woid3UUD446ULWh6FQuhEPXbZkRmHXPLjhBocYuBhOmTlxAcIRu9sghI/orNUJ+hDYi57fd1 +k8LUj/C1NiEHe+8oqmvBbMhlOWccRGQ+swgNnoZ8kjQG/MfW42or2cF16DxQh9GLXzhA+Oo2IrLi +LRh6aky069O0DYscUPoplRughWn1UQIQDVi+MjNgijrNlpfZVu0ahHF6OwZP7HaAqN74HmaMiuT7 +8dk70CYTjNlZUVDzBALzYTsEnIWMaWg9VB0hgJIPb+NrUJe1WG2uWPeNg/B3tqUmUHOgNmyDpqXG +xYd/d4arcg0CQQJAIgfXi5FFhIyO1/QQlGz9AUXPHkXpK6cgrdqZfK6df592zJSSCuua4Q+lxun+ +fgcAT+EyhEJ0BlgiN7KIkFJDUnIdDLjK1yRfjOQ1YiYoxBkYR3yyO9nnLa7FQiQ1jlPtyBxvITFE ++uI0UVJnPguIFlnNc+wD87+8A9/T+xHxD2HwVCtyY+TAY/dNtD2G21MELG63c1Qkx4YuHcHQuSMY +mUu7jEh2v0wXmywbEW956NZSACMcsJ4FLrZh4Ewbxqmp0m5UXOLcH+pLnKmZ3ldEQIsq7r4RFVg+ +sm3FI1ODkw9WNNCFw+VOCYislh94dD/QZsehTQ3BW7UcanHVkm+jfI6Jvn7LVyYGdnX3BD7v7rlc +effAiiIT9dUu5Dc1U5hy6YR1o+f0eUzOyYgbS8YxTrYryUriu0ByXiYdjS9fVAeeXF9eW1Czgu6m +ebhx8iQGxszbUR3NO0/Ep5ZCQuoSzJwMpDlWRHZYID7e6KpRZdTmllZa1Pf++C36R8zpyQW2Ze9v ++jzfGpbg3BQnGFsUAuGQt73CVAsIY8/nexk85TUY7erAtZvz0auTbPsnHQZXavm/dM4d83yJCtMT +IFwZVk9fJCgW+nOpkrSpwGsiNDqM9tO3zM4xtq/1ssEvatVLWDl3yDeHWQHEyAQgQZGeOujpwHHj +8b4xGX3f/4GBefYZOT/3Hz7HEtTr4j/LJkJZxJSz4BGMSLi3woTzGN9Q7YslneIJvxmyQE6ze3V+ +N7sJwyIA96v8JcAAbf9pxPL6PpQAAAAASUVORK5CYII= + +------=_NextPart_000_0013_01C8CBB1.06146930 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: <001201c8cb65$962cc130$c401000a@YOURC6937191ED> + +iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ +bWFnZVJlYWR5ccllPAAABvpJREFUeNrEVwlsFFUY/mZmj570YhdaCrSlLQQoJNxVQNSASBAkgAmY +gBeIEUgIGEUTFEwwBhETY0hARWwwgkdiYhGEIJcK5aYItbZlW3YLpV1Kt8teszPPf449BnYL0Rin ++/e9efPmfd///f87hmOM4f+8uAiBi+/lVVKxmazyP8b8nWz1iLVupYQp0spk9mVBf19p7vB5GrP0 +YsCSd//hpOADoTJPrVreuvRtZeu1tF1ULTEQkGWU5hA4Aw/Zdw3s9nmATyGzxkrBqt9biCEZb6aS +huD4+0udUgQu4IKC4WzeWxxpjylAkWA+F+RQF1jghgbCiwRKxocJg0pZq2sm6RYhoQzFJVcg1E3O +WcH7HIhPu5gCEoPsdZL3LhU8dbaLXoj0ZCpDFvaA+W/QYB1EtgWy+wSY2KUrEiEj9CCDVcOQWAIC +MoXT06R5wTO14Bink+C0nzmLHO1F9+VglLNC/2fAuhsgtR2E3HlGG4RX1FCIJFZDwZDlXokIEJSk +eyuFYqARAaJeaPHiwGnUMstgyiiF3FWLsGMXqXObGiNETPeGQtKwIhdvCIHyULc43fQfF3evWeRP +qfPZFTBXbACfM5pC5ScLakaqMIaoaeMnCQGLAz66PhZLjmKbkT8KppRs5JZOQ++hc2HJ7KerES0o +/FaYS5dQ4mYi7Nqv5YQgEz+TVo8qkCwJ4wiM6B8nGxMREE9C8prQfeIwnIffQXrxVBQ/ug5ptmH6 +iqb3JTbmkgU0mzyQbhxTXWZxSXq3AoYQKOwSGYhxCgmSLoTRJz2EclsQWbf24coXU+A4tF6V+e6w +WMtfpIWsN+WEj4xCIgYAJSTJCEhx8e/ZSCkxhDQ+iOIcP8Taj3B5z7PU5ovlhx42a8UqyGGR1LhD +BHxU+tQxFCzuIKeaIQQsHJO993ItHrK/HbLnKkTnLwi17IfoOhKhrEqTa5HhbduLK7sXYdjCb8gl +ProemTKLYB4wG6H6r8AoPzhSUMFIrICMhLOAT7XB1GccUke/jqw5h5A19zgEe2WcGqKqRlrbPjTu +X6fPFi6qhqVkDvWTIAe9mkkaVpJpGLNklzm/Ejnzj6iEov3DkkoicOYDeFrPES4XJSLQzGkdMBFv +W/7E+0Id2jnWQxKSPBHreWcRkDlxI9LHvGF4J88aRnP1m4a1o6arBptM9bho68KBHCc25TF0mkgC +BSMcNw2lu6T/abnGTbBmIHfQRAycshK2odMNPDInb0SorRaBhuqYQq0/o6u5BlkDx6H6ZjWeOjkT +T+fb8HC/sXB3nEVNXx/aBhNyCDbq3p50Glb01WxIthcZ1/ehbvsM1H23huQOGUk8toX+W6LvZZBL +Hef2oKq5CrOPzcSCfoUYbCvDzZsX4Qv4MJx2dtcQIhDEK2TJl+JoMpJaaTTowGzAd+JD1FYtUfu3 +B9qxoXYDPnMfgLVsjuGdHTd246VfF2FxWRkKcwrR4jwLj9eDIHFXTFZ8CEJQCCRdilOKHkHOjC1q +vXPvKgQcR5CXSvXLVbhy9gl87D+Omls74b7jw7m0aXhLf3crbXSfpLbihYrhSLFYUN94hsIrRset +95AzlwX8UShtNZwJd8+zsnGDYx0LX3PAnD1ArYu3W+DcVKQdqUizTX0LERxpRnlBPi7Vncap1iDm +dFD8aaiv7WYsfKgCYQpVk+MyORabc010dJhwHZh0wYxllSKXZDvWk5IJMMfVI892UZDtjxcg4O9G +zfkaAhJRmkHtXiA3MxWLJ4+Eu7MDjY4GQ6600C49qQ1Y4efQRKsy/Al2Q4utBMG2JvW+ducyjHh+ +u3Zi3rEEebojN++IFIIrtLd4DADD7FZMHj8Kjc3NaHE5Dc+udwIjm4HlJg797CVokFsSEIibBeoD +mloHVhRo4ciidovWviDAYeYFD/rn0wxIj4cJ4ujJc/De8RnA228BUyk8y2lN6B1GbDPyJTiUmnrZ +aeJbEHDWIYP0Hxx3Kme6AuVkn4Y5LHUw5NOWbbHG+viDRvDbbuBJIvAqT+DKZLUXqRiMNScMQcPV +UydLi8aMh6VPCX0SFFIS2hMuhLOVZLzWiLV/nUUe5aZw78kLXvJ6XuogrBk7FDl+D0JuJ0xZdhAG +YfFXIwSis2DbNNNkgcNmIjvmQT9xfkxj+CFXRmax8QwaIPAJLRxm+XhkycZ3KNdPUwRWv9xHOmog +wHHqEEriU04jV1nk1CWup8O+ck3HSqEAC6z6CUpsJ3Pge1zA53DBrZ/WlKWnWxFOEUfphvnaOTee +QGRzUkBpyYESXeG+BDQS7/L5eE4JqHwNVWjCFtSjPfZRoR4egvrkC2EW5Hs+TrmYhnyccQ8UCzsR +HYmlSqKTf9vwG9ruPo1rizrZdMgJv47/8ef1VO5fvf+3AAMAoXePQvnneewAAAAASUVORK5CYII= + +------=_NextPart_000_0013_01C8CBB1.06146930-- + diff --git a/Test/Mail/mails/plain_htmlimg_attachment.eml b/Test/Mail/mails/plain_htmlimg_attachment.eml new file mode 100755 index 0000000..23a6582 --- /dev/null +++ b/Test/Mail/mails/plain_htmlimg_attachment.eml @@ -0,0 +1,217 @@ +Return-Path: +X-Original-To: to11@example.com +Delivered-To: to11@example.com +Message-ID: <484F3128.8090706@sabel.jp> +Date: Wed, 11 Jun 2008 10:58:00 +0900 +From: "from11" +MIME-Version: 1.0 +To: to11@example.com +Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQg==?= +Content-Type: multipart/mixed; + boundary="------------030903050804010805090909" + +This is a multi-part message in MIME format. +--------------030903050804010805090909 +Content-Type: multipart/alternative; + boundary="------------090801000708050000010400" + + +--------------090801000708050000010400 +Content-Type: text/plain; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + +$BK\J8(B + + + +--------------090801000708050000010400 +Content-Type: multipart/related; + boundary="------------000401030302040404070905" + + +--------------000401030302040404070905 +Content-Type: text/html; charset=ISO-2022-JP +Content-Transfer-Encoding: 7bit + + + + + + +$BK\J8(B
+
+
+ + + +--------------000401030302040404070905 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------000401030302040404070905 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------000401030302040404070905-- + +--------------090801000708050000010400-- + +--------------030903050804010805090909 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="comment_rss_32.png" + +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 +AAAASUVORK5CYII= +--------------030903050804010805090909 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; + filename="check_all_32.png" + +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 +--------------030903050804010805090909-- diff --git a/Test/Mail/mails/plain_htmlimg_attachment2.eml b/Test/Mail/mails/plain_htmlimg_attachment2.eml new file mode 100755 index 0000000..fc302cd --- /dev/null +++ b/Test/Mail/mails/plain_htmlimg_attachment2.eml @@ -0,0 +1,218 @@ +Return-Path: +X-Original-To: to12@example.com +Delivered-To: to12@example.com +Message-ID: <002401c8cb65$dfa33650$c401000a@YOURC6937191ED> +From: "from12" +To: +Subject: =?iso-2022-jp?B?GyRCN29MPhsoQg==?= +Date: Wed, 11 Jun 2008 10:52:55 +0900 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_NextPart_000_001E_01C8CBB1.4DB07900" + +This is a multi-part message in MIME format. + +------=_NextPart_000_001E_01C8CBB1.4DB07900 +Content-Type: multipart/related; + type="multipart/alternative"; + boundary="----=_NextPart_001_001F_01C8CBB1.4DB07900" + + +------=_NextPart_001_001F_01C8CBB1.4DB07900 +Content-Type: multipart/alternative; + boundary="----=_NextPart_002_0020_01C8CBB1.4DB07900" + + +------=_NextPart_002_0020_01C8CBB1.4DB07900 +Content-Type: text/plain; + charset="iso-2022-jp" +Content-Transfer-Encoding: 7bit + +$BK\J8(B + + +------=_NextPart_002_0020_01C8CBB1.4DB07900 +Content-Type: text/html; + charset="iso-2022-jp" +Content-Transfer-Encoding: quoted-printable + + + + + + + + +
=1B$BK\J8=1B(B
+
3D""
+
3D""
+ +------=_NextPart_002_0020_01C8CBB1.4DB07900-- + +------=_NextPart_001_001F_01C8CBB1.4DB07900 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-ID: <001c01c8cb65$ddc66000$c401000a@YOURC6937191ED> + +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 + +------=_NextPart_001_001F_01C8CBB1.4DB07900 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-ID: <001d01c8cb65$ddc8d100$c401000a@YOURC6937191ED> + +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 + +------=_NextPart_001_001F_01C8CBB1.4DB07900-- + +------=_NextPart_000_001E_01C8CBB1.4DB07900 +Content-Type: image/png; + name="comment_rss_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="comment_rss_32.png" + +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 + +------=_NextPart_000_001E_01C8CBB1.4DB07900 +Content-Type: image/png; + name="check_all_32.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="check_all_32.png" + +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 + +------=_NextPart_000_001E_01C8CBB1.4DB07900-- + diff --git a/Test/Map/Destination.php b/Test/Map/Destination.php new file mode 100755 index 0000000..16a6322 --- /dev/null +++ b/Test/Map/Destination.php @@ -0,0 +1,92 @@ + + */ +class Test_Map_Destination extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Map_Destination"); + } + + public function testDestination() + { + $destination = $this->createDestination(); + $this->assertEquals("module", $destination->getModule()); + $this->assertEquals("controller", $destination->getController()); + $this->assertEquals("action", $destination->getAction()); + } + + public function testModule() + { + $destination = $this->createDestination(); + $this->assertTrue($destination->hasModule()); + $destination->setModule("admin"); + $this->assertEquals("admin", $destination->getModule()); + } + + public function testController() + { + $destination = $this->createDestination(); + $this->assertTrue($destination->hasController()); + $destination->setController("main"); + $this->assertEquals("main", $destination->getController()); + } + + public function testAction() + { + $destination = $this->createDestination(); + $this->assertTrue($destination->hasAction()); + $destination->setAction("index"); + $this->assertEquals("index", $destination->getAction()); + } + + public function testToArray() + { + list ($m, $c, $a) = $this->createDestination()->toArray(); + $this->assertEquals("module", $m); + $this->assertEquals("controller", $c); + $this->assertEquals("action", $a); + } + + public function testInvalidModuleSet() + { + try { + $this->createDestination()->setModule(1); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testInvalidControllerSet() + { + try { + $this->createDestination()->setController(false); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testInvalidActionSet() + { + try { + $this->createDestination()->setAction(new stdClass()); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + private function createDestination() + { + $param = array("module" => "module", "controller" => "controller", "action" => "action"); + return new Sabel_Map_Destination($param); + } +} diff --git a/Test/Map/Match.php b/Test/Map/Match.php new file mode 100755 index 0000000..fc8be9f --- /dev/null +++ b/Test/Map/Match.php @@ -0,0 +1,369 @@ + + */ +class Test_Map_Match extends SabelTestCase +{ + private $config = null; + private $request = null; + + public static function suite() + { + return self::createSuite("Test_Map_Match"); + } + + public function setUp() + { + $this->config = new ConfigMap(); + } + + public function tearDown() + { + $this->config->clearRoutes(); + } + + public function testSimple() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + $c = $this->routing("test/test"); + $this->assertEquals("default", $c->getName()); + } + + public function testNoMatch() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + try { + $c = $this->routing("test"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testFailMismatchUriAndElement() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + try { + $this->routing("test/test/test"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testFailWithDefault() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + try { + $this->routing("test"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testMatchWithDefault() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array(":controller" => "index", ":action" => "index")); + + $candidate = $this->routing("test"); + $destination = $candidate->getDestination(); + + $this->assertEquals("default", $candidate->getName()); + $this->assertEquals("index", $destination->getAction()); + } + + public function testMatchWithDefaultPriority() + { + $this->route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array(":action" => "index")); + + $candidate = $this->routing("test/test"); + $destination = $candidate->getDestination(); + + $this->assertEquals("default", $candidate->getName()); + $this->assertEquals("test", $destination->getAction()); + } + + public function testMatchWithParameter() + { + $this->route("default") + ->uri(":controller/:action/:param") + ->module("index") + ->requirements(array(":param" => "[0-9]+")); + + $candidate = $this->routing("test/test/1000"); + + $this->assertEquals("default", $candidate->getName()); + $this->assertEquals("1000", $this->request->fetchParameterValue("param")); + } + + public function testMismatchWithParameter() + { + $this->route("default") + ->uri(":controller/:action/:param") + ->module("index") + ->requirements(array(":param" => "[0-9]+")); + + try { + $candidate = $this->routing("test/test/test"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testMismatchWithMultipleParameter() + { + $this->route("default") + ->uri(":controller/:action/:param/:param2") + ->module("index") + ->requirements(array(":param" => "[0-9]+", ":param2" => "[a-z]+")); + + try { + $candidate = $this->routing("test/test/1000/1000"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testMatchhWithMultipleParameterWithDefaultsWithRequirements() + { + $this->route("default") + ->uri(":controller/:action/:param/:param2") + ->module("index") + ->requirements(array(":param" => "0-9]+", ":param2" => "[a-z]+")) + ->defaults(array(":param" => "100", ":param2" => "abc")); + + $candidate = $this->routing("test/test"); + $this->assertEquals("100" ,$this->request->fetchParameterValue("param")); + $this->assertEquals("abc" ,$this->request->fetchParameterValue("param2")); + } + + public function testMisMatchhWithMultipleParameterWithRequirements() + { + $this->route("default") + ->uri(":controller/:action/:param/:param2") + ->module("index") + ->requirements(array(":param" => "[0-9]{1}", ":param2" => "[a-z]+")); + + try { + $candidate = $this->routing("test/test/100/abc"); + } catch (Exception $e) { + return; + } + + $this->fail("matched"); + } + + public function testMultipleRoutePriority() + { + $this->route("article") + ->uri(":controller/:action/:year/:month/:day") + ->module("index") + ->requirements(array(":year" => "[1-3][0-9]{3}", + ":month" => "[0-2][0-9]", + ":day" => "[0-3][0-9]")); + + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + $candidate = $this->routing("blog/article/2008/01/20"); + $this->assertEquals("article", $candidate->getName()); + + $candidate = $this->routing("blog/article"); + $this->assertEquals("default", $candidate->getName()); + + try { + $candidate = $this->routing("blog/article/9999/99/99"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testMultipleRoutePriorityWithDefault() + { + $this->route("article") + ->uri(":controller/:action/:year/:month/:day") + ->module("index") + ->requirements(array(":year" => "[1-3][0-9]{3}", + ":month" => "[0-2][0-9]", + ":day" => "[0-3][0-9]")) + ->defaults(array(":day" => "01")); + + $this->route("default") + ->uri(":controller/:action") + ->module("index"); + + $candidate = $this->routing("blog/article/2008/01"); + + $this->assertEquals("article", $candidate->getName()); + $this->assertEquals("2008", $this->request->fetchParameterValue("year")); + $this->assertEquals("01", $this->request->fetchParameterValue("month")); + $this->assertEquals("01", $this->request->fetchParameterValue("day")); + + $candidate = $this->routing("blog/article"); + $this->assertEquals("default", $candidate->getName()); + + try { + $candidate = $this->routing("blog/article/9999/99/99"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testMultipleRoutePriorityWithAllDefault() + { + $this->route("article") + ->uri(":controller/:action/:year/:month/:day") + ->module("index") + ->requirements(array(":year" => "[1-3][0-9]{3}", + ":month" => "[0-2][0-9]", + ":day" => "[0-3][0-9]")) + ->defaults(array(":year" => "2008", ":month" => "01", ":day" => null)); + + $this->route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array(":action" => "test")); + + $candidate = $this->routing("blog/article"); + + $this->assertEquals("article", $candidate->getName()); + $this->assertEquals("2008", $this->request->fetchParameterValue("year")); + $this->assertEquals("01", $this->request->fetchParameterValue("month")); + $this->assertEquals(null, $this->request->fetchParameterValue("day")); + + $candidate = $this->routing("test"); + $this->assertEquals("default", $candidate->getName()); + + try { + $candidate = $this->routing("blog/article/9999/99/99"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testWithConstant() + { + $this->route("admin") + ->uri("admin/:controller/:action") + ->module("admin"); + + $this->route("manage") + ->uri("manage/:controller/:action") + ->module("manage"); + + $candidate = $this->routing("admin/test/test"); + $this->assertEquals("admin", $candidate->getName()); + + $candidate = $this->routing("manage/test/test"); + $this->assertEquals("manage", $candidate->getName()); + } + + public function testWithConstantWithDefaults() + { + $this->route("admin") + ->uri("admin/:controller/:action/:param") + ->module("admin") + ->defaults(array(":param" => "param")); + + $this->route("manage") + ->uri("manage/:controller/:action") + ->module("manage"); + + $candidate = $this->routing("admin/test/test"); + $destination = $candidate->getDestination(); + $this->assertEquals("admin", $candidate->getName()); + $this->assertEquals("test", $destination->getController()); + $this->assertEquals("test", $destination->getAction()); + $this->assertEquals("param", $this->request->fetchParameterValue("param")); + + $candidate = $this->routing("manage/test/test"); + $this->assertEquals("manage", $candidate->getName()); + } + + public function testMatchAll() + { + $this->route("default") + ->uri(":controller/:action") + ->module("admin"); + + $this->route("matchall") + ->uri("*") + ->module("module") + ->controller("controller") + ->action("action"); + + $candidate = $this->routing("hoge/fuga/foo/bar/baz"); + $this->assertEquals("matchall", $candidate->getName()); + + $destination = $candidate->getDestination(); + $this->assertEquals("module", $destination->getModule()); + $this->assertEquals("controller", $destination->getController()); + $this->assertEquals("action", $destination->getAction()); + } + + protected function route($name) + { + return $this->config->route($name); + } + + protected function request($uri) + { + return $request = new Sabel_Request_Object($uri); + } + + protected function routing($uri) + { + $this->config->configure(); + + $this->request = $request = $this->request($uri); + if (!$candidate = $this->config->getValidCandidate($request->getUri())) { + throw new Sabel_Exception_Runtime("map not match."); + } + + $request->setParameterValues($candidate->getUriParameters()); + + return $candidate; + } +} + +class ConfigMap extends Sabel_Map_Configurator +{ + public function configure() {} +} diff --git a/Test/Map/Tests.php b/Test/Map/Tests.php new file mode 100755 index 0000000..7e20847 --- /dev/null +++ b/Test/Map/Tests.php @@ -0,0 +1,16 @@ +addTest(Test_Map_Match::suite()); + $suite->addTest(Test_Map_Destination::suite()); + + return $suite; + } +} diff --git a/Test/Object.php b/Test/Object.php new file mode 100755 index 0000000..52018d1 --- /dev/null +++ b/Test/Object.php @@ -0,0 +1,63 @@ + + */ +class Test_Object extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Object"); + } + + public function testHasMethod() + { + $obj = new TestObject(); + $this->assertTrue($obj->hasMethod("hoge")); + $this->assertFalse($obj->hasMethod("fuga")); + } + + public function testGetName() + { + $obj = new TestObject(); + $this->assertEquals("TestObject", $obj->getName()); + $this->assertNotEquals("_TestObject", $obj->getName()); + } + + public function testHashCode() + { + $obj = new TestObject(); + $hc = "ca3a664fbcf20ac679384e974cf3d052ffd64695"; + $this->assertEquals($hc, $obj->hashCode()); + $this->assertEquals($hc, $obj->__toString()); + } + + public function testEquals() + { + $obj1 = new TestObject(); + $obj2 = new TestObject(); + + $this->assertTrue($obj1->equals($obj2)); + $obj1->attr = 20; + $this->assertFalse($obj1->equals($obj2)); + } + + public function testReflection() + { + $obj = new TestObject(); + $reflection = $obj->getReflection(); + $this->assertTrue($reflection instanceof ReflectionClass); + $this->assertTrue($reflection instanceof Sabel_Reflection_Class); + $this->assertEquals("TestObject", $reflection->getName()); + $this->assertTrue($reflection->hasMethod("hoge")); + } +} + +class TestObject extends Sabel_Object +{ + public $attr = 10; + public function hoge() {} +} diff --git a/Test/Preference.php b/Test/Preference.php new file mode 100755 index 0000000..2efe8e1 --- /dev/null +++ b/Test/Preference.php @@ -0,0 +1,29 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Test_Preference extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Preference"); + } + + /** + * set up + * + * @access public + * @return void + */ + public function setUp() + { + } +} \ No newline at end of file diff --git a/Test/Preference/Base.php b/Test/Preference/Base.php new file mode 100755 index 0000000..d0b25fc --- /dev/null +++ b/Test/Preference/Base.php @@ -0,0 +1,172 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Test_Preference_Base extends SabelTestCase +{ + protected $pref = null; + + public function testGetInt() + { + $this->assertEquals(1, $this->pref->getInt("test", 1)); + + $this->assertEquals(2, $this->pref->getInt("test", 2)); + + $this->assertEquals(2, $this->pref->getInt("test")); + } + + public function testGetIntWithString() + { + $this->assertEquals(1, $this->pref->getInt("test", "1")); + + $this->pref->setInt("test2", "2"); + $this->assertEquals(2, $this->pref->getInt("test2")); + } + + public function testBoolean() + { + $this->pref->setBoolean("bool1", 1); + $this->assertTrue($this->pref->getBoolean("bool1")); + + $this->pref->setBoolean("bool2", 0); + $this->assertFalse($this->pref->getBoolean("bool2")); + + $this->assertTrue($this->pref->getBoolean("bool3", true)); + $this->assertTrue($this->pref->getBoolean("bool4", "true")); + $this->assertTrue($this->pref->getBoolean("bool5", "t")); + $this->assertTrue($this->pref->getBoolean("bool6", 1.0)); + $this->assertTrue($this->pref->getBoolean("bool7", "false")); + $this->assertTrue($this->pref->getBoolean("bool8", "f")); + + $this->assertFalse($this->pref->getBoolean("bool9", false)); + $this->assertFalse($this->pref->getBoolean("bool10", 0.0)); + } + + public function testFloat() + { + $this->pref->setFloat("float", 1.0); + $this->assertEquals(1.0, $this->pref->getFloat("float")); + + $this->assertEquals(1.1, $this->pref->getFloat("float2", 1.1)); + $this->assertEquals(1.1, $this->pref->getFloat("float2")); + } + + public function testGetAll() + { + $this->pref->setInt("test", 1); + $this->pref->setString("test1", "str"); + $this->pref->setBoolean("test2", false); + $this->pref->setFloat("test3", 1.2); + + $result = $this->pref->getAll(); + + $this->assertTrue(is_int($result["test"])); + $this->assertTrue(is_string($result["test1"])); + $this->assertTrue(is_bool($result["test2"])); + $this->assertTrue(is_float($result["test3"])); + + $this->assertEquals(1, $result["test"]); + $this->assertEquals("str", $result["test1"]); + $this->assertEquals(false, $result["test2"]); + $this->assertEquals(1.2, $result["test3"]); + } + + public function testArrayType() + { + $obj = new StdClass(); + $obj->a = "a"; + $obj->b = 0; + $obj->c = 1.1; + $obj->d = false; + $obj->obj = new StdClass(); + $obj->array = array(0, 1, 2, array(1, 2, 3)); + + $assertValue = array("test", 0, 1, 1.0, false, true, + array("key" => "value", 0 => 1), array(0, 1, 2), + new StdClass(), $obj); + + $this->pref->setArray("test", $assertValue); + $this->assertEquals($assertValue, $this->pref->getArray("test")); + } + + public function testObjectType() + { + $obj = new TestForObjectType(); + + $this->pref->setObject("test", $obj); + + $this->assertEquals($obj, $this->pref->getObject("test")); + } + + public function testObjectTypeWithDefault() + { + $obj = new TestForObjectType(); + + $obj2 = $this->pref->getObject("test", $obj); + + $this->assertEquals($obj, $this->pref->getObject("test")); + $this->assertEquals($obj, $obj2); + } + + public function testDelete() + { + $this->pref->setInt("test", 1); + + $this->pref->delete("test"); + + try { + $this->pref->getInt("test"); + } catch (Sabel_Exception_Runtime $e) { + return; + } + + $this->fail(); + } + + public function testContains() + { + $this->pref->setInt("test", 1); + + $this->assertTrue($this->pref->contains("test")); + $this->assertFalse($this->pref->contains("test1")); + } + + public function testGetUndefinedKeyWithNotDefault() + { + try { + $this->pref->getInt("undefined_key"); + } catch (Sabel_Exception_Runtime $e) { + // exception occured this test pass ok + return; + } + + $this->fail(); + } +} + +class TestForObjectType +{ + private $name = "string"; + private $age = 11; + private $height = 192.1; + + private $composite; + + public function __construct() + { + $this->composite = new StdClass(); + } + + public function getName() + { + return $this->name; + } +} diff --git a/Test/Preference/Database.php b/Test/Preference/Database.php new file mode 100755 index 0000000..7ae457a --- /dev/null +++ b/Test/Preference/Database.php @@ -0,0 +1,129 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Test_Preference_Database extends Test_Preference_Base +{ + public function __construct() + { + Sabel_Db_Config::initialize(new Config_Database()); + } + + public static function suite() + { + return self::createSuite("Test_Preference_Database"); + } + + /** + * set up + * + * @access public + * @return void + */ + public function setUp() + { + $this->pref = Sabel_Preference::create(new __Preference_Database_Config()); + } + + public function tearDown() + { + MODEL("SblPreference")->prepareStatement(Sabel_Db_Statement::DELETE)->execute(); + } + + public function testUseNamespace() + { + $pref = Sabel_Preference::create(new __Preference_Database_Config_Namespace()); + $pref->setInt("test", 1); + + $this->assertEquals(1, MODEL("SblPreference")->getCount("namespace", "myapp")); + } + + public function testUseCustomModelClass() + { + $pref = Sabel_Preference::create(new __Preference_Database_Config_CustomModel()); + $pref->setInt("test", 1); + } +} + +class __Preference_Database_Config implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Database"); + } +} + +class __Preference_Database_Config_Namespace implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Database", + "namespace" => "myapp"); + } +} + +class __Preference_Database_Config_CustomModel implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Database", + "model" => "__Preference_CustomModel"); + } +} + +class __Preference_CustomModel extends Sabel_Db_Model +{ + protected $tableName = "sbl_preference"; +} + +class Config_Database implements Sabel_Config +{ + public function configure() + { + switch (ENVIRONMENT) { + case PRODUCTION: + $params = array("default" => array( + "package" => "sabel.db.*", + "host" => "localhost", + "database" => "dbname", + "user" => "user", + "password" => "password") + ); + break; + + case TEST: + $params = array("default" => array( + "package" => "sabel.db.mysql", + "host" => "localhost", + "database" => "sabel", + "user" => "root", + "password" => "") + ); + break; + + case DEVELOPMENT: + $params = array("default" => array( + "package" => "sabel.db.mysql", + "host" => "localhost", + "database" => "sabel", + "user" => "root", + "password" => "") + ); + break; + } + + return $params; + } +} \ No newline at end of file diff --git a/Test/Preference/Memcache.php b/Test/Preference/Memcache.php new file mode 100755 index 0000000..b24bc6f --- /dev/null +++ b/Test/Preference/Memcache.php @@ -0,0 +1,45 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Test_Preference_Memcache extends Test_Preference_Base +{ + public static function suite() + { + return self::createSuite("Test_Preference_Memcache"); + } + + /** + * set up + * + * @access public + * @return void + */ + public function setUp() + { + $this->pref = Sabel_Preference::create(new __Preference_Memcache_Config()); + } + + public function tearDown() + { + $memcache = new Memcache(); + $memcache->addServer("localhost", 11211); + $memcache->flush(); + } +} + +class __Preference_Memcache_Config implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Memcache"); + } +} diff --git a/Test/Preference/Tests.php b/Test/Preference/Tests.php new file mode 100755 index 0000000..4002b22 --- /dev/null +++ b/Test/Preference/Tests.php @@ -0,0 +1,31 @@ + + */ +class Test_Preference_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + $suite->addTest(Test_Preference_Xml::suite()); + $suite->addTest(Test_Preference_Database::suite()); + $suite->addTest(Test_Preference_Memcache::suite()); + + return $suite; + } +} \ No newline at end of file diff --git a/Test/Preference/Xml.php b/Test/Preference/Xml.php new file mode 100755 index 0000000..f9b7ba2 --- /dev/null +++ b/Test/Preference/Xml.php @@ -0,0 +1,89 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ + +class Test_Preference_Xml extends Test_Preference_Base +{ + public static function suite() + { + return self::createSuite("Test_Preference_Xml"); + } + + /** + * set up + * + * @access public + * @return void + */ + public function setUp() + { + $files = array("/tmp/data/preferences/default.xml", + "/tmp/data/preferences/test.xml"); + + foreach ($files as $file) { + if (is_readable($file)) { + unlink($file); + } + } + + $this->pref = Sabel_Preference::create(); + } + + public function testNotConfigurationFileSpecified() + { + $preference = Sabel_Preference::create(); + $this->assertTrue(is_readable("/tmp/data/preferences/default.xml")); + } + + public function testNotSpecifyFile() + { + $preference = Sabel_Preference::create(new __PrefConfigNotSpecifyFile()); + $this->assertTrue(is_readable("/tmp/data/preferences/default.xml")); + } + + public function testConfig() + { + $preference = Sabel_Preference::create(new __PrefConfig()); + $this->assertTrue(is_readable("/tmp/data/preferences/specified.xml")); + } + + public function testConfigNoDot() + { + $preference = Sabel_Preference::create(new __PrefConfigNoDot()); + $this->assertTrue(is_readable("/tmp/data/preferences/test.xml")); + } +} + +class __PrefConfigNotSpecifyFile implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Xml"); + } +} + +class __PrefConfig implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Xml", "file" => "specified.xml"); + } +} + +class __PrefConfigNoDot implements Sabel_Config +{ + public function configure() + { + return array("backend" => "Sabel_Preference_Xml", + "file" => "test"); + } +} diff --git a/Test/Processor/Abstract.php b/Test/Processor/Abstract.php new file mode 100755 index 0000000..7089d15 --- /dev/null +++ b/Test/Processor/Abstract.php @@ -0,0 +1,21 @@ + + */ +class Test_Processor_Abstract extends SabelTestCase +{ + protected $bus = null; + + public function setUp() + { + $this->bus = new Sabel_Bus(); + $this->bus->set("session", Sabel_Session_InMemory::create()); + $this->bus->setConfig("map", new TestMapConfig()); + $this->bus->setConfig("addon", new TestAddonConfig()); + } +} diff --git a/Test/Processor/Addon.php b/Test/Processor/Addon.php new file mode 100755 index 0000000..24c6ada --- /dev/null +++ b/Test/Processor/Addon.php @@ -0,0 +1,43 @@ + + */ +class Test_Processor_Addon extends Test_Processor_Abstract +{ + public static function suite() + { + Sabel::fileUsing(PROCESSORS_DIR . DS . "Addon.php", true); + return self::createSuite("Test_Processor_Addon"); + } + + public function testProcess() + { + $bus = $this->bus; + + $processor = new Processor_Addon("addon"); + $processor->execute($bus); + + $this->assertEquals(1, $bus->get("hogeAddon")); + $this->assertEquals(2, $bus->get("fugaAddon")); + } +} + +class Hoge_Addon extends Sabel_Object +{ + public function execute($bus) + { + $bus->set("hogeAddon", 1); + } +} + +class Fuga_Addon extends Sabel_Object +{ + public function execute($bus) + { + $bus->set("fugaAddon", 2); + } +} diff --git a/Test/Processor/Controller.php b/Test/Processor/Controller.php new file mode 100755 index 0000000..baddcc5 --- /dev/null +++ b/Test/Processor/Controller.php @@ -0,0 +1,54 @@ + + */ +class Test_Processor_Controller extends Test_Processor_Abstract +{ + public static function suite() + { + Sabel::fileUsing(PROCESSORS_DIR . DS . "Controller.php", true); + return self::createSuite("Test_Processor_Controller"); + } + + public function testHogeController() + { + $bus = $this->bus; + $bus->set("response", new Sabel_Response_Object()); + $bus->set("destination", $this->getDestination("Hoge")); + + $processor = new Processor_Controller("controller"); + $processor->execute($bus); + + $controller = $bus->get("controller"); + $this->assertTrue($controller instanceof Test_Controllers_Hoge); + $this->assertTrue($bus->get("response") instanceof Sabel_Response); + $this->assertTrue($controller->getSession() instanceof Sabel_Session_Abstract); + } + + public function testFugaController() + { + $bus = $this->bus; + $bus->set("response", new Sabel_Response_Object()); + $bus->set("destination", $this->getDestination("Fuga")); + + $processor = new Processor_Controller("controller"); + $processor->execute($bus); + + $this->assertTrue($bus->get("controller") instanceof Test_Controllers_Fuga); + } + + protected function getDestination($name) + { + return new Sabel_Map_Destination(array("module" => "Test", + "controller" => $name, + "action" => "index")); + } +} + +class Test_Controllers_Hoge extends Sabel_Controller_Page {} +class Test_Controllers_Fuga extends Sabel_Controller_Page {} diff --git a/Test/Processor/Flow.php b/Test/Processor/Flow.php new file mode 100755 index 0000000..653a23b --- /dev/null +++ b/Test/Processor/Flow.php @@ -0,0 +1,73 @@ + + * @copyright 2002-2006 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Test_Processor_Flow extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Processor_Flow"); + } + + private $bus = null; + + public function setUp() + { + $bus = new Sabel_Bus(); + + $request = new Sabel_Request_Object("index/index"); + $storage = new Sabel_Storage_InMemory(); + $controller = new StandardFlow(); + $destination = new Sabel_Destination("index", "index", "top"); + + $controller->setup($request, $destination, $storage); + + $bus->set("request", $request); + $bus->set("storage", $storage); + $bus->set("controller", $controller); + $bus->set("destination", $destination); + + $this->bus = $bus; + } + + public function testStandardFlow() + { + $processor = new Processor_Flow("flow"); + $processor->setBus($this->bus); + $processor->execute($this->bus); + } + + public function testFailRequired() + { + $bus = new Sabel_Bus(); + $processor = new Processor_Flow("flow"); + $processor->setBus($this->bus); + + try { + $processor->execute($bus); + $this->fail(); + } catch (Sabel_Exception_Runtime $e) { + $this->assertTrue(true); + } + } +} + +class Config_Factory extends Sabel_Container_Injection +{ + public function configure() + { + $this->bind("Sabel_Response")->to("Sabel_Response_Web"); + $this->bind("Sabel_Locale")->to("Sabel_Locale_Null"); + } +} diff --git a/Test/Processor/Request.php b/Test/Processor/Request.php new file mode 100755 index 0000000..9c1d6f3 --- /dev/null +++ b/Test/Processor/Request.php @@ -0,0 +1,44 @@ + + */ +class Test_Processor_Request extends Test_Processor_Abstract +{ + public static function suite() + { + Sabel::fileUsing(PROCESSORS_DIR . DS . "Request.php", true); + return self::createSuite("Test_Processor_Request"); + } + + public function testProcess() + { + $bus = $this->bus; + + $this->assertFalse($bus->get("session")->isStarted()); + + $processor = new Processor_Request("request"); + $processor->execute($bus); + + $this->assertTrue($bus->get("request") instanceof Sabel_Request); + $this->assertNull($bus->get("request")->fetchPostValue("hoge")); + $this->assertFalse($bus->get("session")->isStarted()); + } + + public function testSetRequestObject() + { + $bus = $this->bus; + $request = new Sabel_Request_Object(""); + $request->setPostValue("hoge", "1"); + $bus->set("request", $request); + + $processor = new Processor_Request("request"); + $processor->execute($bus); + + $this->assertEquals("1", $bus->get("request")->fetchPostValue("hoge")); + } +} diff --git a/Test/Processor/Response.php b/Test/Processor/Response.php new file mode 100755 index 0000000..8971557 --- /dev/null +++ b/Test/Processor/Response.php @@ -0,0 +1,43 @@ + + */ +class Test_Processor_Response extends Test_Processor_Abstract +{ + public static function suite() + { + Sabel::fileUsing(PROCESSORS_DIR . DS . "Response.php", true); + return self::createSuite("Test_Processor_Response"); + } + + public function testProcess() + { + $bus = $this->bus; + $response = new Sabel_Response_Object(); + $response->setResponse("a", "1"); + $response->setResponse("b", "2"); + + $controller = new ResponseTestController($response); + $controller->setAttribute("b", "3"); + $controller->setAttribute("c", "4"); + + $bus->set("controller", $controller); + $bus->set("response", $response); + + $processor = new Processor_Response("response"); + $processor->afterAction($bus); + + $responses = $bus->get("response")->getResponses(); + $this->assertEquals("1", $responses["a"]); + $this->assertEquals("3", $responses["b"]); + $this->assertEquals("4", $responses["c"]); + $this->assertFalse(isset($responses["d"])); + } +} + +class ResponseTestController extends Sabel_Controller_Page {} diff --git a/Test/Processor/Router.php b/Test/Processor/Router.php new file mode 100755 index 0000000..0729afb --- /dev/null +++ b/Test/Processor/Router.php @@ -0,0 +1,44 @@ + + */ +class Test_Processor_Router extends Test_Processor_Abstract +{ + public static function suite() + { + Sabel::fileUsing(PROCESSORS_DIR . DS . "Router.php", true); + return self::createSuite("Test_Processor_Router"); + } + + public function testCreateDefaultCandidate() + { + $bus = $this->bus; + $bus->set("request", new Sabel_Request_Object("index/test")); + + $processor = new Processor_Router("router"); + $processor->execute($bus); + + $candidate = Sabel_Context::getContext()->getCandidate(); + $this->assertTrue($candidate instanceof Sabel_Map_Candidate); + $this->assertEquals("default", $candidate->getName()); + } + + public function testCreateDevelopmentCandidate() + { + $bus = $this->bus; + $bus->set("request", new Sabel_Request_Object("devel/main/index/db")); + + $processor = new Processor_Router("router"); + $processor->execute($bus); + + $candidate = Sabel_Context::getContext()->getCandidate(); + $this->assertTrue($candidate instanceof Sabel_Map_Candidate); + $this->assertEquals("devel", $candidate->getName()); + $this->assertEquals("db", $bus->get("request")->fetchParameterValue("param")); + } +} diff --git a/Test/Processor/Tests.php b/Test/Processor/Tests.php new file mode 100755 index 0000000..9a7e81e --- /dev/null +++ b/Test/Processor/Tests.php @@ -0,0 +1,56 @@ +addTest(Test_Processor_Request::suite()); + $suite->addTest(Test_Processor_Router::suite()); + $suite->addTest(Test_Processor_Addon::suite()); + $suite->addTest(Test_Processor_Controller::suite()); + $suite->addTest(Test_Processor_Response::suite()); + + return $suite; + } +} + +class TestMapConfig extends Sabel_Map_Configurator +{ + public function configure() + { + $this->route("devel") + ->uri("devel/:controller/:action/:param") + ->module("devel") + ->defaults(array(":controller" => "main", + ":action" => "index", + ":param" => null)); + + $this->route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array(":controller" => "index", + ":action" => "index")); + } +} + +class TestAddonConfig implements Sabel_Config +{ + public function configure() + { + $addons = array(); + $addons[] = "hoge"; + $addons[] = "fuga"; + + return $addons; + } +} diff --git a/Test/Processor/classes/Index.php b/Test/Processor/classes/Index.php new file mode 100755 index 0000000..3b447e6 --- /dev/null +++ b/Test/Processor/classes/Index.php @@ -0,0 +1,13 @@ + + */ +class Test_Reflection extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Reflection"); + } + + public function testReflection() + { + $o = new Vircle(); + $reflection = $o->getReflection(); + + $this->assertTrue($reflection->hasAnnotation("hoge")); + $this->assertTrue($reflection->hasAnnotation("class")); + + $annotation = $reflection->getAnnotation("class"); + $this->assertEquals("value", $annotation[0][0]); + } + + public function testReflectionMethod() + { + $o = new Vircle(); + $reflection = $o->getReflection()->getMethod("fooMethod"); + + $this->assertTrue($reflection->hasAnnotation("fuga")); + $this->assertTrue($reflection->hasAnnotation("method")); + + $annotation = $reflection->getAnnotation("method"); + $this->assertEquals("value", $annotation[0][0]); + } + + public function testMethodAnnotation() + { + $o = new Vircle(); + $annotation = $o->getReflection()->getMethodAnnotation("fooMethod", "method"); + $this->assertEquals("value", $annotation[0][0]); + } + + public function testGetMethods() + { + $o = new Vircle(); + $methods = $o->getReflection()->getMethods(); + $annotations = $methods["fooMethod"]->getAnnotations(); + $this->assertEquals("value", $annotations["method"][0][0]); + } + + public function testProperty() + { + $o = new Vircle(); + $hoge = $o->getReflection()->getProperty("hoge"); + $this->assertTrue($hoge->hasAnnotation("var")); + $annotation = $hoge->getAnnotation("var"); + $this->assertEquals("string", $annotation[0][0]); + } + + public function testGetProperties() + { + $o = new Vircle(); + $props = $o->getReflection()->getProperties(); + $annotations = $props["fuga"]->getAnnotations(); + $this->assertEquals("array", $annotations["var"][0][0]); + } +} + +/** + * @hoge + * @class value + */ +class Vircle extends Sabel_Object +{ + /** + * @var string + */ + protected $hoge = ""; + + /** + * @var array + */ + protected $fuga = array(); + + /** + * @fuga + * @method value + */ + public function fooMethod() + { + + } +} diff --git a/Test/Request/Object.php b/Test/Request/Object.php new file mode 100755 index 0000000..22f4f81 --- /dev/null +++ b/Test/Request/Object.php @@ -0,0 +1,176 @@ + + * @author Ebine Yutaka + */ +class Test_Request_Object extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Request_Object"); + } + + public function testUri() + { + $path = "foo/bar"; + $request = new Sabel_Request_Object(""); + $request->get($path); + $this->assertEquals($path, $request->getUri()); + } + + public function testGetValue() + { + $request = new Sabel_Request_Object(""); + $request->get("index/index"); + $request->value("a", "1")->value("b", "2"); + $this->assertEquals("1", $request->fetchGetValue("a")); + $this->assertEquals("2", $request->fetchGetValue("b")); + $this->assertEquals(null, $request->fetchPostValue("a")); + $this->assertEquals(null, $request->fetchPostValue("b")); + } + + public function testPostValue() + { + $request = new Sabel_Request_Object(""); + $request->post("index/index"); + $request->value("a", "1")->value("b", "2"); + $this->assertEquals(null, $request->fetchGetValue("a")); + $this->assertEquals(null, $request->fetchGetValue("b")); + $this->assertEquals("1", $request->fetchPostValue("a")); + $this->assertEquals("2", $request->fetchPostValue("b")); + } + + public function testGetValues() + { + $request = new Sabel_Request_Object(""); + $request->get("index/index")->values(array("a" => "1", "b" => "2")); + $this->assertEquals(array("a" => "1", "b" => "2"), $request->fetchGetValues()); + $this->assertEquals(array(), $request->fetchPostValues()); + } + + public function testPostValues() + { + $request = new Sabel_Request_Object(""); + $request->post("index/index")->values(array("a" => "1", "b" => "2")); + $this->assertEquals(array(), $request->fetchGetValues()); + $this->assertEquals(array("a" => "1", "b" => "2"), $request->fetchPostValues()); + } + + public function testHasValueWithMethod() + { + $request = new Sabel_Request_Object(""); + $request->get("index/index")->values(array("a" => "1", "b" => "2")); + $this->assertTrue($request->hasValueWithMethod("a")); + + $request->post("index/index"); + $this->assertFalse($request->hasValueWithMethod("a")); + } + + public function testGetValueWithMethod() + { + $request = new Sabel_Request_Object(""); + $request->get("index/index")->values(array("a" => "1", "b" => "2")); + $this->assertEquals("2", $request->getValueWithMethod("b")); + + $request->post("index/index"); + $this->assertNull($request->getValueWithMethod("b")); + } + + public function testSetValue() + { + $request = new Sabel_Request_Object(""); + $this->assertEquals(null, $request->fetchGetValue("a")); + $request->setGetValue("a", "1"); + $this->assertEquals("1", $request->fetchGetValue("a")); + } + + public function testSetValues() + { + $request = new Sabel_Request_Object(""); + $this->assertEquals(null, $request->fetchGetValue("a")); + $request->setGetValues(array("a" => "1")); + $this->assertEquals("1", $request->fetchGetValue("a")); + } + + public function testHasGetValue() + { + $request = new Sabel_Request_Object(""); + $this->assertFalse($request->hasGetValue("a")); + $request->setGetValues(array("a" => "1", "b" => "")); + $this->assertTrue($request->hasGetValue("a")); + $this->assertFalse($request->hasGetValue("b")); + } + + public function testIsGetSet() + { + $request = new Sabel_Request_Object(""); + $this->assertFalse($request->hasGetValue("a")); + $request->setGetValues(array("a" => "1", "b" => "")); + + $this->assertTrue($request->hasGetValue("a")); + $this->assertFalse($request->hasGetValue("b")); + + $this->assertTrue($request->isGetSet("a")); + $this->assertTrue($request->isGetSet("b")); + } + + public function testHasPostValue() + { + $request = new Sabel_Request_Object(""); + $request->post(""); + + $this->assertFalse($request->hasPostValue("a")); + $request->setPostValues(array("a" => "1", "b" => "")); + $this->assertTrue($request->hasPostValue("a")); + $this->assertFalse($request->hasPostValue("b")); + } + + public function testIsPostSet() + { + $request = new Sabel_Request_Object(""); + $request->post(""); + + $this->assertFalse($request->hasPostValue("a")); + $request->setPostValues(array("a" => "1", "b" => "")); + + $this->assertTrue($request->hasPostValue("a")); + $this->assertFalse($request->hasPostValue("b")); + + $this->assertTrue($request->isPostSet("a")); + $this->assertTrue($request->isPostSet("b")); + } + + public function testFind() + { + $request = new Sabel_Request_Object(""); + $request->setGetValue("a", "10"); + $request->setPostValue("b", "20"); + $request->setParameterValue("c", "30"); + + $this->assertEquals("10", $request->find("a")); + $this->assertEquals("20", $request->find("b")); + $this->assertEquals("30", $request->find("c")); + } + + public function testFindDuplicateValues() + { + $request = new Sabel_Request_Object(""); + $request->setGetValue("a", "10"); + $request->setPostValue("b", "20"); + $request->setParameterValue("b", "30"); + + $this->assertEquals("10", $request->find("a")); + + try { + $this->assertEquals("20", $request->find("b")); + } catch (Exception $e) { + return; + } + + $this->fail(); + } +} diff --git a/Test/Request/Tests.php b/Test/Request/Tests.php new file mode 100755 index 0000000..dafe5f5 --- /dev/null +++ b/Test/Request/Tests.php @@ -0,0 +1,14 @@ +addTest(Test_Request_Object::suite()); + + return $suite; + } +} diff --git a/Test/Response/Header.php b/Test/Response/Header.php new file mode 100755 index 0000000..580cc24 --- /dev/null +++ b/Test/Response/Header.php @@ -0,0 +1,40 @@ + + */ +class Test_Response_Header extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Response_Header"); + } + + public function testOutputHeader() + { + $response = new Sabel_Response_Object(); + $response->setHeader("Content-Type", "text/html; charset=UTF-8"); + $response->setHeader("Content-Length", "4096"); + + $headers = $response->outputHeader(); + $this->assertEquals("Content-Type: text/html; charset=UTF-8", $headers[1]); + $this->assertEquals("Content-Length: 4096", $headers[2]); + } + + public function testOutputStatus() + { + $response = new Sabel_Response_Object(); + $response->getStatus()->setCode(Sabel_Response::FORBIDDEN); + $headers = $response->outputHeader(); + $this->assertEquals("HTTP/1.0 403 Forbidden", $headers[0]); + + $response = new Sabel_Response_Object(); + $response->getStatus()->setCode(Sabel_Response::NOT_MODIFIED); + $headers = $response->outputHeader(); + $this->assertEquals("HTTP/1.0 304 Not Modified", $headers[0]); + } +} diff --git a/Test/Response/Object.php b/Test/Response/Object.php new file mode 100755 index 0000000..a72a82f --- /dev/null +++ b/Test/Response/Object.php @@ -0,0 +1,92 @@ + + */ +class Test_Response_Object extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Response_Object"); + } + + public function testResponseValue() + { + $response = new Sabel_Response_Object(); + $response->setResponse("a", "10"); + $response->setResponse("b", "20"); + + $this->assertEquals("10", $response->getResponse("a")); + $this->assertEquals("20", $response->getResponse("b")); + $this->assertEquals(null, $response->getResponse("c")); + } + + public function testResponseValues() + { + $response = new Sabel_Response_Object(); + $response->setResponses(array("a" => "10", "b" => "20")); + + $this->assertEquals("10", $response->getResponse("a")); + $this->assertEquals("20", $response->getResponse("b")); + $this->assertEquals(null, $response->getResponse("c")); + + $expected = array("a" => "10", "b" => "20"); + $this->assertEquals($expected, $response->getResponses()); + } + + public function testResponseHeader() + { + $response = new Sabel_Response_Object(); + $response->setHeader("Content-Type", "image/gif"); + $response->setHeader("Content-Length", "4096"); + $this->assertEquals("image/gif", $response->getHeader("Content-Type")); + $this->assertEquals("4096", $response->getHeader("Content-Length")); + $this->assertEquals(array("Content-Type" => "image/gif", "Content-Length" => "4096"), $response->getHeaders()); + $this->assertEquals(null, $response->getHeader("Foo-Bar")); + } + + public function testExpiredCacheHeaders() + { + $response = new Sabel_Response_Object(); + $response->expiredCache("300000000"); + $headers = $response->getHeaders(); + $this->assertTrue(isset($headers["Expires"])); + $this->assertTrue(isset($headers["Last-Modified"])); + $this->assertTrue(isset($headers["Cache-Control"])); + $this->assertTrue(isset($headers["Pragma"])); + } + + public function testStatus() + { + $response = new Sabel_Response_Object(); + $status = $response->getStatus(); + + $this->assertTrue($status->isSuccess()); + + $status->setCode(Sabel_Response::NOT_FOUND); + $this->assertTrue($status->isClientError()); + + $status->setCode(Sabel_Response::INTERNAL_SERVER_ERROR); + $this->assertTrue($status->isServerError()); + } + + public function testIsFailure() + { + $response = new Sabel_Response_Object(); + $status = $response->getStatus(); + + $this->assertFalse($status->isFailure()); + + $status->setCode(Sabel_Response::NOT_FOUND); + $this->assertTrue($status->isFailure()); + + $status->setCode(Sabel_Response::INTERNAL_SERVER_ERROR); + $this->assertTrue($status->isFailure()); + + $status->setCode(Sabel_Response::FORBIDDEN); + $this->assertTrue($status->isFailure()); + } +} diff --git a/Test/Response/Redirector.php b/Test/Response/Redirector.php new file mode 100755 index 0000000..0d0053a --- /dev/null +++ b/Test/Response/Redirector.php @@ -0,0 +1,80 @@ + + */ +class Test_Response_Redirector extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Response_Redirector"); + } + + public function setUp() + { + $config = new TestConfigMap(); + $config->route("default") + ->uri(":controller/:action") + ->module("index"); + + $this->routing($config); + } + + public function testIsRedirected() + { + $redirector = new Sabel_Response_Redirector(); + $this->assertFalse($redirector->isRedirected()); + } + + public function testRedirect() + { + $redirector = new Sabel_Response_Redirector(); + $redirector->to("a: test"); + $this->assertTrue($redirector->isRedirected()); + $this->assertEquals("/index/test", $redirector->getUri()); + } + + public function testRedirectByUrl() + { + $redirector = new Sabel_Response_Redirector(); + $redirector->url("index/test"); + $this->assertTrue($redirector->isRedirected()); + $this->assertEquals("index/test", $redirector->getUrl()); + } + + public function testRedirectWithParameters() + { + $redirector = new Sabel_Response_Redirector(); + $redirector->to("a: test", array("page" => "1")); + $this->assertTrue($redirector->isRedirected()); + $this->assertTrue($redirector->hasParameters()); + $this->assertEquals("/index/test?page=1", $redirector->getUri()); + } + + public function testUriParameter() + { + $redirector = new Sabel_Response_Redirector(); + $redirector->to("n: default"); + $this->assertTrue($redirector->isRedirected()); + //$this->assertEquals("index/index", $redirector->getUri()); + $this->assertEquals("/", $redirector->getUri()); + } + + protected function routing($config) + { + $request = new Sabel_Request_Object("index/index"); + + $config->configure(); + $candidate = $config->getValidCandidate($request->getUri()); + Sabel_Context::getContext()->setCandidate($candidate); + } +} + +class TestConfigMap extends Sabel_Map_Configurator +{ + public function configure() {} +} diff --git a/Test/Response/Tests.php b/Test/Response/Tests.php new file mode 100755 index 0000000..ccda559 --- /dev/null +++ b/Test/Response/Tests.php @@ -0,0 +1,18 @@ +addTest(Test_Response_Object::suite()); + $suite->addTest(Test_Response_Redirector::suite()); + $suite->addTest(Test_Response_Header::suite()); + + return $suite; + } +} diff --git a/Test/SabelTestCase.php b/Test/SabelTestCase.php new file mode 100755 index 0000000..ccfc2c1 --- /dev/null +++ b/Test/SabelTestCase.php @@ -0,0 +1,9 @@ + + */ +class Test_Session_Database extends SabelTestCase +{ + private static $sid = ""; + + private $session = null; + private $sessionId = ""; + + public static function suite() + { + if (self::initTable()) { + self::$sid = md5hash(); + ini_set("session.use_cookies", "0"); + return self::createSuite("Test_Session_Database"); + } else { + return self::createSuite(""); + } + } + + public function setUp() + { + $_SERVER["REQUEST_METHOD"] = "GET"; + $this->session = Sabel_Session_Database::create(); + $this->session->setTableName("session"); + $_GET[session_name()] = self::$sid; + $this->session->start(); + } + + public function testEmpty() + { + $this->assertTrue($this->session->isStarted()); + $this->assertEquals(self::$sid, $this->session->getId()); + $this->assertNull($this->session->read("a")); + $this->assertNull($this->session->read("b")); + + $this->session->write("a", "10"); + $this->session->shutdown(); + } + + public function testWrite() + { + $this->assertEquals("10", $this->session->read("a")); + $this->assertNull($this->session->read("b")); + + $this->session->write("b", "20"); + $this->session->delete("a"); + $this->session->shutdown(); + } + + public function testDelete() + { + $this->assertNull($this->session->read("a")); + $this->assertEquals("20", $this->session->read("b")); + $this->session->shutdown(); + } + + public function testRegeneratedId() + { + $this->session->regenerateId(); + $newId = $this->session->getId(); + $this->assertNotEquals(self::$sid, $newId); + + $this->assertEquals("20", $this->session->read("b")); + + self::$sid = $newId; + $this->session->shutdown(); + } + + public function testDestroy() + { + $this->assertEquals("20", $this->session->read("b")); + $this->session->destroy(); + + $this->assertNull($this->session->read("b")); + $this->session->shutdown(); + } + + private static function initTable() + { + if (extension_loaded("mysql")) { + $params = array("package" => "sabel.db.mysql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } elseif (extension_loaded("pgsql")) { + $params = array("package" => "sabel.db.pgsql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } elseif (extension_loaded("pdo_sqlite")) { + $params = array("package" => "sabel.db.pdo.sqlite", + "database" => SABEL_BASE . "/Test/data/sdb_test.sq3"); + } else { + Sabel_Console::message("skipped 'Test_Session_Database'."); + return false; + } + + Sabel_Db_Config::add("default", $params); + Sabel_Db::createDriver("default")->execute("DELETE FROM session"); + return true; + } +} diff --git a/Test/Session/Tests.php b/Test/Session/Tests.php new file mode 100755 index 0000000..64bb1ab --- /dev/null +++ b/Test/Session/Tests.php @@ -0,0 +1,24 @@ + + */ +class Test_Session_Tests +{ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + + //$suite->addTest(Test_Session_Database::suite()); + + return $suite; + } +} diff --git a/Test/Util/FileSystem.php b/Test/Util/FileSystem.php new file mode 100755 index 0000000..7ebf006 --- /dev/null +++ b/Test/Util/FileSystem.php @@ -0,0 +1,290 @@ + + */ +class Test_Util_FileSystem extends SabelTestCase +{ + protected $basedir = ""; + + public static function suite() + { + return self::createSuite("Test_Util_FileSystem"); + } + + public function setUp() + { + $this->basedir = SABEL_BASE . DS . "Test" . DS . "data" . DS . "application" . DS . "data"; + } + + public function testMakedir() + { + $fs = new Sabel_Util_FileSystem($this->basedir); + + $dir = $fs->mkdir("test"); + $this->assertEquals($this->basedir . DS . "test", $dir->pwd()); + + $this->assertTrue($fs->isDir("test")); + $this->assertTrue($fs->isDir($this->basedir . DS . "test")); + $this->assertTrue(is_dir($this->basedir . DS . "test")); + } + + public function testRecursiveMakedir() + { + $path = "hoge" . DS . "fuga" . DS . "foo"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + + $dir = $fs->mkdir($path); + $this->assertEquals($this->basedir . DS . "test" . DS . $path, $dir->pwd()); + + $this->assertTrue($fs->isDir($path)); + $this->assertTrue($fs->isDir($this->basedir . DS . "test" . DS . $path)); + $this->assertTrue(is_dir($this->basedir . DS . "test" . DS . $path)); + } + + public function testChangeDirectory() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $this->assertTrue($fs->isDir("hoge")); + $this->assertFalse($fs->isDir("fuga")); + $this->assertFalse($fs->isDir("foo")); + + $fs->cd("hoge"); + $this->assertFalse($fs->isDir("hoge")); + $this->assertTrue($fs->isDir("fuga")); + $this->assertFalse($fs->isDir("foo")); + + $fs->cd("fuga"); + $this->assertFalse($fs->isDir("hoge")); + $this->assertFalse($fs->isDir("fuga")); + $this->assertTrue($fs->isDir("foo")); + } + + public function testPwd() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $this->assertEquals($this->basedir . DS . "test", $fs->pwd()); + + $fs->cd("hoge"); + $this->assertEquals($this->basedir . DS . "test" . DS . "hoge", $fs->pwd()); + + $fs->cd("fuga"); + $this->assertEquals($this->basedir . DS . "test" . DS . "hoge" . DS . "fuga", $fs->pwd()); + } + + public function testRmdir() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $fs->cd("hoge" . DS . "fuga"); + + $this->assertTrue($fs->isDir("foo")); + $fs->rmdir("foo"); + $this->assertFalse($fs->isDir("foo")); + } + + public function testRecursiveRmdir() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $this->assertTrue($fs->isDir("hoge")); + $this->assertTrue($fs->isDir("hoge" . DS . "fuga")); + + $fs->rmdir("hoge"); + + $this->assertFalse($fs->isDir("hoge")); + $this->assertFalse($fs->isDir("hoge" . DS . "fuga")); + } + + public function testMkfile() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $fs->mkfile("hoge.txt"); + $this->assertTrue($fs->isFile("hoge.txt")); + $this->assertTrue($fs->isFile($this->basedir . DS . "test" . DS . "hoge.txt")); + $this->assertTrue(is_file($this->basedir . DS . "test" . DS . "hoge.txt")); + } + + public function testRecursiveMakeFile() + { + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $fs->mkfile($file); + $this->assertTrue($fs->isFile($file)); + $this->assertTrue($fs->isFile($this->basedir . DS . "test" . DS . $file)); + $this->assertTrue(is_file($this->basedir . DS . "test" . DS . $file)); + } + + public function testFilePermission() + { + // win + if (DIRECTORY_SEPARATOR === "\\") return; + + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $file = $fs->getFile($file); + $this->assertEquals(0755, $file->getPermission()); + $file->chmod(0777); + $this->assertEquals(0777, $file->getPermission()); + } + + public function testFilePermission2() + { + // win + if (DIRECTORY_SEPARATOR === "\\") return; + + chmod($this->basedir . DS . "readable.txt", 0444); + chmod($this->basedir . DS . "writable.txt", 0222); + chmod($this->basedir . DS . "executable.txt", 0111); + + $fs = new Sabel_Util_FileSystem($this->basedir); + + $readable = $fs->getFile("readable.txt"); + $this->assertTrue($readable->isReadable()); + $this->assertFalse($readable->isWritable()); + $this->assertFalse($readable->isExecutable()); + + $writable = $fs->getFile("writable.txt"); + $this->assertFalse($writable->isReadable()); + $this->assertTrue($writable->isWritable()); + $this->assertFalse($writable->isExecutable()); + + $executable = $fs->getFile("executable.txt"); + $this->assertFalse($executable->isReadable()); + $this->assertFalse($executable->isWritable()); + $this->assertTrue($executable->isExecutable()); + + chmod($this->basedir . DS . "readable.txt", 0777); + chmod($this->basedir . DS . "writable.txt", 0777); + chmod($this->basedir . DS . "executable.txt", 0777); + } + + public function testDirectoryPermission() + { + // win + if (DIRECTORY_SEPARATOR === "\\") return; + + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $dir = $fs->getDirectory("hoge" . DS . "fuga"); + $this->assertEquals(0755, $dir->getPermission()); + $dir->chmod(0777); + $this->assertEquals(0777, $dir->getPermission()); + } + + public function testFileSize() + { + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $file = $fs->getFile($file); + $currentSize = $file->getSize(); + $file->write("abcdefg")->save(); + $this->assertTrue($file->getSize() > $currentSize); + } + + public function testFileContents() + { + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $file = $fs->getFile($file); + $this->assertEquals("abcdefg", $file->getContents()); + + $file->open(); + $file->write("hijklmn")->save(); + $this->assertEquals("abcdefg" . PHP_EOL . "hijklmn", $file->getContents()); + } + + public function testFileContentsAsArray() + { + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $lines = $fs->getFile($file)->getContentsAsArray(); + + $this->assertEquals(2, count($lines)); + $this->assertEquals("abcdefg", $lines[0]); + $this->assertEquals("hijklmn", $lines[1]); + $this->assertFalse(isset($lines[2])); + } + + public function testClearContents() + { + $file = "hoge" . DS . "fuga" . DS . "foo.txt"; + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $file = $fs->getFile($file); + $file->clearContents(); + $this->assertEquals("", $file->getContents()); + } + + public function testFileCopy() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test" . DS . "hoge" . DS . "fuga"); + $file = $fs->getFile("foo.txt"); + $file->copyTo(".." . DS . "test" . DS . "foo2.txt"); + + $fs->cd(".." . DS . "test"); + $this->assertTrue($fs->isFile("foo2.txt")); + + $file->copyTo(".." . DS . "test" . DS . "foo.txt"); + $this->assertTrue($fs->isFile("foo.txt")); + } + + public function testFileMove() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $file = $fs->getFile("hoge" . DS . "test" . DS . "foo2.txt"); + $moved = $file->moveTo(".." . DS . "test2" . DS . "foo2.txt"); + + $fs->cd(".." . DS . "test" . DS . "hoge"); + $this->assertTrue($fs->isFile("test2" . DS . "foo2.txt")); + $this->assertFalse($fs->isFile("hoge" . DS . "foo2.txt")); + + $moved->moveTo("foo3.txt"); + $this->assertTrue($fs->isFile("test2" . DS . "foo3.txt")); + $this->assertFalse($fs->isFile("test2" . DS . "foo2.txt")); + } + + public function testRemoveFile() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $fs->isFile("hoge.txt"); + $fs->getFile("hoge.txt")->remove(); + $this->assertFalse($fs->isFile("hoge.txt")); + $this->assertFalse($fs->isFile($this->basedir . DS . "test" . DS . "hoge.txt")); + $this->assertFalse(is_file($this->basedir . DS . "test" . DS . "hoge.txt")); + } + + public function testRemoveDir() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test" . DS . "hoge"); + $this->assertTrue(in_array("test2", $fs->ls(), true)); + $fs->cd("test2"); + $fs->rmdir(); + + $fs->cd($this->basedir . DS . "test" . DS . "hoge"); + $this->assertFalse(in_array("test2", $fs->ls(), true)); + } + + public function testDirectoryCopy() + { + $fs = new Sabel_Util_FileSystem($this->basedir . DS . "test"); + $this->assertFalse($fs->isDir("moved")); + + $fs->copyTo(".." . DS . "moved"); + $fs->cd(".."); + $this->assertTrue($fs->isDir("moved")); + $fs->cd("moved"); + $this->assertTrue($fs->isDir("hoge")); + $fs->cd("hoge"); + $this->assertTrue($fs->isDir("fuga")); + $this->assertTrue($fs->isDir("test")); + $fs->cd("fuga"); + $this->assertTrue($fs->isFile("foo.txt")); + $fs->cd(".." . DS . "test"); + $this->assertTrue($fs->isFile("foo.txt")); + } + + public function testCleanup() + { + $fs = new Sabel_Util_FileSystem($this->basedir); + $fs->rmdir("test"); + $fs->rmdir("moved"); + } +} diff --git a/Test/Util/HashList.php b/Test/Util/HashList.php new file mode 100755 index 0000000..4a4a6e5 --- /dev/null +++ b/Test/Util/HashList.php @@ -0,0 +1,342 @@ + + */ +class Test_Util_HashList extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Util_HashList"); + } + + public function testAdd() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals(3, $list->count()); + + try { + $list->add("a", "hoge"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testRemove() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals(3, $list->count()); + + $removed = $list->remove("b"); + $this->assertEquals("2", $removed); + + $this->assertEquals(2, $list->count()); + $this->assertEquals("1", $list->get("a")); + $this->assertNull($list->get("b")); + $this->assertEquals("3", $list->get("c")); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("3", $list->next()); + } + + public function testReplace() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->replace("b", "d", "4"); + + $this->assertEquals(3, $list->count()); + + $this->assertEquals("1", $list->get("a")); + $this->assertNull($list->get("b")); + $this->assertEquals("3", $list->get("c")); + $this->assertEquals("4", $list->get("d")); + + try { + $list->replace("z", "e", "5"); + } catch (Sabel_Exception_Runtime $e) { + return; + } + + $this->fail(); + } + + public function testInsertPrevious() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->insertPrevious("c", "d", "4"); + $this->assertEquals(4, $list->count()); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("4", $list->next()); + $this->assertEquals("3", $list->next()); + } + + public function testInsertNext() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->insertNext("a", "d", "4"); + $this->assertEquals(4, $list->count()); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("4", $list->next()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + } + + public function testToArray() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->insertNext("a", "d", "4"); + $list->insertPrevious("c", "e", "5"); + + $array = $list->toArray(); + $this->assertEquals("1", $array["a"]); + $this->assertEquals("2", $array["b"]); + $this->assertEquals("3", $array["c"]); + $this->assertEquals("4", $array["d"]); + $this->assertEquals("5", $array["e"]); + } + + public function testFirst() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + + $list->first(); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + } + + public function testLast() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->last(); + + $this->assertEquals("3", $list->previous()); + } + + public function testPrevious() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->last(); + + $this->assertEquals("3", $list->previous()); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("1", $list->previous()); + } + + public function testCursor() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("1", $list->previous()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("1", $list->previous()); + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + } + + public function testDynamicInsert1() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $list->insertNext("b", "d", "4"); + $this->assertEquals("4", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $list->insertNext("c", "d", "4"); + + $this->assertEquals("2", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertEquals("4", $list->next()); + $this->assertNull($list->next()); + } + + public function testDynamicInsert2() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $list->insertPrevious("b", "d", "4"); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $list->insertPrevious("c", "d", "4"); + + $this->assertEquals("2", $list->next()); + $this->assertEquals("4", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + } + + public function testDynamicInsert3() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->last(); + $this->assertEquals("3", $list->previous()); + $list->insertPrevious("c", "d", "4"); + $this->assertEquals("4", $list->previous()); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("1", $list->previous()); + + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $list->last(); + $this->assertEquals("3", $list->previous()); + $list->insertPrevious("a", "d", "4"); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("1", $list->previous()); + $this->assertEquals("4", $list->previous()); + } + + public function testDynamicInsertAndCursor() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + + $this->assertEquals("1", $list->next()); + $list->insertNext("b", "d", "4"); // 1 2 4 3 + $this->assertEquals("2", $list->next()); + $this->assertEquals("4", $list->next()); + $list->insertPrevious("b", "e", "5"); // 1 5 2 4 3 + $this->assertEquals("3", $list->next()); + $this->assertEquals("4", $list->previous()); + $list->insertPrevious("c", "f", "6"); // 1 5 2 4 6 3 + $this->assertEquals("6", $list->next()); + $this->assertEquals("3", $list->next()); + $this->assertNull($list->next()); + + $list->last(); + $list->insertNext("c", "g", "7"); // 1 5 2 4 6 3 7 + + $this->assertEquals("7", $list->previous()); + $this->assertEquals("3", $list->previous()); + $this->assertEquals("6", $list->previous()); + $this->assertEquals("4", $list->previous()); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("5", $list->previous()); + $this->assertEquals("1", $list->previous()); + $this->assertNull($list->previous()); + } + + public function testDynamicRemoveAndCursor() + { + $list = new Sabel_Util_HashList(); + $list->add("a", "1"); + $list->add("b", "2"); + $list->add("c", "3"); + $list->add("d", "4"); + $list->add("e", "5"); + $list->add("f", "6"); + + $this->assertEquals("1", $list->next()); + $this->assertEquals("2", $list->next()); + $list->remove("d"); // 1 2 3 5 6 + $this->assertEquals("3", $list->next()); + $this->assertEquals("5", $list->next()); + $list->remove("e"); // 1 2 3 6 + $this->assertEquals("6", $list->next()); + $this->assertEquals("3", $list->previous()); + $list->remove("f"); // 1 2 3 + $this->assertEquals("2", $list->previous()); + $list->insertPrevious("a", "g", "0"); // 0 1 2 3 + $list->remove("a"); // 0 2 3 + $this->assertEquals("0", $list->previous()); + $this->assertNull($list->previous()); + + $list->last(); + $list->add("h", "8"); // 0 2 3 8 + + $this->assertEquals("8", $list->previous()); + $this->assertEquals("3", $list->previous()); + $this->assertEquals("2", $list->previous()); + $this->assertEquals("0", $list->previous()); + $this->assertNull($list->previous()); + } +} diff --git a/Test/Util/List.php b/Test/Util/List.php new file mode 100755 index 0000000..62f1172 --- /dev/null +++ b/Test/Util/List.php @@ -0,0 +1,106 @@ + + */ +class Test_Util_LinkedList extends SabelTestCase +{ + private $list = null; + + public static function suite() + { + return self::createSuite("Test_Util_LinkedList"); + } + + public function setUp() + { + $first = new StdClass(); + $first->name = "first"; + + $second = new StdClass(); + $second->name = "second"; + + $third = new StdClass(); + $third->name = "third"; + + $this->list = new Sabel_Util_LinkedList("first", $first); + + $this->list->insertNext("second", $second) + ->insertNext("third", $third); + } + + public function testInsertPreviousAndNext() + { + $list = new Sabel_Util_LinkedList("test", new StdClass()); + + for ($i=0; $i < 299; $i++) { + $list->insertNext("test{$i}", new StdClass()); + } + $this->assertEquals(300, $list->size()); + + for ($i=0; $i<300; $i++) { + $list->insertPrevious("test{$i}", new StdClass()); + } + $this->assertEquals(600, $list->size()); + } + + public function testFindByName() + { + $list = new Sabel_Util_LinkedList("test", new StdClass()); + + $target = new StdClass(); + $target->value = "ebine"; + $next = $list->insertNext("target", $target); + $next->insertNext("test2", new StdClass()); + + $obj = $list->find("target"); + + $this->assertTrue(($obj instanceof Sabel_Util_LinkedList)); + $this->assertTrue(is_object($obj)); + $this->assertEquals("ebine", $obj->current->value); + $this->assertEquals("test", $obj->getFirst()->name); + $this->assertEquals("ebine", $obj->getFirst()->next->current->value); + $this->assertEquals("test2", $obj->getFirst()->next->next->name); + } + + public function testUnlink() + { + $list = $this->list; + $list->getFirst()->next()->unlink(); + $this->assertEquals("first", $list->getFirst()->name); + $this->assertEquals("third", $list->getFirst()->next()->name); + } + + public function testUnlinkWithFind() + { + $list = $this->list; + $list->find("second")->unlink(); + $this->assertEquals("first", $list->getFirst()->name); + $this->assertEquals("third", $list->getFirst()->next()->name); + } + + public function testUnlinkAndInsert() + { + $list = $this->list; + + $list->find("second")->unlink(); + $list->getFirst()->insertNext("second", new StdClass()); + $this->assertEquals("second", $list->getFirst()->next()->name); + } + + public function testUnlinkLast() + { + $this->list->getLast()->unlink(); + $this->assertEquals("second", $this->list->getLast()->name); + } + + public function testInsertNextPreviousPointer() + { + $list = $this->list; + $list->find("third")->insertNext("force", new StdClass()); + $this->assertEquals("third", $list->getLast()->previous->name); + } +} diff --git a/Test/Util/Map.php b/Test/Util/Map.php new file mode 100755 index 0000000..da5c5cd --- /dev/null +++ b/Test/Util/Map.php @@ -0,0 +1,379 @@ + + */ +class Test_Util_Map extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Util_Map"); + } + + public function testIsEmpty() + { + $map = new UtilMap(); + $this->assertTrue($map->isEmpty()); + } + + public function testCount() + { + $map = new UtilMap(); + $this->assertEquals($map->count(), 0); + + $map->set(array("test1" => "hoge", "test2" => "fuga", "test3" => "foo")); + $this->assertEquals($map->count(), 3); + } + + public function testForeach() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + + $through = false; + foreach ($map as $key => $value) { + if ($through) { + $this->assertEquals($key, "test2"); + $this->assertTrue($value->equals("fuga")); + } else { + $this->assertEquals($key, "test1"); + $this->assertTrue($value->equals("hoge")); + } + $through = true; + } + + $this->assertTrue($through); + } + + public function testIterator() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + + $through = false; + while ($map->valid()) { + if ($through) { + $this->assertTrue($map->current()->equals("fuga")); + } else { + $this->assertTrue($map->current()->equals("hoge")); + } + $map->next(); + $through = true; + } + + $this->assertTrue($through); + } + + public function testIterator2() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + + $through = false; + while ($map->hasMoreElements()) { + if ($through) { + $this->assertTrue($map->nextElement()->equals("fuga")); + } else { + $this->assertTrue($map->nextElement()->equals("hoge")); + } + $through = true; + } + + $this->assertTrue($through); + } + + public function testValues() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + $values = $map->values(); + $this->assertEquals(count($values), 2); + $this->assertTrue($values[0]->equals("hoge")); + $this->assertTrue($values[1]->equals("fuga")); + } + + public function testKeys() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + $keys = $map->keys(); + $this->assertEquals(count($keys), 2); + $this->assertEquals($keys[0], "test1"); + $this->assertEquals($keys[1], "test2"); + } + + public function testImplode() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + $this->assertTrue($map->implode()->equals("hoge, fuga")); + $this->assertTrue($map->implode(".")->equals("hoge.fuga")); + } + + public function testPut() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", "fuga"); + + $this->assertEquals($map->count(), 2); + $this->assertTrue($map->get("test1")->equals("hoge")); + $this->assertTrue($map->get("test2")->equals("fuga")); + $this->assertNull($map->get("test3")); + } + + public function testPush() + { + $fuga = new String("fuga"); + $um = new UtilMap(array("test" => "foo")); + + $map = new UtilMap(); + $map->push("hoge")->push($fuga)->push($um); + $this->assertEquals($map->count(), 3); + + $this->assertTrue($map->get(0)->equals("hoge")); + $this->assertTrue($map->get(1)->equals("fuga")); + $this->assertTrue($map->get(1)->equals($fuga)); + $this->assertTrue($map->get(2)->equals($um)); + $this->assertNull($map->get(3)); + } + + public function testRemove() + { + $map = new UtilMap(); + $map->put("test", "hoge") + ->put(new UtilMap(array(1)), "fuga"); + + $this->assertEquals(2, $map->count()); + + $map->remove("test"); + $this->assertEquals(1, $map->count()); + $this->assertNull($map->get("test")); + + $map->remove(new UtilMap()); + $this->assertEquals(1, $map->count()); + $map->remove(new UtilMap(array(2))); + $this->assertEquals(1, $map->count()); + + $this->assertTrue($map->get(new UtilMap(array(1)))->equals("fuga")); + + $map->remove(new UtilMap(array(1))); + $this->assertEquals(0, $map->count()); + + $this->assertNull($map->get(new UtilMap(array(1)))); + } + + public function testClear() + { + $map = new UtilMap(); + $map->push("hoge")->push("fuga"); + $this->assertEquals($map->count(), 2); + + $array = $map->clear(); + $this->assertEquals($map->count(), 0); + $this->assertTrue(is_array($array)); + } + + public function testCannotConvertToString() + { + $map = new UtilMap(); + + try { + $map->put(new stdClass(), "hoge"); + } catch (Sabel_Exception_Runtime $e) { + return; + } + + $this->fail(); + } + + public function testGet() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", new String("fuga")) + ->put(new String("test3"), "foo") + ->put(new UtilMap(array(1)), "bar") + ->put(new UtilMap(array(1, 2)), new UtilMap(array(3, 4))); + + $this->assertTrue($map->get("test1")->equals("hoge")); + $this->assertTrue($map->get("test2")->equals("fuga")); + $this->assertTrue($map->get("test3")->equals("foo")); + $this->assertTrue($map->get(new String("test3"))->equals("foo")); + $this->assertTrue($map->get(new UtilMap(array(1)))->equals("bar")); + + $um = new UtilMap(array(3, 4)); + $this->assertTrue($map->get(new UtilMap(array(1, 2)))->equals($um)); + + $this->assertNull($map->get("test4")); + $this->assertNull($map->get(new UtilMap(array(3, 4)))); + } + + public function testSort() + { + $fruits = array("lemon", "orange", "banana", "apple"); + $map = new UtilMap($fruits); + $map->sort(); + + $this->assertTrue($map->get(0)->equals("apple")); + $this->assertTrue($map->get(1)->equals("banana")); + $this->assertTrue($map->get(2)->equals("lemon")); + $this->assertTrue($map->get(3)->equals("orange")); + } + + public function testRsort() + { + $fruits = array("lemon", "orange", "banana", "apple"); + $map = new UtilMap($fruits); + $map->rsort(); + + $this->assertTrue($map->get(0)->equals("orange")); + $this->assertTrue($map->get(1)->equals("lemon")); + $this->assertTrue($map->get(2)->equals("banana")); + $this->assertTrue($map->get(3)->equals("apple")); + } + + public function testReverse() + { + $fruits = array("lemon", "orange", "banana", "apple"); + $map = new UtilMap($fruits); + $map->reverse(); + + $this->assertTrue($map->get(0)->equals("apple")); + $this->assertTrue($map->get(1)->equals("banana")); + $this->assertTrue($map->get(2)->equals("orange")); + $this->assertTrue($map->get(3)->equals("lemon")); + } + + public function testMerge() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + $this->assertEquals($map->count(), 2); + + $data = array("test3" => "foo", "test4" => "bar"); + $map->merge($data); + $this->assertEquals($map->count(), 4); + + $values = $map->values(); + + $this->assertTrue($values[0]->equals("hoge")); + $this->assertTrue($values[1]->equals("fuga")); + $this->assertTrue($values[2]->equals("foo")); + $this->assertTrue($values[3]->equals("bar")); + + $data = array("test5" => "biz", "test6" => "buz"); + $map->merge(new UtilMap($data)); + $this->assertEquals($map->count(), 6); + + $values = $map->values(); + + $this->assertTrue($values[0]->equals("hoge")); + $this->assertTrue($values[1]->equals("fuga")); + $this->assertTrue($values[2]->equals("foo")); + $this->assertTrue($values[3]->equals("bar")); + $this->assertTrue($values[4]->equals("biz")); + $this->assertTrue($values[5]->equals("buz")); + } + + public function testUnique() + { + $data = array("test1" => "hoge", "test2" => "fuga"); + $map = new UtilMap($data); + $map->put("test4", "foo") + ->put("test5", "hoge") + ->put("test6", "fuga"); + + $this->assertEquals($map->count(), 5); + $this->assertEquals($map->unique()->count(), 3); + } + + public function testSum() + { + $data = array("test1" => 2, "test2" => 3, "test3" => 5); + $map = new UtilMap($data); + $this->assertEquals($map->sum(), 10); + + $data = array("test1" => 2.2, "test2" => 5.3, "test3" => 2.5); + $this->assertEquals($map->sum(), 10.0); + } + + public function testHas() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", null) + ->put(new UtilMap(), "fuga"); + + $this->assertTrue($map->has("test1")); + $this->assertFalse($map->has("test2")); + $this->assertTrue($map->exists("test2")); + $this->assertTrue($map->has(new UtilMap())); + + $this->assertFalse($map->has("test4")); + $this->assertFalse($map->has(new UtilMap(array(1)))); + } + + public function testPop() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", "fuga"); + + $this->assertTrue($map->has("test1")); + $this->assertTrue($map->has("test2")); + + $this->assertTrue($map->pop()->equals("fuga")); + $this->assertTrue($map->has("test1")); + $this->assertFalse($map->has("test2")); + $this->assertEquals($map->count(), 1); + } + + public function testShift() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", "fuga"); + + $this->assertTrue($map->has("test1")); + $this->assertTrue($map->has("test2")); + + $this->assertTrue($map->shift()->equals("hoge")); + $this->assertFalse($map->has("test1")); + $this->assertTrue($map->has("test2")); + $this->assertEquals($map->count(), 1); + } + + public function testSearch() + { + $map = new UtilMap(); + $map->put("test1", "hoge") + ->put("test2", new String("bar")) + ->put(new String("test3"), "biz") + ->put("test4", new UtilMap(array(1))) + ->put("test5", new UtilMap(array("test" => "buz"))) + ->put(new UtilMap(array(1, 2, 3)), "hello world"); + + $this->assertTrue($map->search("hoge")->equals("test1")); + $this->assertFalse($map->search("hogehoge")); + + $this->assertTrue($map->search("bar")->equals("test2")); + $this->assertTrue($map->search(new String("bar"))->equals("test2")); + + $this->assertTrue($map->search("biz")->equals("test3")); + $this->assertTrue($map->search(new String("biz"))->equals("test3")); + + $this->assertTrue($map->search(new UtilMap(array(1)))->equals("test4")); + $this->assertTrue($map->search(new UtilMap(array("test" => "buz")))->equals("test5")); + $this->assertFalse($map->search(new UtilMap(array(2)))); + $this->assertFalse($map->search(new UtilMap(array("test" => "abc")))); + + $um = new UtilMap(array(1, 2, 3)); + $this->assertTrue($map->get($um)->equals("hello world")); + } +} diff --git a/Test/Util/String.php b/Test/Util/String.php new file mode 100755 index 0000000..3638327 --- /dev/null +++ b/Test/Util/String.php @@ -0,0 +1,408 @@ + + */ +class Test_Util_String extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_Util_String"); + } + + public function testIsEmpty() + { + $string = new String(); + $this->assertTrue($string->isEmpty()); + } + + public function testNotString() + { + try { + $string = new String(10000); + } catch (Sabel_Exception_InvalidArgument $e) { + return; + } + + $this->fail(); + } + + public function testCharAt() + { + $string = new String("test"); + $this->assertEquals("t", $string->charAt(0)->toString()); + $this->assertEquals("e", $string->charAt(1)->toString()); + $this->assertEquals("t", $string->charAt(3)->toString()); + $this->assertEquals("", $string->charAt(4)->toString()); + $this->assertEquals("", $string->charAt(-1)->toString()); + + $string = new String("あいうえお"); + $this->assertEquals("い", $string->charAt(1)->toString()); + $this->assertEquals("え", $string->charAt(3)->toString()); + $this->assertEquals("", $string->charAt(5)->toString()); + } + + public function testIndexOf() + { + $string = new String("Hello World"); + $this->assertEquals(6, $string->indexOf("W")); + $this->assertEquals(4, $string->indexOf("o")); + $this->assertEquals(7, $string->indexOf("o", 5)); + + $string = new String("あいうえお あいうえお"); + $this->assertEquals(2, $string->indexOf("う")); + $this->assertEquals(5, $string->indexOf(" ")); + $this->assertEquals(8, $string->indexOf("う", 5)); + } + + public function testLastChar() + { + $string = new String("Hello World"); + $this->assertEquals("d", $string->last()->toString()); + + $string = new String(); + $this->assertEquals("", $string->last()->toString()); + + $string = new String("あいうえお"); + $this->assertEquals("お", $string->last()->toString()); + } + + public function testTrim() + { + $string = new String(" Hello World "); + $this->assertTrue($string->trim()->equals("Hello World")); + + $string = new String("/*/*/Hello World/*/*/"); + $this->assertTrue($string->trim("/*")->equals("Hello World")); + + $str = <<assertTrue($string->trim()->equals("aiueo")); + + // multibyte + + $string = new String("  あいうえお  "); + $this->assertTrue($string->trim()->equals("あいうえお")); + + $string = new String("表能申あいうえお申能表"); + $this->assertTrue($string->trim("表能申")->equals("あいうえお")); + + $str = <<assertTrue($string->trim()->equals("あいうえお")); + } + + public function testRtrim() + { + $string = new String(" Hello World "); + $this->assertTrue($string->rtrim()->equals(" Hello World")); + + $string = new String("  あいうえお  "); + $this->assertTrue($string->rtrim()->equals("  あいうえお")); + } + + public function testLtrim() + { + $string = new String(" Hello World "); + $this->assertTrue($string->ltrim()->equals("Hello World ")); + + $string = new String("  あいうえお  "); + $this->assertTrue($string->ltrim()->equals("あいうえお  ")); + } + + public function testToUpperCase() + { + $string = new String("Hello World"); + $this->assertTrue($string->toUpperCase()->equals("HELLO WORLD")); + } + + public function testToLowerCase() + { + $string = new String("Hello World"); + $this->assertTrue($string->toLowerCase()->equals("hello world")); + } + + public function testUcFirst() + { + $string = new String("test"); + $this->assertTrue($string->ucfirst()->equals("Test")); + } + + public function testLcFirst() + { + $string = new String("ABCDE"); + $this->assertTrue($string->lcfirst()->equals("aBCDE")); + } + + public function testExplode() + { + $string = new String("hoge:fuga:foo:bar"); + $array = $string->explode(":"); + $this->assertEquals("hoge", $array[0]); + $this->assertEquals("fuga", $array[1]); + $this->assertEquals("foo", $array[2]); + $this->assertEquals("bar", $array[3]); + + $string = new String("hoge:fuga:foo:bar"); + $array = $string->explode(":", 3); + $this->assertEquals("hoge", $array[0]); + $this->assertEquals("fuga", $array[1]); + $this->assertEquals("foo:bar", $array[2]); + } + + public function testSplit() + { + $string = new String("hoge.fuga.foo.bar"); + $array = $string->split(); + $this->assertEquals("h", $array[0]); + $this->assertEquals("f", $array[5]); + $this->assertEquals("f", $array[10]); + $this->assertEquals("b", $array[14]); + + $array = $string->split(3); + $this->assertEquals("hog", $array[0]); + $this->assertEquals("e.f", $array[1]); + $this->assertEquals("uga", $array[2]); + $this->assertEquals(".fo", $array[3]); + $this->assertEquals("o.b", $array[4]); + $this->assertEquals("ar", $array[5]); + + // multibyte + + $string = new String("あいうえおかきくけこ"); + $array = $string->split(); + $this->assertEquals("あ", $array[0]); + $this->assertEquals("う", $array[2]); + $this->assertEquals("お", $array[4]); + $this->assertEquals("き", $array[6]); + $this->assertEquals("け", $array[8]); + + $array = $string->split(3); + $this->assertEquals("あいう", $array[0]); + $this->assertEquals("えおか", $array[1]); + $this->assertEquals("きくけ", $array[2]); + $this->assertEquals("こ", $array[3]); + } + + public function testReplace() + { + $string = new String("hoge huga"); + $this->assertTrue($string->replace("hoge", "foo")->equals("foo huga")); + } + + public function testAppend() + { + $string = new String("hoge"); + $this->assertTrue($string->append("hoge")->equals("hogehoge")); + + $hoge = new String("hoge"); + $huga = new String("huga"); + $this->assertTrue($hoge->append($huga)->equals("hogehuga")); + } + + public function testEquals() + { + $string = new String("hoge"); + $this->assertTrue($string->equals("hoge")); + $this->assertTrue($string->equals("huga", "hoge")); + $this->assertFalse($string->equals("huga")); + $this->assertFalse($string->equals("huga", "foo")); + + $hoge1 = new String("hoge"); + $hoge2 = new String("hoge"); + + $this->assertTrue($hoge1->equals($hoge2)); + } + + public function testSha1() + { + $string = new String("hoge"); + $this->assertEquals(sha1("hoge"), $string->sha1()->toString()); + } + + public function testMd5() + { + $string = new String("hoge"); + $this->assertEquals(md5("hoge"), $string->md5()->toString()); + } + + public function testSucc() + { + $string = new String("a"); + $this->assertTrue($string->succ()->equals("b")); + $this->assertTrue($string->succ()->equals("c")); + + $string = new String("00"); + $this->assertTrue($string->succ()->equals("01")); + $this->assertTrue($string->succ()->equals("02")); + + $string = new String("99"); + $this->assertTrue($string->succ()->equals("100")); + $this->assertTrue($string->succ()->equals("101")); + + $string = new String("y"); + $this->assertTrue($string->succ()->equals("z")); + $this->assertTrue($string->succ()->equals("aa")); + $this->assertTrue($string->succ()->equals("ab")); + + $string = new String("Y"); + $this->assertTrue($string->succ()->equals("Z")); + $this->assertTrue($string->succ()->equals("AA")); + $this->assertTrue($string->succ()->equals("AB")); + + $string = new String("ay"); + $this->assertTrue($string->succ()->equals("az")); + $this->assertTrue($string->succ()->equals("ba")); + $this->assertTrue($string->succ()->equals("bb")); + + $string = new String("aY"); + $this->assertTrue($string->succ()->equals("aZ")); + $this->assertTrue($string->succ()->equals("bA")); + $this->assertTrue($string->succ()->equals("bB")); + + $string = new String("0Y"); + $this->assertTrue($string->succ()->equals("0Z")); + $this->assertTrue($string->succ()->equals("1A")); + $this->assertTrue($string->succ()->equals("1B")); + + $string = new String("9Y"); + $this->assertTrue($string->succ()->equals("9Z")); + $this->assertTrue($string->succ()->equals("10A")); + $this->assertTrue($string->succ()->equals("10B")); + + $string = new String("A998"); + $this->assertTrue($string->succ()->equals("A999")); + $this->assertTrue($string->succ()->equals("B000")); + $this->assertTrue($string->succ()->equals("B001")); + } + + public function testSubString() + { + $string = new String("Hello World"); + + $str = $string->substring(6); + $this->assertTrue($str->equals("World")); + $this->assertTrue($string->equals("Hello World")); + + $str = $string->substring(6, 3); + $this->assertTrue($str->equals("Wor")); + + $str = $string->substring(1, -1); + $this->assertTrue($str->equals("ello Worl")); + + $string = new String("あいうえおかきくけこ"); + + $str = $string->substring(5); + $this->assertTrue($str->equals("かきくけこ")); + + $str = $string->substring(6, 3); + $this->assertTrue($str->equals("きくけ")); + + $str = $string->substring(1, -1); + $this->assertTrue($str->equals("いうえおかきくけ")); + } + + public function testInsert() + { + $string = new String("Hello World"); + $string->insert(6, "PHP "); + $this->assertTrue($string->equals("Hello PHP World")); + + $string = new String("Hello World"); + $string->insert(0, "PHP. "); + $this->assertTrue($string->equals("PHP. Hello World")); + + $string = new String("あいうえお さしすせそ"); + $string->insert(6, "かきくけこ "); + $this->assertTrue($string->equals("あいうえお かきくけこ さしすせそ")); + } + + public function testPad() + { + $string = new String("1"); + $this->assertEquals(" 1", $string->pad(" ", 4)->toString()); + + $string = new String("1"); + $this->assertEquals("1 ", $string->pad(" ", 4, STR_PAD_RIGHT)->toString()); + + $string = new String("1"); + $this->assertEquals("=.=.1", $string->pad("=.", 5)->toString()); + + $string = new String("1"); + $this->assertEquals("1=.=.", $string->pad("=.", 5, STR_PAD_RIGHT)->toString()); + + $string = new String("1"); + $this->assertEquals("=.=1", $string->pad("=.", 4)->toString()); + + $string = new String("1"); + $this->assertEquals("_1_", $string->pad("_", 3, STR_PAD_BOTH)->toString()); + + $string = new String("1"); + $this->assertEquals("_1__", $string->pad("_", 4, STR_PAD_BOTH)->toString()); + + $string = new String("1"); + $this->assertEquals("__1__", $string->pad("_", 5, STR_PAD_BOTH)->toString()); + + $string = new String("123"); + $this->assertEquals("aba123abab", $string->pad("ab", 10, STR_PAD_BOTH)->toString()); + + // multibyte + + $string = new String("あ"); + $this->assertEquals("いいいあ", $string->pad("い", 4)->toString()); + + $string = new String("あ"); + $this->assertEquals("あいいい", $string->pad("い", 4, STR_PAD_RIGHT)->toString()); + + $string = new String("あ"); + $this->assertEquals("いういうあ", $string->pad("いう", 5)->toString()); + + $string = new String("あ"); + $this->assertEquals("あいういう", $string->pad("いう", 5, STR_PAD_RIGHT)->toString()); + + $string = new String("あ"); + $this->assertEquals("いういあ", $string->pad("いう", 4)->toString()); + + $string = new String("あ"); + $this->assertEquals("いあい", $string->pad("い", 3, STR_PAD_BOTH)->toString()); + + $string = new String("あ"); + $this->assertEquals("いあいい", $string->pad("い", 4, STR_PAD_BOTH)->toString()); + + $string = new String("あ"); + $this->assertEquals("いいあいい", $string->pad("い", 5, STR_PAD_BOTH)->toString()); + + $string = new String("あいう"); + $this->assertEquals("えおえあいうえおえお", $string->pad("えお", 10, STR_PAD_BOTH)->toString()); + } + + public function testClone() + { + $string = new String("Hello World"); + $cloned = $string->cloning(); + $this->assertTrue($string == $cloned); + $this->assertFalse($string === $cloned); + } +} diff --git a/Test/Util/Tests.php b/Test/Util/Tests.php new file mode 100755 index 0000000..3acecdd --- /dev/null +++ b/Test/Util/Tests.php @@ -0,0 +1,26 @@ + + */ +class Test_Util_Tests +{ + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + $suite->addTest(Test_Util_String::suite()); + $suite->addTest(Test_Util_Map::suite()); + $suite->addTest(Test_Util_LinkedList::suite()); + $suite->addTest(Test_Util_HashList::suite()); + $suite->addTest(Test_Util_FileSystem::suite()); + + return $suite; + } +} diff --git a/Test/ValueObject.php b/Test/ValueObject.php new file mode 100755 index 0000000..82bb11e --- /dev/null +++ b/Test/ValueObject.php @@ -0,0 +1,147 @@ + + */ +class Test_ValueObject extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_ValueObject"); + } + + /** + * @test + */ + public function simpleTest() + { + $object = new Sabel_ValueObject(); + $object->set("a", 10); + $object->set("b", "20"); + $object->set("c", true); + $object->set("d", new stdClass()); + $object->set("e", array("foo", "bar")); + + $this->assertEquals(10, $object->get("a")); + $this->assertEquals("20", $object->get("b")); + $this->assertEquals(true, $object->get("c")); + $this->assertEquals(new stdClass(), $object->get("d")); + $this->assertEquals(array("foo", "bar"), $object->get("e")); + } + + /** + * @test + */ + public function simpleTest2() + { + $object = new Sabel_ValueObject(); + $object->a = 10; + $object->b = "20"; + $object->c = true; + $object->d = new stdClass(); + $object->e = array("foo", "bar"); + + $this->assertEquals(10, $object->a); + $this->assertEquals("20", $object->b); + $this->assertEquals(true, $object->c); + $this->assertEquals(new stdClass(), $object->d); + $this->assertEquals(array("foo", "bar"), $object->e); + } + + /** + * @test + */ + public function toArray() + { + $object = new Sabel_ValueObject(); + $object->a = 10; + $object->b = "20"; + $object->c = true; + + $array = $object->toArray(); + + $this->assertEquals(10, $array["a"]); + $this->assertEquals("20", $array["b"]); + $this->assertEquals(true, $array["c"]); + } + + /** + * @test + */ + public function fromArray() + { + $object = Sabel_ValueObject::fromArray(array( + "a" => 10, + "b" => "20", + "c" => true + )); + + $this->assertEquals(10, $object->a); + $this->assertEquals("20", $object->b); + $this->assertEquals(true, $object->c); + } + + /** + * @test + */ + public function containts() + { + $object = new Sabel_ValueObject(); + $object->a = 10; + $object->b = null; + + $this->assertTrue($object->has("a")); + $this->assertFalse($object->has("b")); + $this->assertTrue($object->exists("a")); + $this->assertTrue($object->exists("b")); + } + + /** + * @test + */ + public function remove() + { + $object = new Sabel_ValueObject(); + $object->a = 10; + + $this->assertTrue($object->has("a")); + + $object->remove("a"); + + $this->assertFalse($object->has("a")); + } + + /** + * @test + */ + public function merge() + { + $object = new Sabel_ValueObject(); + $object->a = 10; + $object->b = 20; + + $this->assertEquals(2, count($object->toArray())); + + $object->merge(array("c" => 30, "d" => 40)); + + $this->assertEquals(4, count($object->toArray())); + + $object2 = new Sabel_ValueObject(); + $object2->e = 50; + $object2->f = 60; + + $object->merge($object2); + + $this->assertEquals(6, count($object->toArray())); + + $this->assertEquals(10, $object->a); + $this->assertEquals(20, $object->b); + $this->assertEquals(30, $object->c); + $this->assertEquals(40, $object->d); + $this->assertEquals(50, $object->e); + $this->assertEquals(60, $object->f); + } +} diff --git a/Test/View/PageViewer.php b/Test/View/PageViewer.php new file mode 100755 index 0000000..4151e2c --- /dev/null +++ b/Test/View/PageViewer.php @@ -0,0 +1,63 @@ + + */ +class Test_View_PageViewer extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_View_PageViewer"); + } + + public function testStandardUse() + { + $pager = new Sabel_View_Pager(200, 10); + $pager->setPageNumber(10); + $pv = new Sabel_View_PageViewer($pager); + + $this->assertTrue($pv->isCurrent()); + $this->assertFalse($pv->isFirst()); + + $this->assertEquals(10, $pv->getCurrent()); + $this->assertEquals(11, $pv->getNext()); + $this->assertEquals(9, $pv->getPrevious()); + + $num = 5; + foreach ($pv as $page) $this->assertEquals($num++, $page->getCurrent()); + $this->assertEquals(15, $num); + $this->assertEquals(10, $pv->getCurrent()); + $this->assertEquals(11, $pv->getNext()); + $this->assertEquals(9, $pv->getPrevious()); + + $this->assertEquals(20, $pv->getLast()); + $this->assertEquals(1, $pv->getFirst()); + } + + public function testStandardUseAndPageNumberFirst() + { + $pager = new Sabel_View_Pager(200, 10); + $pager->setPageNumber(1); + $pv = new Sabel_View_PageViewer($pager, 5); + + $this->assertTrue($pv->isFirst()); + $this->assertTrue($pv->isCurrent()); + $this->assertFalse($pv->isLast()); + + $this->assertEquals(1, $pv->getCurrent()); + $this->assertEquals(2, $pv->getNext()); + $this->assertEquals(1, $pv->getPrevious()); + + $num = 1; + foreach ($pv as $page) $this->assertEquals($num++, $page->getCurrent()); + $this->assertEquals(6, $num); + $this->assertEquals(1, $pv->getCurrent()); + $this->assertEquals(2, $pv->getNext()); + $this->assertEquals(1, $pv->getPrevious()); + } + + // @todo more tests +} diff --git a/Test/View/Pager.php b/Test/View/Pager.php new file mode 100755 index 0000000..5a85502 --- /dev/null +++ b/Test/View/Pager.php @@ -0,0 +1,95 @@ + + */ +class Test_View_Pager extends SabelTestCase +{ + private $pager = null; + + public static function suite() + { + return self::createSuite("Test_View_Pager"); + } + + public function testStandardPagerUse() + { + $pager = new Sabel_View_Pager(100, 10); + $pager->setPageNumber(3); + + $this->assertEquals(100, $pager->getNumberOfItem()); + $this->assertEquals(10, $pager->getLimit()); + $this->assertEquals(3, $pager->getPageNumber()); + $this->assertEquals(10, $pager->getTotalPageNumber()); + $this->assertEquals(20, $pager->getSqlOffset()); + } + + public function testPageNumberRoundPagerUse() + { + $pager = new Sabel_View_Pager(300, 70); + $pager->setPageNumber(100); + + $this->assertEquals(300, $pager->getNumberOfItem()); + $this->assertEquals(70, $pager->getLimit()); + $this->assertEquals(5, $pager->getPageNumber()); + $this->assertEquals(5, $pager->getTotalPageNumber()); + $this->assertEquals(280, $pager->getSqlOffset()); + } + + public function testExceptedPagerUse() + { + try { + $pager = new Sabel_View_Pager(-1, 10); + } catch (Sabel_Exception_InvalidArgument $e) { + return; + } + + $this->fail('set number of item method not thrown.'); + } + + public function testExceptedPagerUse2() + { + try { + $pager = new Sabel_View_Pager('a', 10); + } catch (Sabel_Exception_InvalidArgument $e) { + return; + } + + $this->fail('set number of item method not thrown.'); + } + + public function testUnusualPagerUse() + { + $pager = new Sabel_View_Pager(1, 1); + $pager->setPageNumber(10); + + $this->assertEquals(1, $pager->getPageNumber()); + $this->assertEquals(1, $pager->getTotalPageNumber()); + $this->assertEquals(0, $pager->getSqlOffset()); + + $pager = new Sabel_View_Pager(250, 15); + $pager->setPageNumber(10); + + $this->assertEquals(250, $pager->getNumberOfItem()); + $this->assertEquals(15, $pager->getLimit()); + $this->assertEquals(10, $pager->getPageNumber()); + $this->assertEquals(17, $pager->getTotalPageNumber()); + $this->assertEquals(135, $pager->getSqlOffset()); + } + + public function testInitializedPagerUse() + { + $pager = new Sabel_View_Pager(200, 20); + + $pager->setPageNumber(4.3); + + $this->assertEquals(200, $pager->getNumberOfItem()); + $this->assertEquals(20, $pager->getLimit()); + $this->assertEquals(4, $pager->getPageNumber()); + $this->assertEquals(10, $pager->getTotalPageNumber()); + $this->assertEquals(60, $pager->getSqlOffset()); + } +} diff --git a/Test/View/Renderer.php b/Test/View/Renderer.php new file mode 100755 index 0000000..dcc6a52 --- /dev/null +++ b/Test/View/Renderer.php @@ -0,0 +1,37 @@ + + */ +class Test_View_Renderer extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_View_Renderer"); + } + + public function testRenderingFromString() + { + $renderer = new Sabel_View_Renderer(); + $contents = 'name: '; + $result = $renderer->rendering($contents, array("name" => "hoge")); + $this->assertEquals("name: hoge", $result); + } + + public function testRenderingFromFile() + { + $renderer = new Sabel_View_Renderer(); + $path = MODULES_DIR_PATH . "/views/test.tpl"; + $result = $renderer->rendering(null, array("a" => "10", "b" => "20"), $path); + + $expected = << +b: 20 +CONTENTS; + + $this->assertEquals($expected, rtrim($result)); + } +} diff --git a/Test/View/Template.php b/Test/View/Template.php new file mode 100755 index 0000000..0229cce --- /dev/null +++ b/Test/View/Template.php @@ -0,0 +1,114 @@ + + */ +abstract class Test_View_Template extends SabelTestCase +{ + protected static $view = null; + + public function testValidTemplate() + { + $template = self::$view->getValidLocation("index"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "hoge" . DS . "index" . TPL_SUFFIX, $template->getPath()); + + $template = self::$view->getValidLocation("hoge"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "hoge" . DS . "hoge" . TPL_SUFFIX, $template->getPath()); + + $template = self::$view->getValidLocation("error"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "error" . TPL_SUFFIX, $template->getPath()); + } + + public function testInvalidTemplate() + { + $template = self::$view->getValidLocation("fuga"); + $this->assertNull($template); + + $template = self::$view->getValidLocation("abcdef"); + $this->assertNull($template); + } + + public function testSetup2() + { + $repository = $this->createRepository("fuga"); + + $this->assertEquals(3, count($repository->getLocations())); + $this->assertTrue($repository->getLocation("controller") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("module") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("app") instanceof Sabel_View_Location); + $this->assertNull($repository->getLocation("fuga")); + } + + public function testValidTemplate2() + { + $template = self::$view->getValidLocation("index"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "fuga" . DS . "index" . TPL_SUFFIX, $template->getPath()); + + $template = self::$view->getValidLocation("fuga"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "fuga" . DS . "fuga" . TPL_SUFFIX, $template->getPath()); + + $template = self::$view->getValidLocation("error"); + $this->assertTrue($template instanceof Sabel_View_Location); + $this->assertEquals(MODULES_DIR_PATH . DS . "index" . DS . VIEW_DIR_NAME . DS . "error" . TPL_SUFFIX, $template->getPath()); + } + + public function testInvalidTemplate2() + { + $template = self::$view->getValidLocation("hoge"); + $this->assertNull($template); + + $template = self::$view->getValidLocation("abcdef"); + $this->assertNull($template); + } + + public function testGetContents() + { + $template = self::$view->getValidLocation("index"); + $contents = $template->getContents(); + $this->assertEquals("fuga/index.tpl", rtrim($contents)); + + $template = self::$view->getValidLocation("fuga"); + $contents = $template->getContents(); + $this->assertEquals("fuga/fuga.tpl", rtrim($contents)); + } + + public function testIsValid() + { + $this->assertTrue(self::$view->isValid("controller", "index")); + $this->assertTrue(self::$view->isValid("controller", "fuga")); + + $this->assertTrue(self::$view->isValid("module", "error")); + $this->assertFalse(self::$view->isValid("module", "fuga")); + + $this->assertTrue(self::$view->isValid("app", "serverError")); + $this->assertFalse(self::$view->isValid("app", "error")); + $this->assertFalse(self::$view->isValid("app", "index")); + + try { + self::$view->isValid("hoge", "index"); + } catch (Exception $e) { + return; + } + + $this->fail(); + } + + public function testCreate() + { + $time = microtime(); + self::$view->create("controller", "new", $time); + $this->assertEquals($time, trim(self::$view->getContents("new"))); + } + + public function testDelete() + { + self::$view->delete("controller", "new"); + $this->assertNull(self::$view->getValidLocation("new")); + } +} diff --git a/Test/View/TemplateDb.php b/Test/View/TemplateDb.php new file mode 100755 index 0000000..312f265 --- /dev/null +++ b/Test/View/TemplateDb.php @@ -0,0 +1,100 @@ + + */ +class Test_View_TemplateDb extends Test_View_Template +{ + public static function suite() + { + $base = dirname(__FILE__) . DS . "templates"; + if (!defined("MODULES_DIR_PATH")) define("MODULES_DIR_PATH", $base); + + if (self::initTable()) { + return self::createSuite("Test_View_TemplateDb"); + } else { + return self::createSuite(""); + } + } + + public function testSetup() + { + $repository = $this->createRepository("hoge"); + + $this->assertEquals(3, count($repository->getLocations())); + $this->assertTrue($repository->getLocation("controller") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("module") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("app") instanceof Sabel_View_Location); + $this->assertNull($repository->getLocation("hoge")); + } + + protected function createRepository($controllerName) + { + $controller = new Sabel_View_Location_Database("index" . DS . VIEW_DIR_NAME . DS . $controllerName . DS); + $view = new Sabel_View_Object("controller", $controller); + + $module = new Sabel_View_Location_Database("index" . DS . VIEW_DIR_NAME . DS); + $view->addLocation("module", $module); + + $app = new Sabel_View_Location_Database(VIEW_DIR_NAME . DS); + $view->addLocation("app", $app); + + return self::$view = $view; + } + + private static function initTable() + { + if (extension_loaded("mysql")) { + $params = array("package" => "sabel.db.mysql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } elseif (extension_loaded("pgsql")) { + $params = array("package" => "sabel.db.pgsql", + "host" => "127.0.0.1", + "user" => "root", + "password" => "", + "database" => "sdb_test"); + } elseif (extension_loaded("pdo_sqlite")) { + $params = array("package" => "sabel.db.pdo.sqlite", + "database" => SABEL_BASE . "/Test/data/sdb_test.sq3"); + } else { + Sabel_Console::message("skipped 'TemplateDb'."); + return false; + } + + Sabel_Db_Config::add("default", $params); + $stmt = Sabel_Db::createStatement(); + $tblName = $stmt->quoteIdentifier("sbl_template"); + $nCol = $stmt->quoteIdentifier("name"); + $nsCol = $stmt->quoteIdentifier("namespace"); + $cCol = $stmt->quoteIdentifier("contents"); + $stmt->setQuery("DELETE FROM $tblName")->execute(); + + $data = array(); + $data[0]["path"] = "views" . DS . "serverError" . TPL_SUFFIX; + $data[0]["cont"] = ""; + $data[1]["path"] = "index" . DS . "views" . DS . "error" . TPL_SUFFIX; + $data[1]["cont"] = ""; + $data[2]["path"] = "index" . DS . "views" . DS . "hoge" . DS . "index" . TPL_SUFFIX; + $data[2]["cont"] = "hoge/index.tpl"; + $data[3]["path"] = "index" . DS . "views" . DS . "hoge" . DS . "hoge" . TPL_SUFFIX; + $data[3]["cont"] = "hoge/hoge.tpl"; + $data[4]["path"] = "index" . DS . "views" . DS . "fuga" . DS . "index" . TPL_SUFFIX; + $data[4]["cont"] = "fuga/index.tpl"; + $data[5]["path"] = "index" . DS . "views" . DS . "fuga" . DS . "fuga" . TPL_SUFFIX; + $data[5]["cont"] = "fuga/fuga.tpl"; + + foreach ($data as $d) { + $query = "INSERT INTO {$tblName}({$nCol}, {$nsCol}, {$cCol}) VALUES('{$d["path"]}', '', '{$d["cont"]}')"; + $stmt->setQuery($query)->execute(); + } + + return true; + } +} diff --git a/Test/View/TemplateFile.php b/Test/View/TemplateFile.php new file mode 100755 index 0000000..a1adf3f --- /dev/null +++ b/Test/View/TemplateFile.php @@ -0,0 +1,40 @@ + + */ +class Test_View_TemplateFile extends Test_View_Template +{ + public static function suite() + { + return self::createSuite("Test_View_TemplateFile"); + } + + public function testSetup() + { + $repository = $this->createRepository("hoge"); + + $this->assertEquals(3, count($repository->getLocations())); + $this->assertTrue($repository->getLocation("controller") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("module") instanceof Sabel_View_Location); + $this->assertTrue($repository->getLocation("app") instanceof Sabel_View_Location); + $this->assertNull($repository->getLocation("hoge")); + } + + protected function createRepository($controllerName) + { + $controller = new Sabel_View_Location_File("index" . DS . VIEW_DIR_NAME . DS . $controllerName . DS); + $view = new Sabel_View_Object("controller", $controller); + + $module = new Sabel_View_Location_File("index" . DS . VIEW_DIR_NAME . DS); + $view->addLocation("module", $module); + + $app = new Sabel_View_Location_File(VIEW_DIR_NAME . DS); + $view->addLocation("app", $app); + + return self::$view = $view; + } +} diff --git a/Test/View/Tests.php b/Test/View/Tests.php new file mode 100755 index 0000000..bf05421 --- /dev/null +++ b/Test/View/Tests.php @@ -0,0 +1,29 @@ + + */ +class Test_View_Tests +{ + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite(); + $suite->addTest(Test_View_TemplateFile::suite()); + // $suite->addTest(Test_View_TemplateDb::suite()); + $suite->addTest(Test_View_Renderer::suite()); + $suite->addTest(Test_View_Pager::suite()); + $suite->addTest(Test_View_PageViewer::suite()); + + return $suite; + } +} diff --git a/Test/VirtualInheritance.php b/Test/VirtualInheritance.php new file mode 100755 index 0000000..9a0af67 --- /dev/null +++ b/Test/VirtualInheritance.php @@ -0,0 +1,49 @@ + + */ +class Test_VirtualInheritance extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_VirtualInheritance"); + } + + public function testVirtualInheritance() + { + $inherited = new Sabel_Aspect_VirtualInheritProxy(new InheritedClass()); + $inherited->inherit("VirtualParentClass")->inherit("VirtualParentClassTwo"); + + $this->assertEquals("method", $inherited->method()); + $this->assertEquals("parentMethod 1", $inherited->parentMethod(1)); + $this->assertEquals("parentMethodTwo 1 2", $inherited->parentMethodTwo(1, 2)); + } +} + +class InheritedClass +{ + public function method() + { + return "method"; + } +} + +class VirtualParentClass +{ + public function parentMethod($arg) + { + return "parentMethod $arg"; + } +} + +class VirtualParentClassTwo +{ + public function parentMethodTwo($arg1, $arg2) + { + return "parentMethodTwo $arg1 $arg2"; + } +} diff --git a/Test/XML/Test.php b/Test/XML/Test.php new file mode 100755 index 0000000..343c057 --- /dev/null +++ b/Test/XML/Test.php @@ -0,0 +1,640 @@ + + */ +class Test_XML_Test extends SabelTestCase +{ + public static function suite() + { + return self::createSuite("Test_XML_Test"); + } + + /** + * @test + */ + public function initialize() + { + $this->outputUsersXml(); + } + + public function testDocument() + { + $xml = Sabel_Xml_Document::create(); + $test = $this->loadXML($xml, "simple"); + $this->assertEquals("test", $test->tagName); + $this->assertEquals("utf-8", $xml->getEncoding()); + $this->assertEquals("1.0", $xml->getVersion()); + } + + public function testAttribute() + { + $xml = Sabel_Xml_Document::create(); + $test = $this->loadXML($xml, "simple"); + $this->assertEquals("foo", $test->getChild("foo")->at("attr")); + $this->assertEquals("bar", $test->getChild("bar")->at("attr")); + $this->assertEquals("baz", $test->getChild("baz")->at("attr")); + } + + public function testAttributes() + { + $xml = Sabel_Xml_Document::create(); + $test = $this->loadXML($xml, "simple"); + $attrs = $test->getChild("foo")->getAttributes(); + + $this->assertEquals(true, $attrs->has("a")); + $this->assertEquals(true, $attrs->has("b")); + $this->assertEquals(true, $attrs->has("c")); + $this->assertEquals(false, $attrs->has("d")); + + $this->assertEquals("10", $attrs->get("a")); + $this->assertEquals("20", $attrs->get("b")); + $this->assertEquals("30", $attrs->get("c")); + $this->assertEquals(null, $attrs->get("d")); + + // getter + + $this->assertEquals("10", $attrs->a); + $this->assertEquals("20", $attrs->b); + $this->assertEquals("30", $attrs->c); + $this->assertEquals(null, $attrs->d); + } + + public function testNodeValue() + { + $xml = Sabel_Xml_Document::create(); + $test = $this->loadXML($xml, "simple"); + $this->assertEquals("footext", trim($test->getChild("foo")->getValue())); + $this->assertEquals("bartext", trim($test->getChild("bar")->getValue())); + $this->assertEquals("baztext", trim($test->getChild("baz")->getValue())); + } + + public function testElementsCount() + { + $xml = Sabel_Xml_Document::create(); + $test = $this->loadXML($xml, "test"); + $this->assertEquals(2, $test->getRawElement()->getElementsByTagName("foo")->length); + $this->assertEquals(1, $test->getChildren("foo")->length); + } + + public function testCreateDocument() + { + $xml = Sabel_Xml_Document::create(); + $xml->setEncoding("utf-8")->setVersion("1.0"); + + $users = $xml->createElement("users"); + + $aUser = $users->addChild("user"); + $aUser->addChild("name", "tanaka"); + $aUser->addChild("age", "18"); + + $aUser = $users->addChild("user"); + $aUser->addChild("name", "suzuki"); + $aUser->addChild("age", "25"); + + $aUser = $users->addChild("user"); + $aUser->addChild("name", "satou"); + $aUser->addChild("age", "40"); + + $xml->setDocumentElement($users); + $this->saveXML($xml, "users"); + } + + public function testElements() + { + $xml = Sabel_Xml_Document::create(); + $_users = $this->loadXML($xml, "users"); + $users = $_users->getChildren("user"); + $this->assertEquals(3, $users->length); + + foreach ($users as $i => $user) {} + $this->assertEquals(2, $i); + + $this->assertEquals("tanaka", $users[0]->getChild("name")->getValue()); + $this->assertEquals("18", $users[0]->getChild("age")->getValue()); + $this->assertEquals("suzuki", $users[1]->getChild("name")->getValue()); + $this->assertEquals("25", $users[1]->getChild("age")->getValue()); + $this->assertEquals("satou", $users[2]->getChild("name")->getValue()); + $this->assertEquals("40", $users[2]->getChild("age")->getValue()); + } + + public function testSimpleAccess() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $this->assertEquals("tanaka", $users->user[0]->name[0]->getValue()); + $this->assertEquals("18", $users->user[0]->age[0]->getValue()); + $this->assertEquals("suzuki", $users->user[1]->name[0]->getValue()); + $this->assertEquals("25", $users->user[1]->age[0]->getValue()); + $this->assertEquals("satou", $users->user[2]->name[0]->getValue()); + $this->assertEquals("40", $users->user[2]->age[0]->getValue()); + } + + public function setSetNodeValue() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $users->user[0]->age[0]->setNodeValue("20"); + $this->saveXML($xml, "users"); + + $xml = new Sabel_Xml_Document(); + $users = $this->loadXML($xml, "users"); + $this->assertEquals("20", $users->user[0]->age[0]->getValue()); + } + + public function testSetAttribute() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $users->user[0]->setAttribute("id", 1); + $users->user[1]->setAttribute("id", 2); + $users->user[2]->setAttribute("id", 3); + $this->saveXML($xml, "users"); + + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $this->assertEquals("1", $users->user[0]->getAttribute("id")); + $this->assertEquals("2", $users->user[1]->getAttribute("id")); + $this->assertEquals("3", $users->user[2]->getAttribute("id")); + + $this->assertEquals("1", $users->user[0]->at("id")); + $this->assertEquals("2", $users->user[1]->at("id")); + $this->assertEquals("3", $users->user[2]->at("id")); + } + + public function testInsertBefore() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $this->assertEquals("tanaka", $users->user[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $users->user[1]->name[0]->getValue()); + $this->assertEquals("satou", $users->user[2]->name[0]->getValue()); + + $aUser = $xml->createElement("user"); + $aUser->addChild("name", "yamada"); + $aUser->addChild("age", "60"); + + $users->user[2]->insertPreviousSibling($aUser); + $this->saveXML($xml, "users"); + + //------------------------------------- + + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $this->assertEquals("tanaka", $users->user[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $users->user[1]->name[0]->getValue()); + $this->assertEquals("yamada", $users->user[2]->name[0]->getValue()); + $this->assertEquals("satou", $users->user[3]->name[0]->getValue()); + } + + public function testInsertAfter() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $xml->createElement("user"); + $aUser->addChild("name", "koike"); + $aUser->addChild("age", "80"); + + $users->user[3]->insertNextSibling($aUser); + $this->saveXML($xml, "users"); + + //------------------------------------- + + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $this->assertEquals("tanaka", $users->user[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $users->user[1]->name[0]->getValue()); + $this->assertEquals("yamada", $users->user[2]->name[0]->getValue()); + $this->assertEquals("satou", $users->user[3]->name[0]->getValue()); + $this->assertEquals("koike", $users->user[4]->name[0]->getValue()); + } + + public function testGetParent() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $age = $users->user[0]->age[0]; + $this->assertEquals("age", $age->tagName); + $this->assertEquals("user", $age->getParent()->tagName); + $this->assertEquals("users", $age->getParent("users")->tagName); + } + + public function testGetFirstChild() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $users->user[0]; + $this->assertEquals("name", $aUser->getFirstChild()->tagName); + } + + public function testGetLastChild() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $users->getLastChild(); + $this->assertEquals("user", $aUser->tagName); + $this->assertEquals("age", $aUser->getLastChild()->tagName); + $this->assertEquals("80", $aUser->getLastChild()->getValue()); + } + + public function testGetNextSibling() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $users->getFirstChild(); + $this->assertEquals("tanaka", $aUser->name[0]->getValue()); + $aUser = $aUser->getNextSibling(); + $this->assertEquals("suzuki", $aUser->name[0]->getValue()); + $aUser = $aUser->getNextSibling(); + $this->assertEquals("yamada", $aUser->name[0]->getValue()); + $aUser = $aUser->getNextSibling(); + $this->assertEquals("satou", $aUser->name[0]->getValue()); + $aUser = $aUser->getNextSibling(); + $this->assertEquals("koike", $aUser->name[0]->getValue()); + $aUser = $aUser->getNextSibling(); + $this->assertEquals(null, $aUser); + } + + public function testGetNextSiblings() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $elems = $users->user[2]->getNextSiblings(); + $this->assertEquals(2, $elems->length); + $this->assertEquals("satou", $elems[0]->name[0]->getValue()); + $this->assertEquals("koike", $elems[1]->name[0]->getValue()); + } + + public function testGetPreviousSibling() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $users->getLastChild(); + $this->assertEquals("koike", $aUser->name[0]->getValue()); + $aUser = $aUser->getPreviousSibling(); + $this->assertEquals("satou", $aUser->name[0]->getValue()); + $aUser = $aUser->getPreviousSibling(); + $this->assertEquals("yamada", $aUser->name[0]->getValue()); + $aUser = $aUser->getPreviousSibling(); + $this->assertEquals("suzuki", $aUser->name[0]->getValue()); + $aUser = $aUser->getPreviousSibling(); + + $this->assertEquals("tanaka", $aUser->name[0]->getValue()); + $aUser = $aUser->getPreviousSibling(); + $this->assertEquals(null, $aUser); + } + + public function testGetPreviousSiblings() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $elems = $users->user[2]->getPreviousSiblings(); + $this->assertEquals(2, $elems->length); + $this->assertEquals("suzuki", $elems[0]->name[0]->getValue()); + $this->assertEquals("tanaka", $elems[1]->name[0]->getValue()); + + $elems->reverse(); + + $this->assertEquals("tanaka", $elems[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $elems[1]->name[0]->getValue()); + } + + public function testGetSiblings() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $elems = $users->user[2]->getSiblings(); + $this->assertEquals(4, $elems->length); + $this->assertEquals("tanaka", $elems[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $elems[1]->name[0]->getValue()); + $this->assertEquals("satou", $elems[2]->name[0]->getValue()); + $this->assertEquals("koike", $elems[3]->name[0]->getValue()); + } + + public function testFindFromAttribute() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user where @id = 1"); + $this->assertEquals(1, $elems->length); + + $elem = $elems[0]; + $this->assertEquals("1", $elem->at("id")); + $this->assertEquals("tanaka", $elem->profile[0]->name[0]->getValue()); + + $elems = $users->select("from user.foo.bar where @type = 'b'"); + $this->assertEquals(1, $elems->length); + + $elem = $elems[0]->getParent("user"); + $this->assertEquals("2", $elem->at("id")); + $this->assertEquals("suzuki", $elem->profile[0]->name[0]->getValue()); + + // not equals + $elems = $users->select("from user where not @id = 1"); + $this->assertEquals(4, $elems->length); + } + + public function testSelectByIsNull() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user.foo.bar where @type IS NULL"); + $this->assertEquals(1, $elems->length); + + $elem = $elems[0]->getParent("user"); + $this->assertEquals("5", $elem->at("id")); + $this->assertEquals("koike", $elem->profile[0]->name[0]->getValue()); + + $elems = $users->select("from user.foo.bar where @type IS NOT NULL"); + $this->assertEquals(4, $elems->length); + + $elems = $users->select("from user where test IS NULL"); + $this->assertEquals(3, $elems->length); + + $elems = $users->select("from user where test IS NOT NULL"); + $this->assertEquals(2, $elems->length); + } + + public function testReturnElement() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user.foo.bar where @type = 'b'"); + $this->assertEquals("bar", $elems[0]->tagName); + + $elems = $users->select("from user.foo.bar where @type IS NULL"); + $this->assertEquals("bar", $elems[0]->tagName); + + $elems = $users->select("from user.foo.bar where @type IS NOT NULL"); + $this->assertEquals("bar", $elems[0]->tagName); + + //------------------------------------------- + + $elems = $users->select("from user where foo.bar@type = 'b'"); + $this->assertEquals("user", $elems[0]->tagName); + + $elems = $users->select("from user where foo.bar@type IS NULL"); + $this->assertEquals("user", $elems[0]->tagName); + + $elems = $users->select("from user where foo.bar@type IS NOT NULL"); + $this->assertEquals("user", $elems[0]->tagName); + + //------------------------------------------- + + $aUser = $users->user[0]; + $elems = $aUser->select("from . where @id = 2"); + $this->assertEquals("2", $elems[0]->at("id")); + $this->assertEquals("suzuki", $elems[0]->profile[0]->name[0]->getValue()); + + //------------------------------------------- + + $elems = $users->select("from user.foo.bar.baz where value() = 'test456'"); + $this->assertEquals("baz", $elems[0]->tagName); + $this->assertEquals("test456", $elems[0]->getValue()); + $this->assertEquals("2", $elems[0]->getParent("user")->at("id")); + } + + public function testLike() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user where foo.bar.baz like 'test%'"); + $this->assertEquals(2, $elems->length); + $this->assertEquals("tanaka", $elems[0]->profile[0]->name[0]->getValue()); + $this->assertEquals("suzuki", $elems[1]->profile[0]->name[0]->getValue()); + + $elems = $users->select("from user where foo.bar.baz like '%456%'"); + $this->assertEquals(3, $elems->length); + $this->assertEquals("suzuki", $elems[0]->profile[0]->name[0]->getValue()); + $this->assertEquals("satou", $elems[1]->profile[0]->name[0]->getValue()); + $this->assertEquals("koike", $elems[2]->profile[0]->name[0]->getValue()); + + //------------------------------------------------------- + + $elems = $users->select("from user where not foo.bar.baz like 'test%'"); + $this->assertEquals(3, $elems->length); + $this->assertEquals("yamada", $elems[0]->profile[0]->name[0]->getValue()); + $this->assertEquals("satou", $elems[1]->profile[0]->name[0]->getValue()); + $this->assertEquals("koike", $elems[2]->profile[0]->name[0]->getValue()); + + $elems = $users->select("from user where not foo.bar.baz like '%456%'"); + $this->assertEquals(2, $elems->length); + $this->assertEquals("tanaka", $elems[0]->profile[0]->name[0]->getValue()); + $this->assertEquals("yamada", $elems[1]->profile[0]->name[0]->getValue()); + } + + public function testAnd() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user where foo.bar.baz LIKE '%456%' AND test IS NOT NULL"); + $this->assertEquals(1, $elems->length); + $this->assertEquals("koike", $elems[0]->profile[0]->name[0]->getValue()); + } + + public function testOr() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "find"); + + $elems = $users->select("from user where profile.age >= 60 OR profile.age <= 20"); + $this->assertEquals(3, $elems->length); + $this->assertEquals("tanaka", $elems[0]->profile[0]->name[0]->getValue()); + $this->assertEquals("1", $elems[0]->at("id")); + $this->assertEquals("yamada", $elems[1]->profile[0]->name[0]->getValue()); + $this->assertEquals("3", $elems[1]->at("id")); + $this->assertEquals("koike", $elems[2]->profile[0]->name[0]->getValue()); + $this->assertEquals("5", $elems[2]->at("id")); + } + + public function testSwap() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $tanaka = $users->user[0]; + $satou = $users->user[3]; + $this->assertEquals("tanaka", $tanaka->name[0]->getValue()); + $this->assertEquals("satou", $satou->name[0]->getValue()); + + $tanaka->swap($satou); + + $tanaka = $users->user[3]; + $satou = $users->user[0]; + $this->assertEquals("tanaka", $tanaka->name[0]->getValue()); + $this->assertEquals("satou", $satou->name[0]->getValue()); + + $suzuki = $users->user[1]; + $koike = $users->user[4]; + $this->assertEquals("suzuki", $suzuki->name[0]->getValue()); + $this->assertEquals("koike", $koike->name[0]->getValue()); + + $koike->swap($suzuki); + + $suzuki = $users->user[4]; + $koike = $users->user[1]; + $this->assertEquals("suzuki", $suzuki->name[0]->getValue()); + $this->assertEquals("koike", $koike->name[0]->getValue()); + + $koike = $users->user[1]; + $yamada = $users->user[2]; + $this->assertEquals("koike", $koike->name[0]->getValue()); + $this->assertEquals("yamada", $yamada->name[0]->getValue()); + + $koike->swap($yamada); + + $koike = $users->user[2]; + $yamada = $users->user[1]; + $this->assertEquals("koike", $koike->name[0]->getValue()); + $this->assertEquals("yamada", $yamada->name[0]->getValue()); + } + + public function testRemoveElement() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $this->assertEquals(5, $users->user->length); + + $deleted = $users->user[2]->remove(); + $this->assertEquals("yamada", $deleted->name[0]->getValue()); + $this->assertEquals(4, $users->user->length); + + $deleted = $users->user[2]->remove(); + $this->assertEquals("satou", $deleted->name[0]->getValue()); + $this->assertEquals(3, $users->user->length); + + $this->saveXML($xml, "users"); + } + + public function testDelete() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + + $aUser = $users->user[1]; + $this->assertEquals(1, $aUser->age->length); + $this->assertEquals("25", $aUser->age[0]->getValue()); + + $users->delete("from user.age where value() = 25"); + + $this->assertEquals(0, $aUser->age->length); + + //------------------------------------------------- + + $this->assertEquals(3, $users->user->length); + + $users->delete("from user where age = 18"); + + $this->assertEquals(2, $users->user->length); + + $this->saveXML($xml, "users"); + } + + public function testCDATA() + { + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $aUser = $users->getFirstChild(); + $aUser->name[0]->setValue(null); + + $cdata = $xml->createCDATA(""); + $aUser->name[0]->appendChild($cdata); + $this->saveXML($xml, "users"); + + //-------------------------------------------- + + $xml = Sabel_Xml_Document::create(); + $users = $this->loadXML($xml, "users"); + $aUser = $users->getFirstChild(); + $this->assertEquals("", $aUser->name[0]->getValue()); + } + + public function testNamespace() + { + $xml = Sabel_Xml_Document::create(); + $nodes = $this->loadXML($xml, "ns"); + + $this->assertEquals("defitem4 value", $nodes->defitem3[0]->defitem4[0]->getValue()); + + $foo = $nodes->getChild("foo:foo"); + $this->assertEquals("fooitem2 value", $foo->fooitem1[0]->fooitem2[0]->getValue()); + + $defitem = $foo->getChild("defitem", "http://www.example.com/default"); + $this->assertEquals("defitem2 value", $defitem->defitem2[0]->getValue()); + + $baz = $foo->getChild("baz", "http://www.example.com/baz"); + $this->assertEquals("bazitem3 value", $baz->bazitem1[0]->bazitem2[0]->bazitem3[0]->getValue()); + } + + public function testGetAllChildren() + { + $xml = Sabel_Xml_Document::create(); + $nodes = $this->loadXML($xml, "ns"); + $foo = $nodes->getChild("foo:foo"); + + $children = $foo->getChildren(); + $this->assertEquals(4, $children->length); + $this->assertEquals("foo:fooitem1", $children->item(0)->tagName); + $this->assertEquals("defitem", $children->item(1)->tagName); + $this->assertEquals("bar:baritem1", $children->item(2)->tagName); + $this->assertEquals("baz", $children->item(3)->tagName); + } + + protected function getXmlAsString($name) + { + return file_get_contents(XML_TEST_DIR . DS . "xml" . DS . $name . ".xml"); + } + + protected function loadXML(Sabel_Xml_Document $xml, $name) + { + return $xml->loadXML(file_get_contents(XML_TEST_DIR . DS . "xml" . DS . $name . ".xml")); + } + + protected function saveXML(Sabel_Xml_Document $xml, $name = "_tmp") + { + return $xml->saveXML(XML_TEST_DIR . DS . "xml" . DS . $name . ".xml"); + } + + protected function outputUsersXml() + { + $xml = << + + + tanaka + 18 + + + suzuki + 25 + + + satou + 40 + + +XML; + + file_put_contents(XML_TEST_DIR . DS . "xml" . DS . "users.xml", $xml); + } +} diff --git a/Test/XML/Tests.php b/Test/XML/Tests.php new file mode 100755 index 0000000..7f6087b --- /dev/null +++ b/Test/XML/Tests.php @@ -0,0 +1,18 @@ +addTest(Test_XML_Element::suite()); + //$suite->addTest(Test_XML_Elements::suite()); + $suite->addTest(Test_XML_Test::suite()); + + return $suite; + } +} diff --git a/Test/XML/xml/find.xml b/Test/XML/xml/find.xml new file mode 100755 index 0000000..3129c50 --- /dev/null +++ b/Test/XML/xml/find.xml @@ -0,0 +1,60 @@ + + + + + tanaka + 18 + + + + test123 + + + + + + + suzuki + 25 + + + + test456 + + + + + + yamada + 60 + + + + 123test + + + + + + satou + 40 + + + + 456test + + + + + + koike + 80 + + + + 123456 + + + + + diff --git a/Test/XML/xml/ns.xml b/Test/XML/xml/ns.xml new file mode 100755 index 0000000..fd53803 --- /dev/null +++ b/Test/XML/xml/ns.xml @@ -0,0 +1,26 @@ + + + + + fooitem2 value + + + defitem2 value + + + baritem2 value + + + + + bazitem3 value + + + + + + defitem4 value + + diff --git a/Test/XML/xml/simple.xml b/Test/XML/xml/simple.xml new file mode 100755 index 0000000..23cbbdb --- /dev/null +++ b/Test/XML/xml/simple.xml @@ -0,0 +1,12 @@ + + + + footext + + + bartext + + + baztext + + diff --git a/Test/XML/xml/test.xml b/Test/XML/xml/test.xml new file mode 100755 index 0000000..81ea78d --- /dev/null +++ b/Test/XML/xml/test.xml @@ -0,0 +1,7 @@ + + + test + + hoge + + diff --git a/Test/XML/xml/users.xml b/Test/XML/xml/users.xml new file mode 100755 index 0000000..264f17b --- /dev/null +++ b/Test/XML/xml/users.xml @@ -0,0 +1,10 @@ + + + + ]]> + + + koike + 80 + + diff --git a/Test/data/application/app/helpers/Date.php b/Test/data/application/app/helpers/Date.php new file mode 100755 index 0000000..148972c --- /dev/null +++ b/Test/data/application/app/helpers/Date.php @@ -0,0 +1,387 @@ + + * @copyright 2002-2006 Ebine Yutaka + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Helpers_Date +{ + const NORMAL = 0; + const ATOM = 1; + const RSS = 2; + const COOKIE = 3; + const ISO = 4; + const RFC822 = 5; + const RFC850 = 6; + const RFC1036 = 7; + const RFC1123 = 8; + const RFC2822 = 9; + const RFC = 10; + const W3C = 11; + + private static $formats = array(self::NORMAL => array( + "all" => "Y-m-d H:i:s", + "date" => "Y-m-d", + "time" => "H:i:s"), + + self::ATOM => array( + "all" => "c", + "date" => "Y-m-d", + "time" => "H:i:sP"), + + self::RSS => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::COOKIE => array( + "all" => "l, d-M-y H:i:s T", + "date" => "l, d-M-y", + "time" => "H:i:s T"), + + self::ISO => array( + "all" => "Y-m-d\TH:i:sO", + "date" => "Y-m-d", + "time" => "H:i:sO"), + + self::RFC822 => array( + "all" => "D, d M y H:i:s O", + "date" => "D, d M y", + "time" => "H:i:s O"), + + self::RFC850 => array( + "all" => "l, d-M-y H:i:s T", + "date" => "l, d-M-y", + "time" => "H:i:s T"), + + self::RFC1036 => array( + "all" => "D, d M y H:i:s O", + "date" => "D, d M y", + "time" => "H:i:s O"), + + self::RFC1123 => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::RFC2822 => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::RFC => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::W3C => array( + "all" => "c", + "date" => "Y-m-d", + "time" => "H:i:sP")); + + protected + $timestamp = null, + $format = self::NORMAL; + + public static function format($date, $format) + { + return date(self::$formats[$format]["all"], strtotime($date)); + } + + public function __construct($arg = null) + { + if ($arg === null) { + $this->timestamp = time(); + } elseif (is_string($arg)) { + $this->timestamp = strtotime($arg); + } elseif (is_array($arg)) { + $y = (isset($arg["y"])) ? $arg["y"] : date("Y"); + $m = (isset($arg["m"])) ? $arg["m"] : date("m"); + $d = (isset($arg["d"])) ? $arg["d"] : 1; + $h = (isset($arg["h"])) ? $arg["h"] : 0; + $i = (isset($arg["i"])) ? $arg["i"] : 0; + $s = (isset($arg["s"])) ? $arg["s"] : 0; + + $this->timestamp = mktime($h, $i, $s, $m, $d, $y); + } else { + throw new Exception("Helpers_Date::__construct() invalid parameter."); + } + } + + public function __toString() + { + return $this->getDateTime(); + } + + public function setFormat($format) + { + $this->format = $format; + + return $this; + } + + public function getDatetime() + { + return date(self::$formats[$this->format]["all"], $this->timestamp); + } + + public function getDate() + { + return date(self::$formats[$this->format]["date"], $this->timestamp); + } + + public function getTime() + { + return date(self::$formats[$this->format]["time"], $this->timestamp); + } + + public function getYear($twoDigits = false) + { + if ($twoDigits) { + return date("y", $this->timestamp); + } else { + return date("Y", $this->timestamp); + } + } + + public function getMonth($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("m", $this->timestamp); + } else { + return date("n", $this->timestamp); + } + } + + public function getTextualMonth($short = true) + { + if ($short) { + return date("M", $this->timestamp); + } else { + return date("F", $this->timestamp); + } + } + + public function getDay($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("d", $this->timestamp); + } else { + return date("j", $this->timestamp); + } + } + + public function getLastDay() + { + $timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth() + 1, + 0, + $this->getYear()); + + return date("d", $timestamp); + } + + public function getHour($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("H", $this->timestamp); + } else { + return date("G", $this->timestamp); + } + } + + public function getHourBy12Format($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("h", $this->timestamp); + } else { + return date("g", $this->timestamp); + } + } + + public function getMinute() + { + return date("i", $this->timestamp); + } + + public function getSecond() + { + return date("s", $this->timestamp); + } + + public function getMeridiem($lower = true) + { + return date(($lower) ? "a" : "A", $this->timestamp); + } + + public function getTextualWeek($short = true) + { + if ($short) { + return date("D", $this->timestamp); + } else { + return date("l", $this->timestamp); + } + } + + public function getWeekNumber() + { + return date("w", $this->timestamp); + } + + public function ymd($sep = "-") + { + return $this->getYear() . $sep . $this->getMonth() . $sep . $this->getDay(); + } + + public function his($sep = ":") + { + return $this->getHour() . $sep . $this->getMinute() . $sep . $this->getSecond(); + } + + public function incYear($year = 1) + { + $year = $this->getYear() + $year; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth(), + $this->getDay(), + $year); + + return $year; + } + + public function decYear($year = 1) + { + $year = $this->getYear() - $year; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth(), + $this->getDay(), + $year); + + return $year; + } + + public function incMonth($month = 1) + { + $month = $this->getMonth() + $month; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $month, + $this->getDay(), + $this->getYear()); + + return $month; + } + + public function decMonth($month = 1) + { + $month = $this->getMonth() - $month; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $month, + $this->getDay(), + $this->getYear()); + + return $month; + } + + public function incDay($day = 1) + { + $this->timestamp += 86400 * $day; + + return $this->getDay(); + } + + public function decDay($day = 1) + { + $this->timestamp -= 86400 * $day; + + return $this->getDay(); + } + + public function incHour($hour = 1) + { + $this->timestamp += 3600 * $hour; + + return $this->getHour(); + } + + public function decHour($hour = 1) + { + $this->timestamp -= 3600 * $hour; + + return $this->getHour(); + } + + public function incMinute($min = 1) + { + $this->timestamp += 60 * $min; + + return $this->getMinute(); + } + + public function decMinute($min = 1) + { + $this->timestamp -= 60 * $min; + + return $this->getMinute(); + } + + public function incSecond($second = 1) + { + $this->timestamp += $second; + + return $this->getSecond(); + } + + public function decSecond($second = 1) + { + $this->timestamp -= $second; + + return $this->getSecond(); + } + + public function y() + { + return $this->getYear(); + } + + public function m() + { + return $this->getMonth(); + } + + public function d() + { + return $this->getDay(); + } + + public function h() + { + return $this->getHour(); + } + + public function i() + { + return $this->getMinute(); + } + + public function s() + { + return $this->getSecond(); + } +} diff --git a/Test/data/application/app/helpers/application.php b/Test/data/application/app/helpers/application.php new file mode 100755 index 0000000..7f465ea --- /dev/null +++ b/Test/data/application/app/helpers/application.php @@ -0,0 +1,49 @@ +%s', uri($uri), $anchor); + } else { + return sprintf('%s', uri($uri), $uriQuery, $anchor); + } +} + +function ah($param, $anchor, $uriQuery = "") +{ + return a($param, h($anchor), $uriQuery); +} + +function linkto($file) +{ + if ($bus = Sabel_Context::getContext()->getBus()) { + if ($bus->get("NO_VIRTUAL_HOST")) { + return dirname($_SERVER["SCRIPT_NAME"]) . "/" . $file; + } + } + + return "/" . $file; +} + +function h($string, $charset = null) +{ + return htmlescape($string, $charset); +} + +function mb_trim($string) +{ + $string = new Sabel_Util_String($string); + return $string->trim()->toString(); +} + +function to_date($date, $format) +{ + return Helpers_Date::format($date, constant("Helpers_Date::" . $format)); +} + +function __include($uri, $values = array(), $method = Sabel_Request::GET, $withLayout = false) +{ + $requester = new Sabel_Request_Internal($method); + $requester->values($values)->withLayout($withLayout); + return $requester->request($uri)->getResult(); +} diff --git a/Test/data/application/app/index/controllers/Index.php b/Test/data/application/app/index/controllers/Index.php new file mode 100755 index 0000000..60cc116 --- /dev/null +++ b/Test/data/application/app/index/controllers/Index.php @@ -0,0 +1,15 @@ +hoge = "10"; + $this->response->setResponse("fuga", "20"); + } + + public function hoge() + { + $this->name = "yamada"; + } +} diff --git a/Test/data/application/app/index/controllers/Main.php b/Test/data/application/app/index/controllers/Main.php new file mode 100755 index 0000000..2950314 --- /dev/null +++ b/Test/data/application/app/index/controllers/Main.php @@ -0,0 +1,24 @@ +values(array("pv" => "foo")); + $internal->method(Sabel_Request::POST); + $internal->request("main/bar", new AppBusConfig()); + $response = $internal->getResponse(); + $this->bar = $response->getResponse("bar"); + } + + public function bar() + { + $foo = $this->request->fetchPostValue("pv"); + $this->bar = $foo . " bar"; + } +} diff --git a/Test/data/application/app/index/views/error.tpl b/Test/data/application/app/index/views/error.tpl new file mode 100755 index 0000000..e69de29 diff --git a/Test/data/application/app/index/views/fuga/fuga.tpl b/Test/data/application/app/index/views/fuga/fuga.tpl new file mode 100755 index 0000000..9bfae89 --- /dev/null +++ b/Test/data/application/app/index/views/fuga/fuga.tpl @@ -0,0 +1 @@ +fuga/fuga.tpl diff --git a/Test/data/application/app/index/views/fuga/index.tpl b/Test/data/application/app/index/views/fuga/index.tpl new file mode 100755 index 0000000..ee5052c --- /dev/null +++ b/Test/data/application/app/index/views/fuga/index.tpl @@ -0,0 +1 @@ +fuga/index.tpl diff --git a/Test/data/application/app/index/views/hoge/hoge.tpl b/Test/data/application/app/index/views/hoge/hoge.tpl new file mode 100755 index 0000000..a575ef9 --- /dev/null +++ b/Test/data/application/app/index/views/hoge/hoge.tpl @@ -0,0 +1 @@ +hoge/hoge.tpl diff --git a/Test/data/application/app/index/views/hoge/index.tpl b/Test/data/application/app/index/views/hoge/index.tpl new file mode 100755 index 0000000..4caf5ff --- /dev/null +++ b/Test/data/application/app/index/views/hoge/index.tpl @@ -0,0 +1 @@ +hoge/index.tpl diff --git a/Test/data/application/app/index/views/index/hoge.tpl b/Test/data/application/app/index/views/index/hoge.tpl new file mode 100755 index 0000000..557755a --- /dev/null +++ b/Test/data/application/app/index/views/index/hoge.tpl @@ -0,0 +1 @@ +

diff --git a/Test/data/application/app/index/views/layout.tpl b/Test/data/application/app/index/views/layout.tpl new file mode 100755 index 0000000..675306d --- /dev/null +++ b/Test/data/application/app/index/views/layout.tpl @@ -0,0 +1,5 @@ + + + + + diff --git a/Test/data/application/app/manage/controllers/Index.php b/Test/data/application/app/manage/controllers/Index.php new file mode 100755 index 0000000..2620e37 --- /dev/null +++ b/Test/data/application/app/manage/controllers/Index.php @@ -0,0 +1,21 @@ +request->fetchParameterValue("param1"); + + if (is_numeric($param1)) { + $this->param1 = $param1; + $this->param2 = $this->request->fetchParameterValue("param2"); + } else { + $this->redirect->to("c: login, a: prepare"); + } + } + + public function refuse() + { + throw new Exception(""); + } +} diff --git a/Test/data/application/app/manage/controllers/Login.php b/Test/data/application/app/manage/controllers/Login.php new file mode 100755 index 0000000..7281ace --- /dev/null +++ b/Test/data/application/app/manage/controllers/Login.php @@ -0,0 +1,8 @@ +param1:

+

param2:

diff --git a/Test/data/application/app/manage/views/layout.tpl b/Test/data/application/app/manage/views/layout.tpl new file mode 100755 index 0000000..9fd6ea3 --- /dev/null +++ b/Test/data/application/app/manage/views/layout.tpl @@ -0,0 +1,6 @@ + + +

manage

+ + + diff --git a/Test/data/application/app/views/serverError.tpl b/Test/data/application/app/views/serverError.tpl new file mode 100755 index 0000000..e69de29 diff --git a/Test/data/application/app/views/test.tpl b/Test/data/application/app/views/test.tpl new file mode 100755 index 0000000..d4bc4b2 --- /dev/null +++ b/Test/data/application/app/views/test.tpl @@ -0,0 +1,2 @@ +a:
+b: diff --git a/Test/data/application/data/executable.txt b/Test/data/application/data/executable.txt new file mode 100755 index 0000000..e69de29 diff --git a/Test/data/application/data/readable.txt b/Test/data/application/data/readable.txt new file mode 100755 index 0000000..e69de29 diff --git a/Test/data/application/data/writable.txt b/Test/data/application/data/writable.txt new file mode 100755 index 0000000..e69de29 diff --git a/Test/data/application/lib/Paginate.php b/Test/data/application/lib/Paginate.php new file mode 100755 index 0000000..7a0598e --- /dev/null +++ b/Test/data/application/lib/Paginate.php @@ -0,0 +1,136 @@ + + * @copyright 2002-2006 Ebine Yutaka + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Paginate extends Sabel_Object +{ + protected + $model = null, + $isJoin = false, + $attributes = array(), + $method = "select", + $parameters = array(); + + public function __construct($model) + { + if (is_string($model)) { + $model = MODEL($model); + } + + if (is_model($model)) { + $model->autoReinit(false); + $this->method = "select"; + } elseif ($model instanceof Sabel_Db_Join) { + $model->getModel()->autoReinit(false); + $this->method = "join"; + $this->isJoin = true; + } else { + throw new Exception("Paginate::__construct() invalid instance."); + } + + $this->model = $model; + } + + public function __get($key) + { + if (isset($this->attributes[$key])) { + return $this->attributes[$key]; + } else { + return null; + } + } + + public function getQueryString($page) + { + unset($this->parameters["page"]); + $queryString = array("page={$page}"); + + foreach ($this->parameters as $key => $val) { + $queryString[] = "{$key}={$val}"; + } + + return "?" . implode("&", $queryString); + } + + public function setCondition($arg1, $arg2 = null) + { + $this->model->setCondition($arg1, $arg2); + + return $this; + } + + public function setOrderBy($orderBy) + { + $this->model->setOrderBy($orderBy); + + return $this; + } + + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + } + + public function addParameter($key, $val) + { + $this->parameters[$key] = $val; + } + + public function setMethod($method) + { + $this->method = $method; + + return $this; + } + + public function build($limit, $page) + { + if (!is_numeric($page) || $page < 1) { + $page = 1; + } + + $model = $this->model; + $attributes =& $this->attributes; + + if ($this->isJoin) { + $count = $model->getCount(null, false); + } else { + $count = $model->getCount(); + } + + $attributes["count"] = $count; + $attributes["limit"] = $limit; + $attributes["page"] = $page; + + $pager = Sabel_View_Pager::create($count, $limit); + $pager->setPageNumber($page); + $attributes["viewer"] = new Sabel_View_PageViewer($pager); + + if ($count === 0) { + $attributes["offset"] = 0; + $attributes["results"] = array(); + } else { + $offset = $pager->getSqlOffset(); + + if ($this->isJoin) { + $model->getModel()->setLimit($limit); + $model->getModel()->setOffset($offset); + } else { + $model->setLimit($limit); + $model->setOffset($offset); + } + + $attributes["offset"] = $offset; + $attributes["results"] = $model->{$this->method}(); + } + + return $this; + } +} diff --git a/Test/data/application/lib/db/Model.php b/Test/data/application/lib/db/Model.php new file mode 100755 index 0000000..ea0d88d --- /dev/null +++ b/Test/data/application/lib/db/Model.php @@ -0,0 +1,6 @@ + "validateEmailAddress", + "model" => "MODEL_NAME", + "column" => "COLUMN_NAME"); + +$passwdValidator = array("function" => "validatePasswords", + "model" => "MODEL_NAME", + "column" => "COLUMN_NAME", + "arguments" => "REINPUT"); +*/ + +// Sabel_Db_Validate_Config::addValidator($emailValidator); +// Sabel_Db_Validate_Config::addValidator($passwdValidator); + +function checkEmailAddress($email) +{ + $regex = '/^[\w.\-_]+@([\w\-_]+\.)+[a-zA-Z]+$/'; + return (preg_match($regex, $email) !== 0); +} + +function validateEmailAddress($model, $name, $localizedName) +{ + if ($model->$name !== null && !checkEmailAddress($model->$name)) { + return "invalid mail address format."; + } +} + +function validatePasswords($model, $name, $localizedName, $reInput) +{ + if ($model->$name !== $model->$reInput) { + return "passwords didn't match."; + } else { + $model->unsetValue($reInput); + } +} diff --git a/Test/data/application/lib/processor/Addon.php b/Test/data/application/lib/processor/Addon.php new file mode 100755 index 0000000..3182323 --- /dev/null +++ b/Test/data/application/lib/processor/Addon.php @@ -0,0 +1,16 @@ +getConfig("addon"); + $addons = $config->configure(); + + foreach ($addons as $addon) { + $className = ucfirst($addon) . "_Addon"; + $instance = new $className(); + $instance->execute($bus); + } + } +} diff --git a/Test/data/application/lib/processor/Controller.php b/Test/data/application/lib/processor/Controller.php new file mode 100755 index 0000000..16d4fb4 --- /dev/null +++ b/Test/data/application/lib/processor/Controller.php @@ -0,0 +1,57 @@ +get("destination"); + if (($controller = $this->createController($destination)) === null) { + $controller = $this->createVirtualController(); + } + + if (($response = $bus->get("response")) !== null) { + $controller->setResponse($response); + if ($controller instanceof $this->virtualControllerName) { + $response->getStatus()->setCode(Sabel_Response::NOT_FOUND); + } + } + + if (($request = $bus->get("request")) !== null) { + $controller->setRequest($request); + } + + if (($session = $bus->get("session")) !== null) { + $controller->setSession($session); + } + + $bus->set("controller", $controller); + } + + protected function createController($destination) + { + list ($module, $controller,) = $destination->toArray(); + $class = ucfirst($module) . "_Controllers_" . ucfirst($controller); + + if (Sabel::using($class)) { + l("create controller '{$class}'"); + return new $class(); + } else { + l("controller '{$class}' not found", SBL_LOG_WARN); + return null; + } + } + + protected function createVirtualController() + { + $className = $this->virtualControllerName; + if (!class_exists($className, false)) { + eval ("class $className extends Sabel_Controller_Page {}"); + } + + l("create virtual controller '{$className}'"); + + return new $className(); + } +} diff --git a/Test/data/application/lib/processor/Executer.php b/Test/data/application/lib/processor/Executer.php new file mode 100755 index 0000000..1ec30c2 --- /dev/null +++ b/Test/data/application/lib/processor/Executer.php @@ -0,0 +1,32 @@ +get("response"); + $controller = $bus->get("controller"); + + if ($response->isFailure() || $response->isRedirected()) return; + + $action = $bus->get("destination")->getAction(); + $controller->setAction($action); + + try { + $controller->initialize(); + + if ($response->isSuccess() && !$response->isRedirected()) { + $controller->execute(); + } + + $controller->finalize(); + } catch (Exception $e) { + $response->getStatus()->setCode(Sabel_Response::INTERNAL_SERVER_ERROR); + Sabel_Context::getContext()->setException($e); + } + + if ($controller->getAttribute("layout") === false) { + $bus->set("NO_LAYOUT", true); + } + } +} diff --git a/Test/data/application/lib/processor/Helper.php b/Test/data/application/lib/processor/Helper.php new file mode 100755 index 0000000..b442802 --- /dev/null +++ b/Test/data/application/lib/processor/Helper.php @@ -0,0 +1,25 @@ +get("destination"); + $moduleName = $destination->getModule(); + $controllerName = $destination->getController(); + + $sharedHelper = "application"; + $commonHelpers = MODULES_DIR_PATH . DS . HELPERS_DIR_NAME; + $moduleHelpers = MODULES_DIR_PATH . DS . $moduleName . DS . HELPERS_DIR_NAME; + + $helpers = array(); + + $helpers[] = $commonHelpers . DS . $sharedHelper; + $helpers[] = $moduleHelpers . DS . $sharedHelper; + $helpers[] = $moduleHelpers . DS . $controllerName; + + foreach ($helpers as $helper) { + Sabel::fileUsing($helper . ".php", true); + } + } +} diff --git a/Test/data/application/lib/processor/Initializer.php b/Test/data/application/lib/processor/Initializer.php new file mode 100755 index 0000000..944edad --- /dev/null +++ b/Test/data/application/lib/processor/Initializer.php @@ -0,0 +1,41 @@ +getConfig("database")); + //Sabel::fileUsing(RUN_BASE . DS . LIB_DIR_NAME . DS . "db" . DS . "utility.php", true); + + if (!defined("SBL_BATCH")) { + // start session. + $session = $bus->get("session"); + $session->start(); + l("START SESSION: " . $session->getName() . "=" . $session->getId()); + } + + // default page title. + $bus->get("response")->setResponse("pageTitle", "Sabel"); + + // $request = $bus->get("request"); + // if ($request->isPost()) $this->trim($request); + } + + /** + * strip whitespace from post values. + */ + private function trim($request) + { + $func = (extension_loaded("mbstring")) ? "mb_trim" : "trim"; + + if ($values = $request->fetchPostValues()) { + foreach ($values as &$value) { + if ($value === null || is_array($value)) continue; + $result = $func($value); + $value = ($result === "") ? null : $result; + } + + $request->setPostValues($values); + } + } +} diff --git a/Test/data/application/lib/processor/Request.php b/Test/data/application/lib/processor/Request.php new file mode 100755 index 0000000..0a0fa4f --- /dev/null +++ b/Test/data/application/lib/processor/Request.php @@ -0,0 +1,67 @@ +has("request")) { + $request = $bus->get("request"); + } else { + $uri = $this->getRequestUri($bus); + $request = new Sabel_Request_Object($uri); + + if (SBL_SECURE_MODE) { + $_GET = remove_nullbyte($_GET); + $_POST = remove_nullbyte($_POST); + } + + $request->setGetValues($_GET); + $request->setPostValues($_POST); + + if (isset($_SERVER["REQUEST_METHOD"])) { + $request->method($_SERVER["REQUEST_METHOD"]); + } + + $httpHeaders = array(); + foreach ($_SERVER as $key => $val) { + if (strpos($key, "HTTP") === 0) { + $httpHeaders[$key] = $val; + } + } + + $request->setHttpHeaders($httpHeaders); + $bus->set("request", $request); + } + + l("REQUEST URI: /" . $request->getUri(true)); + + // ajax request. + if ($request->getHttpHeader("X-Requested-With") === "XMLHttpRequest") { + $bus->set("NO_LAYOUT", true); + $bus->set("IS_AJAX_REQUEST", true); + } + } + + protected function getRequestUri($bus) + { + $uri = (isset($_SERVER["REQUEST_URI"])) ? $_SERVER["REQUEST_URI"] : "/"; + + if (isset($_SERVER["SCRIPT_NAME"]) && strpos($_SERVER["SCRIPT_NAME"], "/index.php") >= 1) { + $uri = substr($uri, strlen($_SERVER["SCRIPT_NAME"])); + $bus->set("NO_VIRTUAL_HOST", true); + } + + if (defined("NO_REWRITE_PREFIX") && isset($_GET[NO_REWRITE_PREFIX])) { + $uri = substr($uri, strlen(NO_REWRITE_PREFIX) + 2); + $parsed = parse_url($uri); + if (isset($parsed["query"])) { + parse_str($parsed["query"], $_GET); + } + + unset($_GET[NO_REWRITE_PREFIX]); + $bus->set("NO_REWRITE_MODULE", true); + } + + return normalize_uri($uri); + } +} diff --git a/Test/data/application/lib/processor/Response.php b/Test/data/application/lib/processor/Response.php new file mode 100755 index 0000000..696b172 --- /dev/null +++ b/Test/data/application/lib/processor/Response.php @@ -0,0 +1,75 @@ + "afterAction"); + + public function execute(Sabel_Bus $bus) + { + $bus->set("response", new Sabel_Response_Object()); + } + + public function afterAction($bus) + { + $response = $bus->get("response"); + $response->setResponses(array_merge( + $response->getResponses(), + $bus->get("controller")->getAttributes() + )); + + if ($response->getStatus()->isServerError()) { + $exception = Sabel_Context::getContext()->getException(); + if (!is_object($exception)) return; + + $eol = ((ENVIRONMENT & DEVELOPMENT) > 0) ? "
" : PHP_EOL; + $msg = get_class($exception) . ": " + . $exception->getMessage() . $eol + . "At: " . date("r") . $eol . $eol + . Sabel_Exception_Printer::printTrace($exception, $eol, true); + + if ((ENVIRONMENT & PRODUCTION) > 0) { + + } else { + $response->setResponse("exception_message", $msg); + } + + l(PHP_EOL . str_replace("
", PHP_EOL, $msg), SBL_LOG_ERR); + } + } + + public function shutdown(Sabel_Bus $bus) + { + $response = $bus->get("response"); + $redirector = $response->getRedirector(); + + if ($redirector->isRedirected()) { + if (($url = $redirector->getUrl()) !== "") { + $response->setLocation($url); + } else { + $token = $bus->get("request")->getValueWithMethod("token"); + $hasToken = !empty($token); + $hasParams = $redirector->hasParameters(); + $location = $redirector->getUri(); + + if ($hasToken) { + $glue = ($hasParams) ? "&" : "?"; + $location .= $glue . "token={$token}"; + } + + $session = $bus->get("session"); + if ($session->isStarted() && !$session->isCookieEnabled()) { + $glue = ($hasToken || $hasParams) ? "&" : "?"; + $location .= $glue . $session->getName() . "=" . $session->getId(); + } + + if (function_exists("get_uri_prefix")) { + $location = get_uri_prefix() . "/" . ltrim($location, "/"); + } + + $response->setLocation($location); + } + } + + $response->outputHeader(); + } +} diff --git a/Test/data/application/lib/processor/Router.php b/Test/data/application/lib/processor/Router.php new file mode 100755 index 0000000..dc93785 --- /dev/null +++ b/Test/data/application/lib/processor/Router.php @@ -0,0 +1,22 @@ +get("request"); + $config = $bus->getConfig("map"); + $config->configure(); + + if ($candidate = $config->getValidCandidate($request->getUri())) { + $request->setParameterValues($candidate->getUriParameters()); + $destination = $candidate->getDestination(); + l("DESTINATION: " . $destination); + $bus->set("destination", $destination); + Sabel_Context::getContext()->setCandidate($candidate); + } else { + $message = __METHOD__ . "() didn't match to any routing configuration."; + throw new Sabel_Exception_Runtime($message); + } + } +} diff --git a/Test/data/application/lib/processor/Session.php b/Test/data/application/lib/processor/Session.php new file mode 100755 index 0000000..91ee9ed --- /dev/null +++ b/Test/data/application/lib/processor/Session.php @@ -0,0 +1,20 @@ +has("session")) { + $bus->set("session", Sabel_Session_PHP::create()); + } + } + + public function shutdown(Sabel_Bus $bus) + { + $session = $bus->get("session"); + + if ($session->isStarted() && !$session->isCookieEnabled() && ini_get("session.use_trans_sid") === "0") { + output_add_rewrite_var($session->getName(), $session->getId()); + } + } +} diff --git a/Test/data/application/lib/processor/View.php b/Test/data/application/lib/processor/View.php new file mode 100755 index 0000000..8eba9c2 --- /dev/null +++ b/Test/data/application/lib/processor/View.php @@ -0,0 +1,92 @@ + "initViewObject"); + + /** + * @var Sabel_View + */ + private $view = null; + + public function initViewObject($bus) + { + list ($m, $c, $a) = $bus->get("destination")->toArray(); + + $view = new Sabel_View_Object("controller", new Sabel_View_Location_File( + $m . DS . VIEW_DIR_NAME . DS . $c . DS) + ); + + $view->addLocation("module", new Sabel_View_Location_File($m . DS . VIEW_DIR_NAME . DS)); + $view->addLocation("app", new Sabel_View_Location_File(VIEW_DIR_NAME . DS)); + + if ($renderer = $bus->get("renderer")) { + $view->setRenderer($renderer); + } else { + $view->setRenderer(new Sabel_View_Renderer()); + } + + $this->view = $view; + $bus->set("view", $view); + $bus->get("controller")->setAttribute("view", $view); + } + + public function execute(Sabel_Bus $bus) + { + $response = $bus->get("response"); + if ($response->isRedirected()) return; + + $controller = $bus->get("controller"); + $responses = $response->getResponses(); + $contents = (isset($responses["contents"])) ? $responses["contents"] : ""; + + $view = $this->getView( + $response->getStatus(), + $bus->get("destination")->getAction(), + $bus->get("IS_AJAX_REQUEST") === true + ); + + if ($contents === "") { + if ($location = $view->getValidLocation()) { + $contents = $view->rendering($location, $responses); + } elseif (!$controller->isExecuted()) { + $response->getStatus()->setCode(Sabel_Response::NOT_FOUND); + if ($location = $view->getValidLocation("notFound")) { + $contents = $view->rendering($location, $responses); + } else { + $contents = "

404 Not Found

"; + } + } + } + + if ($bus->get("NO_LAYOUT")) { + $bus->set("result", $contents); + } else { + $layout = (isset($responses["layout"])) ? $responses["layout"] : DEFAULT_LAYOUT_NAME; + if ($location = $view->getValidLocation($layout)) { + $responses["contentForLayout"] = $contents; + $bus->set("result", $view->rendering($location, $responses)); + } else { // no layout. + $bus->set("result", $contents); + } + } + } + + protected function getView($status, $action, $isAjax = false) + { + if ($status->isFailure()) { + $tplName = lcfirst(str_replace(" ", "", $status->getReason())); + if ($location = $this->view->getValidLocation($tplName)) { + $this->view->setName($tplName); + } elseif ($status->isClientError()) { + $this->view->setName("clientError"); + } else { + $this->view->setName("serverError"); + } + } elseif ($this->view->getName() === "") { + $this->view->setName(($isAjax) ? "{$action}.ajax" : $action); + } + + return $this->view; + } +} diff --git a/Test/data/application/lib/schema/example.php b/Test/data/application/lib/schema/example.php new file mode 100755 index 0000000..18c41d8 --- /dev/null +++ b/Test/data/application/lib/schema/example.php @@ -0,0 +1,37 @@ + Sabel_Db_Type::INT, + 'min' => 0, + 'max' => PHP_INT_MAX, + 'increment' => false, + 'nullable' => false, + 'primary' => true, + 'default' => null); + + $cols['column2'] = array('type' => Sabel_Db_Type::STRING, + 'max' => 255, + 'increment' => false, + 'nullable' => false, + 'primary' => false, + 'default' => null); + + return $cols; + } + + public function getProperty() + { + $property = array(); + + $property["tableEngine"] = null; + $property["uniques"] = null; + $property["fkeys"] = null; + + return $property; + } +} diff --git a/Test/data/php.gif b/Test/data/php.gif new file mode 100755 index 0000000..f352c73 Binary files /dev/null and b/Test/data/php.gif differ diff --git a/bin/sabel b/bin/sabel new file mode 100755 index 0000000..7ac913b --- /dev/null +++ b/bin/sabel @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ -z "$SABEL_HOME" ] ; then + SABEL_HOME="/path/to/Sabel" +fi + +if (test -z "$PHP_COMMAND") ; then + export PHP_COMMAND=php +fi + +$PHP_COMMAND -d html_errors=off -qC $SABEL_HOME/generator/generator.php $* diff --git a/bin/sabel.bat b/bin/sabel.bat new file mode 100755 index 0000000..7c7c80c --- /dev/null +++ b/bin/sabel.bat @@ -0,0 +1,23 @@ +@echo off + +if "%OS%"=="Windows_NT" @setlocal + +set SABEL=c:\php\includes\Sabel + +goto init + +:init + +if "%PHP_COMMAND%" == "" goto no_phpcommand + +%PHP_COMMAND% -d html_errors=off -d open_basedir= -q "%SABEL%\generator\generator.php" %1 %2 %3 %4 %5 %6 %7 %8 %9 + +goto cleanup + +:no_phpcommand +set PHP_COMMAND=php +goto init + +:cleanup +if "%OS%"=="Windows_NT" @endlocal +rem pause diff --git a/bin/sakle b/bin/sakle new file mode 100755 index 0000000..c8d2256 --- /dev/null +++ b/bin/sakle @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ -z "$SABEL_HOME" ] ; then + SABEL_HOME="/path/to/Sabel" +fi + +if (test -z "$PHP_COMMAND") ; then + export PHP_COMMAND=php +fi + +$PHP_COMMAND -d html_errors=off -qC $SABEL_HOME/sabel/Sakle.php $* diff --git a/bin/sakle.bat b/bin/sakle.bat new file mode 100755 index 0000000..786c13c --- /dev/null +++ b/bin/sakle.bat @@ -0,0 +1,23 @@ +@echo off + +if "%OS%"=="Windows_NT" @setlocal + +set SABEL=c:\php\includes\Sabel + +goto init + +:init + +if "%PHP_COMMAND%" == "" goto no_phpcommand + +%PHP_COMMAND% -d html_errors=off -d open_basedir= -q "%SABEL%\sabel\Sakle.php" %1 %2 %3 %4 %5 %6 %7 %8 %9 + +goto cleanup + +:no_phpcommand +set PHP_COMMAND=php +goto init + +:cleanup +if "%OS%"=="Windows_NT" @endlocal +rem pause diff --git a/changelog b/changelog new file mode 100755 index 0000000..a69f86c --- /dev/null +++ b/changelog @@ -0,0 +1,169 @@ +2010-07-13 ebin + + * sabel/db/mysql/Metadata.php: MySQL5.1以降用の外部キー取得SQLに誤りがあった + ため修正。(他のスキーマの同名テーブルの外部キー情報も取得してしまう不具合) + +2010-07-13 ebin + + * generator/skeleton/en/lib/form/Object.php: 複数のインプット名によるフォー + ムバリデーションの際、カンマで連結したインプット名をsubmitメソッドに渡さなく + てもいいように変更。 + +2010-05-10 ebin + + * sabel/map/Candidate.php: uriメソッドのバグ修正。 + +2010-05-08 ebin + + * sabel/test/*: test関連のクラスのリファクタリング。モデル(DB)を使用しない + Fixtureに対応。テスト実行時にtestsディレクトリをインクルードパスに追加するよ + うに変更。 + +2010-05-02 ebin + + * sabel/response/Redirector.php: uri()にもパラメータを渡せるように変更。 + flagmentに対応。 + +2010-04-29 ebin + + * generator/skeleton/en/tasks/Install.php: アドオンインストーラ修正。 + Sabel_Xml_AttributesクラスにtoArray()メソッド追加。 + +2010-04-29 ebin + + * generator/skeleton/en/tasks/Install.php: アドオンインストーラ実装。 + +2010-04-28 ebin + + * sabel/db/mysql/Driver.php: mysql_set_charset関数がない環境でも + mysql_set_charsetが実行されて落ちる問題の修正。 + +2010-04-28 ebin + + * sabel/xml/Element.php: insertNextSibling()のバグ修正。 + +2010-04-27 ebin + + * generator/skeleton/en/config/INIT.php : APP_ENCODING定数の追加。それにとも + なう若干の改修。Sabel_Util_String::mbTrim()のバグ修正。 + +2010-04-26 ebin + + * Test/*: テストを全体的に修正。 + +2010-03-12 ebin + + * generator/skeleton/*: フォーム周りを若干更新。 + +2009-12-02 ebin + + * sabel/test/*: 他パッケージの更新に追い付いてない問題の修正。 + +2009-12-02 ebin + + * sabel/http/*: httpパッケージ更新。移植完了。 + +2009-12-01 ebin + + * sabel/http/*: Zend Frameworkから移植(CurlとかProxyとか未完了)。 + +2009-11-30 ebin + + * sabel/kvs/Xml.php: ファイルロック実装。 + +2009-11-27 ebin + + * sabel/session/*: sessionパッケージ改修。 + +2009-11-27 ebin + + * sabel/functions/core.php: get_server_name()関数追加。environment()関数の削 + 除。それに関わる箇所の変更。lib/Cache.php作り直し。 + +2009-11-27 ebin + + * sabel/rss/*: rssパッケージ改修。 + +2009-11-24 ebin + + * sabel/xml/Element.php: Sabel.jsに合わせ、insertPreviousSibling, + insertNextSiblingメソッド実装。insertBefore, insertAfterメソッド改修。 + +2009-11-24 ebin + + * sabel/controller/Page.php: __get()と__set()をpublicに修正。 + * sabel/cache: キャッシュクラス内部でKVSパッケージを使用するように変更。 + +2009-11-24 ebin + + * sabel/db/Model.php: Sabel_Db_ModelにselectForUpdateメソッド追加。 + +2009-11-24 ebin + + * sabel/kvs: KVS(Key-Value-Store)パッケージの追加。 + +2009-11-23 hamaco + + * Sabel.js (Sabel.Widget.Calendar): 色々と改善。 + * Sabel.js (Sabel.Element): insertPreviousSibling, insertNextSiblingメソッド追加。 + +2009-11-23 MoriReo + + * sabel/Container.php: 設定クラスのbind->toにインスタンスを指定可能に変更。 + +2009-11-22 MoriReo + + * sabel/Preference: パッケージを追加。 + +2009-11-21 Ebin + + * lib/Cache.php: lib/cache(キャッシュユーティリティ)を作成。 + +2009-11-19 Ebin + + * sabel/Functions.php: 削除し、sabel/functions/core.phpと + sabel/functions/db.phpに分けた。 + +2009-11-18 Ebin + + * sabel/xml/Document.php: newできないように変更。 + +2009-11-17 Ebin + + * sabel/xml/*: 使い易さの改善。 + +2009-11-14 MoriReo + + * sabel/Container.php: 名前付きでの設定インタフェイスを削除。コードの改善。 + +2009-11-13 Ebin + + * sabel/Bus.php: プロセッサINSERT用のメソッドinsertProcessor追加。 + +2009-11-12 MoriReo + + * sabel/Container.php: Sabel_Containerのload()時に、複数の設定クラスを + 指定できるように変更。 + +2009-11-11 MoriReo + + * sabel/Container.php: Sabel_AspectからStaticProxyを削除。 + +2009-11-10 Ebin + + * sabel/Functions.php: get_mime_type()関数追加。それに応じて + Sabel_Mail_Mime_Html::addImage()のMIMEタイプを省略できるように変更。 + +2009-11-10 Ebin + + * generator/skeleton/en/lib/form/Object.php: toHidden()メソッド追加(フォームの + 値を全てhiddenで書き出す) + +2009-11-09 Ebin + + * sabel/Functions.php: is_ipaddr()関数の正規表現を修正 + +2009-11-09 hamaco + + * Sabel.js (Sabel.Event): getTargetメソッドの返り値をSabel.Elementに変更 + diff --git a/generator/generator.php b/generator/generator.php new file mode 100755 index 0000000..2aa3212 --- /dev/null +++ b/generator/generator.php @@ -0,0 +1,147 @@ + + * @author Ebine Yutaka + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class SabelScaffold +{ + const DEFAULT_LANGUAGE = "en"; + + protected $ignores = array(); + protected $overwrite = array(); + protected $lang = "en"; + + protected $targetDir = ""; + protected $skeletonDir = ""; + protected $basedirNameLength = ""; + + public function __construct($args, $skeletonDir) + { + $this->skeletonDir = $skeletonDir; + $this->basedirNameLength = strlen($skeletonDir) + 3; + $this->targetDir = $this->getTargetDir($args); + $this->readOptions($args); + } + + public function create($dir = null) + { + if ($dir === null) { + $dir = $this->skeletonDir . DS . self::DEFAULT_LANGUAGE; + } + + foreach (scandir($dir) as $item) { + if ($item{0} === "." && $item !== ".htaccess") continue; + + $fullPath = $dir . DS . $item; + $targetItem = substr($fullPath, $this->basedirNameLength + 1); + $targetPath = $this->targetDir . DS . $targetItem; + + if (is_dir($fullPath)) { + if (isset($this->ignore[$targetItem])) { + Sabel_Console::message("ignore '{$targetItem}'."); + } else { + if (is_dir($targetPath)) { + Sabel_Console::warning("'{$targetItem}' already exists."); + } else { + Sabel_Console::success("create $targetItem"); + mkdir($targetPath); + } + + $this->create($fullPath); + } + } else { + if ($this->lang !== self::DEFAULT_LANGUAGE) { + $_target = substr($fullPath, strlen($this->skeletonDir) + 4); // DS(1) + lang(2) + DS(1) + $_target = $this->skeletonDir . DS . $this->lang . DS . $_target; + if (is_dir($_target) || is_file($_target)) { + $fullPath = $_target; + } + } + + if (isset($this->ignore[$targetItem])) { + Sabel_Console::message("ignore '{$targetItem}'."); + } elseif (is_file($targetPath)) { + Sabel_Console::warning("'{$targetItem}' already exists."); + } else { + Sabel_Console::success("create $targetItem"); + copy($fullPath, $targetPath); + } + } + } + } + + public function chmod() + { + $dirs = array("cache", "cache" . DS . "sabel", "data" , "logs"); + + foreach ($dirs as $dir) { + chmod($this->targetDir . DS . $dir, 0777); + } + } + + protected function getTargetDir($args) + { + if (in_array("-d", $args, true)) { + $dir = $args[array_search("-d", $args) + 1]; + } else { + $dir = getcwd(); + } + + if (!is_dir($dir)) mkdir($dir); + return $dir; + } + + protected function readOptions($args) + { + if (in_array("--overwrite", $args, true)) { + $index = array_search("--overwrite", $args) + 1; + for ($i = $index, $c = count($args); $i < $c; $i++) { + if (substr($args[$i], 0, 2) === "--") break; + $path = $this->targetDir . DS . $args[$i]; + if (is_file($path)) { + unlink($path); + } elseif (is_dir($path)) { + $fs = new Sabel_Util_FileSystem($path); + $fs->rmdir(); + } + } + } + + if (in_array("--ignore", $args, true)) { + $index = array_search("--ignore", $args) + 1; + for ($i = $index, $c = count($args); $i < $c; $i++) { + if (substr($args[$i], 0, 2) === "--") break; + $this->ignore[$args[$i]] = 1; + } + } + + if (Sabel_Console::hasOption("l", $args)) { + if (($lang = Sabel_Console::getOption("l", $args)) !== null) { + $lang = strtolower($lang); + if (is_dir($this->skeletonDir . DS . $lang)) { + $this->lang = $lang; + } + } + } + } +} + +if (!defined("TEST_CASE")) { + if (!defined("DS")) define("DS", DIRECTORY_SEPARATOR); + $sabel = realpath(dirname(__FILE__) . DS . ".." . DS . "sabel"); + require_once ($sabel . DS . "Object.php"); + require_once ($sabel . DS . "Console.php"); + require_once ($sabel . DS . "util" . DS . "fileSystem" . DS . "Base.php"); + require_once ($sabel . DS . "util" . DS . "FileSystem.php"); + + $scaffold = new SabelScaffold($_SERVER["argv"], dirname(__FILE__) . DS . "skeleton"); + $scaffold->create(); + $scaffold->chmod(); +} diff --git a/generator/skeleton/en/app/helpers/Date.php b/generator/skeleton/en/app/helpers/Date.php new file mode 100755 index 0000000..e40a9f6 --- /dev/null +++ b/generator/skeleton/en/app/helpers/Date.php @@ -0,0 +1,389 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Helpers_Date +{ + const NORMAL = 0; + const ATOM = 1; + const RSS = 2; + const COOKIE = 3; + const ISO = 4; + const RFC822 = 5; + const RFC850 = 6; + const RFC1036 = 7; + const RFC1123 = 8; + const RFC2822 = 9; + const RFC = 10; + const W3C = 11; + + private static $formats = array(self::NORMAL => array( + "all" => "Y-m-d H:i:s", + "date" => "Y-m-d", + "time" => "H:i:s"), + + self::ATOM => array( + "all" => "c", + "date" => "Y-m-d", + "time" => "H:i:sP"), + + self::RSS => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::COOKIE => array( + "all" => "l, d-M-y H:i:s T", + "date" => "l, d-M-y", + "time" => "H:i:s T"), + + self::ISO => array( + "all" => "Y-m-d\TH:i:sO", + "date" => "Y-m-d", + "time" => "H:i:sO"), + + self::RFC822 => array( + "all" => "D, d M y H:i:s O", + "date" => "D, d M y", + "time" => "H:i:s O"), + + self::RFC850 => array( + "all" => "l, d-M-y H:i:s T", + "date" => "l, d-M-y", + "time" => "H:i:s T"), + + self::RFC1036 => array( + "all" => "D, d M y H:i:s O", + "date" => "D, d M y", + "time" => "H:i:s O"), + + self::RFC1123 => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::RFC2822 => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::RFC => array( + "all" => "r", + "date" => "D, d M Y", + "time" => "H:i:s O"), + + self::W3C => array( + "all" => "c", + "date" => "Y-m-d", + "time" => "H:i:sP")); + + protected + $timestamp = null, + $format = self::NORMAL; + + public static function format($date, $format) + { + return date(self::$formats[$format]["all"], strtotime($date)); + } + + public function __construct($arg = null) + { + if ($arg === null) { + $this->timestamp = time(); + } elseif (is_string($arg)) { + $this->timestamp = strtotime($arg); + } elseif (is_array($arg)) { + $y = (isset($arg["y"])) ? $arg["y"] : date("Y"); + $m = (isset($arg["m"])) ? $arg["m"] : date("m"); + $d = (isset($arg["d"])) ? $arg["d"] : 1; + $h = (isset($arg["h"])) ? $arg["h"] : 0; + $i = (isset($arg["i"])) ? $arg["i"] : 0; + $s = (isset($arg["s"])) ? $arg["s"] : 0; + + $this->timestamp = mktime($h, $i, $s, $m, $d, $y); + } else { + throw new Exception("Helpers_Date::__construct() invalid parameter."); + } + } + + public function __toString() + { + return $this->getDateTime(); + } + + public function setFormat($format) + { + $this->format = $format; + + return $this; + } + + public function getDatetime() + { + return date(self::$formats[$this->format]["all"], $this->timestamp); + } + + public function getDate() + { + return date(self::$formats[$this->format]["date"], $this->timestamp); + } + + public function getTime() + { + return date(self::$formats[$this->format]["time"], $this->timestamp); + } + + public function getYear($twoDigits = false) + { + if ($twoDigits) { + return date("y", $this->timestamp); + } else { + return date("Y", $this->timestamp); + } + } + + public function getMonth($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("m", $this->timestamp); + } else { + return date("n", $this->timestamp); + } + } + + public function getTextualMonth($short = true) + { + if ($short) { + return date("M", $this->timestamp); + } else { + return date("F", $this->timestamp); + } + } + + public function getDay($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("d", $this->timestamp); + } else { + return date("j", $this->timestamp); + } + } + + public function getLastDay() + { + $timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth() + 1, + 0, + $this->getYear()); + + return date("d", $timestamp); + } + + public function getHour($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("H", $this->timestamp); + } else { + return date("G", $this->timestamp); + } + } + + public function getHourBy12Format($withLeadingZeros = true) + { + if ($withLeadingZeros) { + return date("h", $this->timestamp); + } else { + return date("g", $this->timestamp); + } + } + + public function getMinute() + { + return date("i", $this->timestamp); + } + + public function getSecond() + { + return date("s", $this->timestamp); + } + + public function getMeridiem($lower = true) + { + return date(($lower) ? "a" : "A", $this->timestamp); + } + + public function getTextualWeek($short = true) + { + if ($short) { + return date("D", $this->timestamp); + } else { + return date("l", $this->timestamp); + } + } + + public function getWeekNumber() + { + return date("w", $this->timestamp); + } + + public function ymd($sep = "-") + { + return $this->getYear() . $sep . $this->getMonth() . $sep . $this->getDay(); + } + + public function his($sep = ":") + { + return $this->getHour() . $sep . $this->getMinute() . $sep . $this->getSecond(); + } + + public function incYear($year = 1) + { + $year = $this->getYear() + $year; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth(), + $this->getDay(), + $year); + + return $year; + } + + public function decYear($year = 1) + { + $year = $this->getYear() - $year; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $this->getMonth(), + $this->getDay(), + $year); + + return $year; + } + + public function incMonth($month = 1) + { + $month = $this->getMonth() + $month; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $month, + $this->getDay(), + $this->getYear()); + + return $month; + } + + public function decMonth($month = 1) + { + $month = $this->getMonth() - $month; + + $this->timestamp = mktime($this->getHour(), + $this->getMinute(), + $this->getSecond(), + $month, + $this->getDay(), + $this->getYear()); + + return $month; + } + + public function incDay($day = 1) + { + $this->timestamp += 86400 * $day; + + return $this->getDay(); + } + + public function decDay($day = 1) + { + $this->timestamp -= 86400 * $day; + + return $this->getDay(); + } + + public function incHour($hour = 1) + { + $this->timestamp += 3600 * $hour; + + return $this->getHour(); + } + + public function decHour($hour = 1) + { + $this->timestamp -= 3600 * $hour; + + return $this->getHour(); + } + + public function incMinute($min = 1) + { + $this->timestamp += 60 * $min; + + return $this->getMinute(); + } + + public function decMinute($min = 1) + { + $this->timestamp -= 60 * $min; + + return $this->getMinute(); + } + + public function incSecond($second = 1) + { + $this->timestamp += $second; + + return $this->getSecond(); + } + + public function decSecond($second = 1) + { + $this->timestamp -= $second; + + return $this->getSecond(); + } + + public function y() + { + return $this->getYear(); + } + + public function m() + { + return $this->getMonth(); + } + + public function d() + { + return $this->getDay(); + } + + public function h() + { + return $this->getHour(); + } + + public function i() + { + return $this->getMinute(); + } + + public function s() + { + return $this->getSecond(); + } +} diff --git a/generator/skeleton/en/app/helpers/Js.php b/generator/skeleton/en/app/helpers/Js.php new file mode 100755 index 0000000..6f72abc --- /dev/null +++ b/generator/skeleton/en/app/helpers/Js.php @@ -0,0 +1,89 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Helpers_Js +{ + public static function effectUpdater($sourceId, $replaceId, $effect = "Slide") + { + $include = << +INC; + + $script = << +new Sabel.Event(window, "load", function() { + var updater = new Sabel.PHP.EffectUpdater("%s", "%s"); + + Sabel.get("%s").observe("click", function(evt) { + updater.fire(this.href); + Sabel.Event.preventDefault(evt); + }); +}); + +JS; + + $buf = array(); + $buf[] = sprintf($include, linkto("js/helpers/EffectUpdater.js")); + $buf[] = sprintf($script, $replaceId, $effect, $sourceId); + + return join($buf, "\n"); + } + + public static function ajaxPager($replaceId, $pagerClass = "sbl_pager") + { + $include = << +INC; + + $buf = array(); + $buf[] = sprintf($include, linkto("js/helpers/EffectUpdater.js")); + $buf[] = sprintf($include, linkto("js/helpers/AjaxPager.js")); + $buf[] = "\n"; + $buf[] = ''; + + return join($buf, "") . "\n"; + } + + /* @todo + public static function formValidator($formObj, $errBox = "sbl_errmsg") + { + $include = << +INC; + + $model = $formObj->getModel(); + $columns = $model->getColumns(); + $errMsgs = Sabel_Db_Validate_Config::getMessages(); + $lNames = Sabel_Db_Model_Localize::getColumnNames($model->getName()); + + $data = array("data" => array(), "errors" => $errMsgs); + foreach ($columns as $c) { + $name = $c->name; + if (isset($lNames[$c->name])) { + $c->name = $lNames[$c->name]; + } + + $data["data"][$name] = array_change_key_case((array) $c, CASE_UPPER); + } + + $buf = array(); + $buf[] = sprintf($include, linkto("js/helpers/FormValidator.js")); + $buf[] = "\n"; + $buf[] = ''; + + return join($buf, "") . "\n"; + } + */ +} diff --git a/generator/skeleton/en/app/helpers/application.php b/generator/skeleton/en/app/helpers/application.php new file mode 100755 index 0000000..78245c3 --- /dev/null +++ b/generator/skeleton/en/app/helpers/application.php @@ -0,0 +1,87 @@ +%s', uri($uri), $anchor); + } else { + return sprintf('%s', uri($uri), $uriQuery, $anchor); + } +} + +function ah($param, $anchor, $uriQuery = "") +{ + return a($param, h($anchor), $uriQuery); +} + +/** + * create uri for css, image, js, etc... + */ +function linkto($file) +{ + if ($bus = Sabel_Context::getContext()->getBus()) { + if ($bus->get("NO_VIRTUAL_HOST") && defined("URI_PREFIX")) { + return URI_PREFIX . "/" . $file; + } + } + + return "/" . $file; +} + +function get_uri_prefix($secure = false, $absolute = false) +{ + $prefix = ""; + + if ($secure || $absolute) { + $server = get_server_name(); + $prefix = (($secure) ? "https" : "http") . "://" . $server; + } + + if ($bus = Sabel_Context::getContext()->getBus()) { + if ($bus->get("NO_VIRTUAL_HOST") && defined("URI_PREFIX")) { + $prefix .= URI_PREFIX; + } + } + + return $prefix; +} + +/** + * create uri + */ +function uri($uri, $secure = false, $absolute = false) +{ + $context = Sabel_Context::getContext(); + return get_uri_prefix($secure, $absolute) . "/" . $context->getCandidate()->uri($uri); +} + +/** + * Internal request. + */ +function __include($uri, $values = array(), $method = Sabel_Request::GET, $withLayout = false) +{ + $requester = new Sabel_Request_Internal($method); + $requester->values($values)->withLayout($withLayout); + return $requester->request($uri)->getResult(); +} + +function mb_trim($string) +{ + $string = new Sabel_Util_String($string); + return $string->trim()->toString(); +} + +function to_date($date, $format) +{ + return Helpers_Date::format($date, constant("Helpers_Date::" . $format)); +} diff --git a/generator/skeleton/en/app/index/controllers/Index.php b/generator/skeleton/en/app/index/controllers/Index.php new file mode 100755 index 0000000..684d87e --- /dev/null +++ b/generator/skeleton/en/app/index/controllers/Index.php @@ -0,0 +1,5 @@ +Welcome + + diff --git a/generator/skeleton/en/app/logics/Base.php b/generator/skeleton/en/app/logics/Base.php new file mode 100755 index 0000000..e72545b --- /dev/null +++ b/generator/skeleton/en/app/logics/Base.php @@ -0,0 +1,14 @@ +aspect("Logics_Base")->annotate( + "transaction", array("Logics_Aspects_Transaction") + ); + } +} diff --git a/generator/skeleton/en/app/logics/Result.php b/generator/skeleton/en/app/logics/Result.php new file mode 100755 index 0000000..efbdbff --- /dev/null +++ b/generator/skeleton/en/app/logics/Result.php @@ -0,0 +1,103 @@ +set($value); + } + + public function success() + { + $this->isSuccess = true; + + return $this; + } + + public function isSuccess() + { + return $this->isSuccess; + } + + public function failure() + { + $this->isSuccess = false; + + return $this; + } + + public function isFailure() + { + return !$this->isSuccess; + } + + public function set($value) + { + $this->result = $value; + + return $this; + } + + public function get() + { + return $this->result; + } + + public function __toString() + { + $r = $this->result; + + if (is_object($r)) { + if ($r instanceof Sabel_Object) { + return $r->toString(); + } elseif (method_exists($r, "__toString")) { + return $r->__toString(); + } else { + $message = "could not be converted to string."; + throw new Sabel_Exception_Runtime(__METHOD__ . "() " . $message); + } + } elseif (is_bool($r)) { + return ($r) ? "true" : "false"; + } else { + return (string)$r; + } + } + + public function isString() + { + return is_string($this->result); + } + + public function isInt() + { + return is_int($this->result); + } + + public function isFloat() + { + return is_float($this->result); + } + + public function isBoolean() + { + return is_bool($this->result); + } + + public function isArray() + { + return is_array($this->result); + } + + public function isNull() + { + return ($this->result === null); + } + + public function isNotNull() + { + return ($this->result !== null); + } +} diff --git a/generator/skeleton/en/app/logics/aspects/Transaction.php b/generator/skeleton/en/app/logics/aspects/Transaction.php new file mode 100755 index 0000000..4966d3d --- /dev/null +++ b/generator/skeleton/en/app/logics/aspects/Transaction.php @@ -0,0 +1,27 @@ +proceed(); + + if (!$active) { + Sabel_Db_Transaction::commit(); + } + + return $result; + } catch (Exception $e) { + if (!$active) { + Sabel_Db_Transaction::rollback(); + } + + throw $e; + } + } +} diff --git a/generator/skeleton/en/app/views/clientError.tpl b/generator/skeleton/en/app/views/clientError.tpl new file mode 100755 index 0000000..05df538 --- /dev/null +++ b/generator/skeleton/en/app/views/clientError.tpl @@ -0,0 +1,5 @@ +

4xx Client Error

+ +

+ The request contains bad syntax or cannot be fulfilled. +

diff --git a/generator/skeleton/en/app/views/error.tpl b/generator/skeleton/en/app/views/error.tpl new file mode 100755 index 0000000..83bc106 --- /dev/null +++ b/generator/skeleton/en/app/views/error.tpl @@ -0,0 +1,11 @@ + +
+
    + +
  • + +
+ + diff --git a/generator/skeleton/en/app/views/forbidden.tpl b/generator/skeleton/en/app/views/forbidden.tpl new file mode 100755 index 0000000..e57c9b0 --- /dev/null +++ b/generator/skeleton/en/app/views/forbidden.tpl @@ -0,0 +1,5 @@ +

403 Forbidden

+ +

+ Your request was denied. +

diff --git a/generator/skeleton/en/app/views/layout.tpl b/generator/skeleton/en/app/views/layout.tpl new file mode 100755 index 0000000..280ad0f --- /dev/null +++ b/generator/skeleton/en/app/views/layout.tpl @@ -0,0 +1,38 @@ + + + + + <?php echo $pageTitle ?> + + + + + + " /> + + + + + + + +
+ +
+ + + + + + diff --git a/generator/skeleton/en/app/views/linkedPager.tpl b/generator/skeleton/en/app/views/linkedPager.tpl new file mode 100755 index 0000000..49339b4 --- /dev/null +++ b/generator/skeleton/en/app/views/linkedPager.tpl @@ -0,0 +1,12 @@ + + hasPrev() || $paginator->hasNext()) : ?> +
+ hasPrev()) : ?> + prev("<< Prev", array("class" => "prev")) ?> + + hasNext()) : ?> + next("Next >>", array("class" => "next")) ?> + +
+ + \ No newline at end of file diff --git a/generator/skeleton/en/app/views/notFound.tpl b/generator/skeleton/en/app/views/notFound.tpl new file mode 100755 index 0000000..c50bdfd --- /dev/null +++ b/generator/skeleton/en/app/views/notFound.tpl @@ -0,0 +1,5 @@ +

404 Not Found

+ +

+ Sorry, the page you requested was not found. +

diff --git a/generator/skeleton/en/app/views/pager.tpl b/generator/skeleton/en/app/views/pager.tpl new file mode 100755 index 0000000..af60315 --- /dev/null +++ b/generator/skeleton/en/app/views/pager.tpl @@ -0,0 +1,15 @@ +
+count > $paginator->limit) : ?> + + + viewer as $v) : ?> + isCurrent()) : ?> + getCurrent() ?> + + uri, $v->getCurrent(), $paginator->getUriQuery($v->getCurrent())) ?> + + + + + +
diff --git a/generator/skeleton/en/app/views/serverError.tpl b/generator/skeleton/en/app/views/serverError.tpl new file mode 100755 index 0000000..1752fd5 --- /dev/null +++ b/generator/skeleton/en/app/views/serverError.tpl @@ -0,0 +1,11 @@ +

5xx Server Error

+ +

+ The server encountered an internal error and was unable to complete your request. +

+ + +
+ +
+ diff --git a/generator/skeleton/en/config/Addon.php b/generator/skeleton/en/config/Addon.php new file mode 100755 index 0000000..ab29835 --- /dev/null +++ b/generator/skeleton/en/config/Addon.php @@ -0,0 +1,15 @@ + "Processor_Addon", + "request" => "Processor_Request", + "response" => "Processor_Response", + "router" => "Processor_Router", + "session" => "Processor_Session", + "helper" => "Processor_Helper", + "controller" => "Processor_Controller", + "initializer" => "Processor_Initializer", + "action" => "Processor_Action", + "view" => "Processor_View" + ); + + protected $interfaces = array( + "request" => "Sabel_Request", + "response" => "Sabel_Response", + "session" => "Sabel_Session", + "view" => "Sabel_View", + "controller" => "Sabel_Controller_Page" + ); + + protected $configs = array( + "map" => "Config_Map", + "addon" => "Config_Addon", + "database" => "Config_Database" + ); + + public function getProcessors() + { + $baseDir = RUN_BASE . DS . LIB_DIR_NAME . DS . "processor" . DS; + + foreach (array_keys($this->processors) as $name) { + Sabel::fileUsing($baseDir . ucfirst($name) . ".php", true); + } + + return $this->processors; + } +} diff --git a/generator/skeleton/en/config/Container.php b/generator/skeleton/en/config/Container.php new file mode 100755 index 0000000..12f7bd5 --- /dev/null +++ b/generator/skeleton/en/config/Container.php @@ -0,0 +1,11 @@ + array( + "package" => "sabel.db.*", + "host" => "localhost", + "database" => "dbname", + "user" => "user", + "password" => "password") + ); + break; + + case TEST: + $params = array("default" => array( + "package" => "sabel.db.*", + "host" => "localhost", + "database" => "dbname", + "user" => "user", + "password" => "password") + ); + break; + + case DEVELOPMENT: + $params = array("default" => array( + "package" => "sabel.db.*", + "host" => "localhost", + "database" => "dbname", + "user" => "user", + "password" => "password") + ); + break; + } + + return $params; + } +} diff --git a/generator/skeleton/en/config/INIT.php b/generator/skeleton/en/config/INIT.php new file mode 100755 index 0000000..522d7ef --- /dev/null +++ b/generator/skeleton/en/config/INIT.php @@ -0,0 +1,59 @@ +route("default") + ->uri(":controller/:action") + ->module("index") + ->defaults(array( + ":controller" => "index", + ":action" => "index") + ); + + $this->route("notfound") + ->uri("*") + ->module("index") + ->controller("index") + ->action("notFound"); + } +} diff --git a/generator/skeleton/en/config/environment.php b/generator/skeleton/en/config/environment.php new file mode 100755 index 0000000..8b6c830 --- /dev/null +++ b/generator/skeleton/en/config/environment.php @@ -0,0 +1,22 @@ + 0) { + ini_set("display_errors", "0"); + ini_set("log_errors", "1"); + error_reporting(E_ALL); + define("SBL_LOG_LEVEL", SBL_LOG_ERR); +} else { + ini_set("display_errors", "1"); + error_reporting(E_ALL|E_STRICT); + define("SBL_LOG_LEVEL", SBL_LOG_ALL); +} + +//define("SERVICE_DOMAIN", "www.example.com"); +//define("FILEINFO_MAGICDB", "/usr/share/misc/magic"); diff --git a/generator/skeleton/en/lib/Cache.php b/generator/skeleton/en/lib/Cache.php new file mode 100755 index 0000000..d29c9ab --- /dev/null +++ b/generator/skeleton/en/lib/Cache.php @@ -0,0 +1,40 @@ +addServer(/* $host, $port = 11211, $weight = 1 */); + break; + default: + $message = __METHOD__ . "() invalid cache backend."; + throw new Sabel_Exception_Runtime($message); + } + + return $storage; + } +} diff --git a/generator/skeleton/en/lib/LinkedPaginator.php b/generator/skeleton/en/lib/LinkedPaginator.php new file mode 100755 index 0000000..a839902 --- /dev/null +++ b/generator/skeleton/en/lib/LinkedPaginator.php @@ -0,0 +1,103 @@ +lastPage = $num; + } + + public function prev($text, $attrs = array()) + { + return $this->createLink($text, $this->getUriQuery($this->viewer->getPrevious()), $attrs); + } + + public function next($text, $attrs = array()) + { + return $this->createLink($text, $this->getUriQuery($this->viewer->getNext()), $attrs); + } + + public function hasPrev() + { + $attrs = $this->attributes; + return ($attrs[$attrs["pageKey"]] > 1); + } + + public function hasNext() + { + return $this->hasNext; + } + + public function build($limit, array $getValues = array()) + { + $page = 1; + $pageKey = $this->attributes["pageKey"]; + + if (isset($getValues[$pageKey])) { + $page = $getValues[$pageKey]; + if (!is_numeric($page) || $page < 1) $page = 1; + } + + $model = $this->model; + $attributes =& $this->attributes; + + unset($getValues[$pageKey]); + unset($getValues[ini_get("session.name")]); + $attributes["uriQuery"] = http_build_query($getValues, "", "&"); + + $count = $this->lastPage * $limit; + + $attributes["count"] = $count; + $attributes["limit"] = $limit; + $attributes[$pageKey] = $page; + + $pager = new Sabel_View_Pager($count, $limit); + $pager->setPageNumber($page); + $attributes["viewer"] = new Sabel_View_PageViewer($pager); + + if ($count === 0) { + $attributes["offset"] = 0; + $attributes["results"] = array(); + $model->clear(); + } else { + $offset = $pager->getSqlOffset(); + $this->_setOrderBy($getValues); + $model->setLimit($limit + 1); + $model->setOffset($offset); + + $attributes["offset"] = $offset; + $attributes["results"] = $model->{$this->method}(); + + $results = $attributes["results"]; + if (count($results) > $limit) { + array_pop($results); + $attributes["results"] = $results; + + if ($page < $this->lastPage) { + $this->hasNext = true; + } + } + } + + return $this; + } + + protected function createLink($text, $query, $attrs) + { + $_attrs = ""; + if (is_array($attrs) && !empty($attrs)) { + $tmp = array(); + foreach ($attrs as $attr => $value) { + $tmp[] = $attr . '="' . h($value) . '"'; + } + + $_attrs = " " . implode(" ", $tmp); + } + + $format = '%s'; + return sprintf($format, $_attrs, $this->uri, $query, h($text)); + } +} diff --git a/generator/skeleton/en/lib/Paginator.php b/generator/skeleton/en/lib/Paginator.php new file mode 100755 index 0000000..e72a686 --- /dev/null +++ b/generator/skeleton/en/lib/Paginator.php @@ -0,0 +1,226 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Paginator extends Sabel_Object +{ + /** + * @var object Sabel_Db_Model or Sabel_Db_Join + */ + protected $model = null; + + /** + * @var boolean + */ + protected $isJoin = false; + + /** + * @var string + */ + protected $method = "select"; + + /** + * @var array + */ + protected $attributes = array(); + + /** + * @array + */ + protected $defaultOrder = array(); + + /** + * @array or false + */ + protected $orderColumns = false; + + public function __construct($model) + { + if (is_string($model)) { + $model = MODEL($model); + } elseif ($model instanceof Sabel_Db_Finder) { + $model = $model->getRawInstance(); + } + + if (is_model($model)) { + $model->autoReinit(false); + } elseif ($model instanceof Sabel_Db_Join) { + $model->getModel()->autoReinit(false); + $this->isJoin = true; + } else { + $message = __METHOD__ . "() invalid instance."; + throw new Sabel_Exception_Runtime($message); + } + + $this->model = $model; + $this->attributes["pageKey"] = "page"; + } + + public function __set($key, $value) + { + $this->attributes[$key] = $value; + } + + public function __get($key) + { + if (isset($this->attributes[$key])) { + return $this->attributes[$key]; + } else { + return null; + } + } + + public function getPageNumber() + { + $pageKey = $this->attributes["pageKey"]; + return $this->$pageKey; + } + + public function getUriQuery($page) + { + $pageKey = $this->attributes["pageKey"]; + if (!isset($this->attributes["uriQuery"])) { + return "{$pageKey}={$page}"; + } else { + if (($query = $this->attributes["uriQuery"]) === "") { + return "{$pageKey}={$page}"; + } else { + return $query . "&{$pageKey}=" . $page; + } + } + } + + public function setCondition($arg1, $arg2 = null) + { + $this->model->setCondition($arg1, $arg2); + + return $this; + } + + public function setDefaultOrder($column, $mode = "asc") + { + $this->defaultOrder[$column] = $mode; + + return $this; + } + + public function setOrderColumns($columns) + { + $this->orderColumns = $columns; + + return $this; + } + + public function setMethod($method) + { + $this->method = $method; + + return $this; + } + + public function build($limit, array $getValues = array()) + { + $page = 1; + $pageKey = $this->attributes["pageKey"]; + + if (isset($getValues[$pageKey])) { + $page = $getValues[$pageKey]; + if (!is_numeric($page) || $page < 1) $page = 1; + } + + $model = $this->model; + $attributes =& $this->attributes; + + unset($getValues[$pageKey]); + $attributes["uriQuery"] = http_build_query($getValues, "", "&"); + $count = ($this->isJoin) ? $model->getCount(false) : $model->getCount(); + + $attributes["count"] = $count; + $attributes["limit"] = $limit; + $attributes["page"] = $page; + + $pager = new Sabel_View_Pager($count, $limit); + $pager->setPageNumber($page); + $attributes["viewer"] = new Sabel_View_PageViewer($pager); + + if ($count === 0) { + $attributes["offset"] = 0; + $attributes["results"] = array(); + $model->clear(); + } else { + $offset = $pager->getSqlOffset(); + $this->_setOrderBy($getValues); + $model->setLimit($limit); + $model->setOffset($offset); + + $attributes["offset"] = $offset; + $attributes["results"] = $model->{$this->method}(); + } + + return $this; + } + + protected function _setOrderBy($getValues) + { + $orderValues = array(); + $orderColumns = $this->orderColumns; + + if ($orderColumns !== false) { + $oColNum = count($orderColumns); + $pageKey = $this->attributes["pageKey"]; + + if ($this->isJoin) { + $columns = $this->model->getModel()->getColumnNames(); + } else { + $columns = $this->model->getColumnNames(); + } + + foreach ($getValues as $key => $val) { + if (preg_match('/^[A-Z]/', $key{0}) === 1 && strpos($key, "_") !== false) { + list ($mname, $cname) = explode("_", $key, 2); + $key = $mname . "." . $cname; + } else { + if (!in_array($key, $columns, true)) continue; + } + + if ($oColNum === 0 || in_array($key, $orderColumns, true)) { + $orderValues[$key] = $val; + } + } + } + + if (empty($orderValues)) { + if (empty($this->defaultOrder)) { + return; + } else { + $orderValues = $this->defaultOrder; + } + } + + $model = $this->model; + $orders = array(); + + if (empty($orderColumns)) { + foreach ($orderValues as $column => $order) { + $order = strtolower($order); + if ($order !== "asc" && $order !== "desc") $order = "asc"; + $model->setOrderBy($column, $order); + } + } else { + foreach ($orderColumns as $column) { + if (!isset($orderValues[$column])) continue; + + $order = strtolower($orderValues[$column]); + if ($order !== "asc" && $order !== "desc") $order = "asc"; + $model->setOrderBy($column, $order); + } + } + } +} diff --git a/generator/skeleton/en/lib/Validator.php b/generator/skeleton/en/lib/Validator.php new file mode 100755 index 0000000..9abe3ce --- /dev/null +++ b/generator/skeleton/en/lib/Validator.php @@ -0,0 +1,15 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Validator extends Sabel_Validator +{ + // Your custom validation methods. +} diff --git a/generator/skeleton/en/lib/form/Html.php b/generator/skeleton/en/lib/form/Html.php new file mode 100755 index 0000000..021ec17 --- /dev/null +++ b/generator/skeleton/en/lib/form/Html.php @@ -0,0 +1,221 @@ +name = $name; + } else { + $message = __METHOD__ . "() argument must be a string."; + throw new Sabel_Exception_InvalidArgument($message); + } + + return $this; + } + + /** + * @param mixed $value + * + * @return self + */ + public function setValue($value) + { + $this->value = $value; + + return $this; + } + + /** + * @param string $attrs + * + * @throws Sabel_Exception_InvalidArgument + * @return self + */ + public function setAttributes($attributes) + { + if (is_string($attributes)) { + $this->attributes = $attributes; + } else { + $message = __METHOD__ . "() argument must be a string."; + throw new Sabel_Exception_InvalidArgument($message); + } + + return $this; + } + + /** + * @return self + */ + public function clear() + { + $this->name = ""; + $this->value = null; + $this->attributes = ""; + + return $this; + } + + public function text() + { + $html = $this->openTag("input") . 'type="text" '; + $html .= 'name="' . $this->name . '" value="' . $this->value . '" />'; + + return $html; + } + + public function password() + { + $html = $this->openTag("input") . 'type="password" '; + $html .= 'name="' . $this->name . '" value="' . $this->value . '" />'; + + return $html; + } + + public function textarea() + { + $html = $this->openTag("textarea"); + $html .= 'name="' . $this->name . '">' . $this->value . ''; + + return $html; + } + + public function hidden() + { + $html = $this->openTag("input") . 'type="hidden" '; + $html .= 'name="' . $this->name . '" value="' . $this->value . '" />'; + + return $html; + } + + public function file() + { + return $this->openTag("input") . 'type="file" name="' . $this->name . '" />'; + } + + public function select($data) + { + $options = array(); + $value = $this->value; + + foreach ($data as $v => $text) { + if (!is_empty($value) && $v == $value) { + $tag = ''; + } + + $html = $this->openTag("select") . 'name="' . $this->name . '">'; + return $html . implode(PHP_EOL, $options) . PHP_EOL . ""; + } + + public function radio($data) + { + static $rdonm = 0; + + $count = 0; + $html = array(); + $name = $this->name; + $value = $this->value; + + // remove id. + $attrs = preg_replace('/(^id="[^"]*"| id="[^"]*")/', '', $this->attributes); + + foreach ($data as $v => $text) { + $_id = "radio_" . $rdonm++; + $radio = $this->openTag("input", 'id="' . $_id . '" ' . $attrs) . 'type="radio" '; + $radio .= 'name="' . $name . '" value="' . htmlescape($v) . '"'; + + if ($count === 0 && is_empty($value) || !is_empty($value) && $v == $value) { + $radio .= ' checked="checked"'; + } + + $radio .= ' />'; + $html[] = $radio; + + $count++; + } + + return implode(" " . PHP_EOL, $html); + } + + public function checkbox($data) + { + static $chknm = 0; + + $html = array(); + $name = $this->name; + $value = $this->value; + + if (!is_array($value)) { + $value = array(); + } + + // remove id. + $attrs = preg_replace('/(^id="[^"]*"| id="[^"]*")/', '', $this->attributes); + + foreach ($data as $v => $text) { + $_id = "checkbox_" . $chknm++; + $check = $this->openTag("input", 'id="' . $_id . '" ' . $attrs) . 'type="checkbox" '; + $check .= 'name="' . $name . '[]" value="' . htmlescape($v) . '"'; + + if (!is_empty($value) && in_array($v, $value)) { + $check .= ' checked="checked"'; + } + + $check .= ' />'; + $html[] = $check; + } + + return implode(" " . PHP_EOL, $html); + } + + public function datetime($yearRange, $withSecond, $includeBlank) + { + $datetime = new Form_Html_Date_Datetime($this->name, $this->value); + return $datetime->toHtml($yearRange, $withSecond, $includeBlank); + } + + public function date($yearRange, $includeBlank) + { + $date = new Form_Html_Date_Object($this->name, $this->value); + return $date->toHtml($yearRange, $includeBlank); + } + + protected function openTag($tagName, $attributes = null) + { + if ($attributes === null) { + $attributes = $this->attributes; + } + + if (is_empty($attributes)) { + return "<{$tagName} "; + } else { + return "<{$tagName} {$attributes} "; + } + } +} diff --git a/generator/skeleton/en/lib/form/Model.php b/generator/skeleton/en/lib/form/Model.php new file mode 100755 index 0000000..25e0eef --- /dev/null +++ b/generator/skeleton/en/lib/form/Model.php @@ -0,0 +1,169 @@ +modelName = $model->getName(); + } else { + if (is_empty($this->modelName)) { + $exp = explode("_", get_class($this)); + $this->modelName = array_pop($exp); + } + + $model = (is_empty($id)) ? MODEL($this->modelName) : MODEL($this->modelName, $id); + } + + $this->setModel($model); + } + + public function setModel($model) + { + if (is_string($model)) { + $this->model = MODEL($model); + } elseif ($model instanceof Sabel_Db_Model) { + $this->model = $model; + } else { + $message = __METHOD__ . "() argument must be a string or an instance of model."; + throw new Sabel_Exception_Runtime(); + } + + $this->values = $this->model->toArray(); + } + + public function getModel() + { + return $this->model; + } + + /** + * @return boolean + */ + public function validate(Sabel_Validator $validator = null) + { + if ($validator === null) { + $validator = $this->buildValidator(); + } + + $validator->validate($this->values); + $errors = $validator->getErrors(); + + if ($uniques = $this->model->getMetadata()->getUniques()) { + $this->uniqueCheck($uniques, $errors); + } + + $this->errors = $errors; + + return empty($this->errors); + } + + public function buildValidator() + { + $validator = $this->createValidator(); + + $this->setupModelValidator($validator); + $this->setupValidator($validator); + + return $validator; + } + + public function save() + { + $this->model->setValues($this->values); + + return $this->model->save(); + } + + protected function uniqueCheck(array $uniques, array &$errors) + { + $model = $this->model; + + $pkey = $model->getMetadata()->getPrimaryKey(); + if (!is_array($pkey)) $pkey = array($pkey); + + $inputValues = $this->values; + foreach ($uniques as $_uniques) { + $fetch = true; + $values = array(); + $finder = new Sabel_Db_Finder($model->getName(), $pkey); + + foreach ($_uniques as $unique) { + if (isset($inputValues[$unique])) { + $values[] = $inputValues[$unique]; + $finder->eq($unique, $inputValues[$unique]); + } else { + $fetch = false; + break; + } + } + + if (!$fetch) continue; + + $_model = $finder->fetch(); + if ($_model->isSelected()) { + $isValid = true; + if ($model->isSelected()) { // update + foreach ($pkey as $column) { + if ($_model->$column !== $model->$column) { + $isValid = false; + break; + } + } + } else { // insert + $isValid = false; + } + + if (!$isValid) { + $names = array(); + foreach ($_uniques as $unique) { + $names[] = $this->getDisplayName($unique); + } + + $errors[] = implode(", ", $names) . ' "' . implode(", ", $values) . '" already exists.'; + } + } + } + } + + protected function setupModelValidator(Sabel_Validator $validator) + { + $metadata = $this->model->getMetadata(); + $columns = $metadata->getColumns(); + + $validators = $this->validators; + foreach ($this->inputNames as $inputName) { + if (!isset($columns[$inputName])) continue; + + $column = $columns[$inputName]; + if ($column->increment) continue; + + if (!$column->nullable) { + $validator->add($column->name, "required"); + } + + if ($column->isString()) { + $validator->add($column->name, "strwidth({$column->max})"); + } elseif ($column->isNumeric()) { + $validator->add($column->name, "max({$column->max})"); + $validator->add($column->name, "min({$column->min})"); + + if ($column->isInt()) { + $validator->add($column->name, "integer"); + } else { // float, double + $validator->add($column->name, "numeric"); + } + } elseif ($column->isBoolean()) { + $validator->add($column->name, "boolean"); + } elseif ($column->isDate()) { + $validator->add($column->name, "date"); + } elseif ($column->isDatetime()) { + $validator->add($column->name, "datetime"); + } + } + } +} diff --git a/generator/skeleton/en/lib/form/Object.php b/generator/skeleton/en/lib/form/Object.php new file mode 100755 index 0000000..b29f7aa --- /dev/null +++ b/generator/skeleton/en/lib/form/Object.php @@ -0,0 +1,379 @@ +nameSpace = $nameSpace; + + return $this; + } + + public function getNameSpace() + { + return $this->nameSpace; + } + + /** + * @param array $names + * + * @return self + */ + public function setDisplayNames(array $displayNames) + { + $this->displayNames = $displayNames; + + return $this; + } + + /** + * @param string $inputName + * + * @return string + */ + public function getDisplayName($inputName) + { + if (isset($this->displayNames[$inputName])) { + return $this->displayNames[$inputName]; + } else { + return $inputName; + } + } + + public function n($inputName) + { + return $this->getDisplayName($inputName); + } + + /** + * @param array $inputNames + * + * return self + */ + public function setInputNames(array $inputNames) + { + $this->inputNames = $inputNames; + + return $this; + } + + /** + * @return array + */ + public function getInputNames() + { + return $this->inputNames; + } + + /** + * @param array $errors + * + * @return void + */ + public function setErrors($errors) + { + $this->errors = $errors; + } + + /** + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * @return boolean + */ + public function hasError() + { + return !empty($this->errors); + } + + public function text($name, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->text(); + } + + public function password($name, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->password(); + } + + public function textarea($name, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->textarea(); + } + + public function hidden($name, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->hidden(); + } + + public function select($name, $values, $attrs = "") + { + if (is_string($values) && strpos($values, ":") !== false) { + list ($from, $to) = explode(":", $values); + if (is_number($from) && is_number($to)) { + $buf = array(); + for ($i = $from; $i <= $to; $i++) { + $buf[$i] = $i; + } + + $values = $buf; + } else { + trigger_error("argument is not a number: {$values}", E_USER_WARNING); + } + } + + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->select($values); + } + + public function radio($name, $values, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->radio($values); + } + + public function checkbox($name, $values, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->checkbox($values); + } + + public function datetime($name, $yearRange = null, $withSecond = false, $includeBlank = false) + { + $writer = $this->getHtmlWriter($name, $this->createInputName("_datetime") . "[{$name}]"); + return $writer->datetime($yearRange, $withSecond, $includeBlank); + } + + public function date($name, $yearRange = null, $includeBlank = false) + { + $writer = $this->getHtmlWriter($name, $this->createInputName("_date") . "[{$name}]"); + return $writer->date($yearRange, $includeBlank); + } + + public function file($name, $attrs = "") + { + return $this->getHtmlWriter($name, $this->createInputName($name), $attrs)->file(); + } + + public function submit(array $values, array $inputNames = array()) + { + if (empty($values)) { + return $this; + } + + if (empty($inputNames)) { + $inputNames = $this->inputNames; + } else { + $this->inputNames = $inputNames; + } + + foreach ($values as $inputName => $value) { + if ($inputName === "_datetime" || $inputName === "_date") { + list ($k, ) = each($value); + if (!in_array($k, $inputNames, true)) { + continue; + } elseif ($inputName === "_datetime") { + foreach ($value as $key => $date) { + if (!isset($date["s"])) { + $date["s"] = "00"; + } + + if ($this->isValidDateValue($date, true)) { + $this->set( + $key, + $date["y"] . "-" . + $date["m"] . "-" . + $date["d"] . " " . + $date["h"] . ":" . + $date["i"] . ":" . + $date["s"] + ); + } else { + $this->set($key, null); + } + } + } elseif ($inputName === "_date") { + foreach ($value as $key => $date) { + if ($this->isValidDateValue($date)) { + $this->set($key, "{$date['y']}-{$date['m']}-{$date['d']}"); + } else { + $this->set($key, null); + } + } + } + } elseif (!in_array($inputName, $inputNames, true)) { + continue; + } else { + $this->set($inputName, $value); + } + } + + return $this; + } + + /** + * @return boolean + */ + public function validate(Sabel_Validator $validator = null) + { + if ($validator === null) { + $validator = $this->buildValidator(); + } + + $validator->validate($this->values); + $this->errors = $validator->getErrors(); + + return empty($this->errors); + } + + public function toHidden($values = null, $var = null) + { + $html = array(); + + if ($values === null) { + $values = $this->values; + } + + foreach ($values as $k => $v) { + if ($var !== null) { + $k = "{$var}[{$k}]"; + } + + if (is_array($v)) { + $html[] = $this->toHidden($v, $k); + } else { + $html[] = ''; + } + } + + return implode(PHP_EOL, $html); + } + + protected function createValidator() + { + $validator = new Validator(); + $validator->register($this); + $validator->setDisplayNames($this->displayNames); + + return $validator; + } + + protected function buildValidator() + { + $validator = $this->createValidator(); + $this->setupValidator($validator); + + return $validator; + } + + protected function isValidDateValue($values, $isDatetime = false) + { + $keys = array("y", "m", "d"); + + if ($isDatetime) { + $keys = array_merge($keys, array("h", "i", "s")); + } + + foreach ($keys as $key) { + if (!isset($values[$key]) || $values[$key] === "") { + return false; + } + } + + return true; + } + + protected function getHtmlWriter($name, $inputName, $attrs = "") + { + static $htmlWriter = null; + + if ($htmlWriter === null) { + $htmlWriter = new Form_Html(); + } else { + $htmlWriter->clear(); + } + + $value = $this->get($name); + + if (is_string($value)) { + $value = htmlescape($value, APP_ENCODING); + } + + return $htmlWriter->setName($inputName)->setValue($value)->setAttributes($attrs); + } + + protected function createInputName($inputName) + { + if (is_empty($this->nameSpace)) { + return $inputName; + } else { + return $this->nameSpace . "[{$inputName}]"; + } + } + + protected function setupValidator(Sabel_Validator $validator) + { + $keys = array(); + + $validators = $this->validators; + foreach ($this->inputNames as $inputName) { + $keys[$inputName] = true; + if (!isset($validators[$inputName])) continue; + + $validator->add($inputName, $validators[$inputName]); + + unset($validators[$inputName]); + } + + if ($validators) { + foreach ($validators as $inputName => $v) { + if (strpos($inputName, ",") === false) continue; + + $comp = true; + foreach (explode(",", $inputName) as $_inputName) { + if (!isset($keys[$_inputName])) { + $comp = false; + break; + } + } + + if ($comp) { + $validator->add($inputName, $v); + } + } + } + } +} diff --git a/generator/skeleton/en/lib/form/html/date/Base.php b/generator/skeleton/en/lib/form/html/date/Base.php new file mode 100755 index 0000000..aa82059 --- /dev/null +++ b/generator/skeleton/en/lib/form/html/date/Base.php @@ -0,0 +1,95 @@ +name = $name; + $this->value = $value; + } + + protected function numSelect($type, $name, $start, $end, $includeBlank) + { + $html = array('"; + } + + protected function selectedValue($type) + { + if ($this->timestamp === null) { + return null; + } + + switch ($type) { + case "y": + return (int)date("Y", $this->timestamp); + + case "m": + return (int)date("n", $this->timestamp); + + case "d": + return (int)date("j", $this->timestamp); + + case "h": + return (int)date("G", $this->timestamp); + + case "i": + return (int)date("i", $this->timestamp); + + case "s": + return (int)date("s", $this->timestamp); + } + } + + protected function getYearRange($yearRange) + { + if (!is_array($yearRange) && !is_string($yearRange) || is_empty($yearRange)) { + return array(1970, 2037); + } elseif (is_array($yearRange)) { + return $yearRange; + } elseif (strpos($yearRange, ":")) { + return explode(":", $yearRange); + } else { + $char = $yearRange{0}; + $ny = (int)date("Y"); + + if ($char === "-") { + return array($ny + $yearRange, $ny); + } elseif ($char === "+") { + return array($ny, $ny + $yearRange); + } else { + $t = (int)floor($yearRange / 2); + return array($ny - $t, $ny + ($yearRange - $t)); + } + } + } +} diff --git a/generator/skeleton/en/lib/form/html/date/Datetime.php b/generator/skeleton/en/lib/form/html/date/Datetime.php new file mode 100755 index 0000000..0dd4764 --- /dev/null +++ b/generator/skeleton/en/lib/form/html/date/Datetime.php @@ -0,0 +1,29 @@ +value === null) { + $this->timestamp = ($includeBlank) ? null : time(); + } else { + $this->timestamp = strtotime($this->value); + } + + $name = $this->name; + list ($first, $last) = $this->getYearRange($yearRange); + + $html = array(); + $html[] = $this->numSelect("y", $name, $first, $last, $includeBlank); + $html[] = $this->numSelect("m", $name, 1, 12, $includeBlank); + $html[] = $this->numSelect("d", $name, 1, 31, $includeBlank); + $html[] = $this->numSelect("h", $name, 0, 23, $includeBlank); + $html[] = $this->numSelect("i", $name, 0, 59, $includeBlank); + + if ($withSecond) { + $html[] = $this->numSelect("s", $name, 0, 59, $includeBlank); + } + + return implode(" ", $html); + } +} diff --git a/generator/skeleton/en/lib/form/html/date/Object.php b/generator/skeleton/en/lib/form/html/date/Object.php new file mode 100755 index 0000000..8efd619 --- /dev/null +++ b/generator/skeleton/en/lib/form/html/date/Object.php @@ -0,0 +1,23 @@ +value === null) { + $this->timestamp = ($includeBlank) ? null : time(); + } else { + $this->timestamp = strtotime($this->value); + } + + $name = $this->name; + list ($first, $last) = $this->getYearRange($yearRange); + + $html = array(); + $html[] = $this->numSelect("y", $name, $first, $last, $includeBlank); + $html[] = $this->numSelect("m", $name, 1, 12, $includeBlank); + $html[] = $this->numSelect("d", $name, 1, 31, $includeBlank); + + return implode(" ", $html); + } +} diff --git a/generator/skeleton/en/lib/processor/Action.php b/generator/skeleton/en/lib/processor/Action.php new file mode 100755 index 0000000..cb967d6 --- /dev/null +++ b/generator/skeleton/en/lib/processor/Action.php @@ -0,0 +1,42 @@ + + * @author Ebine Yutaka + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Action extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $response = $bus->get("response"); + $controller = $bus->get("controller"); + + if ($response->isFailure() || $response->isRedirected()) return; + + $action = $bus->get("destination")->getAction(); + $controller->setAction($action); + + try { + $controller->initialize(); + + if ($response->isSuccess() && !$response->isRedirected()) { + $controller->execute(); + } + + $controller->finalize(); + } catch (Exception $e) { + $response->getStatus()->setCode(Sabel_Response::INTERNAL_SERVER_ERROR); + Sabel_Context::getContext()->setException($e); + } + + if ($controller->getAttribute("layout") === false) { + $bus->set("NO_LAYOUT", true); + } + } +} diff --git a/generator/skeleton/en/lib/processor/Addon.php b/generator/skeleton/en/lib/processor/Addon.php new file mode 100755 index 0000000..c674e05 --- /dev/null +++ b/generator/skeleton/en/lib/processor/Addon.php @@ -0,0 +1,25 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Addon extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $config = $bus->getConfig("addon"); + $addons = $config->configure(); + + foreach ($addons as $addon) { + $className = ucfirst($addon) . "_Addon"; + $instance = new $className(); + $instance->execute($bus); + } + } +} diff --git a/generator/skeleton/en/lib/processor/Controller.php b/generator/skeleton/en/lib/processor/Controller.php new file mode 100755 index 0000000..e33007c --- /dev/null +++ b/generator/skeleton/en/lib/processor/Controller.php @@ -0,0 +1,66 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Controller extends Sabel_Bus_Processor +{ + protected $virtualControllerName = "SabelVirtualController"; + + public function execute(Sabel_Bus $bus) + { + $destination = $bus->get("destination"); + if (($controller = $this->createController($destination)) === null) { + $controller = $this->createVirtualController(); + } + + if ($response = $bus->get("response")) { + $controller->setResponse($response); + if ($controller instanceof $this->virtualControllerName) { + $response->getStatus()->setCode(Sabel_Response::NOT_FOUND); + } + } + + if ($request = $bus->get("request")) { + $controller->setRequest($request); + } + + if ($session = $bus->get("session")) { + $controller->setSession($session); + } + + $bus->set("controller", $controller); + } + + protected function createController($destination) + { + list ($module, $controller,) = $destination->toArray(); + $class = ucfirst($module) . "_Controllers_" . ucfirst($controller); + + if (Sabel::using($class)) { + l("create controller '{$class}'"); + return new $class(); + } else { + l("controller '{$class}' not found", SBL_LOG_WARN); + return null; + } + } + + protected function createVirtualController() + { + $className = $this->virtualControllerName; + if (!class_exists($className, false)) { + eval ("class $className extends Sabel_Controller_Page {}"); + } + + l("create virtual controller '{$className}'"); + + return new $className(); + } +} diff --git a/generator/skeleton/en/lib/processor/Helper.php b/generator/skeleton/en/lib/processor/Helper.php new file mode 100755 index 0000000..e984316 --- /dev/null +++ b/generator/skeleton/en/lib/processor/Helper.php @@ -0,0 +1,34 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Helper extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $destination = $bus->get("destination"); + $moduleName = $destination->getModule(); + $controllerName = $destination->getController(); + + $sharedHelper = "application"; + $commonHelpers = MODULES_DIR_PATH . DS . HELPERS_DIR_NAME; + $moduleHelpers = MODULES_DIR_PATH . DS . $moduleName . DS . HELPERS_DIR_NAME; + + $helpers = array(); + + $helpers[] = $commonHelpers . DS . $sharedHelper; + $helpers[] = $moduleHelpers . DS . $sharedHelper; + $helpers[] = $moduleHelpers . DS . $controllerName; + + foreach ($helpers as $helper) { + Sabel::fileUsing($helper . ".php", true); + } + } +} diff --git a/generator/skeleton/en/lib/processor/Initializer.php b/generator/skeleton/en/lib/processor/Initializer.php new file mode 100755 index 0000000..5922c77 --- /dev/null +++ b/generator/skeleton/en/lib/processor/Initializer.php @@ -0,0 +1,28 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Initializer extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + Sabel_Db_Config::initialize($bus->getConfig("database")); + + if (!is_cli() && ($session = $bus->get("session")) !== null) { + $session->start(); + l("START SESSION: " . $session->getName() . "=" . $session->getId()); + } + + // default page title. + if ($response = $bus->get("response")) { + $response->setResponse("pageTitle", "Sabel"); + } + } +} diff --git a/generator/skeleton/en/lib/processor/Request.php b/generator/skeleton/en/lib/processor/Request.php new file mode 100755 index 0000000..1967399 --- /dev/null +++ b/generator/skeleton/en/lib/processor/Request.php @@ -0,0 +1,88 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Request extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + if ($bus->has("request")) { + $request = $bus->get("request"); + } else { + $uri = $this->getRequestUri($bus); + $request = new Sabel_Request_Object($uri); + + if (SBL_SECURE_MODE) { + $_GET = remove_nullbyte($_GET); + $_POST = remove_nullbyte($_POST); + } + + $request->setGetValues($_GET); + $request->setPostValues($_POST); + + $this->setFiles($request); + + if (isset($_SERVER["REQUEST_METHOD"])) { + $request->method($_SERVER["REQUEST_METHOD"]); + } + + $httpHeaders = array(); + foreach ($_SERVER as $key => $val) { + if (strpos($key, "HTTP") === 0) { + $httpHeaders[$key] = $val; + } + } + + $request->setHttpHeaders($httpHeaders); + $bus->set("request", $request); + } + + l("REQUEST URI: /" . $request->getUri(true)); + + // Ajax request. + if ($request->getHttpHeader("X-Requested-With") === "XMLHttpRequest") { + $bus->set("NO_LAYOUT", true); + $bus->set("IS_AJAX_REQUEST", true); + } + } + + protected function getRequestUri($bus) + { + $uri = (isset($_SERVER["REQUEST_URI"])) ? $_SERVER["REQUEST_URI"] : "/"; + + if (!is_cli() && isset($_SERVER["SCRIPT_NAME"]) && $_SERVER["SCRIPT_NAME"] !== "/index.php") { + $bus->set("NO_VIRTUAL_HOST", true); + + $pubdir = substr(RUN_BASE . DS . "public", strlen($_SERVER["DOCUMENT_ROOT"])); + define("URI_PREFIX", $pubdir); + + $uri = substr(str_replace("/index.php", "", $uri), strlen($pubdir)); + } + + return normalize_uri($uri); + } + + protected function setFiles(Sabel_Request $request) + { + if (!empty($_FILES)) { + foreach ($_FILES as $name => $_FILE) { + if (isset($_FILE["tmp_name"]) && isset($_FILE["size"]) && $_FILE["size"] > 0) { + $file = new Sabel_Request_File(); + $file->name = (isset($_FILE["name"])) ? $_FILE["name"] : ""; + $file->type = (isset($_FILE["type"])) ? $_FILE["type"] : ""; + $file->path = $_FILE["tmp_name"]; + $file->size = $_FILE["size"]; + + $request->setFile($name, $file); + } + } + } + } +} diff --git a/generator/skeleton/en/lib/processor/Response.php b/generator/skeleton/en/lib/processor/Response.php new file mode 100755 index 0000000..d787d9d --- /dev/null +++ b/generator/skeleton/en/lib/processor/Response.php @@ -0,0 +1,81 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Response extends Sabel_Bus_Processor +{ + protected $afterEvents = array("action" => "afterAction"); + + public function execute(Sabel_Bus $bus) + { + $bus->set("response", new Sabel_Response_Object()); + } + + public function afterAction($bus) + { + $response = $bus->get("response"); + $response->setResponses(array_merge( + $response->getResponses(), + $bus->get("controller")->getAttributes() + )); + + if ($response->getStatus()->isServerError()) { + $exception = Sabel_Context::getContext()->getException(); + if (!is_object($exception)) return; + + $eol = ((ENVIRONMENT & DEVELOPMENT) > 0) ? "
" : PHP_EOL; + $msg = get_class($exception) . ": " + . $exception->getMessage() . $eol + . "At: " . date("r") . $eol . $eol + . Sabel_Exception_Printer::printTrace($exception, $eol, true); + + if ((ENVIRONMENT & PRODUCTION) > 0) { + + } else { + $response->setResponse("exception_message", $msg); + } + + l(PHP_EOL . str_replace("
", PHP_EOL, $msg), SBL_LOG_ERR); + } + } + + public function shutdown(Sabel_Bus $bus) + { + $response = $bus->get("response"); + $redirector = $response->getRedirector(); + + if ($redirector->isRedirected()) { + if (($url = $redirector->getUrl()) !== "") { + $response->setLocation($url); + } else { + $location = $redirector->getUri(true, false); + + if (($session = $bus->get("session")) !== null) { + if ($session->isStarted() && !$session->isCookieEnabled()) { + $glue = ($redirector->hasParameters()) ? "&" : "?"; + $location .= $glue . $session->getName() . "=" . $session->getId(); + } + } + + if (($flagment = $redirector->getFlagment()) !== "") { + $location .= "#{$flagment}"; + } + + if (function_exists("get_uri_prefix")) { + $location = get_uri_prefix() . $location; + } + + $response->setLocation($location); + } + } + + $response->outputHeader(); + } +} diff --git a/generator/skeleton/en/lib/processor/Router.php b/generator/skeleton/en/lib/processor/Router.php new file mode 100755 index 0000000..172e1fd --- /dev/null +++ b/generator/skeleton/en/lib/processor/Router.php @@ -0,0 +1,31 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Router extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + $request = $bus->get("request"); + $config = $bus->getConfig("map"); + $config->configure(); + + if ($candidate = $config->getValidCandidate($request->getUri())) { + $request->setParameterValues(array_map("urldecode", $candidate->getUriParameters())); + $destination = $candidate->getDestination(); + l("DESTINATION: " . $destination); + $bus->set("destination", $destination); + Sabel_Context::getContext()->setCandidate($candidate); + } else { + $message = __METHOD__ . "() didn't match to any routing configuration."; + throw new Sabel_Exception_Runtime($message); + } + } +} diff --git a/generator/skeleton/en/lib/processor/Session.php b/generator/skeleton/en/lib/processor/Session.php new file mode 100755 index 0000000..dc7a4fe --- /dev/null +++ b/generator/skeleton/en/lib/processor/Session.php @@ -0,0 +1,31 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_Session extends Sabel_Bus_Processor +{ + public function execute(Sabel_Bus $bus) + { + if (!$bus->has("session")) { + $bus->set("session", Sabel_Session_PHP::create()); + } + } + + public function shutdown(Sabel_Bus $bus) + { + $session = $bus->get("session"); + + if ($session->isStarted()) { + if (!$session->isCookieEnabled() && ini_get("session.use_trans_sid") === "0") { + output_add_rewrite_var($session->getName(), $session->getId()); + } + } + } +} diff --git a/generator/skeleton/en/lib/processor/View.php b/generator/skeleton/en/lib/processor/View.php new file mode 100755 index 0000000..056c36d --- /dev/null +++ b/generator/skeleton/en/lib/processor/View.php @@ -0,0 +1,96 @@ + + * @copyright 2004-2008 Mori Reo + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ +class Processor_View extends Sabel_Bus_Processor +{ + protected $afterEvents = array("controller" => "initViewObject"); + + public function initViewObject($bus) + { + list ($m, $c, $a) = $bus->get("destination")->toArray(); + + $view = new Sabel_View_Object("controller", new Sabel_View_Location_File( + $m . DS . VIEW_DIR_NAME . DS . $c . DS + )); + + $view->addLocation("module", new Sabel_View_Location_File($m . DS . VIEW_DIR_NAME . DS)); + $view->addLocation("app", new Sabel_View_Location_File(VIEW_DIR_NAME . DS)); + + if ($renderer = $bus->get("renderer")) { + $view->setRenderer($renderer); + } else { + $view->setRenderer(new Sabel_View_Renderer()); + } + + $bus->set("view", $view); + $bus->get("controller")->setAttribute("view", $view); + } + + public function execute(Sabel_Bus $bus) + { + $response = $bus->get("response"); + if ($response->isRedirected()) return; + + $controller = $bus->get("controller"); + $responses = $response->getResponses(); + $contents = (isset($responses["contents"])) ? $responses["contents"] : ""; + + $view = $this->setTemplateName( + $bus->get("view"), + $response->getStatus(), + $bus->get("destination")->getAction(), + $bus->get("IS_AJAX_REQUEST") === true + ); + + if (is_empty($contents)) { + if ($location = $view->getValidLocation()) { + $contents = $view->rendering($location, $responses); + } elseif (!$controller->isExecuted()) { + $response->getStatus()->setCode(Sabel_Response::NOT_FOUND); + if ($location = $view->getValidLocation("notFound")) { + $contents = $view->rendering($location, $responses); + } else { + $contents = "

404 Not Found

"; + } + } + } + + if ($bus->get("NO_LAYOUT")) { + $bus->set("result", $contents); + } else { + $layout = (isset($responses["layout"])) ? $responses["layout"] : DEFAULT_LAYOUT_NAME; + if ($location = $view->getValidLocation($layout)) { + $responses["contentForLayout"] = $contents; + $bus->set("result", $view->rendering($location, $responses)); + } else { // no layout. + $bus->set("result", $contents); + } + } + } + + protected function setTemplateName(Sabel_View $view, $status, $action, $isAjax = false) + { + if ($status->isFailure()) { + $tplName = lcfirst(str_replace(" ", "", $status->getReason())); + if ($location = $view->getValidLocation($tplName)) { + $view->setName($tplName); + } elseif ($status->isClientError()) { + $view->setName("clientError"); + } else { + $view->setName("serverError"); + } + } elseif ($view->getName() === "") { + $view->setName(($isAjax) ? "{$action}.ajax" : $action); + } + + return $view; + } +} diff --git a/generator/skeleton/en/lib/schema/example.php b/generator/skeleton/en/lib/schema/example.php new file mode 100755 index 0000000..18c41d8 --- /dev/null +++ b/generator/skeleton/en/lib/schema/example.php @@ -0,0 +1,37 @@ + Sabel_Db_Type::INT, + 'min' => 0, + 'max' => PHP_INT_MAX, + 'increment' => false, + 'nullable' => false, + 'primary' => true, + 'default' => null); + + $cols['column2'] = array('type' => Sabel_Db_Type::STRING, + 'max' => 255, + 'increment' => false, + 'nullable' => false, + 'primary' => false, + 'default' => null); + + return $cols; + } + + public function getProperty() + { + $property = array(); + + $property["tableEngine"] = null; + $property["uniques"] = null; + $property["fkeys"] = null; + + return $property; + } +} diff --git a/generator/skeleton/en/logs/sabel.log b/generator/skeleton/en/logs/sabel.log new file mode 100755 index 0000000..e69de29 diff --git a/generator/skeleton/en/migration/system/N_SblKvs_create.php b/generator/skeleton/en/migration/system/N_SblKvs_create.php new file mode 100755 index 0000000..8fedc1f --- /dev/null +++ b/generator/skeleton/en/migration/system/N_SblKvs_create.php @@ -0,0 +1,5 @@ +column("key")->type(_STRING)->length(64)->primary(true); +$create->column("value")->type(_TEXT); +$create->column("timeout")->type(_INT)->value(0); diff --git a/generator/skeleton/en/migration/system/N_SblPreference_create.php b/generator/skeleton/en/migration/system/N_SblPreference_create.php new file mode 100755 index 0000000..6708d92 --- /dev/null +++ b/generator/skeleton/en/migration/system/N_SblPreference_create.php @@ -0,0 +1,21 @@ +column("namespace") + ->type(_STRING) + ->length(64); + +$create->column("key") + ->type(_STRING) + ->length(64); + +$create->column("value") + ->type(_STRING) + ->length(1024); + +$create->column("type") + ->type(_STRING) + ->length(32); + +$create->primary(array("namespace", "key")); + +$create->options("engine", "InnoDB"); \ No newline at end of file diff --git a/generator/skeleton/en/migration/system/N_SblSession_create.php b/generator/skeleton/en/migration/system/N_SblSession_create.php new file mode 100755 index 0000000..2c165eb --- /dev/null +++ b/generator/skeleton/en/migration/system/N_SblSession_create.php @@ -0,0 +1,11 @@ +column("sid")->type(_STRING) + ->length(32) # md5 + //->length(40) # sha1 + ->primary(true); + +$create->column("data")->type(_TEXT); + +$create->column("timeout")->type(_INT) + ->value(0); diff --git a/generator/skeleton/en/migration/system/N_SblTemplate_create.php b/generator/skeleton/en/migration/system/N_SblTemplate_create.php new file mode 100755 index 0000000..c6a375a --- /dev/null +++ b/generator/skeleton/en/migration/system/N_SblTemplate_create.php @@ -0,0 +1,11 @@ +column("name")->type(_STRING) + ->nullable(false); + +$create->column("namespace")->type(_STRING) + ->nullable(false); + +$create->column("contents")->type(_TEXT); + +$create->primary(array("name", "namespace")); diff --git a/generator/skeleton/en/public/.htaccess b/generator/skeleton/en/public/.htaccess new file mode 100755 index 0000000..cb2535a --- /dev/null +++ b/generator/skeleton/en/public/.htaccess @@ -0,0 +1,9 @@ + + RewriteEngine On + + RewriteCond %{REQUEST_URI} \/\..+$ + RewriteRule .* /notfound [R,L] + + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule !\.(js|ico|swf|css|html)$ index.php [QSA,L] + diff --git a/generator/skeleton/en/public/css/admin.css b/generator/skeleton/en/public/css/admin.css new file mode 100755 index 0000000..706bff4 --- /dev/null +++ b/generator/skeleton/en/public/css/admin.css @@ -0,0 +1,285 @@ +body { + padding: 0; + margin: 0; + font: .74em Arial, sans-serif; + line-height: 1.5em; + background: #fff url("images/top.jpg") repeat-x top; + color: #454545; +} + +a { + color: #DA3B3B; + background: inherit; +} + +a:hover { + color: #DA3B3B; + background: inherit; + text-decoration: underline; +} + +p { + margin: 5px 0; +} + +h1 { + font: bold 1.8em Arial, Sans-Serif; + padding: 8px 0 4px 0; + margin: 0; + letter-spacing: -1px; +} + +h2 { + font: bold 1.6em Arial, Sans-Serif; + letter-spacing: -1px; +} + +h3 { + padding: 4px 0; + margin: 0; +} + +ul { + margin: 0; + padding : 0; + list-style: none; +} + +img { + border: 0; +} + +hr { + height: 1px; + border-style: none; + color: #d0d0d0; + background-color: #C0C0C0; + margin: 10px 0; +} + +.content { + margin: 0px auto; + width: 800px; +} + +/* Top part */ +#top { + padding-top: 20px; + background: transparent; + height: 101px; +} + +#top h1 { + font: bold 1.8em Arial, Sans-Serif; + padding: 8px 0 4px 0; + margin: 0; + letter-spacing: 1px; + color: #FFF; +} + +#top h2 { + font: bold 1.2em Arial, Sans-Serif; + letter-spacing: 0px; + color: #FFF; + margin: 0; + padding: 0; +} + +#top #icons { + float: right; + margin: 20px 0; + padding: 0; +} + +#top #icons img { + padding-right: 2px; + border: 0; +} + +/* Second part */ +#prec { + height: 30px; + margin: 0; + padding: 0; + background: #F6F6F6; + border-bottom: 1px solid #DCDCDC; + overflow: hidden; + margin-bottom: 15px; +} + +#wrap { + margin: 0 auto; + width: 800px; +} + +#wrap #pic { + float: right; + background: #FF0000 url("images/mainimg.jpg") no-repeat; + height: 199px; + width: 589px; + overflow: hidden; +} + +#wrap #menu { + padding: 0; + margin: 0; + background: inherit; +} + +#wrap #menu a { + padding-left: 25px; + font: 0.9em Arial, Sans-Serif; + text-decoration: none; + background: #F6F6F6 url(images/lm-li.gif) no-repeat left; +} + +#wrap #menu ul { + padding: 10px 0; +} + +#wrap #menu li { + line-height: 26px; + background: #F6F6F6 url("images/li-line.gif") no-repeat bottom left; + list-style: none; +} + +/* Advertising */ +#ad { + padding-left: 95px; + min-height: 10px; + margin-bottom: 15px; +} + +#ad a, #left_side a { + background: #FFF; + text-decoration: none; +} + +#ad a:hover, #left_side a:hover { + text-decoration: underline; +} + +/* main area */ +#main { + +} + +#contents { + background: #FFF; + margin-bottom: 10px; + width: 800px; +} + +#contents h3 { + background: #FFF url(images/hbg.gif) repeat-x; + height: 30px; + padding: 5px 0 0 0px; + margin: 0; + font: bold 1.2em Arial, Sans-Serif; +} + +#contents h3 span { + background: url(images/h-art.gif) no-repeat left; + padding: 1px 10px 0 23px; + line-height: 22px; + margin: 0; +} + +#contents p { + color: #454545; + padding: 0 5px 0 5px; + text-align: justify; +} + +#contents img { + float: left; + padding: 0 10px 5px 0; +} + +#contents blockquote { + padding-left: 10px; + border-left: 2px solid #DA4040; + margin: 10px 0 10px 25px; +} + +#contents .date { + border-top: 1px dotted #ccc; + padding: 5px 0; + margin: 10px 0 25px 0; + text-align: right; +} + +#contents .rs { + float: right; + margin: 0 10px; + border: 1px solid #ddd; + padding: 5px; + background: #f5f5f5; +} + +#contents ul { + list-style-position: inside; + margin-left: 2px; +} + +#contents ul li { + list-style-type: square; + margin-left: 15px; +} + +#contents ul ul li { + list-style: none; + margin-left: 10px; + list-style-type: lower-alpha; + list-style-position: inside; +} + +/* The footer */ +#footer { + clear: both; + border-top: 1px solid #DCDCDC; + margin: 0 0 3em 0; + color: #777; + background: #fff; +} + +#footer .right { + float: right; + margin-top: 10px; + text-align: right; + background: #FFF; +} + +#footer a { + text-decoration: none; + background: #FFF; +} + +#config_area { + display: none; + position: absolute; + top: 100px; + width: 600px; +} + +#black_layer { + display: none; + width: 100%; + height: 100%; + filter: alpha(opacity=65); + background-color: #000; + top: 0px; + left: 0px; + position: absolute; + -moz-opacity: 0.65; + opacity: 0.65; +} + +#edit_textarea { + height: 400px; + width: 600px; + font-family: 'Courier', 'MS Courier New', + 'Prestige', 'Everson Mono', + 'MS ゴシック', 'MS 明朝', + 'Osaka-等幅', 'Monaco'; +} diff --git a/generator/skeleton/en/public/css/default.css b/generator/skeleton/en/public/css/default.css new file mode 100755 index 0000000..0fab813 --- /dev/null +++ b/generator/skeleton/en/public/css/default.css @@ -0,0 +1,279 @@ +/** -------------------- + * 余白 + */ +h1, +h2, +h3, +h4, +h5, +h6, +ul, +ol, +li, +dl, +dt, +dd, +form, +fieldset, +p, +div, +pre, +code, +body, +blockquote, +samp, +dir, +legend, +marquee, +menu, +td, +th { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; +} + +/** -------------------- + * 外枠 + */ +fieldset, +frame, +frameset, +img { + border-width: 0px 0px 0px 0px; + border-style: none none none none; +} + +/** -------------------- + * IE6,7用 文字の大きさを補正 + */ +code, +kbd, +pre, +samp, +tt { + font-size: 100%; +} + +/** -------------------- + * 見出し + */ +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; +} + +/** -------------------- + * 文書作成者やサイト運営者の連絡先、文書に関する情報 + */ +address { + font-style: normal; +} + +/** -------------------- + * テーブル + */ +table { + border-collapse: collapse; + table-layout: auto; +} + +table, +th, +td { + border: 1px solid; +} + +caption { + text-align: center; + caption-side: top; +} + +th { + vertical-align: top; + font-weight: normal; + text-align: left; + empty-cells: show; +} + +td { + vertical-align: top; + text-align: left; + empty-cells: show; +} + +/** -------------------- + * 整形済みテキスト + */ +pre { + white-space: pre; +} + +/** + * IE6,7用 letter-spacingを指定した要素内で連続したbr要素の偶数個目が無視されるバグの回避 + */ +br { + letter-spacing: normal; +} + +/** + * 水平線 + */ +hr { + height: 1px; + border-style: none; + color: #d0d0d0; + background-color: #C0C0C0; + margin: 10px 0; +} + +/** -------------------- + * body + */ +body { + line-height: 1.1; + color: #444; + background: #fff url("images/headerBg.gif") repeat-x 0 0; + font-family: メイリオ,Meiryo,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic Pro",Osaka−等幅,Osaka-Mono,"MS Pゴシック","MS PGothic",Sans-Serif; + font-size: small; +} + +/** -------------------- + * header + */ +div#header { + margin-bottom: 5px; + padding-bottom: 14px; +} + +div#header h1 { + height: 80px; + background: url("images/headerLogo.gif") no-repeat 0 0; + text-indent: -9999px; +} + +/** -------------------- + * contents + */ +div#contents { + margin: 0 auto; + width: 770px; + line-height: 1.6; + min-height: 350px; +} + +.ie_6 div#contents { + height: 350px; +} + +#contents table.sbl_basicTable { + width: 90%; +} + +#contents table.sbl_basicTable th { + background-color: #e8efff; + border: 1px solid #ccc; +} + +#contents table.sbl_basicTable td { + border: 1px solid #ccc; + padding: 0 5px; +} + +/** -------------------- + * error + */ +div.sbl_error { + margin: 10px 0; + padding: 10px; + border: 2px solid #cc6655; + background-color: #feeae6; +} + +div.sbl_error ul { + list-style-type: none; +} + +div.sbl_error ul li { + padding-left: 13px; + background: url("images/icon_1.gif") no-repeat 0 50%; +} + + +/** -------------------- + * pager + */ +div.sbl_pager { + margin: 10px 0; +} + +div.sbl_pager::after { + content: "."; + display: block; + visibility: hidden; + height: 0px; + font-size: 0; + line-height: 0; + clear: both; +} + +.ie_6 div.sbl_pager, +.ie_7 div.sbl_pager { + zoom: 1; +} + +div.sbl_pager span, +div.sbl_pager a { + margin-right: 5px; + padding: 1px 7px; + border: 1px solid #999; + display: block; + float: left; + color: #999; + text-decoration: none; +} + +div.sbl_pager span { + background-color: #eee; + font-weight: bold; +} + +div.sbl_pager a { + text-decoration: none; +} + +div.sbl_pager a.prev, +div.sbl_pager a.next { + background: #fbfbfb url("images/pagerBg.gif") repeat-x 0 100%; +} + +div.sbl_pager a.prev { + margin-right: 10px; +} + +div.sbl_pager a.next { + margin-right: 0px; + margin-left: 5px; +} + +div.sbl_pager a:hover { + color: #fff; + background: #999; +} + +/** -------------------- + * footer + */ +div#footer { + margin-top: 5px; + padding: 12px 20px; + background: #fff url("images/footerBg.gif") repeat-x 0 0; + text-align: center; +} + +div#footer p { + margin-top: 5px; +} diff --git a/generator/skeleton/en/public/css/images/footerBg.gif b/generator/skeleton/en/public/css/images/footerBg.gif new file mode 100755 index 0000000..6b780b5 Binary files /dev/null and b/generator/skeleton/en/public/css/images/footerBg.gif differ diff --git a/generator/skeleton/en/public/css/images/headerBg.gif b/generator/skeleton/en/public/css/images/headerBg.gif new file mode 100755 index 0000000..e36d4ea Binary files /dev/null and b/generator/skeleton/en/public/css/images/headerBg.gif differ diff --git a/generator/skeleton/en/public/css/images/headerLogo.gif b/generator/skeleton/en/public/css/images/headerLogo.gif new file mode 100755 index 0000000..520ebb1 Binary files /dev/null and b/generator/skeleton/en/public/css/images/headerLogo.gif differ diff --git a/generator/skeleton/en/public/css/images/icon_1.gif b/generator/skeleton/en/public/css/images/icon_1.gif new file mode 100755 index 0000000..bf86d2c Binary files /dev/null and b/generator/skeleton/en/public/css/images/icon_1.gif differ diff --git a/generator/skeleton/en/public/css/images/pagerBg.gif b/generator/skeleton/en/public/css/images/pagerBg.gif new file mode 100755 index 0000000..9603589 Binary files /dev/null and b/generator/skeleton/en/public/css/images/pagerBg.gif differ diff --git a/generator/skeleton/en/public/css/images/top.jpg b/generator/skeleton/en/public/css/images/top.jpg new file mode 100755 index 0000000..276100d Binary files /dev/null and b/generator/skeleton/en/public/css/images/top.jpg differ diff --git a/generator/skeleton/en/public/css/sabeljs.css b/generator/skeleton/en/public/css/sabeljs.css new file mode 100755 index 0000000..3fea86f --- /dev/null +++ b/generator/skeleton/en/public/css/sabeljs.css @@ -0,0 +1,208 @@ +.sbl_calendarFrame { + padding: 16px 1px 1px 1px; + border: 1px solid #444; + background: #999 url("../images/js/calendarFrameBg.gif") repeat-x 0 0; + position: absolute; + width: 218px; + line-height: 1.5; +} + +.sbl_calendarFrame a.sbl_cal_close { + position: absolute; + top: 2px; + right: 2px; + width: 12px; + height: 12px; + background: url("../images/js/calendarClose.gif") no-repeat 0 0; + text-indent: -9999px; + cursor: pointer; +} + +.sbl_calendar { + border: solid #444; + border-width: 1px 0 0 1px; + background-color: #fff; +} + +.sbl_calendar .sbl_cal_header { + padding: 2px; + border: solid #444; + border-width: 0 1px 1px 0; + position: relative; + color: #835e4c; + font-weight: bold; + text-align: center; +} + +* html .sbl_calendar .sbl_cal_header, +* html .sbl_calendar .sbl_cal_weekdays, +* html .sbl_calendar .sbl_cal_days { + zoom: 1; +} + +*+html .sbl_calendar .sbl_cal_header, +*+html .sbl_calendar .sbl_cal_weekdays, +*+html .sbl_calendar .sbl_cal_days { + zoom: 1; +} + +.sbl_calendar .sbl_cal_header::after, +.sbl_calendar .sbl_cal_weekdays::after, +.sbl_calendar .sbl_cal_days::after { + content: "."; + display: block; + visibility: hidden; + height: 0px; + font-size: 0; + line-height: 0; + clear: both; +} + +.sbl_calendar .sbl_cal_header a.sbl_page_l { + position: absolute; + width: 30px; + height: 15px; + top: 4px; + left: 4px; + background: url("../images/js/calendarLeftArrow.gif") no-repeat 0 0; + cursor: pointer; +} + +.sbl_calendar .sbl_cal_header a.sbl_page_r { + position: absolute; + width: 30px; + height: 15px; + top: 4px; + right: 4px; + background: url("../images/js/calendarRightArrow.gif") no-repeat 100% 0; + cursor: pointer; +} + +.sbl_calendar .sbl_cal_weekdays div, +.sbl_calendar div.selectable, +.sbl_calendar div.nonselectable { + padding: 0px 2px; + float: left; + width: 26px; + border: solid #444; + border-width: 0 1px 1px 0; + overflow: hidden; +} + +.sbl_calendar div.selectable, +.sbl_calendar div.nonselectable { + text-align: right; +} + +.sbl_calendar .sbl_cal_weekdays div { + color: #835e4c; + background-color: #fbf6e0; + font-weight: bold; + text-align: center; +} + +.sbl_calendar div.nonselectable { + color: #bbb; +} + +.sbl_calendar .sbl_cal_days div { + background-color: #ffffff; +} + +.sbl_calendar div.selected { + background-color: #b99068; +} + +.sbl_calendar div.hover { + background-color: #decebe; +} + +.sbl_calendar div.saturday { + background-color: #e0e8fb; +} + +.sbl_calendar div.sunday { + background-color: #fbe3e0; +} + +div.sbl_dropdown { + position: relative; + zoom: 1; +} + +div.sbl_dropdown:after { + content: "."; + display: block; + visibility: hidden; + height: 0px; + font-size: 0; + line-height: 0; + clear: both; +} + +ul.sbl_dropdown_list, +ul.sbl_dropdown_list li, +ul.sbl_dropdown_list ul { + margin: 0; + padding: 0; +} + +ul.sbl_dropdown_list { + border-top: 1px solid #666; + border-right: 1px solid #666; + float: left; + line-height: 2.4; + font-size: small; + white-space: nowrap; +} + +ul.sbl_dropdown_list li { + padding: 0 30px 0 10px; + border-bottom: 1px solid #666; + border-left: 1px solid #666; + float: left; + background: #eee; + list-style-type: none; + cursor: pointer; +} + +ul.sbl_dropdown_list li.sbl_noclick { + cursor: default; +} + +ul.sbl_dropdown_list li.hover { + background-color: #d6d6d6; +} + +ul.sbl_dropdown_list li ul, +ul.sbl_dropdown_list li ul li { + border: 0 none; + float: none; +} + +ul.sbl_dropdown_list li ul { + border-top: 1px solid #666; + border-left: 1px solid #666; + border-right: 1px solid #666; + position: absolute; + display: none; +} + +ul.sbl_dropdown_list li ul li { + padding-right: 50px; + border-top: 1px solid #fff; + border-bottom: 1px solid #666; + border-left: 3px solid #a03232; + background: #f6f6f6; +} + +ul.sbl_dropdown_list li ul li.icon { + background-image: url("../images/js/dropdownRightArrow.gif"); + background-repeat: no-repeat; + background-position: 100% 50%; +} + +/** IE6 hack */ +* html ul.sbl_dropdown_list li span { + display: inline-block; +} diff --git a/generator/skeleton/en/public/images/js/calendarClose.gif b/generator/skeleton/en/public/images/js/calendarClose.gif new file mode 100755 index 0000000..0c00d10 Binary files /dev/null and b/generator/skeleton/en/public/images/js/calendarClose.gif differ diff --git a/generator/skeleton/en/public/images/js/calendarFrameBg.gif b/generator/skeleton/en/public/images/js/calendarFrameBg.gif new file mode 100755 index 0000000..31489b8 Binary files /dev/null and b/generator/skeleton/en/public/images/js/calendarFrameBg.gif differ diff --git a/generator/skeleton/en/public/images/js/calendarLeftArrow.gif b/generator/skeleton/en/public/images/js/calendarLeftArrow.gif new file mode 100755 index 0000000..e25c1af Binary files /dev/null and b/generator/skeleton/en/public/images/js/calendarLeftArrow.gif differ diff --git a/generator/skeleton/en/public/images/js/calendarRightArrow.gif b/generator/skeleton/en/public/images/js/calendarRightArrow.gif new file mode 100755 index 0000000..a889e76 Binary files /dev/null and b/generator/skeleton/en/public/images/js/calendarRightArrow.gif differ diff --git a/generator/skeleton/en/public/images/js/dropdownRightArrow.gif b/generator/skeleton/en/public/images/js/dropdownRightArrow.gif new file mode 100755 index 0000000..8ad4fc5 Binary files /dev/null and b/generator/skeleton/en/public/images/js/dropdownRightArrow.gif differ diff --git a/generator/skeleton/en/public/images/orderAsc.gif b/generator/skeleton/en/public/images/orderAsc.gif new file mode 100755 index 0000000..1edaa16 Binary files /dev/null and b/generator/skeleton/en/public/images/orderAsc.gif differ diff --git a/generator/skeleton/en/public/images/orderDesc.gif b/generator/skeleton/en/public/images/orderDesc.gif new file mode 100755 index 0000000..f06a9ff Binary files /dev/null and b/generator/skeleton/en/public/images/orderDesc.gif differ diff --git a/generator/skeleton/en/public/images/powered-by-sabel.gif b/generator/skeleton/en/public/images/powered-by-sabel.gif new file mode 100755 index 0000000..1e5756a Binary files /dev/null and b/generator/skeleton/en/public/images/powered-by-sabel.gif differ diff --git a/generator/skeleton/en/public/index.php b/generator/skeleton/en/public/index.php new file mode 100755 index 0000000..13d2b70 --- /dev/null +++ b/generator/skeleton/en/public/index.php @@ -0,0 +1,24 @@ + 0) { + Sabel::init(); + echo Sabel_Bus::create()->run(new Config_Bus()); + Sabel::shutdown(); +} else { + echo Sabel_Bus::create()->run(new Config_Bus()); +} + +ob_flush(); diff --git a/generator/skeleton/en/public/js/Sabel.js b/generator/skeleton/en/public/js/Sabel.js new file mode 100755 index 0000000..de31b59 --- /dev/null +++ b/generator/skeleton/en/public/js/Sabel.js @@ -0,0 +1,3808 @@ +/** + * SabelJS 1.2 + * Header + * + * @author Hamanaka Kazuhiro + * @copyright 2004-2008 Hamanaka Kazuhiro + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + */ + +window.Sabel = {}; + +Sabel.PHP = {}; + +Sabel.emptyFunc = function() {}; + +Sabel.QueryObject = function(object) { + this.data = object; +}; + +Sabel.QueryObject.prototype = { + has: function(key) { + return !!(this.data[key] !== undefined); + }, + + get: function(key) { + return this.data[key] || null; + }, + + set: function(key, val) { + this.data[key] = val; + return this; + }, + + unset: function(key) { + delete this.data[key]; + }, + + serialize: function() { + var data = this.data, buf = new Array(); + for (var key in data) { + if (Sabel.Object.isArray(data[key])) { + Sabel.Array.each(data[key], function(val) { + buf[buf.length] = key + "=" + encodeURIComponent(val); + }); + } else { + buf[buf.length] = key + "=" + encodeURIComponent(data[key]); + } + } + + return buf.join("&"); + } +}; + + +Sabel.Uri = function(uri) +{ + uri = uri || location.href; + + var result = Sabel.Uri.pattern.exec(uri); + + if (result === null) { + var urlPrefix = location.protocol + "//" + location.hostname; + + if (uri[0] === "/") { + uri = urlPrefix + uri; + } else { + var currentPath = location.pathname.substr(0, location.pathname.lastIndexOf("/")+1); + uri = urlPrefix + currentPath + uri; + } + var result = Sabel.Uri.pattern.exec(uri); + } + + for (var i = 0, len = result.length; i < len; i++) { + this[Sabel.Uri.keyNames[i]] = result[i] || ""; + } + this['parseQuery'] = Sabel.Uri.parseQuery(this.query); +}; + +Sabel.Uri.pattern = /^((\w+):\/\/(?:(\w+)(?::(\w+))?@)?([^:\/]*)(?::(\d+))?)(?:([^?#]+?)(?:\/(\w+\.\w+))?)?(?:\?((?:[^&#]+)(?:&[^&#]*)*))?(?:#([^#]+))?$/; +Sabel.Uri.keyNames = ['uri', 'url', 'protocol', 'user', 'password', 'domain', 'port', 'path', 'filename', 'query', 'hash']; + +Sabel.Uri.parseQuery = function(query) +{ + if (query === undefined) return {}; + var queries = query.split("&"), parsed = {}; + + for (var i = 0, len = queries.length; i < len; i++) { + if (queries[i] == "") continue; + var q = queries[i].split("="); + parsed[q[0]] = q[1] || ""; + } + + return new Sabel.QueryObject(parsed); +}; + +Sabel.Uri.prototype = { + has: function(key) { + return this.parseQuery.has(key); + }, + + get: function(key) { + return this.parseQuery.get(key); + }, + + set: function(key, value) { + this.parseQuery.set(key, value); + return this; + }, + + unset: function(key) { + this.parseQuery.unset(key); + return this; + }, + + getQueryObj: function() { + return this.parseQuery; + }, + + toString: function() { + var uri = this.url + this.path; + + if (this.filename !== "") uri += "/" + this.filename; + if ((query = this.parseQuery.serialize())) uri += "?" + query; + return uri; + } +}; + +Sabel.Environment = (function() { + var scripts = document.getElementsByTagName("script"); + var uri = scripts[scripts.length - 1].src; + + this._env = parseInt(Sabel.Uri.parseQuery(uri.substring(uri.indexOf("?") + 1))); + + return this; +})(); +Sabel.Environment.PRODUCTION = 10; +Sabel.Environment.TEST = 5; +Sabel.Environment.DEVELOPMENT = 1; + +Sabel.Environment.isDevelopment = function() { + return this._env === Sabel.Environment.DEVELOPMENT; +}; + +Sabel.Environment.isTest = function() { + return this._env === Sabel.Environment.TEST; +}; + +Sabel.Environment.isProduction = function() { + return this._env === Sabel.Environment.PRODUCTION; +}; + +Sabel.Window = { + getWidth: function() { + if (document.compatMode === "BackCompat" || (Sabel.UserAgent.isOpera && Sabel.UserAgent.version < 9.5)) { + return document.body.clientWidth; + } else if (Sabel.UserAgent.isSafari) { + return window.innerWidth; + } else { + return document.documentElement.clientWidth; + } + }, + + getHeight: function() { + if (document.compatMode === "BackCompat" || (Sabel.UserAgent.isOpera && Sabel.UserAgent.version < 9.5)) { + return document.body.clientHeight; + } else if (Sabel.UserAgent.isSafari) { + return window.innerHeight; + } else { + return document.documentElement.clientHeight; + } + }, + + getScrollWidth: function() { + if (document.compatMode === "CSS1Compat") { + var width = document.documentElement.scrollWidth; + } else { + var width = document.body.scrollWidth; + } + var clientWidth = Sabel.Window.getWidth(); + return (clientWidth > width) ? clientWidth : width; + }, + + getScrollHeight: function() { + if (document.compatMode === "CSS1Compat") { + var height = document.documentElement.scrollHeight; + } else { + var height = document.body.scrollHeight; + } + var clientHeight = Sabel.Window.getHeight(); + return (clientHeight > height) ? clientHeight : height; + }, + + getScrollLeft: function() { + if (document.compatMode === "CSS1Compat") { + return document.documentElement.scrollLeft; + } else { + return document.body.scrollLeft; + } + }, + + getScrollTop: function() { + if (document.compatMode === "CSS1Compat") { + return document.documentElement.scrollTop; + } else { + return document.body.scrollTop; + } + } +}; + +Sabel.UserAgent = new function() { + var ua = navigator.userAgent, w = window; + this.ua = ua; + + this.isIE = false; + this.isFirefox = false; + this.isSafari = false; + this.isOpera = false; + this.isChrome = false; + this.isMozilla = false; + + if (w.ActiveXObject) { // ActiveXObjectが存在すればIE + this.isIE = true; + } else if (w.opera) { // window.operaが存在すればOpera + this.isOpera = true; + this.version = opera.version(); + } else if (w.execScript) { // execScriptが存在すればChrome (IEも存在するが既にチェック済) + this.isChrome = true; + } else if (w.getMatchedCSSRules) { // getMatchedCSSRulesが存在すればSafari3 (Chromeも存在するが既にチェック済) + //} else if (w.defaultstatus) { // Safari2対応ならこっち + this.isSafari = true; + } else if (w.Components) { // Componentsが存在すればGecko + this.isFirefox = true; + } else { + this.isMozilla = /Mozilla/.test(ua); + } + if (this.version === undefined) { + var matches = /(MSIE |Firefox\/|Version\/|Chrome\/)([0-9.]+)/.exec(ua); + this.version = matches ? matches[2] : ""; + } + + this.isWindows = /Win/.test(ua); + this.isMac = /Mac/.test(ua); + this.isLinux = /Linux/.test(ua); + this.isBSD = /BSD/.test(ua); + this.isIPhone = /iPhone/.test(ua); +}; + +Sabel.Window.lineFeedCode = (Sabel.UserAgent.isIE) ? "\r" : "\n"; + + +Sabel.Object = { + _cache: new Array(), + + create: function(object, parent) { + if (typeof object === "undefined") return {}; + + object = Object(object); + + switch (typeof object) { + case "function": + return object; + case "object": + var func = function() {}; + func.prototype = object; + if (parent) Sabel.Object.extend(func.prototype, parent, true); + if (!func.prototype.isAtomic) Sabel.Object.extend(func.prototype, this.Methods, true); + + var obj = new func; + if (obj.isAtomic()) { + obj.toString = function() { return object.toString.apply(object, arguments); }; + obj.valueOf = function() { return object.valueOf.apply(object, arguments); }; + } + } + + return obj; + }, + + extend: function(child, parent, curry, override) { + for (var prop in parent) { + if (typeof child[prop] !== "undefined" && override !== true) continue; + if (typeof parent[prop] !== "function") { + child[prop] = parent[prop]; + } else { + child[prop] = (curry === true) ? Sabel.Object._tmp(parent[prop]) : parent[prop]; + } + } + + return child; + }, + + _tmp: function(method) { + return this._cache[method] = this._cache[method] || function() { + var args = new Array(this); + args.push.apply(args, arguments); + return method.apply(method, args); + } + } +}; + + +Sabel.Object.Methods = { + isAtomic: function(object) { + switch (object.constructor) { + case String: + case Number: + case Boolean: + return true; + default: + return false; + } + }, + + isString: function(object) { + return object.constructor === String; + }, + + isNumber: function(object) { + return object.constructor === Number; + }, + + isBoolean: function(object) { + return object.constructor === Boolean; + }, + + isArray: function(object) { + return object.constructor === Array; + }, + + isFunction: function(object) { + return object.constructor === Function; + }, + + clone: function(object) { + return Sabel.Object.create(object); + }, + + getName: function(object) { + return object.constructor; + }, + + hasMethod: function(object, method) { + return (object[method] !== undefined); + } +}; + +Sabel.Object.extend(Sabel.Object, Sabel.Object.Methods); +Sabel.Class = function() { + if (typeof arguments[0] === "function") { + var superKlass = arguments[0]; + } else { + var superKlass = function() {}; + } + var methods = Array.prototype.pop.call(arguments) || Sabel.Object; + + var tmpKlass = function() {}; + tmpKlass.prototype = superKlass.prototype; + + var subKlass = function() { + this.__super__ = superKlass; + if (typeof methods.init === "function") { + methods.init.apply(this, arguments); + } else { + this.__super__.apply(this, arguments); + } + delete this.__super__; + } + + subKlass.prototype = new tmpKlass; + switch (subKlass.prototype.constructor) { + case String: case Number: case Boolean: + subKlass.prototype.toString = function() { + return superKlass.toString.apply(superKlass, arguments); + }; + subKlass.prototype.valueOf = function() { + return superKlass.valueOf.apply(superKlass, arguments); + }; + } + + if (methods) { + for (var name in methods) subKlass.prototype[name] = methods[name]; + + var ms = ["toString", "valueOf"]; + for (var i = 0, len = ms.length; i < len; i++) { + if (methods.hasOwnProperty(ms[i])) + subKlass.prototype[ms[i]] = methods[ms[i]]; + } + + subKlass.prototype.constructor = subKlass; + } + return subKlass; +}; + +Sabel.String = new Sabel.Class(String, { + init: function(string) { + this._string = string; + }, + + toString: function() { + return this._string; + }, + + valueOf: function() { + return this._string; + }, + + _set: function(string) { + this._string = string; + return this; + }, + + chr: function() { + return this._set(String.fromCharCode.apply(String, this._string.split(','))); + }, + + explode: function(delimiter) { + return this._string.split(delimiter); + }, + + htmlspecialchars: function(quote_style) { + var string = this._string.replace(/&/g, "&").replace(//g, ">"); + + switch (quote_style) { + case 3: case "ENT_QUOTES": + string = string.replace(/'/g, "'"); + case 2: case "ENT_COMPAT": + string = string.replace(/"/g, """); + case 0: case "ENT_NOQUOTES": + } + return this._set(string); + }, + + lcfirst: function() { + var str = this._string; + return this._set(str.charAt(0).toLowerCase() + str.substring(1)); + }, + + ltrim: function() { + return this._set(this._string.replace(/^\s+/, "")); + }, + + nl2br: function() { + return this._set(this._string.replace(/(\r?\n)/g, "
$1")); + }, + + ord: function() { + return this._set(this._string.charCodeAt(0)); + }, + + rtrim: function() { + return this._set(this._string.replace(/\s+$/, "")); + }, + + repeat: function(multiplier) { + var tmp = ""; + for (var i = 0; i < multiplier; i++) { + tmp += this._string; + } + return this._set(tmp); + }, + + shuffle: function() { + var tmp = this._string.split(""); + var i = tmp.length; + + while (i) { + var j = Math.floor(Math.random() * i); + var t = tmp[--i]; + tmp[i] = tmp[j]; + tmp[j] = t; + } + return tmp.join(""); + }, + + sprintf: function(/* mixed args */) { + var args = arguments; + + var i = 0, v, o; + + var pattern = /%(?:([0-9]+)\$)?(-)?([0]|\'.)?([0-9]*)(?:\.([0-9]+))?([bcdfFosxX])/g; + var replaced = this.replace(pattern, function(all, key, sign, padding, alignment, precision, match) { + v = (key) ? args[--key] : args[i++]; + + if (precision) precision = parseInt(precision); + switch (match) { + case "b": + v = v.toString(2); + break; + case "c": + v = String.fromCharCode(v); + break; + case "f": case "F": + if (precision) v = parseFloat(v).toFixed(precision); + break; + case "o": + v = v.toString(8); + break; + case "s": + v = v.substring(0, precision || v.length); + break; + case "x": + v = v.toString(16); + break; + case "X": + v = v.toString(16).toUpperCase(); + break; + } + + if (alignment) { + var len = alignment - v.toString().length; + padding = (padding) ? padding.charAt(padding.length - 1) : " "; + var t = new Sabel.String(padding).repeat(len); + + v = (sign === "-") ? v + t : t + v; + } + + return v; + }); + + return replaced; + }, + + str_pad: function(pad_length, pad_string /* = " " */, pad_type /* = 1 */) { + var string = this._string + var repeat = (pad_length - string.length); + var left = right = 0; + pad_string = new Sabel.String(pad_string || " "); + + switch (pad_type) { + case 0: + left = repeat; + break; + case 2: + left = Math.floor(repeat / 2); + right = Math.ceil(repeat / 2); + break; + case 1: + default: + right = repeat; + break; + } + + if (left > 0) { + string = pad_string.repeat(left).substr(0, left) + string; + } + + if (right > 0) { + string += pad_string.repeat(right).substr(0, right); + } + + return this._set(string); + }, + + trim: function() { + var str = this._string; + return this._set(str.replace(/(^\s+|\s+$)/g, "")); + }, + + format: function(obj) { + var replaceFunc = function(target, key) { + return (obj[key] !== undefined) ? obj[key] : ""; + }; + return this._string.replace(/%(\w+)%/g, replaceFunc).replace(/#\{(\w+)\}/g, replaceFunc); + }, + + ucfirst: function() { + var str = this._string; + return this._set(str.charAt(0).toUpperCase() + str.substring(1)); + }, + + + capitalize: function() { + this._set(this._string.toLowerCase()); + return this.ucfirst(); + }, + + camelize: function() { + var str = this._string; + return this._set(str.replace(/-([a-z])/g, function(dummy, match) { + return match.toUpperCase(); + })); + }, + + decamelize: function() { + return this._set(this._string.replace(/\w[A-Z]/g, function(match) { + return match.charAt(0) + "-" + match.charAt(1).toLowerCase(); + })); + }, + + truncate: function(length, truncation) { + truncation = truncation || ""; + + return this._set(this._string.substring(0, length) + truncation); + }, + + clean: function() { + return this._set(this._string.replace(/\s{2,}/g, " ")); + }, + + toInt: function() { + return parseInt(this._string, 10); + }, + + toFloat: function() { + return parseFloat(this._string); + } +}); + +Sabel.String.prototype.chop = Sabel.String.prototype.rtrim; +Sabel.String.prototype.times = Sabel.String.prototype.repeat; + +var methods = [ + "anchor", "big", "blink", "bold", "charAt", "charCodeAt", "concat", + "decodeURI", "decodeURI_Component", "encodeURI", "encodeURI_Component", + "enumerate", "escape", "fixed", "fontcolor", "fontsize", "fromCharCode", + "getProperty", "indexOf", "italics", "lastIndexOf", "link", "localeCompare", + "match", "replace", "resolve", "search", "slice", "small", "split", "strike", + "sub", "substr", "substring", "sup", "toLocaleLowerCase", "toLocaleUpperCase", + "toLowerCase", "toSource", "toUpperCase", "unescape", "uneval" +]; +for (var i = 0, len = methods.length; i < len; i++) { + var method = methods[i]; + Sabel.String.prototype[method] = (function(method) { + return function() { + return this._set(method.apply(this, arguments)); + } + })(String.prototype[method]); +}; + +Sabel.Number = function(number) { + return Sabel.Object.create(number, Sabel.Number) +}; + +Sabel.Number._units = ["", "k", "M", "G", "T", "P", "E", "Z", "Y"]; +Sabel.Number.toHumanReadable = function(number, unit, ext) { + if (typeof number !== "number") throw "number is not Number object."; + var i = 0; + + while (number > unit) { + i++; + number = number / unit; + } + + return number.toFixed(1) + Sabel.Number._units[i]; +}; + +//Sabel.Number.numberFormat + +Sabel.Number.between = function(number, min, max) { + return number >= min && number <= max; +}; + +Sabel.Array = function(iterable) { + if (typeof iterable === "undefined") { + iterable = new Array(); + } else if (iterable.constructor === String) { + iterable = new Array(iterable); + } else if (iterable.toArray) { + iterable = iterable.toArray(); + } else { + var buf = new Array(); + Sabel.Array.each(iterable, function(v) { buf[buf.length] = v; }); + iterable = buf; + } + + return Sabel.Object.extend(iterable, Sabel.Array, true); +}; + +Sabel.Array.each = function(array, callback) { + for (var i = 0, len = array.length; i < len; i++) { + var r = callback(array[i], i); + if (r === "BREAK") break; + } + return array; +}; + +Sabel.Array.map = function(array, callback) { + var results = new Array(); + for (var i = 0, len = array.length; i < len; i++) { + results[i] = callback(array[i]); + } + return results; +}; + +Sabel.Array.concat = function(array, iterable) { + if (iterable.length === undefined) return array; + + if (iterable.toArray) iterable = iterable.toArray(); + + Sabel.Array.each(iterable, function(data) { + array[array.length] = data; + }); + return array; +}; + +Sabel.Array.inject = function(array, method) { + var buf = new Array(); + Sabel.Array.each(array, function(data) { + if (method(data) === true) buf[buf.length] = data; + }); + return buf; +}; + + +Sabel.Array.callmap = function(/*array, method, args */) { + var args = Sabel.Array(arguments); + var array = args.shift(), method = args.shift(); + for (var i = 0, len = array. length; i < len; i++) { + array[i][method].apply(array[i], args); + } + return array; +}; + +Sabel.Array.include = function(array, value) { + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === value) return true; + } + return false; +}; + +Sabel.Array.sum = function(array) { + var result = 0; + for (var i = 0, len = array.length; i < len; i++) { + result += array[i]; + } + return result; +}; + +Sabel.Array.unique = function(array) { + var result = new Array(); + Sabel.Array.each(array, function(val) { + if (result.indexOf(val) === -1) { + result.push(val); + } + }); + return result; +}; + +Sabel.Object.extend(Sabel.Array, Sabel.Object.Methods); +Sabel.Function = function(method) { + return Sabel.Object.create(method, Sabel.Function); +}; + +Sabel.Function.bind = function() { + var args = Sabel.Array(arguments); + var method = args.shift(), object = args.shift(); + + return function() { + return method.apply(object, args.concat(Sabel.Array(arguments))); + } +}; + +Sabel.Function.bindWithEvent = function() { + var args = Sabel.Array(arguments); + var method = args.shift(), object = args.shift(); + + return function(event) { + return method.apply(object, [event || window.event].concat(args)); + } +}; + +Sabel.Function.delay = function(method, delay) { + var args = Sabel.Array(arguments); + method = args.shift(); + delay = args.shift() || 1000; + scope = args.shift() || method; + setTimeout(function() { method.apply(scope, args); }, delay); +}; + +Sabel.Function.curry = function() { + var args = Sabel.Array(arguments), method = args.shift(); + + return function() { + return method.apply(method, args.concat(Sabel.Array(arguments))); + } +}; + +Sabel.Function.restraint = function(method, obj) { + var methodArgs = Sabel.Function.getArgumentNames(method); + var arglen = methodArgs.length; + + var args = new Array(arglen); + for (var i = 0; i < arglen; i++) { + args[i] = obj[methodArgs[i]]; + } + + return function() { + var ary = Sabel.Array(arguments); + for (var i = 0; i < arglen; i++) { + if (args[i] === undefined) args[i] = ary.shift(); + } + method.apply(method, args); + } +}; + +Sabel.Function.getArgumentNames = function(method) { + var str = method.toString(); + argNames = str.match(/^[\s]*function[\s\w]*\((.*)\)/)[1].split(","); + for (var i = 0, len = argNames.length; i < len; i++) { + new Sabel.String(argNames[i]).trim(); + } + return (argNames[0] === "") ? new Array() : argNames; +}; + +Sabel.Object.extend(Sabel.Function, Sabel.Object.Methods); + + +Sabel.Dom = { + getElementById: function(element, extend) { + if (typeof element === "string") { + element = document.getElementById(element); + } + + return (element) ? (extend === false) ? element : Sabel.Element(element) : null; + }, + + getElementsByClassName: function(className, element, ext) { + element = (element) ? Sabel.get(element, false) : document; + + if (element.getElementsByClassName) { + return element.getElementsByClassName(className); + } else { + var elms = element.getElementsByTagName("*"); + var pat = new RegExp("(?:^|\\s)" + className + "(?:\\s|$)"); + + var buf = (ext) ? Sabel.Elements() : new Array(); + Sabel.Array.each(elms, function(elm) { + if (pat.test(elm.className)) buf.push(elm); + }); + return buf; + } + }, + + getElementsBySelector: function(selector, root) { + var h = Sabel.Dom.Selector.handlers; + root = root || document; + var elms = [root], founds = new Array(), prev; + + if (document.querySelectorAll) { + try { + Sabel.Array.each(root.querySelectorAll(selector), function(el) { + founds.push(el); + }); + return new Sabel.Elements(founds); + } catch (e) {} + } + + while (selector && selector !== prev) { + if (selector.indexOf(',') === 0) { + founds = founds.concat(elms); + elms = [document]; + selector = selector.replace(/^,/, ""); + } + prev = selector; + + ms = Sabel.Dom.Selector.pattern.exec(selector); + ms[2] = (ms[2] || "*").toUpperCase(); + if (ms[1]) { + elms = h.combinator(elms, ms[1], ms[2]); + if (ms[3] /* ID */) + elms = h.id(elms, ms[3]); + } else { + if (ms[3] /* ID */) { + elms = h.id(elms, ms[3], ms[2]); + } else if (ms[2] /* TAG */) { + elms = h.tagName(elms, ms[2]); + } + } + + if (ms[4] /* CLASS */) + elms = h.className(elms, ms[4]); + + if (ms[5] /* ATTR */) + elms = h.attr(elms, ms[5]); + + if (ms[6] /* PSEUDO */) + elms = h.pseudo(elms, ms[6]); + + selector = selector.replace(ms[0], ""); + } + return new Sabel.Elements(founds.concat(elms)); + }, + + getElementsByXPath: function(xpath, root) { + var result = document.evaluate(xpath, root || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + + if (result.snapshotLength) { + var buf = new Array(result.snapshotLength), i = 0, tmp; + while((tmp = result.snapshotItem(i))) buf[i++] = tmp; + return new Sabel.Elements(buf); + } else { + return new Sabel.Elements(); + } + } +}; + +Sabel.get = Sabel.Dom.getElementById; +Sabel.find = Sabel.Dom.getElementsBySelector; +Sabel.xpath = Sabel.Dom.getElementsByXPath; + +Sabel.Dom.Selector = { + pattern: new RegExp( + "^\\s*" + // Space + "([~>+])?\\s*" + // + "(\\w+|\\*)?" + // TagName + "(?:#(\\w+))?" + // ID + "((?:\\.[a-zA-Z0-9_-]+)+)?" + // ClassName + "((?:\\[@?\\w+(?:[$^!~*|]?=['\"]?.+['\"]?)?\\])*)?" + // Attribute + "((?::[\\w-]+(?:\\([^\\s]+\\))?)*)" // + ), + + handlers: { + tagName: function(nodes, tagName) { + var founds = new Array(), elm, i = 0; + while ((elm = nodes[i++])) { + Sabel.Dom.Selector.concat(founds, elm.getElementsByTagName(tagName)); + } + return Sabel.Dom.Selector.clear(founds, "_added"); + }, + + id: function(nodes, id, tagName) { + var founds = new Array(), elm, i = 0; + id = id.replace("#", ""); + + var tmpElm = document.getElementById(id); + if (tagName === "*" || tmpElm.nodeName === tagName) { + if (nodes[0] === document) { + founds.push(tmpElm); + } else { + while ((elm = nodes[i++])) { + if (Sabel.Element.isContain(elm, tmpElm)) { + founds.push(tmpElm); + break; + } + } + } + } else { + while ((elm = nodes[i++])) { + if (elm.getAttribute("id") === id) { + founds[founds.length] = elm; + break; + } + } + } + return founds; + }, + + className: function(nodes, className) { + var founds = new Array(), elm, i = 0; + var classNames = className.split("."), cr = new Array(); + classNames.shift(); + + for (var j = 0, len = classNames.length; j < len; j++) + cr.push(new RegExp("(?:^|\\s+)" + classNames[j] + "(?:\\s+|$)")); + + var c, cn, flag, k; + while ((elm = nodes[i++])) { + k = 0; + flag = true; + + // @todo use Sabel.Element.getAttr + c = elm.className; + if (!c || elm._added === true) continue; + + while ((cn = cr[k++])) { + if (!cn.test(c)) { + flag = false; + break; + } + } + if (flag === true) { + elm._added = true; + founds.push(elm); + } + } + return Sabel.Dom.Selector.clear(founds, "_added"); + }, + + combinator: function(nodes, combName, tagName) { + var founds = new Array(), elm, i = 0, buf; + switch (combName) { + case "+": + while ((elm = nodes[i++])) { + while ((elm = elm.nextSibling) && elm.nodeType !== 1); + if (elm && (elm.nodeName === tagName || tagName === "*")) { + founds[founds.length] = elm; + } + } + break; + case "~": + while ((elm = nodes[i++])) { + while ((elm = elm.nextSibling) && elm._added !== true) { + if (elm.nodeName === tagName || tagName === "*") { + elm._added = true; + founds.push(elm); + } + } + } + Sabel.Dom.Selector.clear(founds, "_added"); + break; + case ">": + while ((elm = nodes[i++])) { + buf = elm.getElementsByTagName(tagName); + for (var j = 0, c; c = buf[j]; j++) { + if (c.parentNode === elm) founds.push(c); + } + } + break; + } + return founds; + }, + + attr: function(nodes, attr) { + var founds = new Array(), elm, i = 0; + var attrPattern = /\[@?(\w+)(?:([$^!~*|]?=)(['"]?)(.+?)\3)?\]/; + var attrs = attr.match(/\[@?(\w+)(?:([$^!~*|]?=)(['"]?)(.+?)\3)?\]/g), attrRegex = new Array(), at,a; + + for (var j = 0, len = attrs.length; j < len; ++j) { + buf = attrPattern.exec(attrs[j]); + if (buf[2] == "|=" && buf[1] !== "lang" && buf[1] !== "hreflang") { + return founds; + } + attrRegex.push(buf); + } + + checkNode: + while ((elm = nodes[i++])) { + if (elm._added) continue; + var k = 0; + + while ((at = attrRegex[k++])) { + if (at[1] === 'class' && window.ActiveXObject) at[1] = 'className'; + a = elm.getAttribute(at[1]); + + switch (at[2]) { + case "=": + if (a !== at[4]) continue checkNode; + break; + case "!=": + if (a === at[4]) continue checkNode; + break; + case "~=": + if ((" "+a+" ").indexOf(" "+at[4]+" ") === -1) continue checkNode; + break; + case "^=": + if ((a||"").indexOf(at[4]) !== 0) continue checkNode; + break; + case "$=": + if ((a||"").lastIndexOf(at[4]) !== ((a||"").length - at[4].length)) continue checkNode; + break; + case "*=": + if ((a||"").indexOf(at[4]) === -1) continue checkNode; + break; + case "|=": + if ((a+"-").toLowerCase().indexOf((at[4]+"-").toLowerCase()) !== 0) + continue checkNode; + break; + default: + if (!a) continue checkNode; + break; + } + } + elm._added = true; + founds.push(elm); + } + return Sabel.Dom.Selector.clear(founds, "_added"); + }, + + pseudo: function(nodes, pseudo) { + var founds = new Array(), elm, i = 0; + var ps = pseudo.replace("):", ") :").match(/:[\w-]+(\([^\s]+\))?/g); + + var buf; + + var chk = function(nodes, next, check, isNot) { + var founds = new Array(), i = 0, elm; + isNot = (isNot) ? true : false; + + while ((elm = nodes[i++])) { + var buf = elm; + var checkValue = (check === "nodeName") ? elm.nodeName : 1; + while ((buf = buf[next]) && buf[check] !== checkValue); + if ((buf === null) !== isNot) founds.push(elm); + } + return founds; + }; + + var chkNth = function(nodes, x, s, init, nextprop, checkNodeName) { + s = parseInt(s); + var founds = new Array(), i = 0, elm; + var searched = new Array(); + while ((elm = nodes[i++])) { + var parent = elm.parentNode; + if (parent._searched !== true) { + var next = s; + var cn = parent[init], counter = 0; + while (cn) { + if (checkNodeName === true) { + if (cn.nodeName === elm.nodeName) { + if (++counter === next) { + founds.push(elm); + next += x; + } + } + } else { + if (cn.nodeType === 1) { + if (++counter === next) { + if (cn.nodeName === elm.nodeName) { + founds.push(elm); + } + next += x; + } + } + } + cn = cn[nextprop]; + } + parent._searched = true; + searched.push(parent); + } + } + Sabel.Dom.Selector.clear(searched, "_searched"); + return founds; + }; + + var getSeq = function(expression) { + var nc = /(?:(odd|even)|((?:[1-9]\d*)?n)([+-]\d+)?)/.exec(expression) + if (nc[1]) { + if (nc[1] === "odd") var x = 2, s = 1; + else var x = 2, s = 2; + } else if (nc[2]) { + var x = parseInt(nc[2], 10) || 1, s = nc[3] || 0; + if (s < 1) { + s += x; + } + } + return [s, x]; + }; + + for (var j = 0, len = ps.length; j < len; ++j) { + // @todo ここにgがあるとおかしくなる(opera) + buf = /:([\w-]+)(?:\(([^\s]+)\))?/.exec(ps[j]); + switch(buf[1]) { + case "first-child": + founds = chk(nodes, "previousSibling", "nodeType"); + break; + case "last-child": + founds = chk(nodes, "nextSibling", "nodeType"); + break; + case "only-child": + founds = chk(nodes, "previousSibling", "nodeType"); + founds = chk(founds, "nextSibling", "nodeType"); + break; + case "nth-child": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "firstChild", "nextSibling", false); + + return founds; + case "nth-last-child": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "lastChild", "previousSibling", false); + + return founds; + case "first-of-type": + founds = chk(nodes, "previousSibling", "nodeName"); + break; + case "last-of-type": + founds = chk(nodes, "nextSibling", "nodeName"); + break; + case "only-of-type": + founds = chk(nodes, "previousSibling", "nodeName"); + founds = chk(founds, "nextSibling", "nodeName"); + break; + case "nth-of-type": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "firstChild", "nextSibling", true); + break; + case "nth-last-of-type": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "lastChild", "previousSibling", true); + break; + case "empty": + while ((elm = nodes[i++])) { + if (elm.childNodes.length === 0) { + founds.push(elm); + } + } + break; + case "contains": + var val = buf[2].replace(/['"]+/g, ""); + while ((elm = nodes[i++])) { + if (Sabel.Element.getTextContent(elm).indexOf(val) !== -1) { + founds.push(elm); + } + } + break; + case "not": + var chkFunc = function(nodes, func) { + var founds = new Array(), i = 0, elm; + while ((elm = nodes[i++])) { + if (func(elm)) founds.push(elm); + } + return founds; + }; + + var mats = Sabel.Dom.Selector.pattern.exec(buf[2]); + if (mats[2] /* TAG */) { + founds = nodes; + if (mats[2] !== "*") { + var tagName = mats[2].toUpperCase(); + founds = chkFunc(nodes, function(elm) { + return elm.nodeName !== tagName; + }); + } + } else if (mats[3] /* ID */) { + var id = mats[3].replace("#", ""); + founds = chkFunc(nodes, function(elm) { + return elm.getAttribute("id") !== id; + }); + } else if (mats[4] /* CLASS */) { + var className = new RegExp("(?:^|\\s+)" + mats[4].replace(".", "") + "(?:\\s+|$)"); + var klass = (window.ActiveXObject) ? "className" : "class"; + founds = chkFunc(nodes, function(elm) { + return !className.test(elm.getAttribute(klass)); + }); + } else if (mats[5] /* ATTR */) { + var b = /\[@?(\w+)(?:([$^!~*|]?=)(['"]?)(.+?)\3)?\]/.exec(mats[5]); + if (b[2] == "|=" && b[1] !== "lang" && b[1] !== "hreflang") return []; + + if (b[1] === 'class' && window.ActiveXObject) b[1] = 'className'; + founds = chkFunc(nodes, function(elm) { + a = elm.getAttribute(b[1]) || ""; + switch (b[2]) { + case "=": + return a !== b[4]; + case "!=": + return a === b[4]; + case "~=": + return (" "+a+" ").indexOf(" "+b[4]+" ") === -1; + case "^=": + return a.indexOf(b[4]) !== 0; + case "$=": + return a.lastIndexOf(b[4]) !== (a.length - b[4].length); + case "*=": + return a.indexOf(b[4]) === -1; + case "|=": + return (a+"-").toLowerCase().indexOf((b[4]+"-").toLowerCase()) !== 0; + default: + return !a; + } + }); + } else if (mats[6] /* PSEUDO */) { + var ps = mats[6].substr(1); + var pat = new RegExp("(\\w+(?:-[\\w-]+)?)(?:\\(([^)]+)\\))?"); + var buf = pat.exec(ps); + switch (buf[1]) { + case "first-child": + founds = chk(nodes, "previousSibling", "nodeType", true); + break; + case "last-child": + founds = chk(nodes, "nextSibling", "nodeType", true); + break; + case "only-child": + founds = chk(nodes, "previousSibling", "nodeType", true); + founds = founds.concat(chk(nodes, "nextSibling", "nodeType", true)); + founds = Sabel.Elements.unique(founds); + break; + case "nth-child": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "firstChild", "nextSibling", false, true); + + return founds; + case "nth-last-child": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "lastChild", "previousSibling", false, true); + + return founds; + case "first-of-type": + founds = chk(nodes, "previousSibling", "nodeName", true); + break; + case "last-of-type": + founds = chk(nodes, "nextSibling", "nodeName", true); + break; + case "only-of-type": + founds = chk(nodes, "previousSibling", "nodeName", true); + founds = founds.concat(chk(nodes, "nextSibling", "nodeName", true)); + founds = Sabel.Elements.unique(founds); + break; + case "nth-of-type": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "firstChild", "nextSibling", true, true); + break; + case "nth-last-of-type": + var seq = getSeq(buf[2]); + founds = chkNth(nodes, seq[1], seq[0], "lastChild", "previousSibling", true, true); + break; + case "empty": + while ((elm = nodes[i++])) { + if (elm.childNodes.length !== 0) + founds.push(elm); + } + break; + case "contains": + var val = buf[2].replace(/(^['"]|['"]$)/g, ""); + while ((elm = nodes[i++])) { + if (Sabel.Element.getTextContent(elm).indexOf(val) === -1) { + founds.push(elm); + } + } + break; + } + } + break; + } + } + return new Sabel.Elements(founds); + } + }, + + concat: function(array, iterable) { + for (var i = 0, data; (data = iterable[i]); i++) { + if (data._added !== true) { + data._added = true; + array[array.length] = data; + } + } + return array; + }, + + clear: function(nodes, prop) { + for (var i = 0, len = nodes.length; i < len; ++i) { + nodes[i][prop] = null; + } + return nodes; + } +}; + +Sabel.Element = function(element) { + if (typeof element === "string") { + element = document.createElement(element); + } else if (typeof element !== "object") { + // @todo throw exception ?? + return null; + } else if (element._extended === true) { + return element; + } + + return Sabel.Object.extend(element, Sabel.Element, true); +}; + +Sabel.Element._extended = true; + +Sabel.Element.get = function(element, id) { + var elm = Sabel.get(id), parent = elm.parentNode; + + do { + if (parent == element) return elm; + } while ((parent = parent.parentNode)); + + return null; +}; + +Sabel.Element.find = function(element, selector) { + return Sabel.Dom.getElementsBySelector(selector, Sabel.get(element, false)); +}; + +Sabel.Element._ieAttrMap = { + "class": "className", + "checked": "defaultChecked", + "for": "htmlFor", + "colspan": "colSpan", + "bgcolor": "bgColor", + "tabindex": "tabIndex", + "accesskey": "accessKey" +}; + +Sabel.Element.setAttr = function(element, name, value) { + if (Sabel.UserAgent.isIE && Sabel.UserAgent.version < 8) { + if (name === "style") { + element.style.cssText = value; + return element; + } + + name = Sabel.Element._ieAttrMap[name] || name; + } + element.setAttribute(name, value); + + return element; +}; + +Sabel.Element.append = function(element, child, text, attributes) { + element = Sabel.get(element); + + if (typeof child === "string") { + child = document.createElement(child); + if (text) child.innerHTML = text; + if (attributes) { + for (var name in attributes) + Sabel.Element.setAttr(child, name, attributes[name]); + } + } + + element.appendChild(new Sabel.Element(child)); + return child; +}; + +Sabel.Element.getDefaultDisplay = function(element) { + var el = document.createElement(Sabel.get(element).nodeName); + document.body.appendChild(el); + var display = Sabel.Element.getStyle(el, "display"); + Sabel.Element.remove(el); + return display; +}; + +Sabel.Element.show = function(element, value) { + Sabel.get(element, false).style.display = value || Sabel.Element.getDefaultDisplay(element); +}; + +Sabel.Element.hide = function(element) { + Sabel.get(element, false).style.display = "none"; +}; + +Sabel.Element.hasClass = function(element, className) { + element = Sabel.get(element, false); + + var pattern = new RegExp("(?:^|\\s+)" + className + "(?:\\s+|$)"); + return pattern.test(element.className); +}; + +Sabel.Element.addClass = function(element, className) { + if (Sabel.Element.hasClass(element, className)) return element; + + element = Sabel.get(element, false); + element.className = element.className + " " + className; + return element; +} + +Sabel.Element.removeClass = function(element, className) { + element = Sabel.get(element, false); + element.className = element.className.replace( + new RegExp("(?:^|\\s+)" + className + "(?:\\s+|$)"), " " + ); + + return element; +}; + +Sabel.Element.replaceClass = function(element, oldClassName, newClassName) { + element = Sabel.get(element, false); + element.className = element.className.replace( + new RegExp("(^|\\s+)" + oldClassName + "(\\s+|$)"), "$1"+newClassName+"$2" + ); + + return element; +}; + +Sabel.Element.hasAttribute = function(element, attribute) { + element = Sabel.get(element, false); + if (element.hasAttribute) return element.hasAttribute(attribute); + var node = element.getAttributeNode(attribute); + return node && node.specified; +}; + +if (Sabel.UserAgent.isIE) { + Sabel.Element.getStyle = function(element, property) { + element = Sabel.get(element, false); + property = (property === "float") ? "styleFloat" : new Sabel.String(property).camelize(); + + var style = element.currentStyle; + return style[property]; + }; +} else { + Sabel.Element.getStyle = function(element, property) { + element = Sabel.get(element, false); + // Operaでelementがwindowだった時の対策 + // CSSでdisplay: noneが指定されている時の対策 + if (element === null || element.nodeType === undefined) return null; + property = (property === "float") ? "cssFloat" : new Sabel.String(property).camelize(); + + var css = document.defaultView.getComputedStyle(element, "") + return css[property]; + }; +} + +Sabel.Element.setStyle = function(element, styles) { + element = Sabel.get(element, false); + + if (arguments.length === 3) { + Sabel.Element._setStyle(element, styles, arguments[2]); + } else if (typeof styles === "string") { + element.style.cssText += ";" + styles; + } else { + for (var prop in styles) { + Sabel.Element._setStyle(element, prop, styles[prop]); + } + } + + return element; +}; + +Sabel.Element._setStyle = function(element, property, value) { + var method = "set" + new Sabel.String(property).ucfirst(); + if (typeof Sabel.Element[method] !== "undefined") { + Sabel.Element[method](element, value); + } else { + element.style[property] = value; + } +}; + +Sabel.Element.deleteStyle = function(element, styles) { + element = Sabel.get(element, false); + + if (typeof styles === "string") { + element.style[styles] = ""; + } else { + for (var i = 0, key; key = styles[i]; i++) { + element.style[key] = ""; + } + } + + return element; +}; + +Sabel.Element.insertAfter = function(element, newChild, refChild) { + element = Sabel.get(element, false); + if (element.lastChild == refChild) { + element.appendChild(newChild); + } else { + refChild = Sabel.get(refChild); + element.insertBefore(newChild, refChild.getNextSibling()); + } + return element; +}; + +Sabel.Element.insertPreviousSibling = function(element, sibling) { + element = Sabel.get(element); + element.parentNode.insertBefore(sibling, element); + return element; +} + +Sabel.Element.insertNextSibling = function(element, sibling) { + element = Sabel.get(element); + element.getParentNode().insertAfter(sibling, element); + return element; +} + +Sabel.Element.setHeight = function(element, value) { + element = Sabel.get(element, false); + if (value !== "" && typeof value === "number") value = value + "px"; + element.style.height = value; + return element; +}; + +Sabel.Element.setWidth = function(element, value) { + element = Sabel.get(element, false); + if (value !== "" && typeof value === "number") value = value + "px"; + element.style.width = value; + return element; +}; + +Sabel.Element.setOpacity = function(element, value) { + element = Sabel.get(element, false); + + if (Sabel.UserAgent.isIE) { + element.style.filter = "alpha(opacity=" + value * 100 + ")"; + } else { + element.style.opacity = value; + } +}; + +Sabel.Element.getBackGroundColor = function(el) { + var color; + el = Sabel.get(el); + do { + color = Sabel.Element.getStyle(el, "backgroundColor"); + if (color !== "" && color !== "transparent" && + (color.indexOf("rgba") === -1 || color.slice(-2) !== "0)")) break; + } while ((el = el.parentNode)); + return (color !== "transparent") ? color : "#ffffff"; +}; + +Sabel.Element.getCumulativeTop = function(element) { + return Sabel.Element.getRegion(element).top; +}; + +Sabel.Element.getCumulativeLeft = function(element) { + return Sabel.Element.getRegion(element).left; +}; + +Sabel.Element.getCumulativePositions = function(element) { + var rect = Sabel.Element.getRegion(element); + return {top: rect.top, left: rect.left}; +}; + +Sabel.Element.getOffsetTop = function(element) { + element = Sabel.get(element, false); + + var position = element.offsetTop; + + if (Sabel.UserAgent.isOpera) { + var parent = element.offsetParent; + if (parent.nodeName !== "BODY") { + position -= parseInt(Sabel.Element.getStyle(parent, "borderTopWidth")); + } + } + + return position; +}; + +Sabel.Element.getOffsetLeft = function(element) { + element = Sabel.get(element, false); + + var position = element.offsetLeft; + + if (Sabel.UserAgent.isOpera) { + var parent = element.offsetParent; + if (parent.nodeName !== "BODY") { + position -= parseInt(Sabel.Element.getStyle(parent, "borderLeftWidth")); + } + } + + return position; +}; + +Sabel.Element.getOffsetPositions = function(element) { + return { + left: this.getOffsetLeft(element), + top: this.getOffsetTop(element) + }; +}; + +Sabel.Element.getDimensions = function(element, ignoreBorder) { + element = Sabel.get(element, false); + if (element.nodeType !== 1) return {}; + + var style = element.style; + + if (Sabel.Element.getStyle(element, "display") !== "none") { + var dimensions = { + width: element.offsetWidth, + height: element.offsetHeight + }; + } else { + var oldV = style.visibility; + var oldP = style.positions; + var oldD = "none"; + + style.visibility = "hidden"; + style.positions = "absolute"; + style.display = "block"; + + var dimensions = { + width: element.offsetWidth, + height: element.offsetHeight + }; + + style.visibility = oldV; + style.positions = oldP; + style.display = oldD; + } + + if (ignoreBorder === true) { + // parseFloat Fx3 fix + // || 0 IE7 fix + dimensions.width -= Math.round(parseFloat(Sabel.Element.getStyle(element, "borderLeftWidth")))||0 + + Math.round(parseFloat(Sabel.Element.getStyle(element, "borderRightWidth")))||0; + dimensions.height -= Math.round(parseFloat(Sabel.Element.getStyle(element, "borderTopWidth")))||0 + + Math.round(parseFloat(Sabel.Element.getStyle(element, "borderBottomWidth")))||0; + } + + return dimensions; +}; + +Sabel.Element.getWidth = function(element, ignoreBorder) { + return Sabel.Element.getDimensions(element, ignoreBorder).width; +}; + +Sabel.Element.getHeight = function(element, ignoreBorder) { + return Sabel.Element.getDimensions(element, ignoreBorder).height; +}; + +Sabel.Element.getRegion = function(element) { + element = Sabel.get(element); + if (element.parentNode === null || element.offsetParent === null) { + return false; + } + + if (element.getBoundingClientRect) { + var rect = element.getBoundingClientRect(); + + var st = Sabel.Window.getScrollTop() - document.documentElement.clientTop; + var sl = Sabel.Window.getScrollLeft() - document.documentElement.clientLeft; + + return { + top: Math.round(rect.top + st), right: Math.round(rect.right + sl), + bottom: Math.round(rect.bottom + st), left: Math.round(rect.left + sl), + toString: function() { + return new Sabel.String("{top: #{top}, right: #{right}, bottom: #{bottom}, left: #{left}}").format(this); + } + }; + } else { + var wh = Sabel.Element.getDimensions(element); + var rect = {top: element.offsetTop, left: element.offsetLeft}; + + var add = function(t, l) { + rect.top += parseInt(t) || 0; + rect.left += parseInt(l) || 0; + }; + + while ((element = element.offsetParent)) { + add(element.offsetTop, element.offsetLeft); + + if (Sabel.UserAgent.isOpera === false) { + var borderTop = Sabel.Element.getStyle(element, "borderTopWidth"); + var borderLeft = Sabel.Element.getStyle(element, "borderLeftWidth"); + add(borderTop, borderLeft); + + if (Sabel.UserAgent.isMozilla) { + var of = Sabel.Element.getStyle(element, "overflow"); + if (!Sabel.Array.include(["visible", "inherit"], of)) { + add(borderTop, borderLeft); + } + } + + if (Sabel.Array.include(["BODY", "HTML"], element.tagName)) { + if (document.compatMode === "CSS1Compat") { + var html = document.getElementsByTagName('html')[0]; + add( + Sabel.Element.getStyle(html, "marginTop"), + Sabel.Element.getStyle(html, "marginLeft") + ); + + if (Sabel.UserAgent.isIE) { + add( + Sabel.Element.getStyle(element, "marginTop"), + Sabel.Element.getStyle(element, "marginLeft") + ); + add( + Sabel.Element.getStyle(html, "borderTopWidth"), + Sabel.Element.getStyle(html, "borderLeftWidth") + ); + } + } + break; + } + } + } + + return { + top: rect.top, right: rect.left + wh.width, + bottom: rect.top + wh.height, left: rect.left, + toString: function() { + return new Sabel.String("{top: #{top}, right: #{right}, bottom: #{bottom}, left: #{left}}").format(this); + } + }; + } +}; + +Sabel.Element.remove = function(element) { + element = Sabel.get(element, false); + element.parentNode.removeChild(element); +}; + +Sabel.Element.update = function(element, contents) { + element = Sabel.get(element, false); + + var newEl = document.createElement(element.nodeName); + newEl.id = element.id; + newEl.className = element.className; + newEl.innerHTML = contents; + + element.parentNode.replaceChild(newEl, element); + + return Sabel.get(newEl); +}; + +Sabel.Element.getXPath = function(element) { + var buf = new Array(), idx, tagName = element.tagName; + + do { + if (element.getAttribute("id")) { + buf.unshift('id("' + element.getAttribute("id") + '")'); + return buf.join("/"); + } else { + if (document.getElementsByTagName(element.nodeName).length === 1) { + buf.unshift("/" + element.nodeName.toLowerCase()); + break; + } else { + idx = Sabel.Element.getPreviousSiblings(element, element.nodeName).length + 1; + buf.unshift(element.nodeName.toLowerCase() + "[" + idx + "]"); + } + } + } while ((element = element.parentNode) && element.nodeType === 1); + return "/" + buf.join("/"); +}; + +if (Sabel.UserAgent.isIE) { + Sabel.Element.getTextContent = function(element) { + return element.innerText; + }; +} else { + Sabel.Element.getTextContent = function(element) { + return element.textContent; + }; +} + +Sabel.Element.observe = function(element, eventName, handler, useCapture, scope) { + element = Sabel.get(element, false); + if (element._events === undefined) element._events = {}; + if (element._events[eventName] === undefined) element._events[eventName] = new Array(); + + var evt = new Sabel.Event(element, eventName, handler, useCapture, scope); + element._events[eventName].push(evt); + + return evt; +}; + +Sabel.Element.stopObserve = function(element, eventName, handler) { + element = Sabel.get(element, false); + var events = (element._events) ? element._events[eventName] : ""; + if (events.constructor === Array) { + if (typeof handler === "function") { + Sabel.Array.each(events, function(e) { if (e.getHandler() === handler) e.stop(); }); + } else { + Sabel.Array.each(events, function(e) { e.stop(); }); + } + } + + return element; +}; + +Sabel.Element.analyze = function(element) { + element = Sabel.get(element, false) + var as = element.attributes, buf = new Array(), attr, i = 0; + + buf.push("<" + element.tagName.toLowerCase()); + if (Sabel.UserAgent.isIE) { + var def = document.createElement(element.nodeName); + + var defAttr; + while ((attr = as[i++])) { + if (typeof attr.nodeValue !== "string") continue; + + defAttr = def.getAttributeNode(attr.nodeName); + if (defAttr != null && attr.nodeValue === defAttr.nodeValue) continue; + + buf[buf.length] = attr.nodeName + '="' + attr.nodeValue + '"'; + } + } else { + while ((attr = as[i++])) { + buf[buf.length] = attr.nodeName + '="' + attr.nodeValue + '"'; + } + } + + return buf.join(" ") + ">"; +}; + +Sabel.Element.getParentNode = function(element, tagName) { + tagName = (tagName || "").toUpperCase(); + element = Sabel.get(element, false); + while ((element = element.parentNode)) { + if (tagName === "" || tagName === element.tagName) + return new Sabel.Element(element); + } + return null; +}; + +Sabel.Element.getChildElements = function(element, tagName) { + tagName = (tagName || "").toUpperCase(); + var buf = new Array(); + element = Sabel.get(element, false); + Sabel.Array.each(element.childNodes, function(elm) { + if (elm.nodeType === 1) { + if (tagName === "" || tagName === elm.tagName) buf[buf.length] = elm; + } + }); + return buf; +}; + +Sabel.Element.getFirstChild = function(element, tagName) { + element = Sabel.Element.getChildElements(element, tagName)[0]; + return (element) ? new Sabel.Element(element) : null; +}; + +Sabel.Element.getLastChild = function(element, tagName) { + var elms = Sabel.Element.getChildElements(element, tagName); + return new Sabel.Element(elms[elms.length - 1]); +}; + +Sabel.Element.getNextSibling = function(element) { + while ((element = element.nextSibling)) { + if (element.nodeType === 1) return new Sabel.Element(element); + } + return null; +}; + +Sabel.Element.getPreviousSibling = function(element) { + while ((element = element.previousSibling)) { + if (element.nodeType === 1) return new Sabel.Element(element); + } + return null; +}; + +Sabel.Element.getPreviousSiblings = function(element, nodeName) { + nodeName = (nodeName || "").toUpperCase(); + var buf = new Array(); + while ((element = element.previousSibling)) { + if (element.nodeType === 1) { + if (nodeName === "" || nodeName === element.nodeName) + buf[buf.length] = element; + } + } + return buf; +}; + +Sabel.Element.getNextSiblings = function(element, nodeName) { + nodeName = (nodeName || "").toUpperCase(); + var buf = new Array(); + while ((element = element.nextSibling)) { + if (element.nodeType === 1) { + if (nodeName === "" || nodeName === element.nodeName) + buf[buf.length] = element; + } + } + return buf; +}; + +Sabel.Element.getNodeIndex = function(element, reverse, ofType) { + var ret; + if (ofType === true) { + ret = Sabel.Element._getOfTypeNodeIndex(element, reverse); + } else { + ret = Sabel.Element._getNodeIndex(element,reverse); + }; + return ret; +}; + +Sabel.Element._getNodeIndex = function(element, reverse) { + var parentNode = element.parentNode; + + var childNodes = parentNode.childNodes; + var propName = (reverse === true) ? "__cachedLastIdx" + : "__cachedIdx"; + if (parentNode.__cachedLength === childNodes.length) { + if (element[propName]) { + return element[propName]; + } + } + parentNode.__cachedLength = childNodes.length; + + if (reverse === true) { + childNodes = new Sabel.Array(childNodes).reverse(); + } + + for (var i = 0, idx = 1, child; child = childNodes[i]; i++) { + if (child.nodeType == 1) child[propName] = idx++; + } + + return element[propName]; +}; + +Sabel.Element._getOfTypeNodeIndex = function(element, reverse) { + var parentNode = element.parentNode; + var childNodes = parentNode.childNodes; + var propName = (reverse === true) ? "__cachedLastOfTypeIdx" + : "__cachedOfTypeIdx"; + + if (parentNode.__cachedLength === childNodes.length) { + if (element[propName]) { + return element[propName]; + } + } + + if (reverse === true) { + childNodes = new Sabel.Array(childNodes).reverse(); + } + parentNode.__cachedLength = childNodes.length; + + for (var i = 0, idx = 1, child; child = childNodes[i]; i++) { + if (child.tagName === element.tagName && child.nodeType === 1) { + child[propName] = idx++; + } + } + + return element[propName]; +}; + +Sabel.Element.isContain = function(element, other) { + if (element === document) element = document.body; + + if (element.contains) { + // IE, Opera, Safari + return element.contains(other); + } else { + // Firefox + return !!(element.compareDocumentPosition(other) & element.DOCUMENT_POSITION_CONTAINED_BY); + } +}; + +Sabel.CSS = {}; + +Sabel.CSS.rgbToHex = function(rgb) { + var hex = "#"; + Sabel.Array.each(rgb, function(num) { + hex += new Sabel.String("%02x").sprintf(num.toString(16)); + }); + return hex; +}; + +Sabel.CSS.getRGB = function(color) { + if (color.indexOf("#") === 0) { + if (color.length === 4) { + return [ + parseInt(color.charAt(1) + color.charAt(1), 16), + parseInt(color.charAt(2) + color.charAt(2), 16), + parseInt(color.charAt(3) + color.charAt(3), 16) + ]; + } else if (color.length === 7) { + return [ + parseInt(color.substr(1,2), 16), + parseInt(color.substr(3,2), 16), + parseInt(color.substr(5,2), 16) + ]; + } + } else if (color.search("\(([0-9, ]+)\)") !== -1) { + return RegExp.$1.replace(/ /g, "").split(","); + } else if (typeof color === "Array" && color.length === 3) { + return color; + } else { + if (color in Sabel.CSS.colorNames) return Sabel.CSS.colorNames[color]; + } + return null; +} + +Sabel.CSS.colorNames = { + black: [ 0, 0, 0], + blue: [ 0, 0, 255], + green: [ 0, 128, 0], + lime: [ 0, 255, 0], + cyan: [ 0, 255, 255], + purple: [128, 0, 128], + gray: [128, 128, 128], + silver: [192, 192, 192], + red: [255, 0, 0], + magenta: [255, 0, 255], + orange: [255, 165, 0], + pink: [255, 192, 203], + yellow: [255, 255, 0], + white: [255, 255, 255] +}; + +Sabel.Object.extend(Sabel.Element, Sabel.Object.Methods); + +Sabel.Elements = function(elements) { + if (typeof elements === "undefined") { + elements = new Sabel.Array(); + // @todo 普通のSabel.Elementが引っかかる + } else if (elements._extended === true) { + return elements; + } else if (elements.constructor !== Array) { + return null; + } else { + elements = new Sabel.Array(elements); + } + + return Sabel.Object.extend(elements, Sabel.Elements, true, true); +}; + +Sabel.Elements._extended = true; + +Sabel.Elements.add = function(elements, element) { + elements[elements.length] = element; +}; + +Sabel.Elements.item = function(elements, pos) { + var elm = elements[pos]; + + return (elm) ? new Sabel.Element(elm) : null; +}; + +Sabel.Elements.observe = function(elements, eventName, handler, useCapture, scope) { + Sabel.Array.each(elements, function(elm) { + Sabel.Element.observe(elm, eventName, handler, useCapture, scope); + }); +}; + +Sabel.Elements.stopObserve = function(elements, eventName, handler) { + Sabel.Array.each(elements, function(elm) { + Sabel.Element.stopObserve(elm, eventName, handler); + }); +}; + +Sabel.Elements.each = function(elements, callback) { + var i = 0, el; + while((el = elements.item(i))) callback(el, i++); + return elements; +}; + +Sabel.Elements.unique = function(elements) { + var finds = Sabel.Array.inject(elements, function(elm) { + if (elm._searched === true) return false; + elm._searched = true; + return true; + }); + + Sabel.Array.each(finds, function(elm) { elm._searched = false; }); + return finds; +}; + +Sabel.Object.extend(Sabel.Elements, Sabel.Object.Methods); + +Sabel.Iterator = function(iterable) { + this.items = Sabel.Array(iterable); + this.index = -1; +}; + +Sabel.Iterator.prototype = { + hasPrev: function() { + return this.index > 0; + }, + + hasNext: function() { + return this.index < this.items.length-1; + }, + + prev: function() { + return this.index > -1 ? this.items[--this.index] || null : null; + }, + + next: function() { + return this.hasNext() ? this.items[++this.index] || null : null; + } +}; + + +if (typeof window.XMLHttpRequest === "undefined") { + window.XMLHttpRequest = function() { + var http; + var objects = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]; + for (var i = 0, obj; obj = objects[i]; i++) { + try { + http = new ActiveXObject(obj); + window.XMLHttpRequest = function() { + return new ActiveXObject(obj); + } + break; + } catch (e) {} + } + return http; + } +}; + +Sabel.Ajax = function() { + this.init.apply(this, arguments); +}; + +Sabel.Ajax.prototype = { + init: function() { + this.xmlhttp = new XMLHttpRequest(); + this.completed = false; + }, + + request: function(url, options) { + var xmlhttp = this.xmlhttp; + options = this.setOptions(options); + + this.completed = false; + this._abort(); + + if (options.method === "get") { + url += ((url.indexOf("?") !== -1) ? "&" : "?") + options.params; + } + + xmlhttp.open(options.method, url, options.async); + xmlhttp.onreadystatechange = Sabel.Function.bind(this.onStateChange, this); + + this.setRequestHeaders(); + if (options.timeout) { + if (typeof xmlhttp.timeout !== "undefined") { + xmlhttp.timeout = options.timeout; + xmlhttp.ontimeout = Sabel.Function.bind(this.abort, this); + } else { + this.timer = setTimeout(Sabel.Function.bind(this.abort, this), options.timeout); + } + } + xmlhttp.send((options.method === "post") ? options.params : ""); + + if (options.async === false) { + this.onStateChange(); + } + }, + + abort: function() { + if (this._abort()) this.options.onTimeout.apply(this.options.scope); + }, + + _abort: function() { + var xmlhttp = this.xmlhttp; + if (xmlhttp.readyState !== 4) { + xmlhttp.onreadystatechange = Sabel.emptyFunc; + xmlhttp.abort(); + + return true; + } + return false; + }, + + updater: function(element, url, options) { + options = options || {}; + + var onComplete = options.onComplete || function() {}; + options.onComplete = function(response) { + Sabel.get(element).innerHTML = response.responseText; + onComplete(response); + } + + this.request(url, options); + }, + + setOptions: function(options) { + if (options === undefined) options = {}; + + var defaultOptions = { + method: "post", + params: "", + contentType: "application/x-www-form-urlencoded", + charset: "UTF-8", + onComplete: function(){}, + onSuccess: function(){}, + onFailure: function(){}, + onTimeout: function(){}, + scope: null, + async: true, + autoEval: false + }; + Sabel.Object.extend(options, defaultOptions); + options.method = options.method.toLowerCase(); + + if (options.params instanceof Object) { + options.params = new Sabel.QueryObject(options.params).serialize(); + } + + return (this.options = options); + }, + + setRequestHeaders: function() { + var headers = { + "X-Requested-With": "XMLHttpRequest", + "Accept": "text/javascript, text/html, application/xml, text/xml, */*" + }; + var xmlhttp = this.xmlhttp; + var options = this.options; + + if (options.method === "post") { + headers["Content-Type"] = options.contentType + "; charset=" + options.charset; + } + + if (typeof options.headers === "object") { + headers = Sabel.Object.extend(options.headers, headers); + } + + for (var key in headers) { + xmlhttp.setRequestHeader(key, headers[key]); + } + }, + + onStateChange: function() { + if (this.completed === true) return; + + if (this.xmlhttp.readyState === 4) { + this.completed = true; + clearTimeout(this.timer); + + var options = this.options; + var response = this.getResponses(); + options["on" + (this.isSuccess() ? "Success" : "Failure")].call(options.scope, response); + options.onComplete.call(options.scope, response); + + this.xmlhttp.onreadystatechange = Sabel.emptyFunc; + } + }, + + getResponses: function() { + var xmlhttp = this.xmlhttp; + var response = new Object(); + response.responseXML = xmlhttp.responseXML; + response.responseText = this.responseFilter(xmlhttp.responseText); + if (this.options.autoEval === true) { + response.responseJson = eval("eval(" + response.responseText+ ")"); + } + response.status = xmlhttp.status; + response.statusText = xmlhttp.statusText; + return response; + }, + + isSuccess: function() { + var status = this.xmlhttp.status; + return (status && (status >= 200 && status < 300)); + }, + + responseFilter: function(text) { + if (Sabel.UserAgent.isKHTML) { + var esc = escape(text); + if (esc.indexOf("%u") < 0 && esc.indexOf("%") > -1) { + text = decodeURIComponent(esc); + } + } + return text; + } +}; + +Sabel.History = function() { + this.init.apply(this, arguments); +}; + +Sabel.History.prototype = { + currentHash: "", + callback: null, + timer: null, + + init: function(callback) { + this.callback = callback || function() {} + var hash = this._getHash(document); + + if (hash !== "") this.callback(hash); + + if (typeof window.onhashchange === "undefined") { + this.timer = setInterval(Sabel.Function.bind(this._check, this), 300); + } else { + new Sabel.Event(window, "hashchange", this._check, false, this); + } + }, + + load: function(hash) { + this._setHash(hash.replace(/^#/, ""), true); + }, + + _check: function() { + var hash = this._getHash(document); + + if (hash !== this.currentHash) { + this._setHash(hash); + } + }, + + _setHash: function(hash, isUpdate) { + if (isUpdate === true) location.hash = "#" + hash; + this.currentHash = hash; + if (hash !== "") this.callback(hash); + }, + + _getHash: function(target) { + return new Sabel.Uri(target.location.href).hash.replace(/^[^#]*#/, ""); + } +}; + +if (Sabel.UserAgent.isIE && Sabel.UserAgent.version < 8) { + Sabel.History.prototype.init = function(callback) { + this.callback = callback || function() {} + var hash = this._getHash(document); + + this.iframe = document.createElement('