Nette Documentation Preview

syntax
Állítások
*********

.[perex]
Az állítások azt bizonyítják, hogy egy tényleges érték megegyezik egy elvárt értékkel. Ezek a `Tester\Assert` metódusai.

Válassza ki a legpontosabb állításokat. Jobb a `Assert::same($a, $b)` mint a `Assert::true($a === $b)`, mert hiba esetén értelmes hibaüzenetet jelenít meg. A második esetben csak `false should be true` kapunk, és ez semmit sem mond a $a és $b változók tartalmáról.

A legtöbb állításnak lehet egy opcionális `$description` is, amely megjelenik a hibaüzenetben, ha az elvárás sikertelen.

A példák feltételezik, hogy a következő osztály alias van definiálva:

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


Assert::same($expected, $actual, ?string $description=null) .[method]
---------------------------------------------------------------------
`$expected` azonosnak kell lennie a `$actual` címmel. Ez megegyezik a `===` PHP-operátorral.


Assert::notSame($expected, $actual, ?string $description=null) .[method]
------------------------------------------------------------------------
Ellentétes a `Assert::same()`-val , tehát megegyezik a `!==` PHP-operátorral.


Assert::equal($expected, $actual, ?string $description=null, bool $matchOrder=false, bool $matchIdentity=false) .[method]
-------------------------------------------------------------------------------------------------------------------------
`$expected` ugyanannak kell lennie, mint a `$actual`. A `Assert::same()`-től eltérően az objektum azonosságát, a kulcspárok => érték sorrendjét a tömbökben, valamint a minimálisan eltérő decimális számokat figyelmen kívül hagyja, ami a `$matchIdentity` és a `$matchOrder` beállításával módosítható.

A következő esetek a `equal()` szempontjából azonosak, de a `same()` szempontjából nem:

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

Azonban vigyázat, a tömb `[1, 2]` és a `[2, 1]` nem egyenlőek, mert csak az értékek sorrendje különbözik, a kulcs => érték párok nem. A tömb `[1, 2]` írható úgy is, hogy `[0 => 1, 1 => 2]` és így `[1 => 2, 0 => 1]` egyenlőnek tekintjük.

Használhatjuk az úgynevezett [elvárásokat |#expectations] is a `$expected`.


Assert::notEqual($expected, $actual, ?string $description=null) .[method]
-------------------------------------------------------------------------
Ellentétben a `Assert::equal()`.


Assert::contains($needle, string|array $actual, ?string $description=null) .[method]
------------------------------------------------------------------------------------
Ha a `$actual` egy karakterlánc, akkor tartalmaznia kell a `$needle` részláncot. Ha tömb, akkor a `$needle` elemet kell tartalmaznia (szigorúan összehasonlításra kerül).


Assert::notContains($needle, string|array $actual, ?string $description=null) .[method]
---------------------------------------------------------------------------------------
A `Assert::contains()` ellentéte.


Assert::hasKey(string|int $needle, array $actual, ?string $description=null) .[method]{data-version:2.4}
--------------------------------------------------------------------------------------------------------
`$actual` tömbnek kell lennie, és tartalmaznia kell a `$needle` kulcsot.


Assert::notHasKey(string|int $needle, array $actual, ?string $description=null) .[method]{data-version:2.4}
-----------------------------------------------------------------------------------------------------------
`$actual` tömbnek kell lennie, és nem tartalmazhatja a `$needle` kulcsot.


Assert::true($value, ?string $description=null) .[method]
---------------------------------------------------------
`$value` a `true` kell, hogy legyen, tehát `$value === true`.


Assert::truthy($value, ?string $description=null) .[method]
-----------------------------------------------------------
`$value` igaznak kell lennie, tehát teljesíti a `if ($value) ...` feltételt.


Assert::false($value, ?string $description=null) .[method]
----------------------------------------------------------
`$value` kell lennie `false`, tehát `$value === false`.


Assert::falsey($value, ?string $description=null) .[method]
-----------------------------------------------------------
`$value` hamisnak kell lennie, tehát teljesíti a `if (!$value) ...` feltételt.


Assert::null($value, ?string $description=null) .[method]
---------------------------------------------------------
`$value` a `null` kell, hogy legyen, tehát `$value === null`.


Assert::notNull($value, ?string $description=null) .[method]
------------------------------------------------------------
`$value` nem lehet `null`, tehát `$value !== null`.


Assert::nan($value, ?string $description=null) .[method]
--------------------------------------------------------
`$value` nem lehet szám. A NAN teszteléshez csak a `Assert::nan()` címet használja. A NAN érték nagyon specifikus, és a `Assert::same()` vagy a `Assert::equal()` állítások kiszámíthatatlanul viselkedhetnek.


Assert::count($count, Countable|array $value, ?string $description=null) .[method]
----------------------------------------------------------------------------------
A `$value` elemszámának a `$count` kell lennie. Tehát ugyanaz, mint a `count($value) === $count`.


Assert::type(string|object $type, $value, ?string $description=null) .[method]
------------------------------------------------------------------------------
`$value` adott típusúnak kell lennie. Mint `$type` használhatjuk a stringet:
- `array`
- `list` - nullától kezdve a numerikus kulcsok növekvő sorrendjében indexelt tömb.
- `bool`
- `callable`
- `float`
- `int`
- `null`
- `object`
- `resource`
- `scalar`
- `string`
- osztály nevét vagy objektumot közvetlenül, akkor át kell adnia `$value instanceof $type`


Assert::exception(callable $callable, string $class, ?string $message=null, $code=null) .[method]
-------------------------------------------------------------------------------------------------
A `$callable` meghívásakor egy `$class` példányú kivételt kell dobni. Ha átadjuk a `$message` címet, a kivétel üzenetének [meg |#assert-match] kell [egyeznie |#assert-match]. És ha átadjuk a `$code`, a kivétel kódjának meg kell egyeznie.

Például ez a teszt sikertelen, mert a kivétel üzenete nem egyezik:

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

A `Assert::exception()` egy dobott kivételt ad vissza, így tesztelhet egy beágyazott kivételt.

```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]
----------------------------------------------------------------------------------------
Ellenőrzi, hogy a `$callable` meghívása a várt hibákat (azaz figyelmeztetéseket, értesítéseket stb.) generálja. Mint `$type` megadjuk a `E_...`, például a `E_WARNING` konstansok egyikét. És ha átadjuk a `$message`, a hibaüzenetnek is [meg |#assert-match] kell [felelnie |#assert-match] a mintának. Például:

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

Ha a visszahívás több hibát generál, akkor mindegyiket a pontos sorrendben kell várnunk. Ebben az esetben a tömböt a `$type` címen adjuk át:

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

.[note]
Ha a `$type` az osztály neve, akkor ez az állítás ugyanúgy viselkedik, mint a `Assert::exception()`.


Assert::noError(callable $callable) .[method]
---------------------------------------------
Ellenőrzi, hogy a `$callable` függvény nem dob-e PHP figyelmeztetést/értesítést/hibát vagy kivételt. Hasznos egy olyan kódrészlet teszteléséhez, ahol nincs más állítás.


Assert::match(string $pattern, $actual, ?string $description=null) .[method]
----------------------------------------------------------------------------
`$actual` kell, hogy egyezzen a `$pattern`. A minták két változatát használhatjuk: a reguláris kifejezéseket vagy a vadkártyákat.

Ha egy reguláris kifejezést adunk át a `$pattern` címen, akkor a `~` or `#` címet kell használnunk az elhatároláshoz. Más elválasztójelek nem támogatottak. Például a teszt, ahol a `$var` csak hexadecimális számjegyeket tartalmazhat:

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

A másik változat hasonló a string-összehasonlításhoz, de használhatunk néhány vad karaktert a `$pattern`:

- `%a%` egy vagy több bármi, kivéve a sor végi karaktereket.
- `%a?%` nulla vagy több bármi más, kivéve a sor végi karaktereket.
- `%A%` egy vagy több bármi, beleértve a sor végi karaktereket is.
- `%A?%` nulla vagy több bármiből, beleértve a sor végi karaktereket is.
- `%s%` egy vagy több szóköz karakter, kivéve a sor végi karaktereket.
- `%s?%` nulla vagy több szóköz karakter, kivéve a sor végi karaktereket
- `%S%` egy vagy több karakter, kivéve a szóközöket.
- `%S?%` nulla vagy több karakter, kivéve a szóközöket.
- `%c%` egyetlen bármilyen karakter (kivéve a sor végét)
- `%d%` egy vagy több számjegy
- `%d?%` nulla vagy több számjegy
- `%i%` előjeles egész érték
- `%f%` lebegőpontos szám
- `%h%` egy vagy több HEX számjegy
- `%w%` egy vagy több alfanumerikus karakter
- `%%` egy % karakter

Példák:

```php
# Again, hexadecimal number test
Assert::match('%h%', $var);

# Generalized path to file and line number
Assert::match('Error in file %a% on line %i%', $errorMessage);
```


Assert::matchFile(string $file, $actual, ?string $description=null) .[method]
-----------------------------------------------------------------------------
Az állítás megegyezik az [Assert::match()-vel |#assert-match], de a minta a `$file` oldalról töltődik be. Nagyon hosszú karakterláncok teszteléséhez hasznos. A tesztfájl olvashatóan áll.


Assert::fail(string $message, $actual=null, $expected=null) .[method]
---------------------------------------------------------------------
Ez az állítás mindig sikertelen. Csak praktikus. Opcionálisan átadhatjuk a várható és a tényleges értékeket.


Várakozások .[#toc-expectations]
--------------------------------
Ha összetettebb, nem konstans elemeket tartalmazó struktúrákat akarunk összehasonlítani, a fenti állítások nem biztos, hogy elegendőek. Például tesztelünk egy olyan metódust, amely létrehoz egy új felhasználót, és az attribútumait tömbként adja vissza. A jelszó hash-értékét nem ismerjük, de azt tudjuk, hogy annak hexadecimális karakterláncnak kell lennie. A következő elemről pedig csak annyit tudunk, hogy annak egy objektumnak kell lennie: `DateTime`.

Ezekben az esetekben a `Assert::equal()` és a `Assert::notEqual()` metódusok `$expected` paraméterén belül használhatjuk a `Tester\Expect` -t, amivel könnyen leírhatjuk a struktúrát.

```php
use Tester\Expect;

Assert::equal([
	'id' => Expect::type('int'),                   # we expect an integer
	'username' => 'milo',
	'password' => Expect::match('%h%'),            # we expect a string matching pattern
	'created_at' => Expect::type(DateTime::class), # we expect an instance of the class
], User::create(123, 'milo', 'RandomPaSsWoRd'));
```

A `Expect` segítségével szinte ugyanazokat az állításokat tehetjük, mint a `Assert` segítségével. Így olyan metódusaink vannak, mint a `Expect::same()`, `Expect::match()`, `Expect::count()`, stb. Ezen kívül láncolhatjuk őket, mint:

```php
Expect::type(MyIterator::class)->andCount(5);  # we expect MyIterator and items count is 5
```

Vagy írhatunk saját állításkezelőket.

```php
Expect::that(function ($value) {
	# return false if expectation fails
});
```


Sikertelen állítások vizsgálata .[#toc-failed-assertions-investigation]
-----------------------------------------------------------------------
A Tester megmutatja, hol van a hiba, ha egy állítás sikertelen. Amikor összetett struktúrákat hasonlítunk össze, a Tester dumps-ot készít az összehasonlított értékekről, és elmenti azokat a `output` könyvtárba. Például amikor a képzeletbeli `Arrays.recursive.phpt` teszt sikertelen, a dumps a következőképpen kerül elmentésre:

```
app/
└── tests/
	├── output/
	│   ├── Arrays.recursive.actual    # actual value
	│   └── Arrays.recursive.expected  # expected value
	│
	└── Arrays.recursive.phpt          # failing test
```

A könyvtár nevét a `Tester\Dumper::$dumpDir` címen változtathatjuk meg.

Állítások

Az állítások azt bizonyítják, hogy egy tényleges érték megegyezik egy elvárt értékkel. Ezek a Tester\Assert metódusai.

Válassza ki a legpontosabb állításokat. Jobb a Assert::same($a, $b) mint a Assert::true($a === $b), mert hiba esetén értelmes hibaüzenetet jelenít meg. A második esetben csak false should be true kapunk, és ez semmit sem mond a $a és $b változók tartalmáról.

A legtöbb állításnak lehet egy opcionális $description is, amely megjelenik a hibaüzenetben, ha az elvárás sikertelen.

A példák feltételezik, hogy a következő osztály alias van definiálva:

use Tester\Assert;

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

$expected azonosnak kell lennie a $actual címmel. Ez megegyezik a === PHP-operátorral.

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

Ellentétes a Assert::same()-val , tehát megegyezik a !== PHP-operátorral.

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

$expected ugyanannak kell lennie, mint a $actual. A Assert::same()-től eltérően az objektum azonosságát, a kulcspárok ⇒ érték sorrendjét a tömbökben, valamint a minimálisan eltérő decimális számokat figyelmen kívül hagyja, ami a $matchIdentity és a $matchOrder beállításával módosítható.

A következő esetek a equal() szempontjából azonosak, de a same() szempontjából nem:

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

Azonban vigyázat, a tömb [1, 2] és a [2, 1] nem egyenlőek, mert csak az értékek sorrendje különbözik, a kulcs ⇒ érték párok nem. A tömb [1, 2] írható úgy is, hogy [0 => 1, 1 => 2] és így [1 => 2, 0 => 1] egyenlőnek tekintjük.

Használhatjuk az úgynevezett elvárásokat is a $expected.

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

Ellentétben a Assert::equal().

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

Ha a $actual egy karakterlánc, akkor tartalmaznia kell a $needle részláncot. Ha tömb, akkor a $needle elemet kell tartalmaznia (szigorúan összehasonlításra kerül).

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

A Assert::contains() ellentéte.

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

$actual tömbnek kell lennie, és tartalmaznia kell a $needle kulcsot.

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

$actual tömbnek kell lennie, és nem tartalmazhatja a $needle kulcsot.

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

$value a true kell, hogy legyen, tehát $value === true.

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

$value igaznak kell lennie, tehát teljesíti a if ($value) ... feltételt.

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

$value kell lennie false, tehát $value === false.

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

$value hamisnak kell lennie, tehát teljesíti a if (!$value) ... feltételt.

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

$value a null kell, hogy legyen, tehát $value === null.

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

$value nem lehet null, tehát $value !== null.

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

$value nem lehet szám. A NAN teszteléshez csak a Assert::nan() címet használja. A NAN érték nagyon specifikus, és a Assert::same() vagy a Assert::equal() állítások kiszámíthatatlanul viselkedhetnek.

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

A $value elemszámának a $count kell lennie. Tehát ugyanaz, mint a count($value) === $count.

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

$value adott típusúnak kell lennie. Mint $type használhatjuk a stringet:

  • array
  • list – nullától kezdve a numerikus kulcsok növekvő sorrendjében indexelt tömb.
  • bool
  • callable
  • float
  • int
  • null
  • object
  • resource
  • scalar
  • string
  • osztály nevét vagy objektumot közvetlenül, akkor át kell adnia $value instanceof $type

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

A $callable meghívásakor egy $class példányú kivételt kell dobni. Ha átadjuk a $message címet, a kivétel üzenetének meg kell egyeznie. És ha átadjuk a $code, a kivétel kódjának meg kell egyeznie.

Például ez a teszt sikertelen, mert a kivétel üzenete nem egyezik:

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

A Assert::exception() egy dobott kivételt ad vissza, így tesztelhet egy beágyazott kivételt.

$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)

Ellenőrzi, hogy a $callable meghívása a várt hibákat (azaz figyelmeztetéseket, értesítéseket stb.) generálja. Mint $type megadjuk a E_..., például a E_WARNING konstansok egyikét. És ha átadjuk a $message, a hibaüzenetnek is meg kell felelnie a mintának. Például:

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

Ha a visszahívás több hibát generál, akkor mindegyiket a pontos sorrendben kell várnunk. Ebben az esetben a tömböt a $type címen adjuk át:

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

Ha a $type az osztály neve, akkor ez az állítás ugyanúgy viselkedik, mint a Assert::exception().

Assert::noError(callable $callable)

Ellenőrzi, hogy a $callable függvény nem dob-e PHP figyelmeztetést/értesítést/hibát vagy kivételt. Hasznos egy olyan kódrészlet teszteléséhez, ahol nincs más állítás.

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

$actual kell, hogy egyezzen a $pattern. A minták két változatát használhatjuk: a reguláris kifejezéseket vagy a vadkártyákat.

Ha egy reguláris kifejezést adunk át a $pattern címen, akkor a ~ or # címet kell használnunk az elhatároláshoz. Más elválasztójelek nem támogatottak. Például a teszt, ahol a $var csak hexadecimális számjegyeket tartalmazhat:

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

A másik változat hasonló a string-összehasonlításhoz, de használhatunk néhány vad karaktert a $pattern:

  • %a% egy vagy több bármi, kivéve a sor végi karaktereket.
  • %a?% nulla vagy több bármi más, kivéve a sor végi karaktereket.
  • %A% egy vagy több bármi, beleértve a sor végi karaktereket is.
  • %A?% nulla vagy több bármiből, beleértve a sor végi karaktereket is.
  • %s% egy vagy több szóköz karakter, kivéve a sor végi karaktereket.
  • %s?% nulla vagy több szóköz karakter, kivéve a sor végi karaktereket
  • %S% egy vagy több karakter, kivéve a szóközöket.
  • %S?% nulla vagy több karakter, kivéve a szóközöket.
  • %c% egyetlen bármilyen karakter (kivéve a sor végét)
  • %d% egy vagy több számjegy
  • %d?% nulla vagy több számjegy
  • %i% előjeles egész érték
  • %f% lebegőpontos szám
  • %h% egy vagy több HEX számjegy
  • %w% egy vagy több alfanumerikus karakter
  • %% egy % karakter

Példák:

# Again, hexadecimal number test
Assert::match('%h%', $var);

# Generalized path to file and line number
Assert::match('Error in file %a% on line %i%', $errorMessage);

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

Az állítás megegyezik az Assert::match()-vel, de a minta a $file oldalról töltődik be. Nagyon hosszú karakterláncok teszteléséhez hasznos. A tesztfájl olvashatóan áll.

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

Ez az állítás mindig sikertelen. Csak praktikus. Opcionálisan átadhatjuk a várható és a tényleges értékeket.

Várakozások

Ha összetettebb, nem konstans elemeket tartalmazó struktúrákat akarunk összehasonlítani, a fenti állítások nem biztos, hogy elegendőek. Például tesztelünk egy olyan metódust, amely létrehoz egy új felhasználót, és az attribútumait tömbként adja vissza. A jelszó hash-értékét nem ismerjük, de azt tudjuk, hogy annak hexadecimális karakterláncnak kell lennie. A következő elemről pedig csak annyit tudunk, hogy annak egy objektumnak kell lennie: DateTime.

Ezekben az esetekben a Assert::equal() és a Assert::notEqual() metódusok $expected paraméterén belül használhatjuk a Tester\Expect -t, amivel könnyen leírhatjuk a struktúrát.

use Tester\Expect;

Assert::equal([
	'id' => Expect::type('int'),                   # we expect an integer
	'username' => 'milo',
	'password' => Expect::match('%h%'),            # we expect a string matching pattern
	'created_at' => Expect::type(DateTime::class), # we expect an instance of the class
], User::create(123, 'milo', 'RandomPaSsWoRd'));

A Expect segítségével szinte ugyanazokat az állításokat tehetjük, mint a Assert segítségével. Így olyan metódusaink vannak, mint a Expect::same(), Expect::match(), Expect::count(), stb. Ezen kívül láncolhatjuk őket, mint:

Expect::type(MyIterator::class)->andCount(5);  # we expect MyIterator and items count is 5

Vagy írhatunk saját állításkezelőket.

Expect::that(function ($value) {
	# return false if expectation fails
});

Sikertelen állítások vizsgálata

A Tester megmutatja, hol van a hiba, ha egy állítás sikertelen. Amikor összetett struktúrákat hasonlítunk össze, a Tester dumps-ot készít az összehasonlított értékekről, és elmenti azokat a output könyvtárba. Például amikor a képzeletbeli Arrays.recursive.phpt teszt sikertelen, a dumps a következőképpen kerül elmentésre:

app/
└── tests/
	├── output/
	│   ├── Arrays.recursive.actual    # actual value
	│   └── Arrays.recursive.expected  # expected value
	│
	└── Arrays.recursive.phpt          # failing test

A könyvtár nevét a Tester\Dumper::$dumpDir címen változtathatjuk meg.