<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*/
namespace seekquarry\yioop\tests;
use seekquarry\yioop\library\JavascriptUnitTest;
use seekquarry\yioop\library\QrCode;
/**
* Holds the two encoders to the same answer. The symbol a page shows while
* it is being written is drawn in the browser and the one it shows once it
* is saved is drawn on the server, so a reader would meet two different
* symbols if the two ever disagreed. Each case draws the same text both
* ways and compares the grids square by square.
*/
class QrCodeJavascriptTest extends JavascriptUnitTest
{
/**
* Nothing is set up before a case.
*/
public function setUp()
{
}
/**
* Nothing is left behind after a case.
*/
public function tearDown()
{
}
/**
* The same text drawn on the server and in the browser must come out
* as the same squares, at every size the two of them make.
*
* @return string the html and Javascript that checks itself, either in
* a browser or, from the command line, under node
*/
public function sameSymbolBothWaysTestCase()
{
$texts = ["short", "HELLO WORLD",
"https://www.seekquarry.com/", str_repeat("a", 100),
str_repeat("b", 180)];
$cases = [];
foreach ($texts as $text) {
$grid = QrCode::grid($text);
$rows = [];
foreach ($grid as $row) {
$line = "";
foreach ($row as $square) {
$line .= $square ? "1" : "0";
}
$rows[] = $line;
}
$cases[] = ["name" => "size " . count($grid) . " across",
"text" => $text, "expected" => $rows];
}
return $this->renderCases("qr-both-ways", "Same Symbol Both Ways",
$cases);
}
/**
* Builds the block of html and Javascript that draws each text again
* in the browser and reports whether every square matches what the
* server drew.
*
* @param string $container_id id of the div the result table is added
* under
* @param string $test_name name shown for this group of cases
* @param array $cases each case's name, text, and the server's rows
* @return string the html and Javascript block for this group
*/
private function renderCases($container_id, $test_name, $cases)
{
$qr_cases = json_encode($cases);
ob_start();
?>
<div id="<?= $container_id ?>">
</div>
<script src="../scripts/basic.js" ></script>
<script src="../scripts/qr.js" ></script>
<script src="../scripts/javascript_unit_test.js" ></script>
<script>
var qr_cases = <?= $qr_cases ?>;
var results = [];
for (let index = 0; index < qr_cases.length; index++) {
let grid = qrGrid(qr_cases[index].text);
let rows = [];
for (let row = 0; row < grid.length; row++) {
let line = "";
for (let column = 0; column < grid[row].length; column++) {
line += grid[row][column] ? "1" : "0";
}
rows.push(line);
}
let same = (rows.length == qr_cases[index].expected.length);
for (let row = 0; same && row < rows.length; row++) {
if (rows[row] !== qr_cases[index].expected[row]) {
same = false;
}
}
results.push({ name: qr_cases[index].name, pass: same });
}
reportUnitTestResults("<?= $container_id ?>", "<?= $test_name ?>",
results);
</script>
<?php
$out_data = ob_get_contents();
ob_end_clean();
return $out_data;
}
}