Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add After Last function with Tests #1494

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/core/etl/src/Flow/ETL/Function/ScalarFunctionChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ public function hash(Algorithm $algorithm = new NativePHPHash()) : self
return new Hash($this, $algorithm);
}

/**
* Returns the index of given $needle in string.
*/
public function indexOf(ScalarFunction|string $needle, ScalarFunction|bool $ignoreCase = false, ScalarFunction|int $offset = 0) : self
{
return new IndexOf($this, $needle, $ignoreCase, $offset);
Expand Down Expand Up @@ -321,6 +324,9 @@ public function isType(string|Type ...$types) : self
return new IsType($this, ...$types);
}

/**
* Check string is utf8 and returns true or false.
*/
public function isUtf8() : IsUtf8
{
return new IsUtf8($this);
Expand Down Expand Up @@ -482,26 +488,50 @@ public function startsWith(ScalarFunction|string $needle) : self
return new StartsWith($this, $needle);
}

/**
* Returns the contents found after the first occurrence of the given string.
*/
public function stringAfter(ScalarFunction|string $needle, ScalarFunction|bool $includeNeedle = false) : self
{
return new StringAfter($this, $needle, $includeNeedle);
}

/**
* Returns the contents found after the last occurrence of the given string.
*/
public function stringAfterLast(ScalarFunction|string $needle, ScalarFunction|bool $includeNeedle = false) : self
{
return new StringAfterLast($this, $needle, $includeNeedle);
}

/**
* Returns the contents found before the first occurrence of the given string.
*/
public function stringBefore(ScalarFunction|string $needle, ScalarFunction|bool $includeNeedle = false) : self
{
return new StringBefore($this, $needle, $includeNeedle);
}

/**
* Returns a string that you can use in case-insensitive comparisons.
*/
public function stringFold() : self
{
return new StringFold($this);
}

/**
* Covert string to a style from enum list, passed in parameter.
* Can be string "upper" or StringStyles::UPPER for Upper (example).
*/
public function stringStyle(ScalarFunction|string|StringStyles $style) : self
{
return new StringStyle($this, $style);
}

/**
* Changes all graphemes/code points to "title case".
*/
public function stringTitle(ScalarFunction|bool $allWords = false) : self
{
return new StringTitle($this, $allWords);
Expand Down
40 changes: 40 additions & 0 deletions src/core/etl/src/Flow/ETL/Function/StringAfterLast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Function;

use function Flow\ETL\DSL\{type_list, type_string};
use function Symfony\Component\String\u;
use Flow\ETL\Function\ScalarFunction\TypedScalarFunction;
use Flow\ETL\PHP\Type\Type;
use Flow\ETL\Row;

final class StringAfterLast extends ScalarFunctionChain implements TypedScalarFunction
{
public function __construct(
private readonly ScalarFunction|string $string,
private readonly ScalarFunction|string $needle,
private readonly ScalarFunction|bool $includeNeedle = false,
) {
}

public function eval(Row $row) : mixed
{
$string = (new Parameter($this->string))->asString($row);

if ($string === null) {
return null;
}

$needle = (new Parameter($this->needle))->as($row, type_string(), type_list(type_string()));
$includeNeedle = (new Parameter($this->includeNeedle))->asBoolean($row);

return u($string)->afterLast($needle, $includeNeedle)->toString();
}

public function returns() : Type
{
return type_string();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Tests\Unit\Function;

use function Flow\ETL\DSL\row;
use function Flow\ETL\DSL\{ref, str_entry, type_string};
use Flow\ETL\Function\{StringAfterLast};
use Flow\ETL\PHP\Type\Type;
use Flow\ETL\Tests\FlowTestCase;

final class StringAfterLastTest extends FlowTestCase
{
public function test_returns_method_returns_string_type() : void
{
$stringAfterFunction = new StringAfterLast('test', 'e');
$returnType = $stringAfterFunction->returns();

self::assertInstanceOf(Type::class, $returnType);

self::assertTrue($returnType->isEqual(type_string()));
}

public function test_string_after_last() : void
{
self::assertSame(
'rld',
ref('str')->stringAfterLast(ref('needle'))->eval(
row(
str_entry('str', 'hello world'),
str_entry('needle', 'o')
)
)
);
}

public function test_string_after_last_including_needle() : void
{
self::assertSame(
'orld',
ref('str')->stringAfterLast(ref('needle'), includeNeedle: true)->eval(
row(
str_entry('str', 'hello world'),
str_entry('needle', 'o')
)
)
);
}

public function test_string_after_last_returns_null() : void
{
self::assertNull(
ref('str')->stringAfterLast('x')->eval(
row(
str_entry('str', null),
)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class DbalPlatformTest extends TestCase
{
public static function provideSQLitePlatform() : iterable
{
yield 'legacy' => ['Doctrine\DBAL\Platforms\SqlitePlatform'];
yield 'legacy' => [\Doctrine\DBAL\Platforms\SqlitePlatform::class];
yield 'new' => [SQLitePlatform::class];
}

Expand Down
Loading