| Author | Dave Jarvis <email> |
|---|---|
| Date | 2026-01-25 22:35:31 GMT-0800 |
| Commit | a2a7c4a7338028fbd1ef3c171f67c993700505b4 |
| Parent | 93d6ee2 |
| private $renderMethod; | ||
| + /** Set to true if processing the order suceeded. */ | ||
| + private $success = false; | ||
| + | ||
| public function process( array $response, int $statusCode ) { | ||
| if( $statusCode === 201 ) { | ||
| $this->processSuccess( $response ); | ||
| } else { | ||
| $this->processError( $response, $statusCode ); | ||
| } | ||
| } | ||
| - protected function processSuccess( array $response ) { | ||
| + protected function processSuccess( array $response ): void { | ||
| $this->summary = $response; | ||
| $this->renderMethod = 'renderSummary'; | ||
| + $this->success = true; | ||
| } | ||
| - protected function processError( array $response, int $statusCode ) { | ||
| + protected function processError( array $response, int $statusCode ): void { | ||
| $this->errorMessage = $response[ 'shipping_address' ][ 'detail' ] | ||
| [ 'errors' ][ 0 ][ 'message' ] | ||
| ?? $response[ 'detail' ] | ||
| ?? "An unexpected error occurred (HTTP $statusCode)."; | ||
| $this->renderMethod = 'renderError'; | ||
| } | ||
| public function render() { | ||
| $this->{$this->renderMethod}(); | ||
| + } | ||
| + | ||
| + public function success(): bool { | ||
| + return $this->success; | ||
| } | ||
| } | ||
| - public function test_Address_MissingFields_Incomplete() { | ||
| + public function test_Address_MissingFields_Incomplete(): bool { | ||
| $addr = new Address( [ 'name' => 'John' ] ); | ||
| $addr->process( [ 'name', 'street1', 'city' ] ); | ||
| return !$addr->isComplete(); | ||
| } | ||
| - public function test_Address_AllFields_Normalized() { | ||
| + public function test_Address_AllFields_Normalized(): bool { | ||
| $addr = new Address( [ | ||
| 'name' => 'John Doe', | ||
| 'street1' => '123 main st', | ||
| 'city' => 'toronto', | ||
| 'state' => 'Ontario', | ||
| 'postcode' => 'm5h 2n2', | ||
| 'country' => 'ca', | ||
| - 'phone' => '555-1234', | ||
| + 'phone' => '1-416-555-1234', | ||
| 'email' => 'john@example.com' | ||
| ] ); | ||
| - $addr->process( [ 'name', 'street1', 'city', 'state' ] ); | ||
| - return $addr->isComplete() && | ||
| - $addr->isField( 'street1', '123 MAIN ST' ) && | ||
| + return $addr->isField( 'street1', '123 MAIN ST' ) && | ||
| $addr->isField( 'city', 'TORONTO' ) && | ||
| $addr->isField( 'state', 'ON' ) && |
| * @return float Random amount with 2 decimal precision. | ||
| */ | ||
| - private function createAmount() { | ||
| + private function createAmount(): float { | ||
| return mt_rand( 0, 1000000 ) / 100.0; | ||
| } |
| 'phone' => '+1 657-278-2011', | ||
| 'email' => 'test@example.org' | ||
| + ], | ||
| + 'XX' => [ | ||
| + 'name' => 'Invalid Location', | ||
| + 'street1' => '123 Fake St', | ||
| + 'street2' => '', | ||
| + 'city' => 'Nowhere', | ||
| + 'state' => 'XX', | ||
| + 'postcode' => '00000', | ||
| + 'country' => 'XX', | ||
| + 'phone' => '+0 000-000-0000', | ||
| + 'email' => 'error@example.org' | ||
| ] | ||
| ]; |
| public function run( $callback ) { | ||
| $callback( [ | ||
| - 'test_Money_ConstructNegativeAmount_Succeeds', | ||
| 'test_Money_ConstructZeroAmount_Succeeds', | ||
| 'test_Money_ConstructLargeAmount_Succeeds', | ||
| + 'test_Money_ConstructNegativeAmount_Succeeds', | ||
| 'test_Money_ConstructManyDecimals_Succeeds', | ||
| - 'test_Money_IsCurrencyMatching_ReturnsTrue', | ||
| - 'test_Money_IsCurrencyDifferent_ReturnsFalse', | ||
| 'test_Money_IsAmountWithinTolerance_ReturnsTrue', | ||
| 'test_Money_IsAmountOutsideTolerance_ReturnsFalse' | ||
| ] ); | ||
| - } | ||
| - | ||
| - public function test_Money_ConstructNegativeAmount_Succeeds() { | ||
| - $money = new Money( -250.75, Currency::EUR ); | ||
| - return $money->isAmount( -250.75 ) && $money->isCurrency( Currency::EUR ); | ||
| } | ||
| - public function test_Money_ConstructZeroAmount_Succeeds() { | ||
| - $money = new Money( 0.0, Currency::GBP ); | ||
| - return $money->isAmount( 0.0 ) && $money->isCurrency( Currency::GBP ); | ||
| + public function test_Money_ConstructZeroAmount_Succeeds(): bool { | ||
| + $money = new Money( 0.0, Currency::CAD ); | ||
| + return $money->isAmount( 0.0 ) && $money->isCurrency( Currency::CAD ); | ||
| } | ||
| - public function test_Money_ConstructLargeAmount_Succeeds() { | ||
| + public function test_Money_ConstructLargeAmount_Succeeds(): bool { | ||
| $money = new Money( 999999999.99, Currency::CAD ); | ||
| - return $money->isAmount( 999999999.99 ) && $money->isCurrency( Currency::CAD ); | ||
| - } | ||
| - | ||
| - public function test_Money_ConstructManyDecimals_Succeeds() { | ||
| - $money = new Money( 123.456789, Currency::AUD ); | ||
| - return $money->isAmount( 123.456789 ) && $money->isCurrency( Currency::AUD ); | ||
| + return $money->isAmount( 999999999.99 ); | ||
| } | ||
| - public function test_Money_IsCurrencyMatching_ReturnsTrue() { | ||
| - $money = new Money( 50.0, Currency::USD ); | ||
| - return $money->isCurrency( Currency::USD ); | ||
| + public function test_Money_ConstructNegativeAmount_Succeeds(): bool { | ||
| + $money = new Money( -250.75, Currency::EUR ); | ||
| + return $money->isAmount( -250.75 ) && $money->isCurrency( Currency::EUR ); | ||
| } | ||
| - public function test_Money_IsCurrencyDifferent_ReturnsFalse() { | ||
| - $money = new Money( 50.0, Currency::USD ); | ||
| - return !$money->isCurrency( Currency::EUR ); | ||
| + public function test_Money_ConstructManyDecimals_Succeeds(): bool { | ||
| + $money = new Money( 123.4567, Currency::AUD ); | ||
| + return $money->isAmount( 123.4567 ) && $money->isCurrency( Currency::AUD ); | ||
| } | ||
| - public function test_Money_IsAmountWithinTolerance_ReturnsTrue() { | ||
| - $money = new Money( 100.005, Currency::USD ); | ||
| + public function test_Money_IsAmountWithinTolerance_ReturnsTrue(): bool { | ||
| + $money = new Money( 100.005, Currency::CAD ); | ||
| return $money->isAmount( 100.00 ); | ||
| } | ||
| - public function test_Money_IsAmountOutsideTolerance_ReturnsFalse() { | ||
| - $money = new Money( 100.00, Currency::USD ); | ||
| + public function test_Money_IsAmountOutsideTolerance_ReturnsFalse(): bool { | ||
| + $money = new Money( 100.00, Currency::CAD ); | ||
| return !$money->isAmount( 100.02 ); | ||
| } |
| require_once '../Configuration.php'; | ||
| require_once 'TestHarness.php'; | ||
| -require_once 'TestableOrder.php'; | ||
| class TestOrder { | ||
| - public function run( $callback ) { | ||
| - $callback( [ | ||
| - 'test_Order_Process_WithCode201_ProcessesSuccessfully', | ||
| - 'test_Order_Process_WithCode400_ProcessesError', | ||
| - 'test_Order_Process_WithCode500_ProcessesError' | ||
| - ] ); | ||
| - } | ||
| - | ||
| - public function test_Order_Process_WithCode201_ProcessesSuccessfully() { | ||
| - return $this->runOrderTest( 201 ); | ||
| - } | ||
| - | ||
| - public function test_Order_Process_WithCode400_ProcessesError() { | ||
| - return $this->runOrderTest( 400 ); | ||
| - } | ||
| - | ||
| - public function test_Order_Process_WithCode500_ProcessesError() { | ||
| - return $this->runOrderTest( 500 ); | ||
| - } | ||
| - | ||
| - private function runOrderTest( int $expectedCode ): bool { | ||
| - $harness = new TestHarness(); | ||
| - $publisher = $this->createPublisher( $expectedCode ); | ||
| - $address = $harness->createAddress( 'US' ); | ||
| - $order = new TestableOrder(); | ||
| - | ||
| - $publisher->process( $address, $order ); | ||
| - | ||
| - return $order->processed( $expectedCode ); | ||
| - } | ||
| + private $publisher; | ||
| + private $harness; | ||
| - private function createPublisher( int $statusCode ): Publisher { | ||
| + public function __construct() { | ||
| + $this->harness = new TestHarness(); | ||
| $config = new Configuration(); | ||
| - $publisher = new TestablePublisher( $statusCode ); | ||
| - | ||
| $config->load(); | ||
| - $config->configure( $publisher ); | ||
| + $this->publisher = new Publisher(); | ||
| + $config->configure( $this->publisher ); | ||
| + } | ||
| - return $publisher; | ||
| + public function run( $callback ): void { | ||
| + $callback( [ | ||
| + 'test_Order_InvalidAddress_Unsuccessful', | ||
| + 'test_Order_ValidAddress_Successful' | ||
| + ] ); | ||
| } | ||
| -} | ||
| -/** | ||
| - * Testable Publisher subclass that returns controlled responses. | ||
| - */ | ||
| -class TestablePublisher extends Publisher { | ||
| - private $statusCode; | ||
| + public function test_Order_InvalidAddress_Unsuccessful(): bool { | ||
| + $order = new Order(); | ||
| + $this->publisher->process( new Address( ['country' => 'XX'] ), $order ); | ||
| - public function __construct( int $statusCode ) { | ||
| - $this->statusCode = $statusCode; | ||
| + return $order->success() === false; | ||
| } | ||
| - protected function post( string $path, string $content, string $header ) { | ||
| - return [ 'body' => [], 'code' => $this->statusCode ]; | ||
| + public function test_Order_ValidAddress_Successful(): bool { | ||
| + $order = new Order(); | ||
| + $this->publisher->process( $this->harness->createAddress( 'US' ), $order ); | ||
| + | ||
| + return $order->success() === true; | ||
| } | ||
| } |
| } | ||
| - public function test_Publisher_Process_WithUSAddress_UsesUSD() { | ||
| + public function test_Publisher_Process_WithUSAddress_UsesUSD(): bool { | ||
| return $this->runPublisherTest( 'US' ); | ||
| } | ||
| - public function test_Publisher_Process_WithCanadianAddress_UsesCAD() { | ||
| + public function test_Publisher_Process_WithCanadianAddress_UsesCAD(): bool { | ||
| return $this->runPublisherTest( 'CA' ); | ||
| } | ||
| - public function test_Publisher_Process_WithUKAddress_UsesGBP() { | ||
| + public function test_Publisher_Process_WithUKAddress_UsesGBP(): bool { | ||
| return $this->runPublisherTest( 'GB' ); | ||
| } | ||
| - public function test_Publisher_Process_WithAustralianAddress_UsesAUD() { | ||
| + public function test_Publisher_Process_WithAustralianAddress_UsesAUD(): bool { | ||
| return $this->runPublisherTest( 'AU' ); | ||
| } |
| Delta | 67 lines added, 87 lines removed, 20-line decrease |
|---|