Skip to content

Commit

Permalink
Merge pull request #31 from pitchart/feature/resource-termination
Browse files Browse the repository at this point in the history
Feature/resource termination
  • Loading branch information
pitchart authored Apr 15, 2020
2 parents c74d579 + d585ecf commit 5c93f6f
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/Reducer/Termination/ToCsv.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php


namespace Pitchart\Transformer\Reducer\Termination;


use Pitchart\Transformer\Termination;
use function Pitchart\Transformer\Transducer\to_array;
use function Pitchart\Transformer\transform;

class ToCsv implements Termination
{
/**
* @var string
*/
private $delimiter;

/**
* @var string
*/
private $enclosure;

/**
* @var string
*/
private $escapeChar;

/**
* ToCsv constructor.
*
* @param string $delimiter
* @param string $enclosure
* @param string $escapeChar
*/
public function __construct(string $delimiter = ',', string $enclosure = '"', string $escapeChar = "\\")
{
$this->delimiter = $delimiter;
$this->enclosure = $enclosure;
$this->escapeChar = $escapeChar;
}

public function init()
{
return fopen('php://temp', 'w+');
}

/**
* @param resource $result
* @param mixed $current
*/
public function step($result, $current)
{
if (!is_array($current)) {
if (is_iterable($current)) {
$current = transform($current)->toArray();
}
else {
$current = [(string) $current];
}
}
fputcsv($result, $current, $this->delimiter, $this->enclosure, $this->escapeChar);
return $result;
}

public function complete($result)
{
return $result;
}
}
49 changes: 49 additions & 0 deletions src/Reducer/Termination/ToResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php


namespace Pitchart\Transformer\Reducer\Termination;


use Pitchart\Transformer\Termination;

class ToResource implements Termination
{
/**
* @var callable
*/
private $callback;

/**
* ToResource constructor.
*
* @param callable $callback
*/
public function __construct(callable $callback = null)
{
if ($callback == null) {
$callback = 'Pitchart\Transformer\identity';
}
$this->callback = $callback;
}

public function init()
{
return fopen('php://temp', 'w+');
}

/**
* @param resource $result
* @param mixed $current
*/
public function step($result, $current)
{
fwrite($result, (string) ($this->callback)($current));
return $result;
}

public function complete($result)
{
return $result;
}

}
16 changes: 16 additions & 0 deletions src/Transducer/transducers.php
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,22 @@ function to_iterator()
return new Reducer\Termination\ToIterator();
}

/**
* @return Reducer\Termination\ToResource
*/
function to_resource(?callable $callback = null)
{
return new Reducer\Termination\ToResource($callback);
}

/**
* @return Reducer\Termination\ToCsv
*/
function to_csv(string $delimiter = ',', string $enclosure = '"', string $escapeChar = "\\")
{
return new Reducer\Termination\ToCsv($delimiter, $enclosure, $escapeChar);
}

/**
* @param string $operator
*
Expand Down
20 changes: 20 additions & 0 deletions src/Transformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,26 @@ public function toIterator()
return $this->terminate(t\to_iterator());
}

/**
* @return resource
*/
public function toResource(?callable $callback = null)
{
return $this->terminate(t\to_resource($callback));
}

/**
* @param string $delimiter
* @param string $enclosure
* @param string $escapeChar
*
* @return mixed
*/
public function toCsv(string $delimiter = ',', string $enclosure = '"', string $escapeChar = "\\")
{
return $this->terminate(t\to_csv());
}

/**
* @return mixed
*/
Expand Down
57 changes: 57 additions & 0 deletions tests/Reducer/Termination/ToCsvTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Pitchart\Transformer\Tests\Reducer\Termination;

use Pitchart\Transformer\Reducer;
use Pitchart\Transformer\Reducer\Termination\ToCsv;
use PHPUnit\Framework\TestCase;
use Pitchart\Transformer\Termination;
use function Pitchart\Transformer\transform;

class ToCsvTest extends TestCase
{
public function test_is_a_reducer()
{
$resource = new ToCsv();
self::assertInstanceOf(Reducer::class, $resource);
}

public function test_is_a_termination()
{
$resource = new ToCsv();
self::assertInstanceOf(Termination::class, $resource);
}

public function test_initializes_with_a_resource()
{
$resource = new ToCsv();
$init = $resource->init();

self::assertInternalType('resource', $init);
}

public function test_writes_array_content_on_resource()
{
$resource = transform([[1, 2, 3, 4]])->toCsv();
rewind($resource);

self::assertEquals("1,2,3,4\n", stream_get_contents($resource));
}

public function test_writes_iterable_content_on_resource()
{
$resource = transform([new \ArrayIterator([1, 2, 3, 4])])->toCsv();
rewind($resource);

self::assertEquals("1,2,3,4\n", stream_get_contents($resource));
}

public function test_writes_flat_content_on_resource()
{
$resource = transform([1, 2, 3, 4])->toCsv();
rewind($resource);

self::assertEquals("1\n2\n3\n4\n", stream_get_contents($resource));
}

}
50 changes: 50 additions & 0 deletions tests/Reducer/Termination/ToResourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Pitchart\Transformer\Tests\Reducer\Termination;

use Pitchart\Transformer\Reducer;
use Pitchart\Transformer\Reducer\Termination\ToResource;
use PHPUnit\Framework\TestCase;
use Pitchart\Transformer\Termination;
use function Pitchart\Transformer\transform;

class ToResourceTest extends TestCase
{
public function test_is_a_reducer()
{
$resource = new ToResource(function ($item) { return (string) $item; });
self::assertInstanceOf(Reducer::class, $resource);
}

public function test_is_a_termination()
{
$resource = new ToResource(function ($item) { return (string) $item; });
self::assertInstanceOf(Termination::class, $resource);
}

public function test_initializes_with_a_resource()
{
$resource = new ToResource(function ($item) { return (string) $item; });
$init = $resource->init();

self::assertInternalType('resource', $init);
}

public function test_writes_content_on_resource()
{
$resource = transform([1, 2, 3, 4])->toResource();
rewind($resource);

self::assertEquals('1234', stream_get_contents($resource));
}

public function test_writes_content_on_resource_with_callback()
{
$resource = transform([1, 2, 3, 4])->toResource(function ($item) {
return sprintf("%s\n", $item);
});
rewind($resource);

self::assertEquals("1\n2\n3\n4\n", stream_get_contents($resource));
}
}

0 comments on commit 5c93f6f

Please sign in to comment.