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 StringBeforeLast function #1507

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
8 changes: 8 additions & 0 deletions src/core/etl/src/Flow/ETL/Function/ScalarFunctionChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,14 @@ public function stringBefore(ScalarFunction|string $needle, ScalarFunction|bool
return new StringBefore($this, $needle, $includeNeedle);
}

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

/**
* Returns a string that you can use in case-insensitive comparisons.
*/
Expand Down
40 changes: 40 additions & 0 deletions src/core/etl/src/Flow/ETL/Function/StringBeforeLast.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 StringBeforeLast 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) : ?string
{
$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)->beforeLast($needle, $includeNeedle)->toString();
}

public function returns() : Type
{
return type_string();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ final class StringAfterLastTest extends FlowTestCase
{
public function test_returns_method_returns_string_type() : void
{
$stringAfterFunction = new StringAfterLast('test', 'e');
$returnType = $stringAfterFunction->returns();
$stringAfterLastFunction = new StringAfterLast('test', 'e');
$returnType = $stringAfterLastFunction->returns();

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?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\StringBeforeLast;
use Flow\ETL\PHP\Type\Type;
use Flow\ETL\Tests\FlowTestCase;

final class StringBeforeLastTest extends FlowTestCase
{
public function test_returns_method_returns_string_type() : void
{
$stringBeforeLastFunction = new StringBeforeLast('str', 't', false);
$returnType = $stringBeforeLastFunction->returns();

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

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

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

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

public function test_string_before_last_returns_empty_string() : void
{
self::assertSame(
'',
ref('str')->stringBeforeLast(ref('needle'))->eval(
row(
str_entry('str', ''),
str_entry('needle', 'o')
)
)
);
}

public function test_string_before_last_returns_null() : void
{
self::assertNull(
ref('str')->stringBeforeLast(ref('needle'))->eval(
row(
str_entry('str', null),
str_entry('needle', 'o')
)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ final class StringBeforeTest extends FlowTestCase
{
public function test_returns_method_returns_string_type() : void
{
$stringTitleFunction = new StringBefore('str', 't', false);
$returnType = $stringTitleFunction->returns();
$stringBeforeFunction = new StringBefore('str', 't', false);
$returnType = $stringBeforeFunction->returns();

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

Expand Down
Loading