/** * Tests PFXUtils::fgetsMB(). */ public function testfgetsMB() { /* Although this sort of violates the spirit of unit testing, I am engineering a test that is designed with knowledge of how PFXUtils::fgetsMB() works internally. It reads from the file handle in chunks of 4096 bytes, and one of the edge cases to worry about is using a two-byte EOL character and having it split between two fread() calls. For that reason I am using a string whose length in bytes (45) is a factor of 4095 so that I can just repeat it a bunch of times. */ $content = 'The quick brown fox jumped over the lazy dog.'; $contentLength = strlen($content); $this->assertEquals(45, $contentLength); $contentEncoding = 'UTF-8'; $tempFile = self::_createTempFile(); $eolChars = array("\n", "\r", "\r\n"); $sourceEncodings = mb_list_encodings(); $skipEncodings = array('UUENCODE', 'Quoted-Printable', 'BASE64', 'SJIS-2004'); $targetEncodings = array('UTF-8', 'ASCII'); foreach ($sourceEncodings as $sourceEncoding) { if (in_array($sourceEncoding, $skipEncodings)) { continue; } foreach ($eolChars as $eol) { foreach ($targetEncodings as $targetEncoding) { // Set up the content $expectedContent = ''; $fh = fopen($tempFile, 'wb'); /* Start with the big long line that's designed to test our edge case handling for UTF-8 and Windows-style line endings. */ $line = str_repeat($content, 4095 / $contentLength) . $eol; $expectedContent .= $line; if ($sourceEncoding != $contentEncoding) { $line = mb_convert_encoding($line, $sourceEncoding, $contentEncoding); } fwrite($fh, $line); // Write a few more lines of varying lengths $lineCount = mt_rand(6, 50); for ($i = 0; $i < $lineCount; $i++) { $line = str_repeat(' ', mt_rand(1, 100)) . $content; $charCount = mt_rand(1, 100); for ($j = 0; $j < $charCount; $j++) { $line .= chr(mt_rand(32, 126)); } $line .= $eol; $expectedContent .= $line; if ($sourceEncoding != $contentEncoding) { $line = mb_convert_encoding($line, $sourceEncoding, $contentEncoding); } fwrite($fh, $line); } fclose($fh); $buffer = ''; $first = true; $fh = fopen($tempFile, 'rb'); $fileContent = ''; while ($line = PFXUtils::fgetsMB($fh, $buffer, $sourceEncoding, $targetEncoding, $eol)) { if ($first) { /* The first line should be equal to our content multiplied by our multiplier followed by the EOL character. */ $this->assertEquals(str_repeat($content, 4095 / $contentLength) . $eol, $line, 'The first line did not contain the expected ' . 'content when reading content encoded as ' . $sourceEncoding . ' and converting to ' . $targetEncoding . ' and using the EOL style ' . str_replace(array("\r", "\n"), array('CR', 'LF'), $eol) . '.'); $first = false; } $fileContent .= $line; } $this->assertEquals($expectedContent, $fileContent, 'Transparent character set conversion failed when ' . 'reading content encoded as ' . $sourceEncoding . ' and converting to ' . $targetEncoding . ' and using the EOL style ' . str_replace(array("\r", "\n"), array('CR', 'LF'), $eol) . '.'); } } } }