Initial commit: apps.supersam24.ru
This commit is contained in:
commit
e955e1da36
6566 files changed
+1271095
No files matched your search
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConstructTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var Csv object
|
||||
*/
|
||||
protected $csv = null;
|
||||
|
||||
public function test_offset_param() {
|
||||
$offset = 10;
|
||||
$this->csv = new Csv(null, $offset);
|
||||
$this->assertTrue(is_numeric($this->csv->offset));
|
||||
$this->assertEquals($offset, $this->csv->offset);
|
||||
}
|
||||
|
||||
public function test_limit_param() {
|
||||
$limit = 10;
|
||||
$this->csv = new Csv(null, null, $limit);
|
||||
$this->assertTrue(is_numeric($this->csv->limit));
|
||||
$this->assertEquals($limit, $this->csv->limit);
|
||||
}
|
||||
|
||||
public function test_conditions_param() {
|
||||
$conditions = 'some column NOT value';
|
||||
$this->csv = new Csv(null, null, null, $conditions);
|
||||
$this->assertTrue(is_string($this->csv->conditions));
|
||||
$this->assertEquals($conditions, $this->csv->conditions);
|
||||
}
|
||||
|
||||
public function test_keep_file_data_param() {
|
||||
$keep = true;
|
||||
$this->csv = new Csv(null, null, null, null, $keep);
|
||||
$this->assertTrue(is_bool($this->csv->keep_file_data));
|
||||
$this->assertEquals($keep, $this->csv->keep_file_data);
|
||||
}
|
||||
|
||||
public function test_input_param() {
|
||||
$csv = "col1,col2,col3\r\nval1,val2,val3\r\nval1A,val2A,val3A\r\n";
|
||||
$this->csv = new Csv($csv, null, null, null, true);
|
||||
$this->assertTrue(is_string($this->csv->file_data));
|
||||
$this->assertEquals($csv, $this->csv->file_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess because download.php uses header()
|
||||
*
|
||||
* @see https://github.com/sebastianbergmann/phpunit/issues/720#issuecomment-10421092
|
||||
*/
|
||||
public function testCodeExamples() {
|
||||
chdir('examples');
|
||||
foreach (glob('*.php') as $script_file) {
|
||||
ob_start();
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require $script_file;
|
||||
$ob_get_clean = ob_get_clean();
|
||||
$verb = strtok($script_file, '_.');
|
||||
|
||||
if (!in_array($verb, ['download', 'save'], true)) {
|
||||
$this->assertContains('<td>', $ob_get_clean);
|
||||
}
|
||||
}
|
||||
chdir('..');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
||||
class DataRowCountTest extends TestCase {
|
||||
|
||||
/**
|
||||
* CSV
|
||||
* The CSV object
|
||||
*
|
||||
* @access protected
|
||||
* @var Csv
|
||||
*/
|
||||
protected $csv;
|
||||
|
||||
/**
|
||||
* Setup
|
||||
* Setup our test environment objects
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->csv = new Csv();
|
||||
}
|
||||
|
||||
public function countRowsProvider() {
|
||||
return [
|
||||
'auto-double-enclosure' => [
|
||||
'auto-double-enclosure.csv',
|
||||
2,
|
||||
],
|
||||
'auto-single-enclosure' => [
|
||||
'auto-single-enclosure.csv',
|
||||
2,
|
||||
],
|
||||
'UTF-8_sep_row' => [
|
||||
'datatype.csv',
|
||||
3,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider countRowsProvider
|
||||
*
|
||||
* @param string $file
|
||||
* @param int $expectedRows
|
||||
*/
|
||||
public function testGetTotalRowCountFromFile($file, $expectedRows) {
|
||||
$this->csv->heading = true;
|
||||
$this->csv->load_data(__DIR__ . '/fixtures/' . $file);
|
||||
$this->assertEquals($expectedRows, $this->csv->getTotalDataRowCount());
|
||||
}
|
||||
|
||||
public function testGetTotalRowCountMissingEndingLineBreak() {
|
||||
$this->csv->heading = false;
|
||||
$this->csv->enclosure = '"';
|
||||
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\"";
|
||||
$this->csv->load_data($sInput);
|
||||
$this->assertEquals(3, $this->csv->getTotalDataRowCount());
|
||||
}
|
||||
|
||||
public function testGetTotalRowCountSingleEnclosure() {
|
||||
$this->csv->heading = false;
|
||||
$this->csv->enclosure = "'";
|
||||
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\'c\r\nd\'";
|
||||
$this->csv->load_data($sInput);
|
||||
$this->assertEquals(3, $this->csv->getTotalDataRowCount());
|
||||
}
|
||||
|
||||
public function testGetTotalRowCountSingleRow() {
|
||||
$this->csv->heading = false;
|
||||
$this->csv->enclosure = "'";
|
||||
$sInput = "86545235689";
|
||||
$this->csv->load_data($sInput);
|
||||
$this->assertEquals(1, $this->csv->getTotalDataRowCount());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sgorzaly
|
||||
* Date: 19.02.18
|
||||
* Time: 20:52
|
||||
*/
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\enums\DatatypeEnum;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DatatypeTest extends TestCase {
|
||||
|
||||
public function testSampleIsValidInteger() {
|
||||
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('+1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('-1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('--1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('test'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1.0'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1,0'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1,1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('0.1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('true'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
|
||||
}
|
||||
|
||||
public function testSampleIsValidBool() {
|
||||
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('true'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('TRUE'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('false'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('FALSE'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('FALS'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('test'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('0'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('0.1'));
|
||||
}
|
||||
|
||||
public function testSampleIsValidFloat() {
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1.0'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('-1.1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('+1,1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,1'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1e-03'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1e+03'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('test'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,,1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1..1'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
|
||||
}
|
||||
|
||||
public function testSampleIsValidDate() {
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('18-2-19'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('01.02.2018'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1.2.18'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('07/31/2018'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('31/07/2018'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1-2'));
|
||||
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1.2.'));
|
||||
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('test'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
/**
|
||||
* This is a very simple implementation of a stream wrapper. All URLs are mapped
|
||||
* to just one buffer. It exists to prove that ParseCsv can read and write
|
||||
* streams.
|
||||
*
|
||||
* @see https://www.php.net/manual/en/class.streamwrapper.php
|
||||
*/
|
||||
class ExampleStream {
|
||||
|
||||
private static $position = 0;
|
||||
|
||||
private static $stream_content;
|
||||
|
||||
public function stream_open($uri, $mode) {
|
||||
if (strpos($mode, 'a') === false) {
|
||||
self::$position = 0;
|
||||
}
|
||||
if (strpos($mode, 'w') !== false) {
|
||||
self::$stream_content = '';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_read($count) {
|
||||
$ret = substr(self::$stream_content, self::$position, $count);
|
||||
self::$position += strlen($ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function stream_write($data) {
|
||||
$left = substr(self::$stream_content, 0, self::$position);
|
||||
$right = substr(self::$stream_content, self::$position + strlen($data));
|
||||
self::$stream_content = $left . $data . $right;
|
||||
self::$position += strlen($data);
|
||||
return strlen($data);
|
||||
}
|
||||
|
||||
public function stream_stat() {
|
||||
return ['size' => strlen(self::$stream_content)];
|
||||
}
|
||||
|
||||
|
||||
public function stream_tell() {
|
||||
return self::$position;
|
||||
}
|
||||
|
||||
public function stream_eof() {
|
||||
return self::$position >= strlen(self::$stream_content);
|
||||
}
|
||||
|
||||
public function url_stat() {
|
||||
return ['size' => strlen(self::$stream_content)];
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence) {
|
||||
switch ($whence) {
|
||||
case SEEK_SET:
|
||||
if ($offset < strlen(self::$stream_content) && $offset >= 0) {
|
||||
self::$position = $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if ($offset >= 0) {
|
||||
self::$position += $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if (strlen(self::$stream_content) + $offset >= 0) {
|
||||
self::$position = strlen(self::$stream_content) + $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_lock($operation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stream_metadata() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
/**
|
||||
* Class HasToString is just a helper to test if cells can be objects.
|
||||
*/
|
||||
class ObjectThatHasToStringMethod {
|
||||
|
||||
public function __toString() {
|
||||
return 'some value';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* This test checks for backwards compatibility: Does it work to
|
||||
* - require the old "parsecsv.lib.php" instead of composer autoloading?
|
||||
* - use the old class name "parseCSV"?
|
||||
*/
|
||||
class OldRequireTest extends TestCase {
|
||||
|
||||
protected function setUp() {
|
||||
rename('vendor/autoload.php', '__autoload');
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
rename('__autoload', 'vendor/autoload.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess so that disabled autoloading has an effect
|
||||
*/
|
||||
public function testOldLibWithoutComposer() {
|
||||
|
||||
file_put_contents('__eval.php', '<?php require "parsecsv.lib.php"; new \ParseCsv\Csv;');
|
||||
exec("php __eval.php", $output, $return_var);
|
||||
unlink('__eval.php');
|
||||
$this->assertEquals($output, []);
|
||||
$this->assertEquals(0, $return_var);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess so that disabled autoloading has an effect
|
||||
*/
|
||||
public function testOldLibWithOldClassName() {
|
||||
|
||||
file_put_contents('__eval.php', '<?php require "parsecsv.lib.php"; new parseCSV;');
|
||||
exec("php __eval.php", $output, $return_var);
|
||||
unlink('__eval.php');
|
||||
$this->assertEquals($output, []);
|
||||
$this->assertEquals(0, $return_var);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class OutputTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess because download.php uses header()
|
||||
*/
|
||||
public function testOutputWithFourParameters() {
|
||||
$csv = new Csv();
|
||||
$data = [0 => ['a', 'b', 'c'], 1 => ['d', 'e', 'f']];
|
||||
$fields = ['col1', 'col2', 'col3'];
|
||||
$output = $csv->output('test.csv', $data, $fields, ',');
|
||||
$expected = "col1,col2,col3\ra,b,c\rd,e,f\r";
|
||||
self::assertEquals($expected, $output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ParseTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var Csv object
|
||||
*/
|
||||
protected $csv;
|
||||
|
||||
/**
|
||||
* Setup
|
||||
* Setup our test environment objects
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->csv = new Csv();
|
||||
}
|
||||
|
||||
public function testParse() {
|
||||
// can we trick 'is_readable' into whining? See #67.
|
||||
$this->parseRepetitiveString('c:/looks/like/a/path');
|
||||
$this->parseRepetitiveString('http://looks/like/an/url');
|
||||
}
|
||||
|
||||
private function parseRepetitiveString($content) {
|
||||
$this->csv->delimiter = ';';
|
||||
$this->csv->heading = false;
|
||||
$success = $this->csv->parse(str_repeat($content . ';', 500));
|
||||
$this->assertEquals(true, $success);
|
||||
|
||||
$row = array_pop($this->csv->data);
|
||||
$expected_data = array_fill(0, 500, $content);
|
||||
$expected_data [] = '';
|
||||
$this->assertEquals($expected_data, $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testParse
|
||||
*
|
||||
* @dataProvider autoDetectionProvider
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
public function testSepRowAutoDetection($file) {
|
||||
// This file (parse_test.php) is encoded in UTF-8, hence comparison will
|
||||
// fail unless we to this:
|
||||
$this->csv->output_encoding = 'UTF-8';
|
||||
|
||||
$this->csv->auto($file);
|
||||
$this->assertEquals($this->_get_magazines_data(), $this->csv->data);
|
||||
}
|
||||
|
||||
public function autoDetectionProvider() {
|
||||
return [
|
||||
'UTF8_no_BOM' => [__DIR__ . '/../example_files/UTF-8_sep_row_but_no_BOM.csv'],
|
||||
'UTF8' => [__DIR__ . '/../example_files/UTF-8_with_BOM_and_sep_row.csv'],
|
||||
'UTF16' => [__DIR__ . '/../example_files/UTF-16LE_with_BOM_and_sep_row.csv'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSingleColumnWithZeros() {
|
||||
$this->csv->delimiter = null;
|
||||
$this->csv->parse("URL\nhttp://www.amazon.com/ROX-Ice-Ball-Maker-Original/dp/B00MX59NMQ/ref=sr_1_1?ie=UTF8&qid=1435604374&sr=8-1&keywords=rox,+ice+molds");
|
||||
$row = array_pop($this->csv->data);
|
||||
$expected_data = ['URL' => 'http://www.amazon.com/ROX-Ice-Ball-Maker-Original/dp/B00MX59NMQ/ref=sr_1_1?ie=UTF8&qid=1435604374&sr=8-1&keywords=rox,+ice+molds'];
|
||||
$this->assertEquals($expected_data, $row);
|
||||
}
|
||||
|
||||
public function testAllNumericalCsv() {
|
||||
$this->csv->heading = false;
|
||||
$sInput = "86545235689\r\n34365587654\r\n13469874576";
|
||||
$this->assertEquals(false, $this->csv->auto($sInput));
|
||||
$this->assertEquals(null, $this->csv->delimiter);
|
||||
$expected_data = explode("\r\n", $sInput);
|
||||
$actual_data = array_map('reset', $this->csv->data);
|
||||
$this->assertEquals($expected_data, $actual_data);
|
||||
}
|
||||
|
||||
public function testMissingEndingLineBreak() {
|
||||
$this->csv->heading = false;
|
||||
$this->csv->enclosure = '"';
|
||||
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\"";
|
||||
$expected_data = [86545235689, 34365587654, 13469874576];
|
||||
|
||||
$actual_data = $this->invokeMethod($this->csv, '_parse_string', array($sInput));
|
||||
$actual_column = array_map('reset', $actual_data);
|
||||
$this->assertEquals($expected_data, $actual_column);
|
||||
$this->assertEquals([
|
||||
'a',
|
||||
'b',
|
||||
"c\r\nd",
|
||||
], array_map('next', $actual_data));
|
||||
}
|
||||
|
||||
public function testSingleColumn() {
|
||||
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
|
||||
$expected = [
|
||||
['SMS' => '0444'],
|
||||
['SMS' => '5555'],
|
||||
['SMS' => '6606'],
|
||||
['SMS' => '7777'],
|
||||
];
|
||||
$this->assertEquals($expected, $this->csv->data);
|
||||
}
|
||||
|
||||
public function testMatomoData() {
|
||||
// Matomo (Piwik) export cannot be read with
|
||||
$this->csv->use_mb_convert_encoding = true;
|
||||
$this->csv->output_encoding = 'UTF-8';
|
||||
$this->csv->auto(__DIR__ . '/../example_files/Piwik_API_download.csv');
|
||||
$aAction27 = array_column($this->csv->data, 'url (actionDetails 27)');
|
||||
$this->assertEquals([
|
||||
'http://application/_Main/_GraphicMeanSTD_MDI/btnConfBandOptions',
|
||||
'',
|
||||
'',
|
||||
], $aAction27);
|
||||
|
||||
$aCity = array_column($this->csv->data, 'city');
|
||||
$this->assertEquals([
|
||||
'São Paulo',
|
||||
'Johannesburg',
|
||||
'',
|
||||
], $aCity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if we can handle BOMs in string data, in contrast to loading files.
|
||||
*/
|
||||
public function testStringWithLeadingBOM() {
|
||||
$string_with_bom = strtr(
|
||||
file_get_contents(__DIR__ . '/../example_files/UTF-8_with_BOM_and_sep_row.csv'),
|
||||
["sep=;\n" => '']);
|
||||
|
||||
// Is the BOM still there?
|
||||
self::assertSame(0xEF, ord($string_with_bom));
|
||||
|
||||
$this->csv->output_encoding = 'UTF-8';
|
||||
$this->csv->delimiter = ';';
|
||||
self::assertTrue($this->csv->load_data($string_with_bom));
|
||||
self::assertTrue($this->csv->parse($this->csv->file_data));
|
||||
|
||||
// This also tests if ::load_data removed the BOM from the data;
|
||||
// otherwise the 'title' column would have 3 extra bytes.
|
||||
$this->assertEquals([
|
||||
'title',
|
||||
'isbn',
|
||||
'publishedAt',
|
||||
], array_keys(reset($this->csv->data)));
|
||||
|
||||
$titles = array_column($this->csv->data, 'title');
|
||||
$this->assertEquals([
|
||||
'Красивая кулинария',
|
||||
'The Wine Connoisseurs',
|
||||
'Weißwein',
|
||||
], $titles);
|
||||
}
|
||||
|
||||
public function testWithMultipleNewlines() {
|
||||
$this->csv->auto(__DIR__ . '/../example_files/multiple_empty_lines.csv');
|
||||
$aElse9 = array_column($this->csv->data, 'else9');
|
||||
|
||||
/** @noinspection SpellCheckingInspection */
|
||||
$this->assertEquals([
|
||||
'Abweichung',
|
||||
'Abweichung',
|
||||
'Abweichung',
|
||||
'Alt',
|
||||
'Fehlt',
|
||||
'Neu',
|
||||
'OK',
|
||||
'Fehlt',
|
||||
'Fehlt',
|
||||
'Fehlt',
|
||||
], $aElse9);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSepRowAutoDetection
|
||||
*/
|
||||
public function testGetColumnDatatypes() {
|
||||
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
|
||||
$this->csv->getDatatypes();
|
||||
$expected = [
|
||||
'title' => 'string',
|
||||
'isbn' => 'string',
|
||||
'publishedAt' => 'date',
|
||||
'published' => 'boolean',
|
||||
'count' => 'integer',
|
||||
'price' => 'float',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $this->csv->data_types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSepRowAutoDetection
|
||||
*/
|
||||
public function testAutoDetectFileHasHeading() {
|
||||
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
|
||||
$this->assertTrue($this->csv->autoDetectFileHasHeading());
|
||||
|
||||
$this->csv->heading = false;
|
||||
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
|
||||
$this->assertTrue($this->csv->autoDetectFileHasHeading());
|
||||
|
||||
$this->csv->heading = false;
|
||||
$sInput = "86545235689\r\n34365587654\r\n13469874576";
|
||||
$this->csv->auto($sInput);
|
||||
$this->assertFalse($this->csv->autoDetectFileHasHeading());
|
||||
|
||||
$this->csv->heading = true;
|
||||
$sInput = "86545235689\r\n34365587654\r\n13469874576";
|
||||
$this->csv->auto($sInput);
|
||||
$this->assertFalse($this->csv->autoDetectFileHasHeading());
|
||||
}
|
||||
|
||||
public function testVeryLongNonExistingFile() {
|
||||
$this->csv->parse(str_repeat('long_string', PHP_MAXPATHLEN));
|
||||
$this->csv->auto(str_repeat('long_string', PHP_MAXPATHLEN));
|
||||
}
|
||||
|
||||
protected function _get_magazines_data() {
|
||||
return [
|
||||
[
|
||||
'title' => 'Красивая кулинария',
|
||||
'isbn' => '5454-5587-3210',
|
||||
'publishedAt' => '21.05.2011',
|
||||
],
|
||||
[
|
||||
'title' => 'The Wine Connoisseurs',
|
||||
'isbn' => '2547-8548-2541',
|
||||
'publishedAt' => '12.12.2011',
|
||||
],
|
||||
[
|
||||
'title' => 'Weißwein',
|
||||
'isbn' => '1313-4545-8875',
|
||||
'publishedAt' => '23.02.2012',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function autoQuotesDataProvider() {
|
||||
return array(
|
||||
array('auto-double-enclosure.csv', '"'),
|
||||
array('auto-single-enclosure.csv', "'"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSepRowAutoDetection
|
||||
*
|
||||
* @dataProvider autoQuotesDataProvider
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $enclosure
|
||||
*/
|
||||
public function testAutoQuotes($file, $enclosure) {
|
||||
$csv = new Csv();
|
||||
$csv->auto(__DIR__ . '/fixtures/' . $file, true, null, null, $enclosure);
|
||||
$this->assertArrayHasKey('column1', $csv->data[0], 'Data parsed incorrectly with enclosure ' . $enclosure);
|
||||
$this->assertEquals('value1', $csv->data[0]['column1'], 'Data parsed incorrectly with enclosure ' . $enclosure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call protected/private method of a class.
|
||||
*
|
||||
* @param object &$object Instantiated object that we will run method on.
|
||||
* @param string $methodName Method name to call
|
||||
* @param array $parameters Array of parameters to pass into method.
|
||||
*
|
||||
* @return mixed Method return.
|
||||
*/
|
||||
private function invokeMethod(&$object, $methodName, array $parameters = array()) {
|
||||
$reflection = new \ReflectionClass(get_class($object));
|
||||
$method = $reflection->getMethod($methodName);
|
||||
$method->setAccessible(true);
|
||||
|
||||
return $method->invokeArgs($object, $parameters);
|
||||
}
|
||||
|
||||
public function testWaiverFieldSeparator() {
|
||||
$this->assertSame(false, $this->csv->auto(__DIR__ . '/../example_files/waiver_field_separator.csv'));
|
||||
$expected = [
|
||||
'liability waiver',
|
||||
'release of liability form',
|
||||
'release of liability',
|
||||
'sample waiver',
|
||||
'sample waiver form',
|
||||
];
|
||||
$actual = array_column($this->csv->data, 'keyword');
|
||||
$this->assertSame($expected, $actual);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SaveTest extends TestCase {
|
||||
|
||||
/** @var Csv */
|
||||
private $csv;
|
||||
|
||||
private $temp_filename;
|
||||
|
||||
/**
|
||||
* Setup our test environment objects; will be called before each test.
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->csv = new Csv();
|
||||
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
|
||||
|
||||
// Remove last 2 lines to simplify comparison
|
||||
unset($this->csv->data[2], $this->csv->data[3]);
|
||||
|
||||
$temp_dir = str_replace("\\", '/', sys_get_temp_dir());
|
||||
if (substr($temp_dir, -1) != '/') {
|
||||
// From the PHP.net documentation:
|
||||
// This function does not always add trailing slash. This behaviour
|
||||
// is inconsistent across systems.
|
||||
$temp_dir .= '/';
|
||||
}
|
||||
$this->temp_filename = $temp_dir . 'parsecsv_test_file.csv';
|
||||
}
|
||||
|
||||
public function testSaveWithDefaultSettings() {
|
||||
$expected = "SMS\r0444\r5555\r";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testSaveWithDosLineEnding() {
|
||||
$this->csv->linefeed = "\r\n";
|
||||
$expected = "SMS\r\n0444\r\n5555\r\n";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testSaveWithUnixLineEnding() {
|
||||
$this->csv->linefeed = "\n";
|
||||
$expected = "SMS\n0444\n5555\n";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testSaveWithNewHeader() {
|
||||
$this->csv->linefeed = "\n";
|
||||
$this->csv->titles = array("NewTitle");
|
||||
$expected = "NewTitle\n0444\n5555\n";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testSaveWithoutHeader() {
|
||||
$this->csv->linefeed = "\n";
|
||||
$this->csv->heading = false;
|
||||
$expected = "0444\n5555\n";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testAllQuotes() {
|
||||
$this->csv->enclose_all = true;
|
||||
$expected = "\"SMS\"\r\"0444\"\r\"5555\"\r";
|
||||
$this->saveAndCompare($expected);
|
||||
}
|
||||
|
||||
private function saveAndCompare($expected) {
|
||||
$this->csv->save($this->temp_filename);
|
||||
$content = file_get_contents($this->temp_filename);
|
||||
$this->assertEquals($expected, $content);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Writes roughly 1 MB of data. This is useful because of a limit of 8 KB
|
||||
* encountered with stream operations in certain PHP versions.
|
||||
*/
|
||||
class StreamTest extends TestCase {
|
||||
|
||||
public function setUp() {
|
||||
static $done;
|
||||
if ($done) {
|
||||
// Make sure we register the stream just once - or PHP will scream.
|
||||
return;
|
||||
}
|
||||
|
||||
stream_wrapper_register("example", ExampleStream::class)
|
||||
or die("Failed to register protocol");
|
||||
$done = 1;
|
||||
}
|
||||
|
||||
public function testReadStream() {
|
||||
$csv = new Csv();
|
||||
|
||||
// Write data to our stream:
|
||||
$filename = 'example://tmp';
|
||||
copy(__DIR__ . '/fixtures/datatype.csv', $filename);
|
||||
$many_dots = str_repeat('.', 1000 * 1000) . ";;;;;\n";
|
||||
file_put_contents($filename, $many_dots, FILE_APPEND);
|
||||
|
||||
self::assertSame(';', $csv->auto(file_get_contents($filename)));
|
||||
self::assertCount(4, $csv->data);
|
||||
self::assertCount(6, reset($csv->data));
|
||||
}
|
||||
|
||||
public function testWriteStream() {
|
||||
$csv = new Csv();
|
||||
$csv->linefeed = "\n";
|
||||
$many_dots = str_repeat('.', 1000 * 1000);
|
||||
$csv->data = [
|
||||
[
|
||||
'Name' => 'Rudolf',
|
||||
'Question' => 'Which color is his nose?',
|
||||
],
|
||||
[
|
||||
'Name' => 'Sponge Bob',
|
||||
'Question' => 'Which shape are his pants?',
|
||||
],
|
||||
[
|
||||
'Name' => $many_dots,
|
||||
'Question' => 'Can you count one million dots?',
|
||||
],
|
||||
];
|
||||
|
||||
// Just export the first column, but with a new name
|
||||
$csv->titles = ['Name' => 'Character'];
|
||||
|
||||
// Write data to our stream:
|
||||
$filename = 'example://data';
|
||||
copy(__DIR__ . '/fixtures/datatype.csv', $filename);
|
||||
|
||||
self::assertSame(true, $csv->save($filename));
|
||||
$expected = "Character\nRudolf\nSponge Bob\n";
|
||||
$expected .= $many_dots . "\n";
|
||||
self::assertSame($expected, file_get_contents($filename));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace ParseCsv\tests\methods;
|
||||
|
||||
use ParseCsv\Csv;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
||||
class UnparseTest extends Testcase {
|
||||
|
||||
/** @var Csv */
|
||||
private $csv;
|
||||
|
||||
/**
|
||||
* Setup our test environment objects; will be called before each test.
|
||||
*/
|
||||
public function setUp() {
|
||||
$this->csv = new Csv();
|
||||
$this->csv->auto(__DIR__ . '/fixtures/auto-double-enclosure.csv');
|
||||
}
|
||||
|
||||
public function testUnparseWithParameters() {
|
||||
$fields = array('a' => 'AA', 'b' => 'BB');
|
||||
$data = [['a' => 'value1', 'b' => 'value2']];
|
||||
$csv_object = new Csv();
|
||||
$csv_string = $csv_object->unparse($data, $fields);
|
||||
$this->assertEquals("AA,BB\rvalue1,value2\r", $csv_string);
|
||||
|
||||
$csv_object = new Csv();
|
||||
$csv_object->linefeed = "\n";
|
||||
$csv_string = $csv_object->unparse([[55, 66]]);
|
||||
$this->assertEquals("55,66\n", $csv_string);
|
||||
|
||||
$csv_object = new Csv();
|
||||
$data2 = [['a' => "multi\rline", 'b' => 'value2']];
|
||||
$csv_object->enclosure = "'";
|
||||
$csv_string = $csv_object->unparse($data2, $fields);
|
||||
$this->assertEquals("AA,BB\r'multi\rline',value2\r", $csv_string);
|
||||
}
|
||||
|
||||
public function testUnparseDefault() {
|
||||
$expected = "column1,column2\rvalue1,value2\rvalue3,value4\r";
|
||||
$this->unparseAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testUnparseDefaultWithoutHeading() {
|
||||
$this->csv->heading = false;
|
||||
$this->csv->auto(__DIR__ . '/fixtures/auto-double-enclosure.csv');
|
||||
$expected = "column1,column2\rvalue1,value2\rvalue3,value4\r";
|
||||
$this->unparseAndCompare($expected);
|
||||
|
||||
}
|
||||
|
||||
public function testUnparseRenameFields() {
|
||||
$expected = "C1,C2\rvalue1,value2\rvalue3,value4\r";
|
||||
$this->unparseAndCompare($expected, array("C1", "C2"));
|
||||
}
|
||||
|
||||
public function testReorderFields() {
|
||||
$expected = "column2,column1\rvalue2,value1\rvalue4,value3\r";
|
||||
$this->unparseAndCompare($expected, array("column2", "column1"));
|
||||
}
|
||||
|
||||
public function testSubsetFields() {
|
||||
$expected = "column1\rvalue1\rvalue3\r";
|
||||
$this->unparseAndCompare($expected, array("column1"));
|
||||
}
|
||||
|
||||
public function testReorderAndRenameFields() {
|
||||
$fields = array(
|
||||
'column2' => 'C2',
|
||||
'column1' => 'C1',
|
||||
);
|
||||
$expected = "C2,C1\rvalue2,value1\rvalue4,value3\r";
|
||||
$this->unparseAndCompare($expected, $fields);
|
||||
}
|
||||
|
||||
public function testUnparseDefaultFirstRowMissing() {
|
||||
unset($this->csv->data[0]);
|
||||
$expected = "column1,column2\rvalue3,value4\r";
|
||||
$this->unparseAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testUnparseDefaultWithoutData() {
|
||||
unset($this->csv->data[0]);
|
||||
unset($this->csv->data[1]);
|
||||
$expected = "column1,column2\r";
|
||||
$this->unparseAndCompare($expected);
|
||||
}
|
||||
|
||||
public function testObjectCells() {
|
||||
$this->csv->data = [
|
||||
[
|
||||
'column1' => new ObjectThatHasToStringMethod(),
|
||||
'column2' => 'boring',
|
||||
],
|
||||
];
|
||||
$this->csv->linefeed = "\n";
|
||||
$expected = "column1,column2\nsome value,boring\n";
|
||||
$this->unparseAndCompare($expected);
|
||||
}
|
||||
|
||||
private function unparseAndCompare($expected, $fields = array()) {
|
||||
$str = $this->csv->unparse($this->csv->data, $fields);
|
||||
$this->assertEquals($expected, $str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
"column1","column2"
|
||||
"value1","value2"
|
||||
"value3","value4"
|
||||
|
@@ -0,0 +1,3 @@
|
||||
'column1','column2'
|
||||
'value1','value2'
|
||||
'value3','value4'
|
||||
|
@@ -0,0 +1,5 @@
|
||||
sep=;
|
||||
title;isbn;publishedAt;published;count;price
|
||||
Красивая кулинария;5454-5587-3210;21.05.2011;true;1;10.99
|
||||
The Wine Connoisseurs;2547-8548-2541;12.12.2011;TRUE;;20.33
|
||||
Weißwein;1313-4545-8875;23.02.2012;false;10;10
|
||||
|
Reference in new issue
Block a user