Skip to content

Commit

Permalink
Add pattern()->match()->groupBy()->flatMap() #35
Browse files Browse the repository at this point in the history
  • Loading branch information
danon committed Feb 23, 2020
1 parent faaf006 commit 85debcc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 34 deletions.
15 changes: 14 additions & 1 deletion src/TRegx/CleanRegex/Internal/Match/GroupBy/FlatMapStrategy.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
<?php
namespace TRegx\CleanRegex\Internal\Match\GroupBy;

use TRegx\CleanRegex\Internal\Match\FlatMapper;
use TRegx\CleanRegex\Internal\Match\MatchAll\EagerMatchAllFactory;
use TRegx\CleanRegex\Internal\Model\Factory\MatchObjectFactory;
use TRegx\CleanRegex\Internal\Model\Match\IndexedRawMatchOffset;
use TRegx\CleanRegex\Internal\Model\Matches\IRawMatchesOffset;

class FlatMapStrategy implements Strategy
{
/** @var callable */
private $mapper;
/** @var MatchObjectFactory */
private $factory;

public function __construct(callable $mapper)
public function __construct(callable $mapper, MatchObjectFactory $factory)
{
$this->mapper = $mapper;
$this->factory = $factory;
}

function transform(array $groups, IRawMatchesOffset $matches): array
{
foreach ($groups as &$group) {
$group = (new FlatMapper($group, function (IndexedRawMatchOffset $match) use ($matches) {
$mapper = $this->mapper;
return $mapper($this->factory->create($match->getIndex(), $match, new EagerMatchAllFactory($matches)));
}))->get();
}
return $groups;
}
}
9 changes: 7 additions & 2 deletions src/TRegx/CleanRegex/Match/GroupByPattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,17 @@ public function texts(): array

public function map(callable $mapper): array
{
return $this->groupBy(new MapStrategy($mapper, new MatchObjectFactoryImpl($this->base, -1, $this->base->getUserData())));
return $this->groupBy(new MapStrategy($mapper, $this->factory()));
}

public function flatMap(callable $mapper): array
{
return $this->groupBy(new FlatMapStrategy($mapper));
return $this->groupBy(new FlatMapStrategy($mapper, $this->factory()));
}

private function factory(): MatchObjectFactoryImpl
{
return new MatchObjectFactoryImpl($this->base, -1, $this->base->getUserData());
}

private function groupBy(Strategy $strategy): array
Expand Down
117 changes: 86 additions & 31 deletions test/Feature/TRegx/CleanRegex/Match/groupBy/MatchPatternTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,11 @@ class MatchPatternTest extends TestCase
{
/**
* @test
* @dataProvider mappers
* @param string $function
* @param array $arguments
*/
public function shouldGroup(string $function, array $arguments)
public function shouldGroupBy_texts()
{
// given
$pattern = $this->groupBy();

// when
$result = $pattern->$function(...$arguments);
$result = $this->groupBy()->texts();

// then
$this->assertEquals([
Expand All @@ -31,17 +25,48 @@ public function shouldGroup(string $function, array $arguments)

/**
* @test
* @dataProvider mappers
* @param string $function
* @param array $arguments
*/
public function shouldNotIncludeFilteredOut(string $function, array $arguments)
public function shouldGroupBy_map()
{
// when
$result = $this->groupBy()->map(function (Match $match) {
return "$match";
});

// then
$this->assertEquals([
'cm' => ['14cm', '19cm', '2cm'],
'mm' => ['13mm', '18mm'],
], $result);
}

/**
* @test
*/
public function shouldGroupBy_flatMap()
{
// when
$result = $this->groupBy()->flatMap(function (Match $match) {
return ["$match", $match->offset()];
});

// then
$this->assertEquals([
'cm' => ['14cm', 4, '19cm', 14, '2cm', 24],
'mm' => ['13mm', 9, '18mm', 19],
], $result);
}

/**
* @test
*/
public function shouldNotIncludeFilteredOut_texts()
{
// given
$groupByPattern = $this->filtered();

// when
$result = $groupByPattern->$function(...$arguments);
$result = $groupByPattern->texts();

// then
$this->assertEquals([
Expand All @@ -50,30 +75,45 @@ public function shouldNotIncludeFilteredOut(string $function, array $arguments)
], $result);
}

public function mappers(): array
/**
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $expected
*/
public function shouldNotIncludeFilteredOut(string $function, array $expected)
{
return array_merge(
['texts' => ['texts', []]],
$this->mappersWithMatch()
);
// given
$groupByPattern = $this->filtered();

// when
$result = $groupByPattern->$function(function (Match $match) {
return [$match->text(), $match->offset()];
});

// then
$this->assertEquals($expected, $result);
}

/**
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $arguments
*/
public function shouldNotHaveLimit(string $function, array $arguments)
public function shouldNotHaveLimit(string $function)
{
// given
$groupBy = $this->filtered();
$called = 0;

// when
$groupBy->$function(function (Match $match) use (&$called) {
// when
$called++;
$this->assertEquals(-1, $match->limit());

// clean
return [];
});

// then
Expand All @@ -85,43 +125,48 @@ public function shouldNotHaveLimit(string $function, array $arguments)
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $arguments
*/
public function shouldReturnOtherMatches_whenFiltered(string $function, array $arguments)
public function shouldReturnOtherMatches_whenFiltered(string $function)
{
// given
$groupByPattern = $this->filtered();

// when
$groupByPattern->$function(function (Match $match) {
// when
$this->assertEquals(['12', '19cm', '18mm', '2cm'], $match->all());

// clean
return [];
});
}

/**
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $arguments
*/
public function shouldPreserveUserData(string $function, array $arguments)
public function shouldPreserveUserData(string $function)
{
// given
$groupByPattern = $this->filtered();

// when
$groupByPattern->$function(function (Match $match) {
// when
$this->assertEquals("verify me:$match", $match->getUserData());

// clean
return [];
});
}

/**
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $arguments
*/
public function shouldIndexMatches(string $function, array $arguments)
public function shouldIndexMatches(string $function)
{
// given
$groupByPattern = $this->groupBy();
Expand All @@ -131,6 +176,9 @@ public function shouldIndexMatches(string $function, array $arguments)
$groupByPattern->$function(function (Match $match) use (&$indexes) {
// when
$indexes[$match->text()] = $match->index();

// clean
return [];
});

// then
Expand All @@ -141,9 +189,8 @@ public function shouldIndexMatches(string $function, array $arguments)
* @test
* @dataProvider mappersWithMatch
* @param string $function
* @param array $arguments
*/
public function shouldIndexMatches_filtered(string $function, array $arguments)
public function shouldIndexMatches_filtered(string $function)
{
// given
$groupByPattern = $this->filtered();
Expand All @@ -153,6 +200,9 @@ public function shouldIndexMatches_filtered(string $function, array $arguments)
$groupByPattern->$function(function (Match $match) use (&$indexes) {
// when
$indexes[$match->text()] = $match->index();

// clean
return [];
});

// then
Expand All @@ -162,9 +212,14 @@ public function shouldIndexMatches_filtered(string $function, array $arguments)
public function mappersWithMatch(): array
{
return [
'map' => ['map', [function (Match $match) {
return "$match";
}]],
'map' => ['map', [
'cm' => [['19cm', 14], ['2cm', 24]],
'mm' => [['18mm', 19]],
]],
'flatMap' => ['flatMap', [
'cm' => ['19cm', 14, '2cm', 24],
'mm' => ['18mm', 19],
]],
];
}

Expand Down

0 comments on commit 85debcc

Please sign in to comment.