Skip to content

Conversation

@ChiragAgg5k
Copy link
Member

@ChiragAgg5k ChiragAgg5k commented Jan 13, 2026

Summary

Adds configurable bit size and signed/unsigned support to the Integer validator, making it more flexible for different integer type requirements.

Changes

  • Add configurable bit sizes: 8, 16, 32, or 64 bits (default: 32)
  • Add signed/unsigned option (default: signed)
  • Add automatic range validation based on bit size and signedness
  • Add new methods:
    • getBits(): Returns the configured bit size
    • isUnsigned(): Returns whether the integer is unsigned
    • getFormat(): Returns OpenAPI/JSON Schema format string (e.g., "int8", "int32", "int64")
  • Update getDescription() to reflect specific bit size and range constraints
  • Add comprehensive test coverage for new functionality

Usage Examples

// Default: 32-bit signed integer
$validator = new Integer();

// 8-bit signed integer (-128 to 127)
$validator = new Integer(false, 8);

// 16-bit unsigned integer (0 to 65,535)
$validator = new Integer(false, 16, true);

// 64-bit signed integer with loose mode
$validator = new Integer(true, 64);

Backwards Compatibility

Fully backwards compatible - all existing uses of new Integer() and new Integer(true) continue to work with the default 32-bit signed behavior.

Summary by CodeRabbit

  • New Features

    • Integer validator now supports selectable bit-widths (8, 16, 32, 64) and unsigned mode; new accessors expose bit-width, signedness, and format.
  • Improvements

    • Validation enforces concrete ranges per bit-width/sign and produces clearer signed/unsigned range messages.
    • Constructor validates parameters and raises clear errors for invalid bit sizes and unsupported 64-bit unsigned.
  • Tests

    • Added coverage for bit-size/signedness variants, formats, edge cases, and invalid-bit scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add configurable bit sizes (8, 16, 32, 64) with 32-bit as default
- Add signed/unsigned option with signed as default
- Add range validation based on bit size and signedness
- Add getBits(), isUnsigned(), and getFormat() methods
- Update getDescription() to reflect specific constraints
- Add comprehensive tests for new functionality
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 13, 2026

Walkthrough

The Integer validator constructor now is __construct(bool $loose = false, int $bits = 32, bool $unsigned = false) and validates bits (allowed: 8, 16, 32, 64) and disallows 64-bit unsigned. Two protected properties bits and unsigned were added. isValid() computes min/max from bit-width and sign and enforces range checks. getDescription() produces dynamic signed/unsigned, bit-width, and range text. New public accessors getBits(), isUnsigned(), and getFormat() were added. Tests were added/updated to cover bit sizes, signedness, formats, and constructor exceptions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add bit size and signed/unsigned support to Integer validator' clearly and concisely summarizes the main change, accurately reflecting the extension of the Integer validator with configurable bit sizes and sign support.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0c7678 and 982d4fd.

📒 Files selected for processing (2)
  • src/Validator/Integer.php
  • tests/Validator/IntegerTest.php
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/Validator/IntegerTest.php
  • src/Validator/Integer.php

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/Validator/Integer.php (2)

58-67: Consider extracting range calculation to avoid duplication.

The min/max calculation logic is duplicated between getDescription() and isValid(). Consider extracting this into a private helper method or caching the values as properties set during construction.

♻️ Suggested refactor
 class Integer extends Validator
 {
     protected bool $loose = false;
     protected int $bits = 32;
     protected bool $unsigned = false;
+    protected int $min;
+    protected int $max;

     public function __construct(bool $loose = false, int $bits = 32, bool $unsigned = false)
     {
         if (!\in_array($bits, [8, 16, 32, 64])) {
             throw new \InvalidArgumentException('Bits must be 8, 16, 32, or 64');
         }

         $this->loose = $loose;
         $this->bits = $bits;
         $this->unsigned = $unsigned;
+
+        if ($this->unsigned) {
+            $this->min = 0;
+            $this->max = (2 ** $this->bits) - 1;
+        } else {
+            $this->min = -(2 ** ($this->bits - 1));
+            $this->max = (2 ** ($this->bits - 1)) - 1;
+        }
     }

Then use $this->min and $this->max in both getDescription() and isValid().

Also applies to: 158-165


133-136: getFormat() doesn't distinguish unsigned integers.

OpenAPI and JSON Schema use formats like uint8, uint16, etc. for unsigned integers. The current implementation returns int32 for both signed and unsigned 32-bit integers, which may lead to incorrect schema generation.

♻️ Suggested fix
 public function getFormat(): string
 {
-    return 'int' . $this->bits;
+    return ($this->unsigned ? 'uint' : 'int') . $this->bits;
 }
tests/Validator/IntegerTest.php (1)

37-67: Test coverage looks good but could be more comprehensive.

The tests cover the core functionality well. Consider adding tests for:

  • getDescription() output format verification
  • 32-bit signed boundary values (-2147483648 to 2147483647)
  • Loose mode combined with bit-size validation (e.g., new Integer(true, 8) with string inputs)
💡 Additional test suggestions
public function testGetDescription()
{
    $validator = new Integer(false, 8);
    $this->assertStringContainsString('signed', $validator->getDescription());
    $this->assertStringContainsString('8-bit', $validator->getDescription());
    
    $validatorU = new Integer(false, 8, true);
    $this->assertStringContainsString('unsigned', $validatorU->getDescription());
}

public function testLooseModeWithBitSize()
{
    $validator = new Integer(true, 8);
    $this->assertTrue($validator->isValid('127'));
    $this->assertFalse($validator->isValid('128'));
}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c34146 and c89545f.

📒 Files selected for processing (2)
  • src/Validator/Integer.php
  • tests/Validator/IntegerTest.php
🧰 Additional context used
🧬 Code graph analysis (1)
tests/Validator/IntegerTest.php (1)
src/Validator/Integer.php (5)
  • Integer (12-174)
  • getBits (109-112)
  • isUnsigned (121-124)
  • getFormat (133-136)
  • isValid (146-173)
🔇 Additional comments (3)
src/Validator/Integer.php (2)

19-27: LGTM!

New properties for bit size and signedness are well-documented and have sensible defaults that maintain backward compatibility.


38-47: LGTM!

Constructor properly validates the $bits parameter against allowed values and throws a clear exception message. The default values ensure backward compatibility with existing code.

tests/Validator/IntegerTest.php (1)

69-74: LGTM!

Exception testing is properly implemented using PHPUnit's expectException and expectExceptionMessage methods.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/Validator/Integer.php:
- Around line 138-141: getFormat() currently always returns 'int' + $this->bits,
ignoring the unsigned flag; update it to check isUnsigned() (or $unsigned) and
return 'uint' + $this->bits when true (e.g.,
'uint8','uint16','uint32','uint64'), otherwise return 'int' + $this->bits so the
format matches OpenAPI's unsigned integer formats; modify the getFormat() method
accordingly and keep the existing $bits and isUnsigned() usage for determining
the returned string.
🧹 Nitpick comments (2)
tests/Validator/IntegerTest.php (1)

37-67: Consider adding test coverage for edge cases and 32-bit signed range.

The test covers several bit sizes but could benefit from additional coverage:

  1. 32-bit signed range validation: The default 32-bit signed validator is created but its range (-2,147,483,648 to 2,147,483,647) is not tested.
  2. 64-bit signed boundary values: Only getFormat() is tested for 64-bit, but not actual range validation.
  3. getDescription() output: Not tested for any configuration.
📝 Suggested additional test coverage
         // 64-bit signed
         $validator64 = new Integer(false, 64);
         $this->assertSame('int64', $validator64->getFormat());
+        $this->assertTrue($validator64->isValid(PHP_INT_MAX));
+        $this->assertTrue($validator64->isValid(PHP_INT_MIN));
+
+        // 32-bit signed range validation
+        $validator32 = new Integer(false, 32);
+        $this->assertTrue($validator32->isValid(-2147483648));
+        $this->assertTrue($validator32->isValid(2147483647));
+        $this->assertFalse($validator32->isValid(-2147483649));
+        $this->assertFalse($validator32->isValid(2147483648));
+
+        // Test getDescription output
+        $this->assertStringContainsString('signed', $validator->getDescription());
+        $this->assertStringContainsString('32-bit', $validator->getDescription());
     }
src/Validator/Integer.php (1)

63-80: Consider extracting range calculation to reduce duplication.

The min/max calculation logic is duplicated in both getDescription() and isValid(). Extracting this to a private method would improve maintainability.

♻️ Suggested refactor to extract range calculation
+    /**
+     * Get Min/Max Range
+     *
+     * Returns the min and max values based on bit size and signedness.
+     *
+     * @return array{min: int, max: int}
+     */
+    private function getRange(): array
+    {
+        if ($this->unsigned) {
+            return ['min' => 0, 'max' => (2 ** $this->bits) - 1];
+        }
+        return [
+            'min' => -(2 ** ($this->bits - 1)),
+            'max' => (2 ** ($this->bits - 1)) - 1
+        ];
+    }
+
     public function getDescription(): string
     {
         $signedness = $this->unsigned ? 'unsigned' : 'signed';
-
-        // Calculate min and max values based on bit size and signed/unsigned
-        if ($this->unsigned) {
-            $min = 0;
-            $max = (2 ** $this->bits) - 1;
-        } else {
-            $min = -(2 ** ($this->bits - 1));
-            $max = (2 ** ($this->bits - 1)) - 1;
-        }
+        $range = $this->getRange();

         return \sprintf(
             'Value must be a valid %s %d-bit integer between %s and %s',
             $signedness,
             $this->bits,
-            \number_format($min),
-            \number_format($max)
+            \number_format($range['min']),
+            \number_format($range['max'])
         );
     }

Then similarly update isValid() to use $this->getRange().

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c2ca5a and e0c7678.

📒 Files selected for processing (2)
  • src/Validator/Integer.php
  • tests/Validator/IntegerTest.php
🧰 Additional context used
🧬 Code graph analysis (2)
tests/Validator/IntegerTest.php (1)
src/Validator/Integer.php (5)
  • Integer (12-179)
  • getBits (114-117)
  • isUnsigned (126-129)
  • getFormat (138-141)
  • isValid (151-178)
src/Validator/Integer.php (1)
src/Validator/Range.php (2)
  • __construct (34-39)
  • getFormat (66-69)
🔇 Additional comments (4)
tests/Validator/IntegerTest.php (1)

69-81: LGTM!

Exception tests properly verify both invalid bit size and 64-bit unsigned rejection using PHPUnit's expectException and expectExceptionMessage.

src/Validator/Integer.php (3)

19-27: LGTM!

New properties for bit size and signedness are well-documented and have sensible defaults that maintain backward compatibility.


38-52: LGTM!

Constructor validation is solid:

  • Correctly restricts bit sizes to valid values (8, 16, 32, 64)
  • Appropriately rejects 64-bit unsigned due to PHP's signed integer representation
  • Maintains backward compatibility with existing code using new Integer() or new Integer(true)

151-178: LGTM!

The validation logic is correct:

  • Properly handles loose mode by converting numeric strings to numbers
  • Correctly validates that the value is an integer type
  • Range checking correctly uses the calculated min/max based on bit size and signedness

@ChiragAgg5k ChiragAgg5k merged commit 30b6030 into main Jan 13, 2026
4 checks passed
@ChiragAgg5k ChiragAgg5k deleted the feat-integer-validator-bit-size-signedness branch January 13, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants