Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a NumberType that maps to the BcMath\Number value object #6686

Merged
merged 1 commit into from
Jan 6, 2025

Conversation

derrabus
Copy link
Member

@derrabus derrabus commented Jan 5, 2025

Q A
Type feature
Fixed issues #6644

Summary

PHP 8.4 introduces a new Number class (RFC, php/php-src#13741) that feels like a perfect fit for DECIMAL values. This PR introduces a new NumberType class and a corresponding Types::NUMBER constant which maps decimal values to Number objects instead of plain strings.

greg0ire
greg0ire previously approved these changes Jan 5, 2025
@@ -49,6 +49,8 @@ jobs:

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
Copy link
Member

Choose a reason for hiding this comment

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

This is necessary because of Psalm, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I know, we need to kick it.

Copy link
Member

@morozov morozov left a comment

Choose a reason for hiding this comment

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

Would it be possible to add some test coverage for value conversion? There is a functional BigIntTypeTest, so maybe add one for the new type as well.

$originalValue = new Number('13.37');
$dbValue = $this->processValue(Types::NUMBER, $originalValue);

self::assertSame(0, $originalValue->compare($dbValue));
Copy link
Member

Choose a reason for hiding this comment

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

It took me a minute to understand why zero is expected. I'm curious if assertEquals() can be used instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

We cannot use assertEquals() because PHPUnit 10 would compare two Number objects by comparing all properties. That's a problem because new Number('13.37') and new Number('13.3700') should be considered equal despite all properties being different. And that's a problem for us because the database might decide to normalize decimals by stripping or padding trailing zeros.

That's an issue that could be fixed upstream however. I can look into this, but given PHPUnit's release schedule, that fix would land in PHPUnit 12 earliest.

For now, the compare() method or the overloaded operators == and <=> are the proper ways of checking if two numbers are equal. Our PHPCS rules would however fix assertTrue($a == $b) to assertEquals(), so I decided to not use that either. But I've alternated between compare() and <=>, so I've now changed all tests to consistently use the spaceship operator. The value range of that operator is defined as [-1, 0, 1], so maybe that makes things a little clearer.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've opened sebastianbergmann/comparator#121 to address this issue.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think <=> makes it clearer since it's more visually distinct. Thanks for the explanation and addressing it upstream. I believe, ultimately, using assertEquals() will be the clearest approach as it's the standard.

@derrabus derrabus force-pushed the feature/number-type branch from cf6a9fe to 8f39a40 Compare January 6, 2025 07:11
@derrabus derrabus changed the title Add a NumberType that maps to the BCMath\Number value object Add a NumberType that maps to the BcMath\Number value object Jan 6, 2025
@derrabus
Copy link
Member Author

derrabus commented Jan 6, 2025

Would it be possible to add some test coverage for value conversion? There is a functional BigIntTypeTest, so maybe add one for the new type as well.

The PR already contains two new NumberTest classes (unit + functional). Did I miss important test cases?

@eugene-borovov
Copy link

There is a polyfill for BcMath\Number. Is it worth to use it?

@derrabus
Copy link
Member Author

derrabus commented Jan 6, 2025

There is a polyfill for BcMath\Number.

I would expect that my new type is compatible with that polyfill.

Is it worth to use it?

That's something you have to decide for yourself. 🙂

@morozov
Copy link
Member

morozov commented Jan 6, 2025

Did I miss important test cases?

The previous inline coverage report shown quite a few places in the conversion code as uncovered, but probably it was a glitch. Now, the diff coverage is at 100%, so we're good.

@derrabus derrabus merged commit eea8aaf into doctrine:4.3.x Jan 6, 2025
68 checks passed
@derrabus derrabus deleted the feature/number-type branch January 6, 2025 18:00
derrabus added a commit to derrabus/dbal that referenced this pull request Jan 6, 2025
* 4.3.x:
  Enable platformOptions to be considered for ColumnDiff (PostgreSQL jsonb support) (doctrine#6693)
  Ignore new PHPStan errors
  Cleanup obsolete PHPStan ignore rules (doctrine#6697)
  Add a `NumberType` that maps to the `BcMath\Number` value object (doctrine#6686)
  PHPStan 2.1.1 (doctrine#6690)
  PHPUnit 10.5.39 (doctrine#6692)
  PHPUnit 9.6.22 (doctrine#6691)
  Bump doctrine/.github from 6.0.0 to 7.1.0 (doctrine#6649)
  Bump doctrine/.github from 5.3.0 to 6.0.0 (doctrine#6642)
derrabus added a commit to derrabus/dbal that referenced this pull request Jan 6, 2025
* 4.3.x:
  Enable platformOptions to be considered for ColumnDiff (PostgreSQL jsonb support) (doctrine#6693)
  Ignore new PHPStan errors
  Cleanup obsolete PHPStan ignore rules (doctrine#6697)
  Add a `NumberType` that maps to the `BcMath\Number` value object (doctrine#6686)
  PHPStan 2.1.1 (doctrine#6690)
  PHPUnit 10.5.39 (doctrine#6692)
  PHPUnit 9.6.22 (doctrine#6691)
  Bump doctrine/.github from 6.0.0 to 7.1.0 (doctrine#6649)
  Bump doctrine/.github from 5.3.0 to 6.0.0 (doctrine#6642)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use the BcMath\Number as new Type to work easier with arbitrary precision numbers
4 participants