feat: add sync result value object
This commit is contained in:
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Immutable sync operation result.
|
||||||
|
*
|
||||||
|
* @package WPContentSync
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace WPContentSync\Sync;
|
||||||
|
|
||||||
|
final class SyncResult {
|
||||||
|
private bool $successful;
|
||||||
|
private int $created;
|
||||||
|
private int $updated;
|
||||||
|
private int $skipped;
|
||||||
|
private int $conflicts;
|
||||||
|
|
||||||
|
/** @var array<int, string> */
|
||||||
|
private array $errors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, string> $errors Error messages.
|
||||||
|
*/
|
||||||
|
private function __construct( bool $successful, int $created, int $updated, int $skipped, int $conflicts, array $errors ) {
|
||||||
|
$this->successful = $successful;
|
||||||
|
$this->created = max( 0, $created );
|
||||||
|
$this->updated = max( 0, $updated );
|
||||||
|
$this->skipped = max( 0, $skipped );
|
||||||
|
$this->conflicts = max( 0, $conflicts );
|
||||||
|
$this->errors = array_values( array_map( 'strval', $errors ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, int> $counts Result counts.
|
||||||
|
*/
|
||||||
|
public static function success( array $counts = array() ): self {
|
||||||
|
return new self(
|
||||||
|
true,
|
||||||
|
(int) ( $counts['created'] ?? 0 ),
|
||||||
|
(int) ( $counts['updated'] ?? 0 ),
|
||||||
|
(int) ( $counts['skipped'] ?? 0 ),
|
||||||
|
(int) ( $counts['conflicts'] ?? 0 ),
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, string> $errors Error messages.
|
||||||
|
*/
|
||||||
|
public static function failure( array $errors ): self {
|
||||||
|
return new self( false, 0, 0, 0, 0, $errors );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, self> $results Results to merge.
|
||||||
|
*/
|
||||||
|
public static function merge( array $results ): self {
|
||||||
|
$successful = true;
|
||||||
|
$created = 0;
|
||||||
|
$updated = 0;
|
||||||
|
$skipped = 0;
|
||||||
|
$conflicts = 0;
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
foreach ( $results as $result ) {
|
||||||
|
$successful = $successful && $result->isSuccessful();
|
||||||
|
$created += $result->created();
|
||||||
|
$updated += $result->updated();
|
||||||
|
$skipped += $result->skipped();
|
||||||
|
$conflicts += $result->conflicts();
|
||||||
|
$errors = array_merge( $errors, $result->errors() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self( $successful, $created, $updated, $skipped, $conflicts, $errors );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSuccessful(): bool {
|
||||||
|
return $this->successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function created(): int {
|
||||||
|
return $this->created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updated(): int {
|
||||||
|
return $this->updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function skipped(): int {
|
||||||
|
return $this->skipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function conflicts(): int {
|
||||||
|
return $this->conflicts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function errors(): array {
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(): array {
|
||||||
|
return array(
|
||||||
|
'successful' => $this->successful,
|
||||||
|
'created' => $this->created,
|
||||||
|
'updated' => $this->updated,
|
||||||
|
'skipped' => $this->skipped,
|
||||||
|
'conflicts' => $this->conflicts,
|
||||||
|
'errors' => $this->errors,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Tests for sync result summaries.
|
||||||
|
*
|
||||||
|
* @package WPContentSync
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace WPContentSync\Tests\Unit\Sync;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use WPContentSync\Sync\SyncResult;
|
||||||
|
|
||||||
|
class SyncResultTest extends TestCase {
|
||||||
|
public function test_it_tracks_successful_counts(): void {
|
||||||
|
$result = SyncResult::success(
|
||||||
|
array(
|
||||||
|
'created' => 2,
|
||||||
|
'updated' => 3,
|
||||||
|
'skipped' => 1,
|
||||||
|
'conflicts' => 1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertTrue( $result->isSuccessful() );
|
||||||
|
self::assertSame( 2, $result->created() );
|
||||||
|
self::assertSame( 3, $result->updated() );
|
||||||
|
self::assertSame( 1, $result->skipped() );
|
||||||
|
self::assertSame( 1, $result->conflicts() );
|
||||||
|
self::assertSame( array(), $result->errors() );
|
||||||
|
self::assertSame(
|
||||||
|
array(
|
||||||
|
'successful' => true,
|
||||||
|
'created' => 2,
|
||||||
|
'updated' => 3,
|
||||||
|
'skipped' => 1,
|
||||||
|
'conflicts' => 1,
|
||||||
|
'errors' => array(),
|
||||||
|
),
|
||||||
|
$result->toArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_it_tracks_failed_results(): void {
|
||||||
|
$result = SyncResult::failure( array( 'posts import failed.' ) );
|
||||||
|
|
||||||
|
self::assertFalse( $result->isSuccessful() );
|
||||||
|
self::assertSame( array( 'posts import failed.' ), $result->errors() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_it_merges_multiple_results(): void {
|
||||||
|
$result = SyncResult::merge(
|
||||||
|
array(
|
||||||
|
SyncResult::success( array( 'created' => 1 ) ),
|
||||||
|
SyncResult::success(
|
||||||
|
array(
|
||||||
|
'updated' => 2,
|
||||||
|
'skipped' => 1,
|
||||||
|
'conflicts' => 1,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SyncResult::failure( array( 'terms import failed.' ) ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertFalse( $result->isSuccessful() );
|
||||||
|
self::assertSame( 1, $result->created() );
|
||||||
|
self::assertSame( 2, $result->updated() );
|
||||||
|
self::assertSame( 1, $result->skipped() );
|
||||||
|
self::assertSame( 1, $result->conflicts() );
|
||||||
|
self::assertSame( array( 'terms import failed.' ), $result->errors() );
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user