32. Testovací script: PHP část

Ilustrační obrázek k článku: Testovací script: PHP část
V minulém díle jsme popsali princip testování a založili první testovací soubor. Dnes první část scriptu, který testy spustí a vyhodnotí jejich výsledky v PHP.

V minulém článku jsme definovali strukturu testů uložených v globální proměnné $Tests. Dnes se zaměříme na skript, který tyto testy spustí a zajistí konzistenci mezi PHP a JS – kritický požadavek pro naši kreativní platformu.

Struktura každého testu je jednoduchá:

  1. $Tests['nm_Util']['nm_IsNumber'][0] = [1, function()
  2. {
  3. Out(nm_IsNumber(5));
  4. },
  5. '5 je číslo'];

První výzva: zachytávání výstupů. K porovnání výsledků potřebujeme funkci Out(), která umí:

Místo globálních proměnných či objektů jsem se rozhodl pro statickou proměnnou uvnitř funkce – čisté řešení bez znečištění globálního prostoru:

  1. // Definice jednoznačných instancí
  2. define('TST_OUT_RESET', new stdClass());
  3. define('TST_OUT_GET', new stdClass());
  4. function Out($x)
  5. {
  6. static $buffer = '';
  7. if ($x === TST_OUT_RESET) return $buffer = '';
  8. if ($x === TST_OUT_GET) return $buffer;
  9. if (is_string($x) || is_int($x) || is_float($x) || is_bool($x) || is_null($x))
  10. {
  11. $buffer .= tst_ToHtml(json_encode($x, JSON_UNESCAPED_UNICODE));
  12. return;
  13. }
  14. if ($x instanceof Exception)
  15. {
  16. $s = ($x instanceof cs_Error) ? '#Err:' : '?Err:';
  17. $s .= $x->getMessage();
  18. if ($x instanceof cs_Error)
  19. {
  20. $data = $x->getData();
  21. if ($data && is_array($data) && count($data))
  22. {
  23. $s .= ' ' . json_encode($data, JSON_UNESCAPED_UNICODE);
  24. }
  25. }
  26. $buffer .= $s;
  27. return;
  28. }
  29. $buffer .= 'Out-UnknownType';
  30. }

Pro řízení funkce Out() jsem se rozhodl použít instance objektů protože nějaký "speciální string" by určitě mohl kolidovat s výsledkem testu.

Prozatím ukládáme data jako JSON – jednoduchý způsob, jak odlišit např. 5 (číslo) od "5" (řetězec). Očekáváme, že serializace v PHP a JS bude kompatibilní (později otestujeme hranice tohoto předpokladu :-).

Dále si definujeme základní strukturu stránky a v ní si definujeme, jaké knihovny budeme vkládat (jak pro PHP tak pro JS). Abychom tyto knihovny zadávalli jen 1x tak si je dáme do pole. A z tohoto pole je budeme cyklem vkládat jak do PHP (pomocí include), tak do JS (jako hodnotu atributu scr tagu SCRIPT). Pro systénové knihovny si určíme podadresář cs_src pro testovací cs_tests.

Základ našeho testovací scriptu bude tedy vypadat takto:

  1. <!DOCTYPE html>
  2. <HTML lang="cs">
  3. <HEAD>
  4. <META charset="UTF-8"/>
  5. <META name="viewport" content="width=device-width, initial-scale=1.0">
  6. <LINK rel="shortcut icon" href="./favicon.ico"/>
  7. <TITLE>CombiScript Tests</TITLE>
  8. <STYLE>
  9. BODY {
  10. background-color:#EEE;
  11. font-family:sans-serif;
  12. }
  13. .Tests {
  14. border-collapse: collapse;
  15. width:100%;
  16. }
  17. .Tests TD, .Tests TH {
  18. border:1px solid black;
  19. position:relative;
  20. }
  21. </STYLE>
  22. </HEAD>
  23. <BODY>
  24. <?php
  25. $Libs = ['cs_Util', 'nm_Util'];
  26. $TestLibs = ['nm_Util_Test'];
  27. foreach ($Libs AS $Nr => $Lib)
  28. include('./cs_src/'.$Lib.'.php.js');
  29. foreach ($TestLibs AS $Nr => $Lib)
  30. include('./cs_tests/'.$Lib.'.php.js');

Pro každý test generujeme HTML tabulku s pěti sloupci:

  1. Popis testu,
  2. Zdrojový kód,
  3. Výsledek v PHP,
  4. Výsledek v JS (později),
  5. Shoda/rozdíl (barevně odlišená).

Každý řádek má unikátní ID pro snadné ovládání z JavaScriptu:

  1. foreach ($Tests AS $File=>$FileArr)
  2. {
  3. foreach ($FileArr AS $Func=>$FuncArr)
  4. {
  5. echo '<H3>'.$Func.'</H3>';
  6. echo '<TABLE class=Tests><TR><TH>Popis</TH><TH>Zdroj</TH><TH>PHP</TH><TH>JS</TH><TH>Vysledek</TH></TR>';
  7. foreach ($FuncArr AS $TestId=>$TestArr)
  8. {
  9. echo '<TR id="'.$File.'-'.$Func.'-'.$TestId.'">';
  10. echo '<TD>'.tst_ToHtml($TestArr[2]).'</TD>';
  11. echo '<TD style="white-space:pre; font-family:monospace">'.htmlspecialchars(tst_GetClosureCode($TestArr[1])).'</TD>';
  12. echo '<TD>'.tst_RunTest($TestArr[1]).'</TD>';
  13. echo '<TD></TD>';
  14. echo '<TD></TD>';
  15. echo '</TR>';
  16. }
  17. echo '</TABLE>';
  18. }
  19. }

tst_ToHtml pro převedení textu na HTML:

  1. function tst_ToHtml($x)
  2. {
  3. return nl2br(htmlspecialchars($x));
  4. }

Obtížnější je funkce tst_SourceAnonymFunc, která zjistí zdrojový kód předané anonymní funkce. PHP bohužel nemá žádnou funkci, která by vracela zdrojový kód anonymní funkce v proměnné a proto si ji musíme napsat sami.

Takže jak na to půjdeme? Pomocí ReflectionFunction si zjistíme soubor a řádky kde funkce začíná a končí a vyparsujeme ji. Parsování bychom mohli udělat přes tokenizaci, ale zvolíme jednodušší metodu pomocí regulárního výrazu, s tím, že definujeme, že první výskyt function ( na řadku kde je deklarace funkce musí být tato funkce a funkce končí posledním výskytem }

  1. function tst_GetClosureCode($func)
  2. {
  3. static $cache = [];
  4. $ref = new ReflectionFunction($func);
  5. if (!$ref->isUserDefined()) return null;
  6. $file = $ref->getFileName();
  7. if (!isset($cache[$file]))
  8. $cache[$file] = file($file);
  9. $start = $ref->getStartLine() - 1;
  10. $end = $ref->getEndLine();
  11. $ret = implode('', array_slice($cache[$file], $start, $end - $start)); //\n uz je soucasti kazdy line ziskane pomoci funkce file()
  12. if (preg_match('/function\s*\(/i', $ret, $matches, PREG_OFFSET_CAPTURE)) $Begin = $matches[0][1]; //Pocitam s tim ze je to prvni "function (" na radku kde zacina deklarace funkce
  13. $End = strrpos($ret, '}'); //Pocitam s tim ze je to posledni "}" na radku kde konci deklarace funkce
  14. $ret = substr($ret, $Begin, $End-$Begin+1);
  15. return $ret;
  16. }

No a nakonec máme funkci tst_RunTest, u teré si musíme uvědomit, že běžící kód může vygenerovat i výjimku a my ji chceme převést na string.

  1. function tst_RunTest($test)
  2. {
  3. Out(TST_OUT_RESET);
  4. try
  5. {
  6. $test();
  7. }
  8. catch (Exception $e)
  9. {
  10. Out($e);
  11. }
  12. return Out(TST_OUT_GET);
  13. }

No a pokud všechny scripty spojíme získáme takovýto výstup:

    
  1. <!DOCTYPE html>
  2. <HTML lang="cs">
  3. <HEAD>
  4. <META charset="UTF-8"/>
  5. <META name="viewport" content="width=device-width, initial-scale=1.0">
  6. <LINK rel="shortcut icon" href="./favicon.ico"/>
  7. <TITLE>CombiScript Tests</TITLE>
  8. <STYLE>
  9. BODY {
  10. background-color:#EEE;
  11. font-family:sans-serif;
  12. }
  13. .Tests {
  14. border-collapse: collapse;
  15. width:100%;
  16. }
  17. .Tests TD, .Tests TH {
  18. border:1px solid black;
  19. position:relative;
  20. }
  21. </STYLE>
  22. </HEAD>
  23. <BODY>
  24. <?php
  25. $Libs = ['cs_Util', 'nm_Util'];
  26. $TestLibs = ['nm_Util_Test'];
  27. foreach ($Libs AS $Nr => $Lib)
  28. include('./cs_src/'.$Lib.'.php.js');
  29. foreach ($TestLibs AS $Nr => $Lib)
  30. include('./cs_tests/'.$Lib.'.php.js');
  31. function tst_ToHtml($x)
  32. {
  33. return nl2br(htmlspecialchars($x));
  34. }
  35. // Definice jednoznačných instancí
  36. define('TST_OUT_RESET', new stdClass());
  37. define('TST_OUT_GET', new stdClass());
  38. function Out($x)
  39. {
  40. static $buffer = '';
  41. if ($x === TST_OUT_RESET) return $buffer = '';
  42. if ($x === TST_OUT_GET) return $buffer;
  43. if (is_string($x) || is_int($x) || is_float($x) || is_bool($x) || is_null($x))
  44. {
  45. $buffer .= tst_ToHtml(json_encode($x, JSON_UNESCAPED_UNICODE));
  46. return;
  47. }
  48. if ($x instanceof Exception)
  49. {
  50. $s = ($x instanceof cs_Error) ? '#Err:' : '?Err:';
  51. $s .= $x->getMessage();
  52. if ($x instanceof cs_Error)
  53. {
  54. $data = $x->getData();
  55. if ($data && is_array($data) && count($data))
  56. {
  57. $s .= ' ' . json_encode($data, JSON_UNESCAPED_UNICODE);
  58. }
  59. }
  60. $buffer .= $s;
  61. return;
  62. }
  63. $buffer .= 'Out-UnknownType';
  64. }
  65. function tst_RunTest($test)
  66. {
  67. Out(TST_OUT_RESET);
  68. try
  69. {
  70. $test();
  71. }
  72. catch (Exception $e)
  73. {
  74. Out($e);
  75. }
  76. return Out(TST_OUT_GET);
  77. }
  78. function tst_GetClosureCode($func)
  79. {
  80. static $cache = [];
  81. $ref = new ReflectionFunction($func);
  82. if (!$ref->isUserDefined()) return null;
  83. $file = $ref->getFileName();
  84. if (!isset($cache[$file]))
  85. $cache[$file] = file($file);
  86. $start = $ref->getStartLine() - 1;
  87. $end = $ref->getEndLine();
  88. $ret = implode('', array_slice($cache[$file], $start, $end - $start)); //\n uz je soucasti kazdy line ziskane pomoci funkce file()
  89. if (preg_match('/function\s*\(/i', $ret, $matches, PREG_OFFSET_CAPTURE)) $Begin = $matches[0][1]; //Pocitam s tim ze je to prvni "function (" na radku kde zacina deklarace funkce
  90. $End = strrpos($ret, '}'); //Pocitam s tim ze je to posledni "}" na radku kde konci deklarace funkce
  91. $ret = substr($ret, $Begin, $End-$Begin+1);
  92. return $ret;
  93. }
  94. foreach ($Tests AS $File=>$FileArr)
  95. {
  96. foreach ($FileArr AS $Func=>$FuncArr)
  97. {
  98. echo '<H3>'.$Func.'</H3>';
  99. echo '<TABLE class=Tests><TR><TH>Popis</TH><TH>Zdroj</TH><TH>PHP</TH><TH>JS</TH><TH>Vysledek</TH></TR>';
  100. foreach ($FuncArr AS $TestId=>$TestArr)
  101. {
  102. echo '<TR id="'.$File.'-'.$Func.'-'.$TestId.'">';
  103. echo '<TD>'.tst_ToHtml($TestArr[2]).'</TD>';
  104. echo '<TD style="white-space:pre; font-family:monospace">'.htmlspecialchars(tst_GetClosureCode($TestArr[1])).'</TD>';
  105. echo '<TD>'.tst_RunTest($TestArr[1]).'</TD>';
  106. echo '<TD></TD>';
  107. echo '<TD></TD>';
  108. echo '</TR>';
  109. }
  110. echo '</TABLE>';
  111. }
  112. }
  113. ?>
  114. </BODY>
  115. <?php
  116. foreach ($Libs AS $Nr => $Lib)
  117. echo '<SCRIPT src="./cs_src/'.$Lib.'.php.js?'.date('YmdHis').'"></SCRIPT>';
  118. foreach ($TestLibs AS $Nr => $Lib)
  119. echo '<SCRIPT src="./cs_tests/'.$Lib.'.php.js?'.date('YmdHis').'"></SCRIPT>';
  120. ?>
  121. <SCRIPT>
  122. "use strict";
  123. </SCRIPT>
  124. </HTML>
  1. <!-- --><?php /*
  2. "use strict";
  3. //*/
  4. function nm_IsNumber($num)
  5. {
  6. 0&&0<!--$_;/*
  7. return typeof $num === 'number'
  8. /*/
  9. return is_int($num) OR is_float($num);
  10. //*/
  11. }
  12. function nm_Abs($num)
  13. {
  14. if (!nm_IsNumber($num)) throw new cs_Error('nm_Abs-$num-NotNumber', [cs_Type($num)]);
  15. 0&&0<!--$_;/*
  16. return Math.abs($num);
  17. /*/
  18. return abs($num);
  19. //*/
  20. }
  21. function nm_Sign($num)
  22. {
  23. if (!nm_IsNumber($num)) throw new cs_Error('nm_Sign-$num-NotNumber', [cs_Type($num)]);
  24. 0&&0<!--$_;/*
  25. return Math.sign($num);
  26. /*/
  27. return ($num > 0) - ($num < 0);
  28. //*/
  29. }
  30. function nm_IsAsInt($num)
  31. {
  32. 0&&0<!--$_;/*
  33. return Number.isInteger($num);
  34. /*/
  35. if (is_int($num)) return true;
  36. return (is_float($num) && floor($num) === $num);
  37. //*/
  38. }
  39. function nm_Pi()
  40. {
  41. 0&&0<!--$_;/*
  42. return Math.PI;
  43. /*/
  44. return Pi();
  45. //*/
  46. }
  47. function nm_Rad2Deg($rad)
  48. {
  49. if (!nm_IsNumber($rad)) throw new cs_Error('nm_Rad2Deg-$rad-NotNumber', [cs_Type($rad)]);
  50. 0&&0<!--$_;/*
  51. return $rad * (180/Math.PI);
  52. /*/
  53. return rad2deg($rad);
  54. //*/
  55. }
  56. function nm_Deg2Rad($deg)
  57. {
  58. if (!nm_IsNumber($deg)) throw new cs_Error('nm_Deg2Rad-$deg-NotNumber', [cs_Type($deg)]);
  59. 0&&0<!--$_;/*
  60. return $deg/180*Math.PI;
  61. /*/
  62. return deg2rad($deg);
  63. //*/
  64. }
  65. function nm_Sin($rad)
  66. {
  67. if (!nm_IsNumber($rad)) throw new cs_Error('nm_Sin-$rad-NotNumber', [cs_Type($rad)]);
  68. 0&&0<!--$_;/*
  69. return Math.sin($rad);
  70. /*/
  71. return sin($rad);
  72. //*/
  73. }
  74. function nm_Cos($rad)
  75. {
  76. if (!nm_IsNumber($rad)) throw new cs_Error('nm_Cos-$rad-NotNumber', [cs_Type($rad)]);
  77. 0&&0<!--$_;/*
  78. return Math.cos($rad);
  79. /*/
  80. return cos($rad);
  81. //*/
  82. }
  83. function nm_Tan($rad)
  84. {
  85. if (!nm_IsNumber($rad)) throw new cs_Error('nm_Tan-$rad-NotNumber', [cs_Type($rad)]);
  86. 0&&0<!--$_;/*
  87. return Math.tan($rad);
  88. /*/
  89. return tan($rad);
  90. //*/
  91. }
  92. function nm_ASin($num)
  93. {
  94. if (!nm_IsNumber($num)) throw new cs_Error('nm_ASin-$num-NotNumber', [cs_Type($num)]);
  95. if ($num>1 || $num<-1) throw new cs_Error('nm_ASin-$num-OutOfRange');
  96. 0&&0<!--$_;/*
  97. return Math.asin($num);
  98. /*/
  99. return asin($num);
  100. //*/
  101. }
  102. function nm_ACos($num)
  103. {
  104. if (!nm_IsNumber($num)) throw new cs_Error('nm_ACos-$num-NotNumber', [cs_Type($num)]);
  105. if ($num>1 || $num<-1) throw new cs_Error('nm_ACos-$num-OutOfRange');
  106. 0&&0<!--$_;/*
  107. return Math.acos($num);
  108. /*/
  109. return acos($num);
  110. //*/
  111. }
  112. function nm_ATan($num)
  113. {
  114. if (!nm_IsNumber($num)) throw new cs_Error('nm_ATan-$num-NotNumber', [cs_Type($num)]);
  115. 0&&0<!--$_;/*
  116. return Math.atan($num);
  117. /*/
  118. return atan($num);
  119. //*/
  120. }
  121. function nm_ATan2($y, $x)
  122. {
  123. if (!nm_IsNumber($y)) throw new cs_Error('nm_ATan2-$y-NotNumber', [cs_Type($y)]);
  124. if (!nm_IsNumber($x)) throw new cs_Error('nm_ATan2-$x-NotNumber', [cs_Type($x)]);
  125. 0&&0<!--$_;/*
  126. return Math.atan2($y, $x);
  127. /*/
  128. return atan2($y, $x);
  129. //*/
  130. }
  1. <!-- --><?php /*
  2. "use strict";
  3. class cs_Error extends Error
  4. {
  5. constructor($message, $data=[])
  6. {
  7. super($message);
  8. if (Error.captureStackTrace) Error.captureStackTrace(this, cs_Error);
  9. this.data = $data;
  10. }
  11. getData()
  12. {
  13. return this.data;
  14. }
  15. }
  16. /*/
  17. class cs_Error extends Exception
  18. {
  19. private $_data = '';
  20. public function __construct($message, $data=[])
  21. {
  22. $this->_data = $data;
  23. parent::__construct($message);
  24. }
  25. public function getData()
  26. {
  27. return $this->_data;
  28. }
  29. }
  30. //*/
  31. function cs_Type($var)
  32. {
  33. if ($var === null) return 'Null';
  34. if (nm_IsNumber($var)) return 'Number';
  35. //if (bl_IsBoolean($var)) return 'Boolean'; //TODO next
  36. //if (st_IsString($var)) return 'String';
  37. //if (ar_IsArray($var)) return 'Array';
  38. return 'Unknown';
  39. }
  1. <!-- --><?php
  2. "use strict";
  3. $Tests['nm_Util'] = [];
  4. $Tests['nm_Util']['nm_IsNumber'] = [
  5. [1, function()
  6. {
  7. Out(nm_IsNumber(5));
  8. },
  9. 'Ověřuje, že kladné celé číslo je číslo'],
  10. [1, function()
  11. {
  12. Out(nm_IsNumber(-5));
  13. },
  14. 'Ověřuje, že záporné celé číslo je číslo'],
  15. [1, function()
  16. {
  17. Out(nm_IsNumber(0));
  18. },
  19. 'Ověřuje, že nula je číslo'],
  20. [1, function()
  21. {
  22. Out(nm_IsNumber(2.5));
  23. },
  24. 'Ověřuje, že kladné desetinné číslo je číslo'],
  25. [1, function()
  26. {
  27. Out(nm_IsNumber(-2.5));
  28. },
  29. 'Ověřuje, že záporné desetinné číslo je číslo'],
  30. [1, function()
  31. {
  32. Out(nm_IsNumber(.5));
  33. },
  34. 'Ověřuje, že desetinné číslo s vynechanou úvodní nulou je číslo'],
  35. [1, function()
  36. {
  37. Out(nm_IsNumber(-.5));
  38. },
  39. 'Ověřuje, že záporné desetinné číslo s vynechanou úvodní nulou je číslo'],
  40. [1, function()
  41. {
  42. Out(nm_IsNumber(3.21E4));
  43. },
  44. 'Ověřuje, že číslo v exponenciálním tvaru je číslo'],
  45. [1, function()
  46. {
  47. Out(nm_IsNumber(-3.21E4));
  48. },
  49. 'Ověřuje, že záporné číslo v exponenciálním tvaru je číslo'],
  50. [1, function()
  51. {
  52. Out(nm_IsNumber(3.21E-4));
  53. },
  54. 'Ověřuje, že číslo s negativním exponentem je číslo'],
  55. [1, function()
  56. {
  57. Out(nm_IsNumber(-3.21E-4));
  58. },
  59. 'Ověřuje, že záporné číslo s negativním exponentem je číslo'],
  60. [1, function()
  61. {
  62. Out(nm_IsNumber(-3.21e-4));
  63. },
  64. 'Ověřuje, že se akceptuje malé "e" v exponenciálním tvaru'],
  65. [1, function()
  66. {
  67. Out(nm_IsNumber("123"));
  68. },
  69. 'Ověřuje, že string obsahující číslo není číslo'],
  70. [1, function()
  71. {
  72. Out(nm_IsNumber([1]));
  73. },
  74. 'Ověřuje, že pole není číslo']
  75. ];
  76. $Tests['nm_Util']['nm_IsAsInt'] = [
  77. [1, function()
  78. {
  79. Out(nm_IsAsInt(5));
  80. },
  81. 'Ověřuje, že kladné celé číslo je celé číslo'],
  82. [1, function()
  83. {
  84. Out(nm_IsAsInt(-5));
  85. },
  86. 'Ověřuje, že záporné celé číslo je celé číslo'],
  87. [1, function()
  88. {
  89. Out(nm_IsAsInt(5.0));
  90. },
  91. 'Ověřuje, že celočíselný float je celé číslo'],
  92. [1, function()
  93. {
  94. Out(nm_IsAsInt(-5.0));
  95. },
  96. 'Ověřuje, že záporný celočíselný float je celé číslo'],
  97. [1, function()
  98. {
  99. Out(nm_IsAsInt(0));
  100. },
  101. 'Ověřuje, že nula je celé číslo'],
  102. [1, function()
  103. {
  104. Out(nm_IsAsInt(-0));
  105. },
  106. 'Ověřuje, že minus nula je celé číslo'],
  107. [1, function()
  108. {
  109. Out(nm_IsAsInt(2.5));
  110. },
  111. 'Ověřuje, že kladné desetinné číslo není celé číslo'],
  112. [1, function()
  113. {
  114. Out(nm_IsAsInt(-2.5));
  115. },
  116. 'Ověřuje, že záporné desetinné číslo není celé číslo'],
  117. [1, function()
  118. {
  119. Out(nm_IsAsInt("123"));
  120. },
  121. 'Ověřuje, že string obsahující číslo není celé číslo'],
  122. [1, function()
  123. {
  124. Out(nm_IsAsInt(9007199254740991.5));
  125. },
  126. 'Ověřuje, že velké číslo s desetinnou částí se stále jeví jako integer (rozložení na číselné ose je už tak hrubé)'],
  127. [1, function()
  128. {
  129. Out(nm_IsAsInt(4.9999999999999995));
  130. },
  131. 'Toto ještě není 5'],
  132. [1, function()
  133. {
  134. Out(nm_IsAsInt(4.9999999999999996));
  135. },
  136. 'Toto už je 5']
  137. ];
  138. $Tests['nm_Util']['nm_Abs'] = [
  139. [1, function()
  140. {
  141. Out(nm_Abs(2.5));
  142. },
  143. 'Ověřuje, že absolutní hodnota kladného čísla je to samé číslo'],
  144. [1, function()
  145. {
  146. Out(nm_Abs(-2.5));
  147. },
  148. 'Ověřuje, že absolutní hodnota záporného čísla změní znaménko na kladné'],
  149. [1, function()
  150. {
  151. Out(nm_Abs(0));
  152. },
  153. 'Ověřuje, že absolutní hodnota nuly je nula'],
  154. [1, function()
  155. {
  156. Out(nm_Abs("123"));
  157. },
  158. 'Ověřuje, že pro nečíselný parametr se vyhodí chyba'],
  159. ];
  160. $Tests['nm_Util']['nm_Sign'] = [
  161. [1, function()
  162. {
  163. Out(nm_Sign(2.5));
  164. },
  165. 'Ověřuje, že signum kladného čísla je +1'],
  166. [1, function()
  167. {
  168. Out(nm_Sign(-2.5));
  169. },
  170. 'Ověřuje, že signum záporného čísla je -1'],
  171. [1, function()
  172. {
  173. Out(nm_Sign(0));
  174. },
  175. 'Ověřuje, že signum nuly je 0'],
  176. [1, function()
  177. {
  178. Out(nm_Sign(-0));
  179. },
  180. 'Ověřuje, že signum záporné nuly je také 0'],
  181. [1, function()
  182. {
  183. Out(nm_Sign("0"));
  184. },
  185. 'Ověřuje, že pro nečíselný parametr se vyhodí chyba'],
  186. ];

A příště si testovací script dokončíme doplněním jeho JS části

Předchozí