Nette Documentation Preview

syntax
Ισχυρισμοί
**********

.[perex]
Οι ισχυρισμοί χρησιμοποιούνται για να επιβεβαιώσουν ότι η πραγματική τιμή αντιστοιχεί στην αναμενόμενη τιμή. Πρόκειται για μεθόδους της κλάσης `Tester\Assert`.

Επιλέξτε τους καταλληλότερους ισχυρισμούς. Είναι καλύτερο το `Assert::same($a, $b)` από το `Assert::true($a === $b)`, επειδή σε περίπτωση αποτυχίας εμφανίζει ένα ουσιαστικό μήνυμα σφάλματος. Στη δεύτερη περίπτωση, μόνο το `false should be true` το οποίο δεν μας λέει τίποτα για το περιεχόμενο των μεταβλητών `$a` και `$b`.

Οι περισσότεροι ισχυρισμοί μπορούν επίσης να έχουν μια προαιρετική περιγραφή στην παράμετρο `$description`, η οποία εμφανίζεται στο μήνυμα σφάλματος εάν η προσδοκία αποτύχει.

Τα παραδείγματα προϋποθέτουν τη δημιουργία ενός alias:

```php
use Tester\Assert;
```


Assert::same($expected, $actual, ?string $description=null) .[method]
---------------------------------------------------------------------
Το `$expected` πρέπει να είναι ταυτόσημο με το `$actual`. Το ίδιο με τον τελεστή PHP `===`.


Assert::notSame($expected, $actual, ?string $description=null) .[method]
------------------------------------------------------------------------
Το αντίθετο του `Assert::same()`, δηλαδή το ίδιο με τον τελεστή PHP `!==`.


Assert::equal($expected, $actual, ?string $description=null, bool $matchOrder=false, bool $matchIdentity=false) .[method]
-------------------------------------------------------------------------------------------------------------------------
Το `$expected` πρέπει να είναι ίδιο με το `$actual`. Σε αντίθεση με το `Assert::same()`, αγνοείται η ταυτότητα των αντικειμένων, η σειρά των ζευγών κλειδιού => τιμής στους πίνακες και οι οριακά διαφορετικοί δεκαδικοί αριθμοί, κάτι που μπορεί να αλλάξει ρυθμίζοντας τα `$matchIdentity` και `$matchOrder`.

Οι ακόλουθες περιπτώσεις είναι ίδιες από την άποψη του `equal()`, αλλά όχι του `same()`:

```php
Assert::equal(0.3, 0.1 + 0.2);
Assert::equal($obj, clone $obj);
Assert::equal(
	['first' => 11, 'second' => 22],
	['second' => 22, 'first' => 11],
);
```

Ωστόσο, προσοχή, οι πίνακες `[1, 2]` και `[2, 1]` δεν είναι ίδιοι, επειδή διαφέρουν μόνο στη σειρά των τιμών, όχι των ζευγών κλειδιού => τιμής. Ο πίνακας `[1, 2]` μπορεί επίσης να γραφτεί ως `[0 => 1, 1 => 2]` και επομένως ως ίδιος θα θεωρηθεί ο `[1 => 2, 0 => 1]`.

Επιπλέον, στο `$expected` μπορούν να χρησιμοποιηθούν οι λεγόμενες [#Προσδοκίες].


Assert::notEqual($expected, $actual, ?string $description=null) .[method]
-------------------------------------------------------------------------
Το αντίθετο του `Assert::equal()`.


Assert::contains($needle, string|array $actual, ?string $description=null) .[method]
------------------------------------------------------------------------------------
Εάν το `$actual` είναι string, πρέπει να περιέχει το substring `$needle`. Εάν είναι array, πρέπει να περιέχει το στοιχείο `$needle` (συγκρίνεται αυστηρά).


Assert::notContains($needle, string|array $actual, ?string $description=null) .[method]
---------------------------------------------------------------------------------------
Το αντίθετο του `Assert::contains()`.


Assert::hasKey(string|int $needle, array $actual, ?string $description=null) .[method]{data-version:2.4}
--------------------------------------------------------------------------------------------------------
Το `$actual` πρέπει να είναι array και πρέπει να περιέχει το κλειδί `$needle`.


Assert::notHasKey(string|int $needle, array $actual, ?string $description=null) .[method]{data-version:2.4}
-----------------------------------------------------------------------------------------------------------
Το `$actual` πρέπει να είναι array και δεν πρέπει να περιέχει το κλειδί `$needle`.


Assert::true($value, ?string $description=null) .[method]
---------------------------------------------------------
Το `$value` πρέπει να είναι `true`, δηλαδή `$value === true`.


Assert::truthy($value, ?string $description=null) .[method]
-----------------------------------------------------------
Το `$value` πρέπει να είναι αληθές (truthy), δηλαδή να ικανοποιεί τη συνθήκη `if ($value) ...`.


Assert::false($value, ?string $description=null) .[method]
----------------------------------------------------------
Το `$value` πρέπει να είναι `false`, δηλαδή `$value === false`.


Assert::falsey($value, ?string $description=null) .[method]
-----------------------------------------------------------
Το `$value` πρέπει να είναι ψευδές (falsey), δηλαδή να ικανοποιεί τη συνθήκη `if (!$value) ...`.


Assert::null($value, ?string $description=null) .[method]
---------------------------------------------------------
Το `$value` πρέπει να είναι `null`, δηλαδή `$value === null`.


Assert::notNull($value, ?string $description=null) .[method]
------------------------------------------------------------
Το `$value` δεν πρέπει να είναι `null`, δηλαδή `$value !== null`.


Assert::nan($value, ?string $description=null) .[method]
--------------------------------------------------------
Το `$value` πρέπει να είναι Not a Number. Για τον έλεγχο της τιμής NAN χρησιμοποιείτε αποκλειστικά το `Assert::nan()`. Η τιμή NAN είναι πολύ συγκεκριμένη και οι assertions `Assert::same()` ή `Assert::equal()` μπορεί να λειτουργήσουν απροσδόκητα.


Assert::count($count, Countable|array $value, ?string $description=null) .[method]
----------------------------------------------------------------------------------
Ο αριθμός των στοιχείων στο `$value` πρέπει να είναι `$count`. Δηλαδή το ίδιο με `count($value) === $count`.


Assert::type(string|object $type, $value, ?string $description=null) .[method]
------------------------------------------------------------------------------
Το `$value` πρέπει να είναι του δεδομένου τύπου. Ως `$type` μπορούμε να χρησιμοποιήσουμε μια συμβολοσειρά:
- `array`
- `list` - πίνακας με δείκτες σε αύξουσα σειρά αριθμητικών κλειδιών από το μηδέν
- `bool`
- `callable`
- `float`
- `int`
- `null`
- `object`
- `resource`
- `scalar`
- `string`
- όνομα κλάσης ή απευθείας αντικείμενο, τότε το `$value` πρέπει να είναι `instanceof $type`


Assert::exception(callable $callable, string $class, ?string $message=null, $code=null) .[method]
-------------------------------------------------------------------------------------------------
Κατά την κλήση του `$callable` πρέπει να δημιουργηθεί μια εξαίρεση της κλάσης `$class`. Εάν αναφέρουμε `$message`, πρέπει να [αντιστοιχεί στο πρότυπο |#Assert::match] και το μήνυμα της εξαίρεσης, και αν αναφέρουμε `$code`, πρέπει να ταιριάζουν αυστηρά και οι κωδικοί.

Η ακόλουθη δοκιμή αποτυγχάνει, επειδή το μήνυμα της εξαίρεσης δεν αντιστοιχεί:

```php
Assert::exception(
	fn() => throw new App\InvalidValueException('Zero value'),
	App\InvalidValueException::class,
	'Value is to low',
);
```

Το `Assert::exception()` επιστρέφει την εξαίρεση που δημιουργήθηκε, οπότε μπορεί να ελεγχθεί και μια ένθετη εξαίρεση.

```php
$e = Assert::exception(
	fn() => throw new MyException('Something is wrong', 0, new RuntimeException),
	MyException::class,
	'Something is wrong',
);

Assert::type(RuntimeException::class, $e->getPrevious());
```


Assert::error(string $callable, int|string|array $type, ?string $message=null) .[method]
----------------------------------------------------------------------------------------
Ελέγχει ότι η συνάρτηση `$callable` δημιούργησε τα αναμενόμενα σφάλματα (δηλ. προειδοποιήσεις, ειδοποιήσεις κ.λπ.). Ως `$type` αναφέρουμε μία από τις σταθερές `E_...`, δηλαδή για παράδειγμα `E_WARNING`. Και αν αναφέρουμε `$message`, πρέπει να [αντιστοιχεί στο πρότυπο |#Assert::match] και το μήνυμα σφάλματος. Για παράδειγμα:

```php
Assert::error(
	fn() => $i++,
	E_NOTICE,
	'Undefined variable: i',
);
```

Εάν το callback δημιουργήσει περισσότερα σφάλματα, πρέπει να τα περιμένουμε όλα με την ακριβή σειρά. Σε αυτήν την περίπτωση, περνάμε στο `$type` έναν πίνακα:

```php
Assert::error(function () {
	$a++;
	$b++;
}, [
	[E_NOTICE, 'Undefined variable: a'],
	[E_NOTICE, 'Undefined variable: b'],
]);
```

.[note]
Εάν ως `$type` αναφέρετε όνομα κλάσης, συμπεριφέρεται το ίδιο με το `Assert::exception()`.


Assert::noError(callable $callable) .[method]
---------------------------------------------
Ελέγχει ότι η συνάρτηση `$callable` δεν δημιούργησε καμία προειδοποίηση, σφάλμα ή εξαίρεση. Είναι χρήσιμο για τον έλεγχο κομματιών κώδικα όπου δεν υπάρχει καμία άλλη assertion.


Assert::match(string $pattern, $actual, ?string $description=null) .[method]
----------------------------------------------------------------------------
Το `$actual` πρέπει να ταιριάζει με το πρότυπο `$pattern`. Μπορούμε να χρησιμοποιήσουμε δύο παραλλαγές προτύπων: κανονικές εκφράσεις ή μπαλαντέρ.

Εάν ως `$pattern` περάσουμε μια κανονική έκφραση, για τον οριοθέτησή της πρέπει να χρησιμοποιήσουμε `~` ή `#`, άλλοι οριοθέτες δεν υποστηρίζονται. Για παράδειγμα, μια δοκιμή όπου το `$var` πρέπει να περιέχει μόνο δεκαεξαδικούς αριθμούς:

```php
Assert::match('#^[0-9a-f]$#i', $var);
```

Η δεύτερη παραλλαγή είναι παρόμοια με τη συνήθη σύγκριση συμβολοσειρών, αλλά στο `$pattern` μπορούμε να χρησιμοποιήσουμε διάφορους μπαλαντέρ:

- `%a%` ένας ή περισσότεροι χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
- `%a?%` κανένας ή περισσότεροι χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
- `%A%` ένας ή περισσότεροι χαρακτήρες, συμπεριλαμβανομένων των χαρακτήρων τέλους γραμμής
- `%A?%` κανένας ή περισσότεροι χαρακτήρες, συμπεριλαμβανομένων των χαρακτήρων τέλους γραμμής
- `%s%` ένας ή περισσότεροι λευκοί χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
- `%s?%` κανένας ή περισσότεροι λευκοί χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
- `%S%` ένας ή περισσότεροι χαρακτήρες, εκτός από τους λευκούς χαρακτήρες
- `%S?%` κανένας ή περισσότεροι χαρακτήρες, εκτός από τους λευκούς χαρακτήρες
- `%c%` οποιοσδήποτε ένας χαρακτήρας, εκτός από τον χαρακτήρα τέλους γραμμής
- `%d%` ένα ή περισσότερα ψηφία
- `%d?%` κανένα ή περισσότερα ψηφία
- `%i%` προσημασμένη ακέραια τιμή
- `%f%` αριθμός με δεκαδικό σημείο
- `%h%` ένα ή περισσότερα δεκαεξαδικά ψηφία
- `%w%` ένας ή περισσότεροι αλφαριθμητικοί χαρακτήρες
- `%%` ο χαρακτήρας %

Παραδείγματα:

```php
# Πάλι έλεγχος για δεκαεξαδικό αριθμό
Assert::match('%h%', $var);

# Γενίκευση της διαδρομής αρχείου και του αριθμού γραμμής
Assert::match('Error in file %a% on line %i%', $errorMessage);
```


Assert::matchFile(string $file, $actual, ?string $description=null) .[method]
-----------------------------------------------------------------------------
Η assertion είναι ταυτόσημη με την [#Assert::match()], αλλά το πρότυπο φορτώνεται από το αρχείο `$file`. Αυτό είναι χρήσιμο για τον έλεγχο πολύ μεγάλων συμβολοσειρών. Το αρχείο με τη δοκιμή παραμένει ευανάγνωστο.


Assert::fail(string $message, $actual=null, $expected=null) .[method]
---------------------------------------------------------------------
Αυτή η assertion αποτυγχάνει πάντα. Μερικές φορές αυτό είναι απλά χρήσιμο. Προαιρετικά, μπορούμε να αναφέρουμε και την αναμενόμενη και την πραγματική τιμή.


Προσδοκίες
----------
Όταν θέλουμε να συγκρίνουμε πιο σύνθετες δομές με μη σταθερά στοιχεία, οι παραπάνω assertions μπορεί να μην είναι επαρκείς. Για παράδειγμα, ελέγχουμε μια μέθοδο που δημιουργεί έναν νέο χρήστη και επιστρέφει τα χαρακτηριστικά του ως πίνακα. Την τιμή του hash του κωδικού πρόσβασης δεν τη γνωρίζουμε, αλλά ξέρουμε ότι πρέπει να είναι μια δεκαεξαδική συμβολοσειρά. Και για ένα άλλο στοιχείο ξέρουμε μόνο ότι πρέπει να είναι ένα αντικείμενο `DateTime`.

Σε αυτές τις καταστάσεις μπορούμε να χρησιμοποιήσουμε το `Tester\Expect` μέσα στην παράμετρο `$expected` των μεθόδων `Assert::equal()` και `Assert::notEqual()`, με τις οποίες μπορούμε εύκολα να περιγράψουμε τη δομή.

```php
use Tester\Expect;

Assert::equal([
	'id' => Expect::type('int'),                   # περιμένουμε ακέραιο αριθμό
	'username' => 'milo',
	'password' => Expect::match('%h%'),            # περιμένουμε συμβολοσειρά που ταιριάζει με το πρότυπο
	'created_at' => Expect::type(DateTime::class), # περιμένουμε παρουσία της κλάσης
], User::create(123, 'milo', 'RandomPaSsWoRd'));
```

Με το `Expect` μπορούμε να εκτελέσουμε σχεδόν τις ίδιες assertions όπως με το `Assert`. Δηλαδή, έχουμε στη διάθεσή μας τις μεθόδους `Expect::same()`, `Expect::match()`, `Expect::count()` κ.λπ. Επιπλέον, μπορούμε να τις συνδέσουμε:

```php
Expect::type(MyIterator::class)->andCount(5);  # περιμένουμε MyIterator και αριθμό στοιχείων 5
```

Ή μπορούμε να γράψουμε τους δικούς μας handlers assertions.

```php
Expect::that(function ($value) {
	# επιστρέφουμε false, εάν η προσδοκία αποτύχει
});
```


Διερεύνηση λανθασμένων assertions
---------------------------------
Όταν μια assertion αποτυγχάνει, ο Tester εκτυπώνει πού είναι το λάθος. Εάν συγκρίνουμε πιο σύνθετες δομές, ο Tester δημιουργεί dumps των συγκρινόμενων τιμών και τις αποθηκεύει στον κατάλογο `output`. Για παράδειγμα, κατά την αποτυχία της φανταστικής δοκιμής `Arrays.recursive.phpt`, τα dumps θα αποθηκευτούν ως εξής:

```
app/
└── tests/
	├── output/
	│   ├── Arrays.recursive.actual    # πραγματική τιμή
	│   └── Arrays.recursive.expected  # αναμενόμενη τιμή
	│
	└── Arrays.recursive.phpt          # αποτυχημένη δοκιμή
```

Το όνομα του καταλόγου μπορούμε να το αλλάξουμε μέσω του `Tester\Dumper::$dumpDir`.

Ισχυρισμοί

Οι ισχυρισμοί χρησιμοποιούνται για να επιβεβαιώσουν ότι η πραγματική τιμή αντιστοιχεί στην αναμενόμενη τιμή. Πρόκειται για μεθόδους της κλάσης Tester\Assert.

Επιλέξτε τους καταλληλότερους ισχυρισμούς. Είναι καλύτερο το Assert::same($a, $b) από το Assert::true($a === $b), επειδή σε περίπτωση αποτυχίας εμφανίζει ένα ουσιαστικό μήνυμα σφάλματος. Στη δεύτερη περίπτωση, μόνο το false should be true το οποίο δεν μας λέει τίποτα για το περιεχόμενο των μεταβλητών $a και $b.

Οι περισσότεροι ισχυρισμοί μπορούν επίσης να έχουν μια προαιρετική περιγραφή στην παράμετρο $description, η οποία εμφανίζεται στο μήνυμα σφάλματος εάν η προσδοκία αποτύχει.

Τα παραδείγματα προϋποθέτουν τη δημιουργία ενός alias:

use Tester\Assert;

Assert::same($expected, $actual, ?string $description=null)

Το $expected πρέπει να είναι ταυτόσημο με το $actual. Το ίδιο με τον τελεστή PHP ===.

Assert::notSame($expected, $actual, ?string $description=null)

Το αντίθετο του Assert::same(), δηλαδή το ίδιο με τον τελεστή PHP !==.

Assert::equal($expected, $actual, ?string $description=null, bool $matchOrder=false, bool $matchIdentity=false)

Το $expected πρέπει να είναι ίδιο με το $actual. Σε αντίθεση με το Assert::same(), αγνοείται η ταυτότητα των αντικειμένων, η σειρά των ζευγών κλειδιού ⇒ τιμής στους πίνακες και οι οριακά διαφορετικοί δεκαδικοί αριθμοί, κάτι που μπορεί να αλλάξει ρυθμίζοντας τα $matchIdentity και $matchOrder.

Οι ακόλουθες περιπτώσεις είναι ίδιες από την άποψη του equal(), αλλά όχι του same():

Assert::equal(0.3, 0.1 + 0.2);
Assert::equal($obj, clone $obj);
Assert::equal(
	['first' => 11, 'second' => 22],
	['second' => 22, 'first' => 11],
);

Ωστόσο, προσοχή, οι πίνακες [1, 2] και [2, 1] δεν είναι ίδιοι, επειδή διαφέρουν μόνο στη σειρά των τιμών, όχι των ζευγών κλειδιού ⇒ τιμής. Ο πίνακας [1, 2] μπορεί επίσης να γραφτεί ως [0 => 1, 1 => 2] και επομένως ως ίδιος θα θεωρηθεί ο [1 => 2, 0 => 1].

Επιπλέον, στο $expected μπορούν να χρησιμοποιηθούν οι λεγόμενες Προσδοκίες.

Assert::notEqual($expected, $actual, ?string $description=null)

Το αντίθετο του Assert::equal().

Assert::contains($needle, string|array $actual, ?string $description=null)

Εάν το $actual είναι string, πρέπει να περιέχει το substring $needle. Εάν είναι array, πρέπει να περιέχει το στοιχείο $needle (συγκρίνεται αυστηρά).

Assert::notContains($needle, string|array $actual, ?string $description=null)

Το αντίθετο του Assert::contains().

Assert::hasKey(string|int $needle, array $actual, ?string $description=null)

Το $actual πρέπει να είναι array και πρέπει να περιέχει το κλειδί $needle.

Assert::notHasKey(string|int $needle, array $actual, ?string $description=null)

Το $actual πρέπει να είναι array και δεν πρέπει να περιέχει το κλειδί $needle.

Assert::true($value, ?string $description=null)

Το $value πρέπει να είναι true, δηλαδή $value === true.

Assert::truthy($value, ?string $description=null)

Το $value πρέπει να είναι αληθές (truthy), δηλαδή να ικανοποιεί τη συνθήκη if ($value) ....

Assert::false($value, ?string $description=null)

Το $value πρέπει να είναι false, δηλαδή $value === false.

Assert::falsey($value, ?string $description=null)

Το $value πρέπει να είναι ψευδές (falsey), δηλαδή να ικανοποιεί τη συνθήκη if (!$value) ....

Assert::null($value, ?string $description=null)

Το $value πρέπει να είναι null, δηλαδή $value === null.

Assert::notNull($value, ?string $description=null)

Το $value δεν πρέπει να είναι null, δηλαδή $value !== null.

Assert::nan($value, ?string $description=null)

Το $value πρέπει να είναι Not a Number. Για τον έλεγχο της τιμής NAN χρησιμοποιείτε αποκλειστικά το Assert::nan(). Η τιμή NAN είναι πολύ συγκεκριμένη και οι assertions Assert::same() ή Assert::equal() μπορεί να λειτουργήσουν απροσδόκητα.

Assert::count($count, Countable|array $value, ?string $description=null)

Ο αριθμός των στοιχείων στο $value πρέπει να είναι $count. Δηλαδή το ίδιο με count($value) === $count.

Assert::type(string|object $type, $value, ?string $description=null)

Το $value πρέπει να είναι του δεδομένου τύπου. Ως $type μπορούμε να χρησιμοποιήσουμε μια συμβολοσειρά:

  • array
  • list – πίνακας με δείκτες σε αύξουσα σειρά αριθμητικών κλειδιών από το μηδέν
  • bool
  • callable
  • float
  • int
  • null
  • object
  • resource
  • scalar
  • string
  • όνομα κλάσης ή απευθείας αντικείμενο, τότε το $value πρέπει να είναι instanceof $type

Assert::exception(callable $callable, string $class, ?string $message=null, $code=null)

Κατά την κλήση του $callable πρέπει να δημιουργηθεί μια εξαίρεση της κλάσης $class. Εάν αναφέρουμε $message, πρέπει να αντιστοιχεί στο πρότυπο και το μήνυμα της εξαίρεσης, και αν αναφέρουμε $code, πρέπει να ταιριάζουν αυστηρά και οι κωδικοί.

Η ακόλουθη δοκιμή αποτυγχάνει, επειδή το μήνυμα της εξαίρεσης δεν αντιστοιχεί:

Assert::exception(
	fn() => throw new App\InvalidValueException('Zero value'),
	App\InvalidValueException::class,
	'Value is to low',
);

Το Assert::exception() επιστρέφει την εξαίρεση που δημιουργήθηκε, οπότε μπορεί να ελεγχθεί και μια ένθετη εξαίρεση.

$e = Assert::exception(
	fn() => throw new MyException('Something is wrong', 0, new RuntimeException),
	MyException::class,
	'Something is wrong',
);

Assert::type(RuntimeException::class, $e->getPrevious());

Assert::error(string $callable, int|string|array $type, ?string $message=null)

Ελέγχει ότι η συνάρτηση $callable δημιούργησε τα αναμενόμενα σφάλματα (δηλ. προειδοποιήσεις, ειδοποιήσεις κ.λπ.). Ως $type αναφέρουμε μία από τις σταθερές E_..., δηλαδή για παράδειγμα E_WARNING. Και αν αναφέρουμε $message, πρέπει να αντιστοιχεί στο πρότυπο και το μήνυμα σφάλματος. Για παράδειγμα:

Assert::error(
	fn() => $i++,
	E_NOTICE,
	'Undefined variable: i',
);

Εάν το callback δημιουργήσει περισσότερα σφάλματα, πρέπει να τα περιμένουμε όλα με την ακριβή σειρά. Σε αυτήν την περίπτωση, περνάμε στο $type έναν πίνακα:

Assert::error(function () {
	$a++;
	$b++;
}, [
	[E_NOTICE, 'Undefined variable: a'],
	[E_NOTICE, 'Undefined variable: b'],
]);

Εάν ως $type αναφέρετε όνομα κλάσης, συμπεριφέρεται το ίδιο με το Assert::exception().

Assert::noError(callable $callable)

Ελέγχει ότι η συνάρτηση $callable δεν δημιούργησε καμία προειδοποίηση, σφάλμα ή εξαίρεση. Είναι χρήσιμο για τον έλεγχο κομματιών κώδικα όπου δεν υπάρχει καμία άλλη assertion.

Assert::match(string $pattern, $actual, ?string $description=null)

Το $actual πρέπει να ταιριάζει με το πρότυπο $pattern. Μπορούμε να χρησιμοποιήσουμε δύο παραλλαγές προτύπων: κανονικές εκφράσεις ή μπαλαντέρ.

Εάν ως $pattern περάσουμε μια κανονική έκφραση, για τον οριοθέτησή της πρέπει να χρησιμοποιήσουμε ~ ή #, άλλοι οριοθέτες δεν υποστηρίζονται. Για παράδειγμα, μια δοκιμή όπου το $var πρέπει να περιέχει μόνο δεκαεξαδικούς αριθμούς:

Assert::match('#^[0-9a-f]$#i', $var);

Η δεύτερη παραλλαγή είναι παρόμοια με τη συνήθη σύγκριση συμβολοσειρών, αλλά στο $pattern μπορούμε να χρησιμοποιήσουμε διάφορους μπαλαντέρ:

  • %a% ένας ή περισσότεροι χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
  • %a?% κανένας ή περισσότεροι χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
  • %A% ένας ή περισσότεροι χαρακτήρες, συμπεριλαμβανομένων των χαρακτήρων τέλους γραμμής
  • %A?% κανένας ή περισσότεροι χαρακτήρες, συμπεριλαμβανομένων των χαρακτήρων τέλους γραμμής
  • %s% ένας ή περισσότεροι λευκοί χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
  • %s?% κανένας ή περισσότεροι λευκοί χαρακτήρες, εκτός από τους χαρακτήρες τέλους γραμμής
  • %S% ένας ή περισσότεροι χαρακτήρες, εκτός από τους λευκούς χαρακτήρες
  • %S?% κανένας ή περισσότεροι χαρακτήρες, εκτός από τους λευκούς χαρακτήρες
  • %c% οποιοσδήποτε ένας χαρακτήρας, εκτός από τον χαρακτήρα τέλους γραμμής
  • %d% ένα ή περισσότερα ψηφία
  • %d?% κανένα ή περισσότερα ψηφία
  • %i% προσημασμένη ακέραια τιμή
  • %f% αριθμός με δεκαδικό σημείο
  • %h% ένα ή περισσότερα δεκαεξαδικά ψηφία
  • %w% ένας ή περισσότεροι αλφαριθμητικοί χαρακτήρες
  • %% ο χαρακτήρας %

Παραδείγματα:

# Πάλι έλεγχος για δεκαεξαδικό αριθμό
Assert::match('%h%', $var);

# Γενίκευση της διαδρομής αρχείου και του αριθμού γραμμής
Assert::match('Error in file %a% on line %i%', $errorMessage);

Assert::matchFile(string $file, $actual, ?string $description=null)

Η assertion είναι ταυτόσημη με την Assert::match(), αλλά το πρότυπο φορτώνεται από το αρχείο $file. Αυτό είναι χρήσιμο για τον έλεγχο πολύ μεγάλων συμβολοσειρών. Το αρχείο με τη δοκιμή παραμένει ευανάγνωστο.

Assert::fail(string $message, $actual=null, $expected=null)

Αυτή η assertion αποτυγχάνει πάντα. Μερικές φορές αυτό είναι απλά χρήσιμο. Προαιρετικά, μπορούμε να αναφέρουμε και την αναμενόμενη και την πραγματική τιμή.

Προσδοκίες

Όταν θέλουμε να συγκρίνουμε πιο σύνθετες δομές με μη σταθερά στοιχεία, οι παραπάνω assertions μπορεί να μην είναι επαρκείς. Για παράδειγμα, ελέγχουμε μια μέθοδο που δημιουργεί έναν νέο χρήστη και επιστρέφει τα χαρακτηριστικά του ως πίνακα. Την τιμή του hash του κωδικού πρόσβασης δεν τη γνωρίζουμε, αλλά ξέρουμε ότι πρέπει να είναι μια δεκαεξαδική συμβολοσειρά. Και για ένα άλλο στοιχείο ξέρουμε μόνο ότι πρέπει να είναι ένα αντικείμενο DateTime.

Σε αυτές τις καταστάσεις μπορούμε να χρησιμοποιήσουμε το Tester\Expect μέσα στην παράμετρο $expected των μεθόδων Assert::equal() και Assert::notEqual(), με τις οποίες μπορούμε εύκολα να περιγράψουμε τη δομή.

use Tester\Expect;

Assert::equal([
	'id' => Expect::type('int'),                   # περιμένουμε ακέραιο αριθμό
	'username' => 'milo',
	'password' => Expect::match('%h%'),            # περιμένουμε συμβολοσειρά που ταιριάζει με το πρότυπο
	'created_at' => Expect::type(DateTime::class), # περιμένουμε παρουσία της κλάσης
], User::create(123, 'milo', 'RandomPaSsWoRd'));

Με το Expect μπορούμε να εκτελέσουμε σχεδόν τις ίδιες assertions όπως με το Assert. Δηλαδή, έχουμε στη διάθεσή μας τις μεθόδους Expect::same(), Expect::match(), Expect::count() κ.λπ. Επιπλέον, μπορούμε να τις συνδέσουμε:

Expect::type(MyIterator::class)->andCount(5);  # περιμένουμε MyIterator και αριθμό στοιχείων 5

Ή μπορούμε να γράψουμε τους δικούς μας handlers assertions.

Expect::that(function ($value) {
	# επιστρέφουμε false, εάν η προσδοκία αποτύχει
});

Διερεύνηση λανθασμένων assertions

Όταν μια assertion αποτυγχάνει, ο Tester εκτυπώνει πού είναι το λάθος. Εάν συγκρίνουμε πιο σύνθετες δομές, ο Tester δημιουργεί dumps των συγκρινόμενων τιμών και τις αποθηκεύει στον κατάλογο output. Για παράδειγμα, κατά την αποτυχία της φανταστικής δοκιμής Arrays.recursive.phpt, τα dumps θα αποθηκευτούν ως εξής:

app/
└── tests/
	├── output/
	│   ├── Arrays.recursive.actual    # πραγματική τιμή
	│   └── Arrays.recursive.expected  # αναμενόμενη τιμή
	│
	└── Arrays.recursive.phpt          # αποτυχημένη δοκιμή

Το όνομα του καταλόγου μπορούμε να το αλλάξουμε μέσω του Tester\Dumper::$dumpDir.