packages/ztd-query-core/tests/Unit/Shadow/Mutation/Upsert/UpsertNumberTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Upsert;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Exception\UnsupportedSqlException;
11use ZtdQuery\Shadow\Mutation\Upsert\UpsertNumber;
12
13#[CoversClass(UpsertNumber::class)]
14#[UsesClass(UnsupportedSqlException::class)]
15final class UpsertNumberTest extends TestCase
16{
17 public function testOfKeepsANumberAsItIs(): void
18 {
19 self::assertSame(7, (new UpsertNumber())->of(7));
20 self::assertSame(1.5, (new UpsertNumber())->of(1.5));
21 }
22
23 public function testOfReadsWholeTextAsAnIntegerRatherThanAFloat(): void
24 {
25 self::assertSame(12, (new UpsertNumber())->of('12'));
26 }
27
28 public function testOfReadsTextWrittenTheWayAFloatIsAsAFloat(): void
29 {
30 self::assertSame(1.5, (new UpsertNumber())->of('1.5'));
31 self::assertSame(1000.0, (new UpsertNumber())->of('1e3'));
32 }
33
34 public function testOfRefusesTextThatIsNotWrittenAsANumber(): void
35 {
36 $this->expectException(UnsupportedSqlException::class);
37
38 (new UpsertNumber())->of('paid');
39 }
40
41 public function testOfRefusesABooleanBecauseArithmeticOnItIsNotSomethingSqlAgreesOn(): void
42 {
43 $this->expectException(UnsupportedSqlException::class);
44
45 (new UpsertNumber())->of(true);
46 }
47
48 public function testIsNumericAnswersForTheValuesArithmeticCanBeDoneOn(): void
49 {
50 self::assertTrue((new UpsertNumber())->isNumeric(7));
51 self::assertTrue((new UpsertNumber())->isNumeric(1.5));
52 self::assertTrue((new UpsertNumber())->isNumeric('12'));
53 self::assertFalse((new UpsertNumber())->isNumeric('paid'));
54 self::assertFalse((new UpsertNumber())->isNumeric(null));
55 }
56
57 public function testPositiveKeepsTheNumberAndItsSign(): void
58 {
59 self::assertSame(-3, (new UpsertNumber())->positive('-3'));
60 }
61
62 public function testPositiveIsUnknownForAnUnknownValue(): void
63 {
64 self::assertNull((new UpsertNumber())->positive(null));
65 }
66
67 public function testNegativeTurnsTheSignAround(): void
68 {
69 self::assertSame(-3, (new UpsertNumber())->negative(3));
70 self::assertSame(3, (new UpsertNumber())->negative(-3));
71 }
72
73 public function testNegativeIsUnknownForAnUnknownValue(): void
74 {
75 self::assertNull((new UpsertNumber())->negative(null));
76 }
77
78 public function testAddSumsBothSides(): void
79 {
80 self::assertSame(5, (new UpsertNumber())->add(2, '3'));
81 }
82
83 public function testAddIsUnknownWhenEitherSideIs(): void
84 {
85 self::assertNull((new UpsertNumber())->add(null, 3));
86 self::assertNull((new UpsertNumber())->add(3, null));
87 }
88
89 public function testSubtractTakesTheRightSideFromTheLeft(): void
90 {
91 self::assertSame(2, (new UpsertNumber())->subtract(5, 3));
92 }
93
94 public function testSubtractIsUnknownWhenEitherSideIs(): void
95 {
96 self::assertNull((new UpsertNumber())->subtract(null, 3));
97 self::assertNull((new UpsertNumber())->subtract(3, null));
98 }
99
100 public function testMultiplyMultipliesBothSides(): void
101 {
102 self::assertSame(6, (new UpsertNumber())->multiply(2, 3));
103 }
104
105 public function testMultiplyIsUnknownWhenEitherSideIs(): void
106 {
107 self::assertNull((new UpsertNumber())->multiply(null, 3));
108 self::assertNull((new UpsertNumber())->multiply(3, null));
109 }
110
111 public function testDivideDividesTheLeftSideByTheRight(): void
112 {
113 self::assertSame(2, (new UpsertNumber())->divide(6, 3));
114 }
115
116 public function testDivideIsUnknownWhenEitherSideIs(): void
117 {
118 self::assertNull((new UpsertNumber())->divide(null, 3));
119 self::assertNull((new UpsertNumber())->divide(3, null));
120 }
121
122 public function testDivideRefusesAZeroDivisor(): void
123 {
124 $this->expectException(UnsupportedSqlException::class);
125
126 (new UpsertNumber())->divide(6, 0);
127 }
128
129 public function testDivideRefusesAZeroDivisorWrittenAsAFloat(): void
130 {
131 $this->expectException(UnsupportedSqlException::class);
132
133 (new UpsertNumber())->divide(6, 0.0);
134 }
135
136 public function testModuloAnswersWhatIsLeftOver(): void
137 {
138 self::assertSame(1, (new UpsertNumber())->modulo(7, 3));
139 }
140
141 public function testModuloTakesBothSidesAsWholeNumbersFirst(): void
142 {
143 self::assertSame(1, (new UpsertNumber())->modulo(7.9, 3.9));
144 }
145
146 public function testModuloIsUnknownWhenEitherSideIs(): void
147 {
148 self::assertNull((new UpsertNumber())->modulo(null, 3));
149 self::assertNull((new UpsertNumber())->modulo(3, null));
150 }
151
152 public function testModuloRefusesADivisorThatIsZeroOnceItIsAWholeNumber(): void
153 {
154 $this->expectException(UnsupportedSqlException::class);
155
156 (new UpsertNumber())->modulo(7, 0.5);
157 }
158}
159