validate('phone', $number); expect($errors)->toBeEmpty("Failed for: {$number}"); } }); it('fails validation for invalid phone numbers', function () { $rule = new Phone(); $invalidNumbers = [ 'abc', '123', // too short '123456789012345678901', // too long '+49#123#456', // invalid characters 'not-a-phone', '++49123456789', // double plus ]; foreach ($invalidNumbers as $number) { $errors = $rule->validate('phone', $number); expect($errors)->not->toBeEmpty("Should fail for: {$number}"); expect($errors)->toHaveKey('phone'); } }); it('allows null and empty values', function () { $rule = new Phone(); expect($rule->validate('phone', null))->toBeEmpty(); expect($rule->validate('phone', ''))->toBeEmpty(); }); it('fails validation for non-string values', function () { $rule = new Phone(); $nonStringValues = [ 123456789, 12.34, true, [], new stdClass(), ]; foreach ($nonStringValues as $value) { $errors = $rule->validate('phone', $value); expect($errors)->not->toBeEmpty(); expect($errors['phone'])->toBe('Phone number must be a string.'); } }); it('uses custom error message', function () { $customMessage = 'Please enter a valid phone number.'; $rule = new Phone($customMessage); $errors = $rule->validate('phone', 'invalid'); expect($errors['phone'])->toBe($customMessage); }); it('returns correct default message', function () { $rule = new Phone(); expect($rule->getMessage())->toBe('The field must be a valid phone number.'); }); it('validates real-world phone number formats', function () { $rule = new Phone(); $realWorldNumbers = [ // German numbers '+49 30 12345678', // Berlin landline '+49 151 12345678', // Mobile '030 12345678', // National format // US numbers '+1 212 555 1234', // New York '(212) 555-1234', // National format '212-555-1234', // Alternative format // UK numbers '+44 20 7946 0958', // London // French numbers '+33 1 23 45 67 89', // Paris // International toll-free '+800 12345678', // International toll-free ]; foreach ($realWorldNumbers as $number) { $errors = $rule->validate('phone', $number); expect($errors)->toBeEmpty("Failed for real-world number: {$number}"); } }); it('handles edge cases gracefully', function () { $rule = new Phone(); $edgeCases = [ '+1234567890123456789', // Very long but valid '+1 12345', // Short but valid ' +49 123 456789 ', // With whitespace ]; foreach ($edgeCases as $case) { $errors = $rule->validate('phone', $case); expect($errors)->toBeEmpty("Failed for edge case: {$case}"); } }); });