Skip to content

Commit

Permalink
Improve command line runner errors
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Nov 17, 2023
1 parent a520e49 commit 3900fb8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ Web change log

## ?.?.? / ????-??-??

## 3.9.0 / 2023-11-17

* Improve error messages when class reference given on the command line
is not a `web.Application` subclass
(@thekid)

## 3.8.1 / 2023-05-22

* Extended EOF handling inside server protocol handler to include NULL,
Expand Down
39 changes: 29 additions & 10 deletions src/main/php/xp/web/Source.class.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,41 @@
<?php namespace xp\web;

use lang\{ClassLoader, XPClass};
use lang\{ClassLoader, XPClass, IllegalArgumentException, ClassLoadingException};
use web\Application;

/**
* An application source
*
* @test xp://web.unittest.SourceTest
* @test web.unittest.SourceTest
*/
class Source {
private $application;

/**
* Creates a new instance
*
* @param string $application
* @param web.Environment $environment
* @return web.Application
* @throws lang.IllegalArgumentException
*/
private function newInstance($application, $environment) {
if ('-' === $application) return new ServeDocumentRootStatically($environment);

$cl= ClassLoader::getDefault();
try {
$class= is_file($application) ? $cl->loadUri($application) : $cl->loadClass($application);
} catch (ClassLoadingException $e) {
throw new IllegalArgumentException('Cannot load class '.$application, $e);
}

if (!$class->isSubclassOf(Application::class)) {
throw new IllegalArgumentException($class->getName().' is not a web.Application');
}

return $class->newInstance($environment);
}

/**
* Creates a new application from a given name and environment
*
Expand All @@ -18,14 +44,7 @@ class Source {
*/
public function __construct($name, $environment) {
sscanf($name, '%[^+]+%s', $application, $filters);

if ('-' === $application) {
$this->application= new ServeDocumentRootStatically($environment);
} else if (is_file($application)) {
$this->application= ClassLoader::getDefault()->loadUri($application)->newInstance($environment);
} else {
$this->application= ClassLoader::getDefault()->loadClass($application)->newInstance($environment);
}
$this->application= $this->newInstance($application, $environment);

if ($filters) {
$this->application->install(array_map(
Expand Down
17 changes: 14 additions & 3 deletions src/test/php/web/unittest/SourceTest.class.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<?php namespace web\unittest;

use io\Path;
use lang\XPClass;
use test\{Assert, Before, Test};
use lang\{XPClass, IllegalArgumentException};
use test\{Assert, Before, Expect, Test};
use web\Environment;
use xp\web\{ServeDocumentRootStatically, Source};

class SourceTest {
private $environment;

public function __construct() {
#[Before]
public function environment() {
$this->environment= new Environment('dev', '.', 'static', []);
}

Expand Down Expand Up @@ -37,4 +38,14 @@ public function application_class_and_filter() {
$src= new Source('web.unittest.HelloWorld+xp.web.dev.Console', $this->environment);
Assert::instance(HelloWorld::class, $src->application());
}

#[Test, Expect(class: IllegalArgumentException::class, message: 'Cannot load class not.a.class')]
public function non_existant_class() {
(new Source('not.a.class', $this->environment))->application();
}

#[Test, Expect(class: IllegalArgumentException::class, message: 'util.Date is not a web.Application')]
public function unrelated_class() {
(new Source('util.Date', $this->environment))->application();
}
}

0 comments on commit 3900fb8

Please sign in to comment.