Skip to content

Commit e3d1bb1

Browse files
authored
Merge pull request #46 from blitz-php/devs
test: ajout des test des classes de Formattage
2 parents 51192fc + 2b708c8 commit e3d1bb1

5 files changed

Lines changed: 329 additions & 1 deletion

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
use BlitzPHP\Formatter\ArrayFormatter;
13+
14+
describe('ArrayFormatter', function () {
15+
16+
beforeEach(function () {
17+
$this->formatter = new ArrayFormatter();
18+
});
19+
20+
describe('->format()', function () {
21+
22+
it('devrait formater un tableau simple', function () {
23+
$data = ['clé' => 'valeur'];
24+
$result = $this->formatter->format($data);
25+
expect($result)->toBe($data);
26+
});
27+
28+
it('devrait formater un objet en tableau', function () {
29+
$data = (object) ['clé' => 'valeur'];
30+
$result = $this->formatter->format($data);
31+
expect($result)->toBe(['clé' => 'valeur']);
32+
});
33+
34+
it('devrait formater un tableau imbriqué', function () {
35+
$data = ['clé' => ['sous_clé' => 'valeur']];
36+
$result = $this->formatter->format($data);
37+
expect($result)->toBe($data);
38+
});
39+
40+
it('devrait formater un objet imbriqué en tableau', function () {
41+
$data = (object) ['clé' => (object) ['sous_clé' => 'valeur']];
42+
$result = $this->formatter->format($data);
43+
expect($result)->toBe(['clé' => ['sous_clé' => 'valeur']]);
44+
});
45+
});
46+
47+
describe('->parse()', function () {
48+
49+
it('devrait retourner une chaîne dans un tableau', function () {
50+
$data = 'chaîne';
51+
$result = $this->formatter->parse($data);
52+
expect($result)->toBe([$data]);
53+
});
54+
});
55+
});
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
use BlitzPHP\Formatter\CsvFormatter;
13+
14+
use function Kahlan\allow;
15+
use function Kahlan\expect;
16+
17+
describe('CsvFormatter', function() {
18+
beforeEach(function() {
19+
$this->formatter = new CsvFormatter();
20+
});
21+
22+
describe('->format()', function() {
23+
it('devrait formater un tableau simple en CSV', function() {
24+
$data = ['nom' => 'Jean', 'age' => 30];
25+
$result = $this->formatter->format($data);
26+
$expected = mb_convert_encoding("nom,age\nJean,30\n", 'UTF-16LE', 'UTF-8');
27+
expect($result)->toBe($expected);
28+
});
29+
30+
it('devrait formater un tableau multidimensionnel en CSV', function() {
31+
$data = [
32+
['nom' => 'Jean', 'age' => 30],
33+
['nom' => 'Marie', 'age' => 25]
34+
];
35+
$result = $this->formatter->format($data);
36+
$expected = mb_convert_encoding("nom,age\nJean,30\nMarie,25\n", 'UTF-16LE', 'UTF-8');
37+
expect($result)->toBe($expected);
38+
});
39+
40+
xit('devrait retourner null si l\'ouverture du fichier temporaire échoue', function() {
41+
allow('fopen')->toBeCalled()->andReturn(false);
42+
expect($this->formatter->format(['test' => 'data']))->toBeNull();
43+
});
44+
});
45+
46+
describe('->parse()', function() {
47+
it('devrait analyser une chaîne CSV en tableau', function() {
48+
$csv = "nom,age\nJean,30\nMarie,25";
49+
$expected = [
50+
['nom' => 'Jean', 'age' => '30'],
51+
['nom' => 'Marie', 'age' => '25']
52+
];
53+
expect($this->formatter->parse($csv))->toBe($expected);
54+
});
55+
56+
it('devrait analyser une chaîne CSV en tableau', function() {
57+
$csv = "nom,age,sexe";
58+
$expected = ['nom', 'age', 'sexe'];
59+
expect($this->formatter->parse($csv))->toBe($expected);
60+
});
61+
});
62+
63+
describe('->setDelimiter()', function() {
64+
it('devrait définir le délimiteur', function() {
65+
$this->formatter->setDelimiter(';');
66+
expect($this->formatter->getDelimiter())->toBe(';');
67+
});
68+
69+
it('devrait utiliser le premier caractère si une chaîne plus longue est fournie', function() {
70+
$this->formatter->setDelimiter('abc');
71+
expect($this->formatter->getDelimiter())->toBe('a');
72+
});
73+
74+
it('devrait utiliser la virgule par défaut si une chaîne vide est fournie', function() {
75+
$this->formatter->setDelimiter('');
76+
expect($this->formatter->getDelimiter())->toBe(',');
77+
});
78+
});
79+
80+
describe('->setEnclosure()', function() {
81+
it('devrait définir l\'encadrement', function() {
82+
$this->formatter->setEnclosure('\'');
83+
expect($this->formatter->getEnclosure())->toBe('\'');
84+
});
85+
86+
it('devrait utiliser le premier caractère si une chaîne plus longue est fournie', function() {
87+
$this->formatter->setEnclosure('abc');
88+
expect($this->formatter->getEnclosure())->toBe('a');
89+
});
90+
91+
it('devrait utiliser les guillemets doubles par défaut si une chaîne vide est fournie', function() {
92+
$this->formatter->setEnclosure('');
93+
expect($this->formatter->getEnclosure())->toBe('"');
94+
});
95+
});
96+
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
use BlitzPHP\Formatter\Formatter;
13+
use BlitzPHP\Formatter\JsonFormatter;
14+
use BlitzPHP\Formatter\XmlFormatter;
15+
use BlitzPHP\Formatter\CsvFormatter;
16+
use BlitzPHP\Formatter\ArrayFormatter;
17+
use BlitzPHP\Exceptions\FormatException;
18+
19+
use function Kahlan\expect;
20+
21+
describe('Formatter', function() {
22+
describe('::type()', function() {
23+
it('doit renvoyer le formateur correct pour un type MIME valide', function() {
24+
expect(Formatter::type('application/json'))->toBeAnInstanceOf(JsonFormatter::class);
25+
expect(Formatter::type('json'))->toBeAnInstanceOf(JsonFormatter::class);
26+
expect(Formatter::type('application/xml'))->toBeAnInstanceOf(XmlFormatter::class);
27+
expect(Formatter::type('text/xml'))->toBeAnInstanceOf(XmlFormatter::class);
28+
expect(Formatter::type('xml'))->toBeAnInstanceOf(XmlFormatter::class);
29+
expect(Formatter::type('application/csv'))->toBeAnInstanceOf(CsvFormatter::class);
30+
expect(Formatter::type('csv'))->toBeAnInstanceOf(CsvFormatter::class);
31+
expect(Formatter::type('php/array'))->toBeAnInstanceOf(ArrayFormatter::class);
32+
expect(Formatter::type('array'))->toBeAnInstanceOf(ArrayFormatter::class);
33+
});
34+
35+
it('doit lever une exception FormatException si le type MIME n\'est pas valide', function() {
36+
$closure = function() {
37+
Formatter::type('invalid/mime');
38+
};
39+
expect($closure)->toThrow(FormatException::invalidMime('invalid/mime'));
40+
});
41+
42+
it('devrait lever une exception FormatException pour une classe de formateur inexistante', function() {
43+
// nous devons modifier une propriété protégée pour ce test
44+
$reflection = new ReflectionClass(Formatter::class);
45+
$formatters = $reflection->getProperty('formatters');
46+
$formatters->setAccessible(true);
47+
$originalFormatters = $formatters->getValue();
48+
49+
$formatters->setValue(array_merge($originalFormatters, ['test/mime' => 'NonExistentFormatter']));
50+
51+
$closure = function() {
52+
Formatter::type('test/mime');
53+
};
54+
expect($closure)->toThrow(FormatException::invalidFormatter('NonExistentFormatter'));
55+
56+
// Restaurer les formatters d'origine
57+
$formatters->setValue($originalFormatters);
58+
});
59+
60+
it('devrait lancer une exception FormatException pour une classe de formateur n\'implémentant pas FormatterInterface', function() {
61+
// nous devons modifier une propriété protégée pour ce test
62+
$reflection = new ReflectionClass(Formatter::class);
63+
$formatters = $reflection->getProperty('formatters');
64+
$formatters->setAccessible(true);
65+
$originalFormatters = $formatters->getValue();
66+
67+
$formatters->setValue(array_merge($originalFormatters, ['test/mime' => stdClass::class]));
68+
69+
$closure = function() {
70+
Formatter::type('test/mime');
71+
};
72+
expect($closure)->toThrow(FormatException::invalidFormatter('stdClass'));
73+
74+
// Restaurer les formatters d'origine
75+
$formatters->setValue($originalFormatters);
76+
});
77+
});
78+
});
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Blitz PHP framework.
5+
*
6+
* (c) 2022 Dimitri Sitchet Tomkeu <devcode.dst@gmail.com>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
use BlitzPHP\Formatter\JsonFormatter;
13+
use BlitzPHP\Container\Services;
14+
use BlitzPHP\Http\Request;
15+
16+
describe('JsonFormatter', function() {
17+
beforeEach(function() {
18+
$this->formatter = new JsonFormatter();
19+
});
20+
21+
describe('->format()', function() {
22+
it('devrait formater un tableau simple en JSON', function() {
23+
$data = ['nom' => 'Jean', 'age' => 30];
24+
$expected = '{"nom":"Jean","age":30}';
25+
expect($this->formatter->format($data))->toBe($expected);
26+
});
27+
28+
it('devrait gérer les caractères Unicode', function() {
29+
$data = ['nom' => 'Éloïse'];
30+
$expected = '{"nom":"Éloïse"}';
31+
expect($this->formatter->format($data))->toBe($expected);
32+
});
33+
34+
it('devrait gérer les barres obliques', function() {
35+
$data = ['url' => 'http://exemple.com/chemin/vers/ressource'];
36+
$expected = '{"url":"http://exemple.com/chemin/vers/ressource"}';
37+
expect($this->formatter->format($data))->toBe($expected);
38+
});
39+
40+
it('devrait gérer le rappel JSONP valide', function() {
41+
Services::set(
42+
Request::class,
43+
Services::request()->withQueryParams(['callback' => 'maFonction'])
44+
);
45+
46+
$data = ['nom' => 'Jean'];
47+
$expected = 'maFonction({"nom":"Jean"});';
48+
expect($this->formatter->format($data))->toBe($expected);
49+
});
50+
51+
it('devrait gérer le rappel JSONP invalide', function() {
52+
Services::set(
53+
Request::class,
54+
Services::request()->withQueryParams(['callback' => 'fonction invalide'])
55+
);
56+
57+
$data = ['nom' => 'Jean'];
58+
$expected = '{"nom":"Jean","warning":"INVALID JSONP CALLBACK: fonction invalide"}';
59+
expect($this->formatter->format($data))->toBe($expected);
60+
});
61+
});
62+
63+
describe('->parse()', function() {
64+
it('devrait analyser une chaîne JSON en tableau', function() {
65+
$json = '{"nom":"Jean","age":30}';
66+
$expected = ['nom' => 'Jean', 'age' => 30];
67+
expect($this->formatter->parse($json))->toBe($expected);
68+
});
69+
70+
it('devrait retourner un tableau vide pour une chaîne vide', function() {
71+
expect($this->formatter->parse(''))->toBe([]);
72+
});
73+
74+
it('devrait supprimer les espaces blancs avant et après', function() {
75+
$json = ' {"nom":"Jean"} ';
76+
$expected = ['nom' => 'Jean'];
77+
expect($this->formatter->parse($json))->toBe($expected);
78+
});
79+
});
80+
});

src/Formatter/CsvFormatter.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,26 @@ public function format($data)
9090
*/
9191
public function parse(string $data): array
9292
{
93-
return str_getcsv($data, $this->delimiter, $this->enclosure);
93+
$array = [];
94+
$lines = explode("\n", trim($data));
95+
96+
foreach ($lines as $line) {
97+
$array[] = str_getcsv($line, $this->delimiter, $this->enclosure);
98+
}
99+
100+
$head = array_shift($array);
101+
102+
if ($array === []) {
103+
return $head;
104+
}
105+
106+
$result = [];
107+
108+
foreach ($array as $values) {
109+
$result[] = array_combine($head, $values);
110+
}
111+
112+
return $result;
94113
}
95114

96115
/**

0 commit comments

Comments
 (0)