12 Commits

Author SHA1 Message Date
Christian Bläul
02a8c1995d Semantic versioning: Marked the current state of the repo as 1.0.0-rc.1 2018-02-23 15:03:57 +01:00
Christian Bläul
72a7c29ed6 Updated remaining occurrences for old class/project name. 2018-02-02 17:31:26 +01:00
Christian Bläul
c905c9abfd Updated README.md 2018-02-02 17:26:13 +01:00
Christian Bläul
221c175217 Further improved ChangeLog.txt 2018-02-02 17:22:35 +01:00
Christian Bläul
4376cc8bd6 Added conditions to SortByTest because otherwise different PHP versions...
yielded different sort orders (that's sort of ok, as rating is ambiguous).

See https://travis-ci.org/parsecsv/parsecsv-for-php/jobs/336540118
2018-02-02 14:28:51 +01:00
Christian Bläul
5c157efbc3 output(): Use better mime type for \t separator.
Fixes #79
2018-02-02 13:49:57 +01:00
Christian Bläul
387a0f5761 Renamed class to follow the PHP community guidelines such as:
- https://svn.apache.org/repos/asf/shindig/attic/php/docs/style-guide.html:
  "Acryonyms are treated as normal words."

- https://softwareengineering.stackexchange.com/a/149321/80632
  Overview of class naming conventions of PHP frameworks

- https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
  No .lib allowed: "The class name corresponds to a file name ending in .php"

See issue #50
2018-02-02 13:22:58 +01:00
Christian Bläul
7a9d55dd1e Prepared new release in ChangeLog.txt 2018-02-02 12:27:12 +01:00
Christian Bläul
979e9ed0cd Moved ConditionsTest to properties subfolder 2018-02-02 12:26:06 +01:00
Christian Bläul
adcd258ea2 Added PHPUnit test for sorting; I could not get the rows in the right...
order without calling array_values - maybe this helps just PHPUnit. I
consider the risk of breaking library users' code unlikely.
2018-02-02 12:22:23 +01:00
Christian Bläul
34d28f7435 PHPUnit: Repaired file paths in autoQuotesDataProvider() 2018-02-02 12:10:25 +01:00
Christian Bläul
5cdec32466 Test some conditions 2018-02-02 11:14:41 +01:00
27 changed files with 159 additions and 592 deletions

View File

@@ -9,7 +9,6 @@ php:
- 5.4
script:
- phpunit --version
- phpunit --configuration tests/phpunit.xml
notifications:

View File

@@ -1,25 +1,19 @@
ParseCSV 1.0.0
ParseCsvForPhp 1.0.0-rc.1
-----------------------------------
Date: 3-March-2018
Date: unreleased
- Renamed class from parseCSV to Csv and added name-
space "ParseCsv" for PSR compliance.
- Renamed class from parseCSV to ParseCsvForPhp
- Added support for MS Excel's "sep=" to detect the
delimiter (Issue #60).
- Added data type detection - function getDatatypes()
guesses the type of each column.
- MIME: output() sends correct MIME type to browser
if the separator is a tab tab (Issue #79).
if the separator is a tab tab (Issue #79)
- Added support for mb_convert_encoding() instead of
iconv() - see issue #109.
iconv() (Issue #109)
- A number of minor bug fixes - see GitHub issues.
- Added many more unit tests.
- A number of minor bug fixes - see GitHub issues
-----------------------------------

View File

@@ -1,13 +1,9 @@
<?php
namespace ParseCsv;
use ParseCsv\extensions\DatatypeTrait;
class Csv {
class ParseCsvForPhp {
/*
Class: ParseCSV 1.0.0
Class: ParseCsvForPhp 1.0.0-rc.1
https://github.com/parsecsv/parsecsv-for-php
Fully conforms to the specifications lined out on Wikipedia:
@@ -39,7 +35,43 @@ class Csv {
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
For code examples, please read the files within the 'examples' dir.
Code Examples
----------------
# general usage
$csv = new ParseCsvForPhp('data.csv');
print_r($csv->data);
----------------
# tab delimited, and encoding conversion
$csv = new ParseCsvForPhp();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
print_r($csv->data);
----------------
# auto-detect delimiter character
$csv = new ParseCsvForPhp();
$csv->auto('data.csv');
print_r($csv->data);
----------------
# modify data in a csv file
$csv = new ParseCsvForPhp();
$csv->sort_by = 'id';
$csv->parse('data.csv');
# "4" is the value of the "id" column of the CSV row
$csv->data[4] = array('firstname' => 'John', 'lastname' => 'Doe', 'email' => 'john@doe.com');
$csv->save();
----------------
# add row/entry to end of CSV file
# - only recommended when you know the exact structure of the file
$csv = new ParseCsvForPhp();
$csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
----------------
# convert 2D array to csv data and send headers
# to browser to treat output as a file and download it
$csv = new ParseCsvForPhp();
$csv->output('movies.csv', $array, array('field 1', 'field 2'), ',');
----------------
*/
/**
@@ -290,8 +322,6 @@ class Csv {
*/
public $data = array();
use DatatypeTrait;
/**
* Constructor
* Class constructor
@@ -440,8 +470,8 @@ class Csv {
* Encoding
* Convert character encoding
*
* @param string $input Input character encoding, uses default if left blank
* @param string $output Output character encoding, uses default if left blank
* @param [string] $input Input character encoding, uses default if left blank
* @param [string] $output Output character encoding, uses default if left blank
*/
public function encoding($input = null, $output = null) {
$this->convert_encoding = true;
@@ -703,6 +733,9 @@ class Csv {
$this->sort_reverse ? krsort($rows, $sort_type) : ksort($rows, $sort_type);
// Avoid issues with mixing string and integer keys:
$rows = array_values($rows);
if ($this->offset !== null || $this->limit !== null) {
$rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset), $this->limit, true);
}
@@ -955,8 +988,7 @@ class Csv {
return
$this->sort_by !== null ||
$this->offset === null ||
$current_row >= $this->offset ||
($this->heading && $current_row == 0);
$current_row >= $this->offset;
}
/**

View File

@@ -1,20 +1,30 @@
# ParseCsv
# ParseCsvForPhp
ParseCsv is an easy-to-use PHP class that reads and writes CSV data properly. It
This is an easy-to-use PHP class that reads and writes CSV data properly. It
fully conforms to the specifications outlined on the on the
[Wikipedia article][CSV] (and thus RFC 4180). It has many advanced features which help make your
life easier when dealing with CSV data.
You may not need a library at all: before using ParseCsv, please make sure if PHP's own `str_getcsv()`, ``fgetcvs()`` or `fputcsv()` meets your needs.
You may not need a library at all: before using ParseCsvForPhp, please make sure if PHP's own `str_getcsv()`, ``fgetcvs()`` or `fputcsv()` meets your needs.
This library was originally created in early 2007 by [jimeh](https://github.com/jimeh) due to the lack of built-in
and third-party support for handling CSV data in PHP.
[csv]: http://en.wikipedia.org/wiki/Comma-separated_values
## Installation
Installation is easy using Composer. Include the following in your composer.json
```
"parsecsv/php-parsecsv": "1.0.0"
```
You may also manually include the ParseCsvForPhp.php file
```php
require_once 'ParseCsvForPhp.php';
```
## Features
* ParseCsv is a complete and fully featured CSV solution for PHP
* Supports enclosed values, enclosed commas, double quotes and new lines.
* Automatic delimiter character detection.
* Sort data by specific fields/columns.
@@ -24,45 +34,25 @@ and third-party support for handling CSV data in PHP.
* Error detection for incorrectly formatted input. It attempts to be
intelligent, but can not be trusted 100% due to the structure of CSV, and
how different programs like Excel for example outputs CSV data.
* Support for character encoding conversion using PHP's
`iconv()` and `mb_convert_encoding()` functions.
* Supports PHP 5.4 and higher.
* Support for character encoding conversion using PHP's
`iconv()` and `mb_convert_encoding()` functions (requires PHP 5).
* Supports PHP 5.4 and higher.
It certainly works with PHP 7.2 and all versions in between.
## Installation
Installation is easy using Composer. Just run the following on the
command line:
```
composer require parsecsv/php-parsecsv
```
If you don't use a framework such as Drupal, Laravel, Symfony, Yii etc.,
you may have to manually include Composer's autoloader file in your PHP
script:
```php
require_once __DIR__ . '/vendor/autoload.php';
```
#### Without composer
Not recommended, but technically possible: you can also clone the
repository or extract the
[ZIP](https://github.com/parsecsv/parsecsv-for-php/archive/master.zip).
To use ParseCSV, you then have to add a `require 'parsecsv.lib.php';` line.
## Example Usage
**General**
```php
$csv = new ParseCsv\Csv('data.csv');
$csv = new ParseCsvForPhp('data.csv');
print_r($csv->data);
```
**Tab delimited, and encoding conversion**
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
@@ -72,7 +62,7 @@ print_r($csv->data);
**Auto-detect delimiter character**
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->auto('data.csv');
print_r($csv->data);
```
@@ -80,7 +70,7 @@ print_r($csv->data);
**Modify data in a CSV file**
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->sort_by = 'id';
$csv->parse('data.csv');
# "4" is the value of the "id" column of the CSV row
@@ -91,7 +81,7 @@ $csv->save();
**Replace field names or set ones if missing**
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->fields = ['id', 'name', 'category']
$csv->parse('data.csv');
```
@@ -101,7 +91,7 @@ $csv->parse('data.csv');
_Only recommended when you know the exact structure of the file._
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
```
@@ -109,7 +99,7 @@ $csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
a file and download it**
```php
$csv = new ParseCsv\Csv();
$csv = new ParseCsvForPhp();
$csv->output('movies.csv', $array, array('field 1', 'field 2'), ',');
```
@@ -117,7 +107,7 @@ For more complex examples, see the ``tests`` and `examples` directories.
## Credits
* ParseCsv is based on the concept of [Ming Hong Ng][ming]'s [CsvFileParser][]
* ParseCsvForPhp is based on the concept of [Ming Hong Ng][ming]'s [CsvFileParser][]
class.
[ming]: http://minghong.blogspot.com/
@@ -155,5 +145,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[![Build Status](https://travis-ci.org/parsecsv/parsecsv-for-php.svg?branch=master)](https://travis-ci.org/parsecsv/parsecsv-for-php)

View File

@@ -12,17 +12,10 @@
"email": "will.knauss@gmail.com"
}
],
"autoload":{
"psr-4":{
"ParseCsv\\": "src",
"ParseCsv\\extensions\\": "src\\extensions",
"ParseCsv\\tests\\": "tests"
}
},
"autoload-dev":{
"psr-4":{
"ParseCsv\\tests\\": "tests"
}
"autoload": {
"classmap": [
"."
]
},
"require-dev": {
"phpunit/phpunit": "4.1.*"

View File

@@ -1,13 +1,13 @@
<pre>
<?php
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new Csv();
# create new object.
$csv = new ParseCsvForPhp();
# Parse '_books.csv' using automatic delimiter detection...

View File

@@ -2,13 +2,12 @@
<?php
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new Csv();
# create new object.
$csv = new ParseCsvForPhp();
# Example conditions:

View File

@@ -1,13 +1,12 @@
<?php
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new Csv();
# create new object.
$csv = new ParseCsvForPhp();
# Parse '_books.csv' using automatic delimiter detection...

View File

@@ -2,13 +2,12 @@
<?php
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# include class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new Csv();
# create new object.
$csv = new ParseCsvForPhp();
# if sorting is enabled, the whole CSV file

View File

@@ -1,20 +0,0 @@
<?php
// This file should not be used at all! Instead, please use Composer's autoload.
// It purely exists to reduce the maintenance burden for existing code using
// this repository.
// Check if people used Composer to include this project in theirs
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
require __DIR__ . '/src/extensions/DatatypeTrait.php';
require __DIR__ . '/src/Csv.php';
} else {
require __DIR__ . '/vendor/autoload.php';
}
// This wrapper class should not be used by new projects. Please look at the
// examples to find the up-to-date way of using this repo.
class parseCSV extends ParseCsv\Csv {
}

View File

@@ -1,120 +0,0 @@
<?php
namespace ParseCsv\enums;
/**
* Class DatatypeEnum
*
* @package ParseCsv\enums
*
* todo: needs a basic parent enum class for error handling.
*/
class DatatypeEnum {
const __DEFAULT = self::TYPE_STRING;
const TYPE_STRING = 'string';
const TYPE_FLOAT = 'float';
const TYPE_INT = 'integer';
const TYPE_BOOL = 'boolean';
const TYPE_DATE = 'date';
const REGEX_FLOAT = '/(^[+-]?$)|(^[+-]?[0-9]+([,.][0-9])?[0-9]*(e[+-]?[0-9]+)?$)/';
const REGEX_INT = '/^[-+]?[0-9]\d*$/';
const REGEX_BOOL = '/^(?i:true|false)$/';
/**
* Define validator functions here.
*
* @var array
*
* @uses isValidFloat
* @uses isValidInteger
* @uses isValidBoolean
* @uses isValidDate
*/
private static $validators = array(
self::TYPE_STRING => null,
self::TYPE_INT => 'isValidInteger',
self::TYPE_BOOL => 'isValidBoolean',
self::TYPE_FLOAT => 'isValidFloat',
self::TYPE_DATE => 'isValidDate',
);
/**
* Checks data type for given string.
*
* @param string $value
*
* @return bool|string
*/
public static function getValidTypeFromSample($value) {
$value = trim((string) $value);
if (empty($value)) {
return false;
}
foreach (self::$validators as $type => $validator) {
if ($validator === null) {
continue;
}
if (method_exists(__CLASS__, $validator) && self::$validator($value)) {
return $type;
}
}
return self::__DEFAULT;
}
/**
* Check if string is float value.
*
* @param string $value
*
* @return bool
*/
private static function isValidFloat($value) {
return (bool) preg_match(self::REGEX_FLOAT, $value);
}
/**
* Check if string is integer value.
*
* @param string $value
*
* @return bool
*/
private static function isValidInteger($value) {
return (bool) preg_match(self::REGEX_INT, $value);
}
/**
* Check if string is boolean.
*
* @param string $value
*
* @return bool
*/
private static function isValidBoolean($value) {
return (bool) preg_match(self::REGEX_BOOL, $value);
}
/**
* Check if string is date.
*
* @param string $value
*
* @return bool
*/
private static function isValidDate($value) {
return (bool) strtotime($value);
}
}

View File

@@ -1,74 +0,0 @@
<?php
namespace ParseCsv\extensions;
trait DatatypeTrait {
/**
* Datatypes
* Datatypes of CSV data-columns
*
* @access public
* @var array
*/
public $data_types = [];
/**
* Check data type for one column.
* Check for most commonly data type for one column.
*
* @access private
*
* @param array $datatypes
*
* @return string|false
*/
private function getMostFrequentDatatypeForColumn($datatypes) {
// remove 'false' from array (can happen if CSV cell is empty)
$typesFiltered = array_filter($datatypes);
if (empty($typesFiltered)) {
return false;
}
$typesFreq = array_count_values($typesFiltered);
arsort($typesFreq);
reset($typesFreq);
return key($typesFreq);
}
/**
* Check data type foreach Column
* Check data type for each column and returns the most commonly.
*
* Requires PHP >= 5.5
*
* @access public
*
* @uses getDatatypeFromString
*
* @return array|bool
*/
public function getDatatypes() {
if (empty($this->data)) {
$this->data = $this->parse_string();
}
if (!is_array($this->data)) {
throw new \UnexpectedValueException('No data set yet.');
}
$result = [];
foreach ($this->titles as $cName) {
$column = array_column($this->data, $cName);
$cDatatypes = array_map('ParseCsv\enums\DatatypeEnum::getValidTypeFromSample', $column);
$result[$cName] = $this->getMostFrequentDatatypeForColumn($cDatatypes);
}
$this->data_types = $result;
return !empty($this->data_types) ? $this->data_types : [];
}
}

View File

@@ -1,13 +1,13 @@
<?php
chdir(__DIR__ . '/..');
if (!file_exists('vendor/autoload.php')) {
`composer dump-autoload`;
}
require __DIR__ . '/../vendor/autoload.php';
$dir = realpath(__DIR__);
defined('BASE') OR define('BASE', dirname($dir) . '/');
if (!class_exists('PHPUnit\Framework\TestCase') && class_exists('PHPUnit_Framework_TestCase')) {
require_once BASE . 'ParseCsvForPhp.php';
if (!class_exists('PHPUnit\Framework\TestCase')) {
// we run on an older PHPUnit version without namespaces.
require_once __DIR__ . '/PHPUnit_Framework_TestCase.inc.php';
}
require_once BASE . 'tests/properties/BaseClass.php';

View File

@@ -1,67 +1,45 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class ConstructTest extends TestCase {
class ConstructTest extends PHPUnit\Framework\TestCase {
/**
* @var Csv object
* @access protected
* @var ParseCsvForPhp object
*/
protected $csv = null;
public function test_offset_param() {
$offset = 10;
$this->csv = new Csv(null, $offset);
$this->csv = new ParseCsvForPhp(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->csv = new ParseCsvForPhp(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->csv = new ParseCsvForPhp(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->csv = new ParseCsvForPhp(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->csv = new ParseCsvForPhp($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;
if ($script_file != 'download.php') {
$this->assertContains('<td>', ob_get_clean());
}
}
chdir('..');
}
}

View File

@@ -1,69 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: sgorzaly
* Date: 19.02.18
* Time: 20:52
*/
namespace ParseCsv\tests\methods;
use PHPUnit\Framework\TestCase;
use ParseCsv\enums\DatatypeEnum;
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'));
}
}

View File

@@ -1,28 +0,0 @@
<?php
namespace ParseCsv\tests\methods;
use PHPUnit\Framework\TestCase;
class OldRequireTest extends TestCase {
protected function setUp() {
rename('vendor/autoload.php', '__autoload');
}
protected function tearDown() {
rename('__autoload', 'vendor/autoload.php');
}
/**
* @runInSeparateProcess because download.php uses header()
*/
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);
}
}

View File

@@ -1,14 +1,10 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class ParseTest extends TestCase {
class ParseTest extends PHPUnit\Framework\TestCase {
/**
* @var Csv object
* @access protected
* @var ParseCsvForPhp
*/
protected $csv;
@@ -19,7 +15,7 @@ class ParseTest extends TestCase {
* @access public
*/
public function setUp() {
$this->csv = new Csv();
$this->csv = new ParseCsvForPhp();
}
public function test_parse() {
@@ -40,26 +36,9 @@ class ParseTest extends TestCase {
$this->assertEquals($expected_data, $row);
}
/**
* @depends test_parse
*
* @dataProvider autoDetectionProvider
*/
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 test_sep_row_auto_detection_UTF8_no_BOM() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-8_sep_row_but_no_BOM.csv');
}
public function testSingleColumnWithZeros() {
@@ -95,6 +74,25 @@ class ParseTest extends TestCase {
], array_map('next', $actual_data));
}
public function test_sep_row_auto_detection_UTF8() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-8_with_BOM_and_sep_row.csv');
}
public function test_sep_row_auto_detection_UTF16() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-16LE_with_BOM_and_sep_row.csv');
}
protected function _autoparse_magazine_file($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 test_single_column() {
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
$expected = [
@@ -129,55 +127,6 @@ class ParseTest extends TestCase {
], $aCity);
}
/**
* @depends testSepRowAutoDetection
*/
public function testGetColumnDatatypes() {
if (!function_exists('array_column')) {
// getDatatypes requires array_column, but that
// function is only available in PHP >= 5.5
return;
}
$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);
}
public function testDataArrayKeysWhenSettingOffsetWithHeading() {
$this->csv->offset = 2;
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
$expected = [
'title',
'isbn',
'publishedAt',
'published',
'count',
'price'
];
$this->assertEquals($expected, array_keys($this->csv->data[0]));
}
public function testDataArrayKeysWhenSettingOffsetWithoutHeading() {
$this->csv->heading = false;
$this->csv->offset = 2;
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
$expected = range(0, 5, 1);
$this->assertEquals($expected, array_keys($this->csv->data[0]));
}
protected function _get_magazines_data() {
return [
[
@@ -206,16 +155,14 @@ class ParseTest extends TestCase {
}
/**
* @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);
$csv = new ParseCsvForPhp();
$csv->auto(__DIR__ . '/../example_files/' . $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);
}

View File

@@ -1,13 +1,8 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class SaveTest extends PHPUnit\Framework\TestCase {
class SaveTest extends TestCase
{
/** @var Csv */
/** @var ParseCsvForPhp */
private $csv;
private $temp_filename;
@@ -16,7 +11,7 @@ class SaveTest extends TestCase
* Setup our test environment objects; will be called before each test.
*/
public function setUp() {
$this->csv = new Csv();
$this->csv = new ParseCsvForPhp();
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
// Remove last 2 lines to simplify comparison

View File

@@ -1,5 +0,0 @@
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
1 sep=;
2 title;isbn;publishedAt;published;count;price
3 Красивая кулинария;5454-5587-3210;21.05.2011;true;1;10.99
4 The Wine Connoisseurs;2547-8548-2541;12.12.2011;TRUE;;20.33
5 Weißwein;1313-4545-8875;23.02.2012;false;10;10

View File

@@ -10,7 +10,7 @@
stopOnIncomplete="true"
stopOnSkipped="false">
<testsuites>
<testsuite name="parseCSV Test Suite">
<testsuite name="ParseCsvForPhp Test Suite">
<directory suffix="est.php">properties/</directory>
<directory suffix="est.php">methods/</directory>
</testsuite>

View File

@@ -1,18 +1,10 @@
<?php
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class BaseClass extends TestCase {
class BaseClass extends PHPUnit\Framework\TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var Csv
* @var ParseCsvForPhp object
*/
protected $csv;
@@ -23,7 +15,7 @@ class BaseClass extends TestCase {
* @access public
*/
public function setUp() {
$this->csv = new Csv();
$this->csv = new ParseCsvForPhp();
}
protected function _compareWithExpected($expected) {
@@ -31,6 +23,6 @@ class BaseClass extends TestCase {
$actual = array_map(function ($row) {
return $row['title'];
}, $this->csv->data);
$this->assertEquals($expected, array_values($actual));
$this->assertEquals($expected, $actual);
}
}

View File

@@ -1,7 +1,5 @@
<?php
namespace ParseCsv\tests\properties;
class ConditionsTest extends BaseClass {
public function testNotDanBrown() {

View File

@@ -1,7 +1,5 @@
<?php
namespace ParseCsv\tests\properties;
class SortByTest extends BaseClass {
public function testSortByRating() {

View File

@@ -1,18 +1,10 @@
<?php
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class DefaultValuesPropertiesTest extends TestCase {
class default_values_properties_Test extends PHPUnit\Framework\TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var Csv
* @var ParseCsvForPhp object
*/
protected $csv = null;
@@ -24,17 +16,7 @@ class DefaultValuesPropertiesTest extends TestCase {
*/
public function setUp() {
//setup parse CSV
$this->csv = new Csv();
}
/**
* Tear down
* Tear down our test environment objects
*
* @access public
*/
public function tearDown() {
$this->csv = null;
$this->csv = new ParseCsvForPhp();
}
public function test_heading_default() {

View File

@@ -1,18 +1,10 @@
<?php
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class PublicPropertiesTest extends TestCase {
class worthless_properties_Test extends PHPUnit\Framework\TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var Csv
* @var ParseCsvForPhp
*/
protected $csv = null;
@@ -21,7 +13,7 @@ class PublicPropertiesTest extends TestCase {
* The reflection class object
*
* @access protected
* @var \ReflectionClass
* @var ReflectionClass
*/
protected $reflection = null;
@@ -29,8 +21,8 @@ class PublicPropertiesTest extends TestCase {
* Reflection Properties
* The reflected class properties
*
* @var \ReflectionProperty[]
* @access protected
* @var ReflectionProperty[]
*/
protected $properties = null;
@@ -42,10 +34,10 @@ class PublicPropertiesTest extends TestCase {
*/
public function setUp() {
//setup parse CSV
$this->csv = new Csv();
$this->csv = new ParseCsvForPhp();
//setup the reflection class
$this->reflection = new \ReflectionClass($this->csv);
$this->reflection = new ReflectionClass($this->csv);
//setup the reflected class properties
$this->properties = $this->reflection->getProperties();
@@ -71,7 +63,7 @@ class PublicPropertiesTest extends TestCase {
* @access public
*/
public function test_propertiesCount() {
$this->assertCount(29, $this->properties);
$this->assertCount(28, $this->properties);
}
/**
@@ -114,11 +106,10 @@ class PublicPropertiesTest extends TestCase {
'error_info',
'titles',
'data',
'data_types',
);
// Find our real properties
$real_properties = array_map(function (\ReflectionProperty $property) {
$real_properties = array_map(function (ReflectionProperty $property) {
return $property->getName();
}, $this->properties);
@@ -136,8 +127,7 @@ class PublicPropertiesTest extends TestCase {
public function test_count_public_properties() {
$counter = 0;
$propertiesCount = count($this->properties);
for ($a = 0; $a < $propertiesCount; $a++) {
for ($a = count($this->properties) - 1; $a >= 0; $a--) {
if ($this->properties[$a]->isPublic() === true) {
$counter++;
}