'value']; $exception = new class($message, $code, null, $context) extends WangdianException {}; $this->assertEquals($message, $exception->getMessage()); $this->assertEquals($code, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); $this->assertInstanceOf(\Exception::class, $exception); $this->assertInstanceOf(WangdianException::class, $exception); } public function testWangdianExceptionWithPrevious(): void { $previous = new \Exception('Previous exception'); $exception = new class('Test', 0, $previous) extends WangdianException {}; $this->assertSame($previous, $exception->getPrevious()); } public function testConfigException(): void { $message = 'Configuration error'; $context = ['config_key' => 'invalid_value']; $exception = new ConfigException($message, 100, null, $context); $this->assertInstanceOf(WangdianException::class, $exception); $this->assertInstanceOf(ConfigException::class, $exception); $this->assertEquals($message, $exception->getMessage()); $this->assertEquals(100, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); } public function testAuthException(): void { $message = 'Authentication failed'; $context = ['user_id' => '123']; $exception = new AuthException($message, 401, null, $context); $this->assertInstanceOf(WangdianException::class, $exception); $this->assertInstanceOf(AuthException::class, $exception); $this->assertEquals($message, $exception->getMessage()); $this->assertEquals(401, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); } public function testHttpException(): void { $message = 'HTTP request failed'; $httpStatusCode = 500; $context = ['url' => 'https://api.example.com']; $exception = new HttpException($message, 0, null, $context, $httpStatusCode); $this->assertInstanceOf(WangdianException::class, $exception); $this->assertInstanceOf(HttpException::class, $exception); $this->assertEquals($message, $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); $this->assertEquals($httpStatusCode, $exception->getHttpStatusCode()); } public function testHttpExceptionWithDefaults(): void { $exception = new HttpException(); $this->assertEquals('', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertNull($exception->getContext()); $this->assertNull($exception->getHttpStatusCode()); } public function testApiException(): void { $message = 'API error occurred'; $apiCode = 'E1001'; $responseData = ['error' => 'Invalid parameter', 'code' => 1001]; $context = ['request_id' => 'req_123']; $exception = new ApiException($message, 0, null, $context, $apiCode, $responseData); $this->assertInstanceOf(WangdianException::class, $exception); $this->assertInstanceOf(ApiException::class, $exception); $this->assertEquals($message, $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); $this->assertEquals($apiCode, $exception->getApiCode()); $this->assertEquals($responseData, $exception->getResponseData()); } public function testApiExceptionWithDefaults(): void { $exception = new ApiException(); $this->assertEquals('', $exception->getMessage()); $this->assertEquals(0, $exception->getCode()); $this->assertNull($exception->getContext()); $this->assertNull($exception->getApiCode()); $this->assertNull($exception->getResponseData()); } public function testValidationException(): void { $message = 'Validation failed'; $errors = ['field1' => 'Field 1 is required', 'field2' => 'Field 2 is invalid']; $context = ['form_id' => 'user_form']; $exception = new ValidationException($message, 422, null, $context, $errors); $this->assertInstanceOf(WangdianException::class, $exception); $this->assertInstanceOf(ValidationException::class, $exception); $this->assertEquals($message, $exception->getMessage()); $this->assertEquals(422, $exception->getCode()); $this->assertEquals($context, $exception->getContext()); $this->assertEquals($errors, $exception->getErrors()); } public function testValidationExceptionWithEmptyErrors(): void { $exception = new ValidationException('Test validation error'); $this->assertEquals([], $exception->getErrors()); } public function testExceptionInheritance(): void { $configException = new ConfigException(); $authException = new AuthException(); $httpException = new HttpException(); $apiException = new ApiException(); $validationException = new ValidationException(); // All should inherit from WangdianException $this->assertInstanceOf(WangdianException::class, $configException); $this->assertInstanceOf(WangdianException::class, $authException); $this->assertInstanceOf(WangdianException::class, $httpException); $this->assertInstanceOf(WangdianException::class, $apiException); $this->assertInstanceOf(WangdianException::class, $validationException); // All should inherit from standard Exception $this->assertInstanceOf(\Exception::class, $configException); $this->assertInstanceOf(\Exception::class, $authException); $this->assertInstanceOf(\Exception::class, $httpException); $this->assertInstanceOf(\Exception::class, $apiException); $this->assertInstanceOf(\Exception::class, $validationException); } public function testExceptionChaining(): void { $rootCause = new \RuntimeException('Root cause'); $httpException = new HttpException('HTTP error', 0, $rootCause); $apiException = new ApiException('API error', 0, $httpException); $this->assertSame($httpException, $apiException->getPrevious()); $this->assertSame($rootCause, $apiException->getPrevious()->getPrevious()); } public function testContextDataTypes(): void { $complexContext = [ 'string' => 'value', 'integer' => 123, 'float' => 45.67, 'boolean' => true, 'array' => ['nested' => 'data'], 'null' => null, ]; $exception = new ApiException('Test', 0, null, $complexContext); $this->assertEquals($complexContext, $exception->getContext()); $this->assertIsString($exception->getContext()['string']); $this->assertIsInt($exception->getContext()['integer']); $this->assertIsFloat($exception->getContext()['float']); $this->assertIsBool($exception->getContext()['boolean']); $this->assertIsArray($exception->getContext()['array']); $this->assertNull($exception->getContext()['null']); } public function testUnicodeInExceptions(): void { $unicodeMessage = '错误信息:参数无效'; $unicodeContext = ['错误码' => '1001', '描述' => '用户名包含非法字符']; $unicodeApiCode = 'E错误1001'; $exception = new ApiException($unicodeMessage, 0, null, $unicodeContext, $unicodeApiCode); $this->assertEquals($unicodeMessage, $exception->getMessage()); $this->assertEquals($unicodeContext, $exception->getContext()); $this->assertEquals($unicodeApiCode, $exception->getApiCode()); } }