Skip to content

Commit

Permalink
Improve tests (#44)
Browse files Browse the repository at this point in the history
* build: hard dependencies

* test: ensure asArray is called

* maintenance: phpstan

* test: code sniffer tests

* wip: mess detector - working on reducing complexity

* test: improve tests

* test: improve coverage
  • Loading branch information
g105b committed Mar 5, 2023
1 parent 28604ad commit 1f12c0a
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 120 deletions.
24 changes: 13 additions & 11 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions example/01-shop.php
@@ -0,0 +1,82 @@
<?php
/**
* To run this example, from a terminal navigate to the example directory and run:
* php -S 0.0.0.0:8080
* then visit http://localhost:8080/01-shop.php in your web browser.
*/

use Gt\Dom\HTMLDocument;
use Gt\DomValidation\ValidationException;
use Gt\DomValidation\Validator;

require __DIR__ . "/../vendor/autoload.php";

$html = <<<HTML
<!doctype html>
<style>
[data-validation-error] {
border-left: 2px solid red;
}
[data-validation-error]::before {
content: attr(data-validation-error);
color: red;
font-weight: bold;
}
label {
display: block;
padding: 1rem;
}
label span {
display: block;
}
</style>
<form method="post">
<label>
<span>Your name</span>
<input name="name" required />
</label>
<label>
<span>Credit Card number</span>
<input name="credit-card" pattern="\d{16}" required />
</label>
<label>
<span>Expiry month</span>
<input name="expiry-month" type="number" min="1" max="12" required />
</label>
<label>
<span>Expiry year</span>
<input name="expiry-year" type="number" min="18" max="26" required />
</label>
<label>
<span>amount</span>
<input name="amount" type="number" value="100.50" readonly required />
</label>
<button name="do" value="buy">Buy the thing!</button>
</form>
HTML;

function example(HTMLDocument $document, array $input) {
$validator = new Validator();
$form = $document->forms[0];

try {
$validator->validate($form, $input);
} catch(ValidationException $exception) {
foreach($validator->getLastErrorList() as $name => $message) {
$errorElement = $form->querySelector("[name=$name]");
$errorElement->parentNode->dataset->validationError = $message;
}
return;
}

echo "Payment succeeded!";
exit;
}

$document = new HTMLDocument($html);

if(isset($_POST["do"]) && $_POST["do"] === "buy") {
example($document, $_POST);
}

echo $document;
7 changes: 7 additions & 0 deletions phpcs.xml
@@ -1,5 +1,7 @@
<?xml version="1.0"?>
<ruleset name="PHP.Gt Standard" namespace="Gt\CS\Standard">
<file>./src</file>

<description>Created from PHP.Gt/Styleguide</description>
<arg name="extensions" value="php" />

Expand Down Expand Up @@ -62,4 +64,9 @@
<rule ref="Generic.WhiteSpace.DisallowSpaceIndent" />
<rule ref="Generic.WhiteSpace.IncrementDecrementSpacing" />
<rule ref="Generic.WhiteSpace.LanguageConstructSpacing" />

<!-- We allow empty catch statements -->
<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedCATCH">
<severity>0</severity>
</rule>
</ruleset>
9 changes: 6 additions & 3 deletions src/ErrorList.php
Expand Up @@ -5,7 +5,7 @@
use Gt\Dom\Element;
use Iterator;

/** @implements Iterator<string, string[]> */
/** @implements Iterator<string, string> */
class ErrorList implements Countable, Iterator {
/** @var array<string, string[]> */
protected array $errorArray;
Expand Down Expand Up @@ -38,9 +38,12 @@ public function valid():bool {
return isset($keys[$this->iteratorKey]);
}

public function current():array {
public function current():string {
$keys = array_keys($this->errorArray);
return $this->errorArray[$keys[$this->iteratorKey]];
return implode(
"; ",
array_unique($this->errorArray[$keys[$this->iteratorKey]] ?? [])
);
}

public function next():void {
Expand Down
11 changes: 2 additions & 9 deletions src/Rule/TypeDate.php
Expand Up @@ -68,12 +68,8 @@ public function getHint(Element $element, string $value):string {

private function extractDateTime(
string $value,
?string $type,
string $type,
):?DateTime {
if(is_null($type)) {
return null;
}

if($type === "week") {
return $this->extractDateTimeWeek($value);
}
Expand All @@ -83,11 +79,8 @@ private function extractDateTime(
"month" => self::FORMAT_MONTH,
"datetime-local" => self::FORMAT_DATETIME_LOCAL,
"time" => self::FORMAT_TIME,
default => null,
default => "",
};
if(!$format) {
return null;
}

return DateTime::createFromFormat($format, $value) ?: null;
}
Expand Down
6 changes: 3 additions & 3 deletions test/phpunit/Rule/EmailTypeTest.php
Expand Up @@ -42,10 +42,10 @@ public function testEmailInvalid() {
catch(ValidationException) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(1, $errorArray);
$emailErrorArray = $errorArray["email"];
self::assertContains(
$emailError = $errorArray["email"];
self::assertSame(
"Field must be an email address",
$emailErrorArray
$emailError
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/phpunit/Rule/MaxLengthTest.php
Expand Up @@ -38,7 +38,7 @@ public function testMaxLength() {
}
catch(ValidationException $exception) {
$errorList = iterator_to_array($validator->getLastErrorList());
self::assertContains(
self::assertSame(
"This field's value must not contain more than 120 characters",
$errorList["tweet"]
);
Expand Down
2 changes: 1 addition & 1 deletion test/phpunit/Rule/MinLengthTest.php
Expand Up @@ -40,7 +40,7 @@ public function testMinLength() {
}
catch(ValidationException $exception) {
$errorList = iterator_to_array($validator->getLastErrorList());
self::assertContains(
self::assertSame(
"This field's value must contain at least 12 characters",
$errorList["password"]
);
Expand Down
23 changes: 8 additions & 15 deletions test/phpunit/Rule/PatternTest.php
Expand Up @@ -45,11 +45,10 @@ public function testPatternInvalid() {
catch(ValidationException $exception) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(1, $errorArray);
$creditCardErrorArray = $errorArray["credit-card"];
self::assertCount(1, $creditCardErrorArray);
self::assertEquals(
$creditCardError = $errorArray["credit-card"];
self::assertSame(
"This field does not match the required pattern",
$creditCardErrorArray[0]
$creditCardError
);
}
}
Expand All @@ -68,15 +67,9 @@ public function testPatternWithMissingRequiredFields() {
catch(ValidationException $exception) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(3, $errorArray);
$expiryMonthErrorArray = $errorArray["expiry-month"];
$expiryYearErrorArray = $errorArray["expiry-year"];
$amountErrorArray = $errorArray["amount"];
self::assertCount(1, $expiryMonthErrorArray);
self::assertCount(1, $expiryYearErrorArray);
self::assertCount(1, $amountErrorArray);
self::assertEquals($expiryMonthErrorArray[0], "This field is required");
self::assertEquals($expiryYearErrorArray[0], "This field is required");
self::assertEquals($amountErrorArray[0], "This field is required");
self::assertEquals($errorArray["expiry-month"], "This field is required");
self::assertEquals($errorArray["expiry-year"], "This field is required");
self::assertEquals($errorArray["amount"], "This field is required");
}
}

Expand All @@ -93,8 +86,8 @@ public function testPatternTitleShown() {
}
catch(ValidationException $exception) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertContains(
"This field does not match the required pattern: The 16 digit number on the front of your card",
self::assertSame(
"This field is required; This field does not match the required pattern: The 16 digit number on the front of your card",
$errorArray["credit-card"]
);
}
Expand Down
12 changes: 5 additions & 7 deletions test/phpunit/Rule/RequiredTest.php
Expand Up @@ -42,9 +42,8 @@ public function testSimpleMissingRequiredInputErrorList() {
$validator->validate($form, ["username" => "g105b"]);
}
catch(ValidationException $exception) {
foreach($validator->getLastErrorList() as $name => $errors) {
self::assertIsArray($errors);
self::assertContains("This field is required", $errors);
foreach($validator->getLastErrorList() as $error) {
self::assertSame("This field is required; This field's value must contain at least 12 characters", $error);
}
}
}
Expand All @@ -61,10 +60,9 @@ public function testSimpleEmptyRequiredInputErrorList() {
]);
}
catch(ValidationException $exception) {
foreach($validator->getLastErrorList() as $name => $errors) {
self::assertIsArray($errors);
self::assertContains("This field is required", $errors);
self::assertEquals("password", $name);
foreach($validator->getLastErrorList() as $name => $error) {
self::assertSame("This field is required; This field's value must contain at least 12 characters", $error);
self::assertSame("password", $name);
}
}
}
Expand Down
30 changes: 12 additions & 18 deletions test/phpunit/Rule/SelectElementTest.php
Expand Up @@ -39,10 +39,9 @@ public function testSelectMissingRequired() {
catch(ValidationException) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(1, $errorArray);
$currencyErrorArray = $errorArray["currency"];
self::assertContains(
self::assertSame(
"This field is required",
$currencyErrorArray
$errorArray["currency"]
);
}
}
Expand Down Expand Up @@ -80,10 +79,9 @@ public function testSelectTextContentInvalid() {
catch(ValidationException) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(1, $errorArray);
$currencyErrorArray = $errorArray["sort"];
self::assertContains(
self::assertSame(
"This field's value must match one of the available options",
$currencyErrorArray
$errorArray["sort"]
);
}
}
Expand Down Expand Up @@ -122,10 +120,9 @@ public function testSelectValue_invalid() {
catch(ValidationException $exception) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(1, $errorArray);
$currencyErrorArray = $errorArray["connections"];
self::assertContains(
self::assertSame(
"This field's value must match one of the available options",
$currencyErrorArray
$errorArray["connections"]
);
}
}
Expand All @@ -144,20 +141,17 @@ public function testSelectTwoInvalidOptionsAndOneMissing() {
catch(ValidationException $exception) {
$errorArray = iterator_to_array($validator->getLastErrorList());
self::assertCount(3, $errorArray);
$currencyErrorArray = $errorArray["currency"];
$sortErrorArray = $errorArray["sort"];
$connectionsErrorArray = $errorArray["connections"];
self::assertContains(
self::assertSame(
"This field is required",
$currencyErrorArray
$errorArray["currency"]
);
self::assertContains(
self::assertSame(
"This field's value must match one of the available options",
$sortErrorArray
$errorArray["sort"]
);
self::assertContains(
self::assertSame(
"This field's value must match one of the available options",
$connectionsErrorArray
$errorArray["connections"]
);
}
}
Expand Down

0 comments on commit 1f12c0a

Please sign in to comment.