/** * Provide tests from a given package to the test suite. Handles recursion. * * @param lang.reflect.Package $package * @param unittest.TestSuite $suite * @param var[] $arguments * @return void */ private function provideFrom($package, $suite, $arguments) { foreach ($package->getClasses() as $class) { if ($class->isSubclassOf(TestCase::class) && !Modifiers::isAbstract($class->getModifiers())) { $suite->addTestClass($class, $arguments); } } if ($this->recursive) { foreach ($package->getPackages() as $package) { $this->provideFrom($package, $suite, $arguments); } } }
/** * Returns a list of all classes inside a given package * * @param lang.reflect.Package * @param bool recursive whether to include subpackages * @return lang.XPClass[] */ protected static function testClassesIn(Package $package, $recursive) { $r = array(); foreach ($package->getClasses() as $class) { if (!$class->isSubclassOf('unittest.TestCase') || Modifiers::isAbstract($class->getModifiers())) { continue; } $r[] = $class; } if ($recursive) { foreach ($package->getPackages() as $package) { $r = array_merge($r, self::testClassesIn($package, $recursive)); } } return $r; }
/** * Configure router * * @param string setup * @param string base The base URI */ public function configure($setup, $base = '') { $package = \lang\reflect\Package::forName($setup); foreach ($package->getClasses() as $handler) { if ($handler->hasAnnotation('webservice')) { $this->addWebservice($handler, $base); } } }
/** * Creates a new resource-based XML input * * @param var $arg Either a lang.reflect.Package, a lang.XPClass or a string referring to a package * @param string $name */ public function __construct($arg, $name) { if ($arg instanceof XPClass) { $this->package = $arg->getPackage(); } else { if ($arg instanceof Package) { $this->package = $arg; } else { $this->package = Package::forName(strtr($arg, '\\', '.')); } } $this->name = $name; }
public function getPackage_returns_package_class_resides_in() { $this->assertEquals(Package::forName('net.xp_framework.unittest.reflection'), $this->fixture->getPackage()); }
public static function fixturePackage() { self::$package = Package::forName('webservices.rest.unittest.srv.fixture'); }
public function libPackageComment() { $this->assertEquals('Fixture libraries for package reflection tests', trim(Package::forName('net.xp_framework.unittest.reflection.lib')->getComment())); }
/** * Runs suite * * @param string[] args * @return int exitcode */ public function run(array $args) { if (!$args) { return $this->usage(); } // Setup suite $suite = new TestSuite(); // Parse arguments $sources = new Vector(); $listener = TestListeners::$DEFAULT; $arguments = []; $colors = null; try { for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-v' == $args[$i]) { $listener = TestListeners::$VERBOSE; } else { if ('-q' == $args[$i]) { $listener = TestListeners::$QUIET; } else { if ('-cp' == $args[$i]) { foreach (explode(PATH_SEPARATOR, $this->arg($args, ++$i, 'cp')) as $element) { ClassLoader::registerPath($element, null); } } else { if ('-e' == $args[$i]) { $arg = ++$i < $s ? $args[$i] : '-'; if ('-' === $arg) { $sources->add(new EvaluationSource(Streams::readAll($this->in->getStream()))); } else { $sources->add(new EvaluationSource($this->arg($args, $i, 'e'))); } } else { if ('-l' == $args[$i]) { $arg = $this->arg($args, ++$i, 'l'); $class = XPClass::forName(strstr($arg, '.') ? $arg : 'xp.unittest.' . ucfirst($arg) . 'Listener'); $arg = $this->arg($args, ++$i, 'l'); if ('-?' == $arg || '--help' == $arg) { return $this->listenerUsage($class); } $output = $this->streamWriter($arg); $instance = $suite->addListener($class->newInstance($output)); // Get all @arg-annotated methods $options = []; foreach ($class->getMethods() as $method) { if ($method->hasAnnotation('arg')) { $arg = $method->getAnnotation('arg'); if (isset($arg['position'])) { $options[$arg['position']] = $method; } else { $name = isset($arg['name']) ? $arg['name'] : strtolower(preg_replace('/^set/', '', $method->getName())); $short = isset($arg['short']) ? $arg['short'] : $name[0]; $options[$name] = $options[$short] = $method; } } } $option = 0; } else { if ('-o' == $args[$i]) { if (isset($options[$option])) { $name = '#' . ($option + 1); $method = $options[$option]; } else { $name = $this->arg($args, ++$i, 'o'); if (!isset($options[$name])) { $this->err->writeLine('*** Unknown listener argument ' . $name . ' to ' . nameof($instance)); return 2; } $method = $options[$name]; } $option++; if (0 == $method->numParameters()) { $pass = []; } else { $pass = $this->arg($args, ++$i, 'o ' . $name); } try { $method->invoke($instance, $pass); } catch (TargetInvocationException $e) { $this->err->writeLine('*** Error for argument ' . $name . ' to ' . $instance->getClassName() . ': ' . $e->getCause()->toString()); return 2; } } else { if ('-?' == $args[$i] || '--help' == $args[$i]) { return $this->usage(); } else { if ('-a' == $args[$i]) { $arguments[] = $this->arg($args, ++$i, 'a'); } else { if ('-w' == $args[$i]) { $this->arg($args, ++$i, 'w'); } else { if ('--color' == substr($args[$i], 0, 7)) { $remainder = (string) substr($args[$i], 7); if (!array_key_exists($remainder, self::$cmap)) { throw new IllegalArgumentException('Unsupported argument for --color (must be <empty>, "on", "off", "auto" (default))'); } $colors = self::$cmap[$remainder]; } else { if (strstr($args[$i], '.ini')) { $sources->add(new PropertySource(new Properties($args[$i]))); } else { if (strstr($args[$i], \xp::CLASS_FILE_EXT)) { $sources->add(new ClassFileSource(new File($args[$i]))); } else { if (strstr($args[$i], '.**')) { $sources->add(new PackageSource(Package::forName(substr($args[$i], 0, -3)), true)); } else { if (strstr($args[$i], '.*')) { $sources->add(new PackageSource(Package::forName(substr($args[$i], 0, -2)))); } else { if (false !== ($p = strpos($args[$i], '::'))) { $sources->add(new ClassSource(XPClass::forName(substr($args[$i], 0, $p)), substr($args[$i], $p + 2))); } else { if (is_dir($args[$i])) { $sources->add(new FolderSource(new Folder($args[$i]))); } else { $sources->add(new ClassSource(XPClass::forName($args[$i]))); } } } } } } } } } } } } } } } } } } catch (Throwable $e) { $this->err->writeLine('*** ', $e->getMessage()); \xp::gc(); return 2; } if ($sources->isEmpty()) { $this->err->writeLine('*** No tests specified'); return 2; } // Set up suite $l = $suite->addListener($listener->newInstance($this->out)); if ($l instanceof ColorizingListener) { $l->setColor($colors); } foreach ($sources as $source) { try { $tests = $source->testCasesWith($arguments); foreach ($tests as $test) { $suite->addTest($test); } } catch (NoSuchElementException $e) { $this->err->writeLine('*** Warning: ', $e->getMessage()); continue; } catch (IllegalArgumentException $e) { $this->err->writeLine('*** Error: ', $e->getMessage()); return 2; } catch (MethodNotImplementedException $e) { $this->err->writeLine('*** Error: ', $e->getMessage(), ': ', $e->method, '()'); return 2; } } // Run it! if (0 == $suite->numTests()) { return 3; } else { $r = $suite->run(); return $r->failureCount() > 0 ? 1 : 0; } }
/** * Set operation * * @param xp.xar.instruction.AbstractInstruction operation * @param string name */ protected static function setOperation(&$operation, $name) { if (null !== $operation) { self::bail('Cannot execute more than one instruction at a time.'); } $operation = \lang\reflect\Package::forName('xp.xar.instruction')->loadClass(ucfirst($name) . 'Instruction'); }
/** * Lists commands * * @return void */ protected function listCommands() { $commandsIn = function ($package) { $text = ''; foreach ($package->getClasses() as $class) { if ($class->isSubclassOf('util.cmd.Command') && !Modifiers::isAbstract($class->getModifiers())) { $text .= ' $ xpcli ' . $class->getSimpleName() . "\n"; } } return $text ?: ' (no commands)'; }; self::$err->writeLine('Named commands'); self::$err->writeLine(); if ($packages = Commands::allPackages()) { foreach (Commands::allPackages() as $package) { self::$err->writeLine('* ', $package); self::$err->writeLine($commandsIn($package)); } self::$err->writeLine(); } self::$err->writeLine('* Global package'); self::$err->writeLine($commandsIn(Package::forName(null))); }
/** * Main runner method * * @param string[] args */ public static function main(array $args) { if (!$args) { self::usage(); } // Parse arguments $output = '-'; for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-O' == $args[$i]) { $output = $args[++$i]; } else { if ('-?' == $args[$i] || '--help' == $args[$i]) { self::usage(); } else { $package = $args[$i]; break; } } } // Load generator class try { $class = \lang\reflect\Package::forName('xp.codegen')->getPackage($package)->loadClass('Generator'); } catch (\lang\ElementNotFoundException $e) { Console::$err->writeLine('*** No generator named "' . $package . '"'); exit(2); } $params = new ParamString(array_slice($args, $i + 1)); if ($params->exists('help', '?')) { Console::$err->writeLine(self::textOf($class->getComment())); exit(1); } // Instantiate generator $generator = $class->newInstance($params); $generator->storage = new FileSystemStorage(System::tempDir()); // Output if ('-' === $output) { $generator->output = new ConsoleOutput(Console::$err); } else { if (strstr($output, '.xar')) { $generator->output = new ArchiveOutput($output); } else { $generator->output = new FileSystemOutput($output); } } $generator->output->addObserver(newinstance('util.Observer', array(), '{ public function update($obs, $arg= NULL) { Console::writeLine(" >> ", $arg); } }')); Console::writeLine('===> Starting ', $generator); // Compile target chain $empty = new \lang\types\ArrayList(); $targets = create('new util.collections.HashTable<lang.reflect.Method, util.collections.HashTable<string, lang.Generic>>()'); foreach ($class->getMethods() as $method) { if (!$method->hasAnnotation('target')) { continue; } $target = create('new util.collections.HashTable<string, lang.Generic>()'); // Fetch dependencies if ($method->hasAnnotation('target', 'depends')) { $depends = create('new util.collections.Vector<lang.reflect.Method>()'); foreach ((array) $method->getAnnotation('target', 'depends') as $dependency) { $depends[] = $class->getMethod($dependency); } $target['depends'] = $depends; } // Fetch input if ($method->hasAnnotation('target', 'input')) { $arguments = create('new util.collections.Vector<lang.reflect.Method>()'); foreach ((array) $method->getAnnotation('target', 'input') as $input) { $arguments[] = $class->getMethod($input); } $target['arguments'] = $arguments; } $targets->put($method, $target); } // Invoke try { foreach ($targets->keys() as $method) { self::invoke($generator, $method, $targets); } } catch (\lang\reflect\TargetInvocationException $e) { Console::$err->writeLine('*** ', $e->getCause()); exit(3); } $generator->output->commit(); Console::writeLine('===> Done'); }
public function packageOfNewInstancedNamespacedClass() { $i = newinstance(NamespacedClass::class, []); $this->assertEquals(Package::forName('net.xp_framework.unittest.core'), $i->getClass()->getPackage()); }
public function register_package() { self::withPackage('util.cmd.unittest', function ($package) { $this->assertEquals([Package::forName($package)], Commands::allPackages()); }); }
/** * Main * * @param string[] args */ public static function main(array $args) { if (sizeof($args) < 1 || '' == $args[0]) { Console::$err->writeLine('*** No class or package name given'); return 2; } // Check whether a file, class or a package directory or name is given $cl = \lang\ClassLoader::getDefault(); if (strstr($args[0], \xp::CLASS_FILE_EXT)) { $class = $cl->loadUri(realpath($args[0])); } else { if ($cl->providesClass($args[0])) { $class = XPClass::forName($args[0], $cl); } else { if (strcspn($args[0], '\\/') < strlen($args[0])) { $package = self::findPackageBy(new Folder($args[0])); } else { $package = $args[0]; } $provided = false; foreach (\lang\ClassLoader::getLoaders() as $loader) { if (!$loader->providesPackage($package)) { continue; } Console::writeLine('@', $loader); $provided = true; } if ($provided) { self::printPackage(\lang\reflect\Package::forName($package)); return 0; } // Not found Console::$err->writeLine('*** Failed to locate either a class or a package named "', $args[0], '", tried all of {'); foreach (\lang\ClassLoader::getLoaders() as $loader) { Console::$err->writeLine(' ', $loader); } Console::$err->writeLine('}'); return 1; } } Console::writeLine('@', $class->getClassLoader()); if ($class->isInterface()) { self::printInterface($class); } else { if ($class->isEnum()) { self::printEnum($class); } else { self::printClass($class); } } return 0; }
public static function fixturePackage() { self::$package = \lang\reflect\Package::forName('net.xp_framework.unittest.webservices.rest.srv.fixture'); }
/** * Register named commands * * @param string $package * @return void */ public static function registerPackage($package) { self::$packages[$package] = Package::forName($package); }
/** * Retrieves the package associated with this class * * @return lang.reflect.Package */ public function getPackage() { return Package::forName(substr($this->name, 0, strrpos($this->name, '.'))); }
public function packageOfNewInstancedNamespacedClass() { $i = newinstance('net.xp_framework.unittest.core.NamespacedClass', array(), '{}'); $this->assertEquals(\lang\reflect\Package::forName('net.xp_framework.unittest.core'), $i->getClass()->getPackage()); }
public function remoteInterfaceMapping() { $this->serializer->mapPackage('net.xp_framework.easc.beans', \lang\reflect\Package::forName('remote.beans')); $this->serializer->mapping('I', new RemoteInterfaceMapping()); $class = $this->unserialize('I:12036987:{s:41:"net.xp_framework.easc.beans.BeanInterface";}', null, array('handler' => 'remote.protocol.XPProtocolHandler')); $this->assertSubclass($class, 'lang.reflect.Proxy'); $this->assertSubclass($class, 'remote.beans.BeanInterface'); }
/** * Main runner method * * @param string[] args */ public static function main(array $args) { // Parse args $api = new RestClient('http://builds.planet-xp.net/'); $action = null; $cat = null; for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-?' === $args[$i] || '--help' === $args[$i]) { break; } else { if ('-a' === $args[$i]) { $api->setBase($args[++$i]); } else { if ('-v' === $args[$i]) { $cat = create(new LogCategory('console'))->withAppender(new ColoredConsoleAppender()); } else { if ('-' === $args[$i][0]) { Console::$err->writeLine('*** Unknown argument ', $args[$i]); return 128; } else { $action = $args[$i]; // First non-option is the action name break; } } } } } if (null === $action) { Console::$err->writeLine(self::textOf(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getComment())); return 1; } try { $class = \lang\reflect\Package::forName('xp.install')->loadClass(ucfirst($action) . 'Action'); } catch (\lang\ClassNotFoundException $e) { Console::$err->writeLine('*** No such action "' . $action . '"'); return 2; } // Show help if (in_array('-?', $args) || in_array('--help', $args)) { Console::$out->writeLine(self::textOf($class->getComment())); return 3; } // Perform action $instance = $class->newInstance($api); $instance->setTrace($cat); try { return $instance->perform(array_slice($args, $i + 1)); } catch (\lang\Throwable $e) { Console::$err->writeLine('*** Error performing action ~ ', $e); return 1; } }
/** * Lists commands * * @return void */ protected function listCommands() { $commandsIn = function ($package) { $markdown = ''; foreach ($package->getClasses() as $class) { if ($class->isSubclassOf('util.cmd.Command') && !Modifiers::isAbstract($class->getModifiers())) { $markdown .= ' $ xp cmd ' . $class->getSimpleName() . "\n"; } } return $markdown ?: ' *(no commands)*'; }; $markdown = "# Named commands\n\n"; if ($packages = Commands::allPackages()) { foreach ($packages as $package) { $markdown .= '* In package **' . $package->getName() . "**\n\n" . $commandsIn($package); } $markdown .= "\n"; } $markdown .= "* In global package\n\n" . $commandsIn(Package::forName(null)); Help::render(self::$err, $markdown, []); }
public function loadClassFileWithRecusionInStaticBlock() { with($p = \lang\reflect\Package::forName('net.xp_framework.unittest.reflection.classes')); $two = $p->loadClass('StaticRecursionTwo'); $one = $p->loadClass('StaticRecursionOne'); $this->assertEquals($two, $one->getField('two')->get(null)); }
/** * Entry point method * * @param string[] args */ public static function main(array $args) { if (empty($args)) { return self::usage(); } foreach (ClassLoader::getLoaders() as $loader) { if ($loader instanceof JitClassLoader) { ClassLoader::removeLoader($loader); } } // Set up compiler $compiler = new Compiler(); $manager = new FileManager(); $manager->setSourcePaths(\xp::$classpath); // Handle arguments $profiles = ['default']; $emitter = 'php5.5'; $result = function ($success) { return $success ? 0 : 1; }; $files = []; $listener = new DefaultDiagnosticListener(Console::$out); for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-?' === $args[$i] || '--help' === $args[$i]) { return self::usage(); } else { if ('-cp' === $args[$i]) { \lang\ClassLoader::registerPath($args[++$i]); } else { if ('-sp' === $args[$i]) { $manager->addSourcePath($args[++$i]); } else { if ('-v' === $args[$i]) { $listener = new VerboseDiagnosticListener(Console::$out); } else { if ('-q' === $args[$i]) { $listener = new QuietDiagnosticListener(Console::$out); } else { if ('-t' === $args[$i]) { $levels = LogLevel::NONE; foreach (explode(',', $args[++$i]) as $level) { $levels |= LogLevel::named($level); } $compiler->setTrace(create(new LogCategory('xcc'))->withAppender(new ConsoleAppender(), $levels)); } else { if ('-E' === $args[$i]) { $emitter = $args[++$i]; } else { if ('-p' === $args[$i]) { $profiles = explode(',', $args[++$i]); } else { if ('-o' === $args[$i]) { $output = $args[++$i]; $folder = new Folder($output); $folder->exists() || $folder->create(); $manager->setOutput($folder); } else { if ('-N' === $args[$i]) { $dir = $args[++$i]; $manager->addSourcePath($dir); $files = array_merge($files, self::fromFolder($dir, false)); } else { if (is_dir($args[$i])) { $dir = $args[$i]; $manager->addSourcePath($dir); $files = array_merge($files, self::fromFolder($dir, true)); } else { $files[] = new FileSource(new File($args[$i])); } } } } } } } } } } } } // Check if (empty($files)) { Console::$err->writeLine('*** No files given (-? will show usage)'); return 2; } // Setup emitter sscanf($emitter, '%[^0-9]%d.%d', $language, $major, $minor); try { $emit = \lang\XPClass::forName('xp.compiler.emit.Emitter')->cast(Package::forName('xp.compiler.emit')->getPackage($language)->loadClass(($major ? 'V' . $major . $minor : '') . 'Emitter')->newInstance()); } catch (\lang\ClassCastException $e) { Console::$err->writeLine('*** Not an emitter implementation: ', $e->compoundMessage()); return 4; } catch (\lang\IllegalAccessException $e) { Console::$err->writeLine('*** Cannot use emitter named "', $emitter, '": ', $e->compoundMessage()); return 4; } catch (\lang\Throwable $e) { Console::$err->writeLine('*** No emitter named "', $emitter, '": ', $e->compoundMessage()); return 4; } // Load compiler profile configurations try { $reader = new CompilationProfileReader(); foreach ($profiles as $configuration) { $reader->addSource(new Properties('res://xp/compiler/' . $configuration . '.xcp.ini')); } $emit->setProfile($reader->getProfile()); } catch (\lang\Throwable $e) { Console::$err->writeLine('*** Cannot load profile configuration(s) ' . implode(',', $profiles) . ': ' . $e->getMessage()); return 3; } // Compile files and pass return value to result handler return $result($compiler->compile($files, $listener, $manager, $emit), array_slice($args, $i + 1)); }