Skip to content

Commit 537f9a5

Browse files
committed
Add tryFromMixed tests for various type classes, including string, integer, boolean, and date-time, to ensure proper handling of valid and invalid inputs.
1 parent 6f01a30 commit 537f9a5

26 files changed

+770
-10
lines changed

tests/Unit/Bool/BoolStandardTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,34 @@
105105
it('jsonSerialize returns bool', function (): void {
106106
expect(BoolStandard::tryFromString('1')->jsonSerialize())->toBeBool();
107107
});
108+
109+
it('tryFromMixed handles various inputs returning BoolStandard or Undefined', function (): void {
110+
// valid inputs
111+
$fromString = BoolStandard::tryFromMixed('true');
112+
$fromInt = BoolStandard::tryFromMixed(0);
113+
$fromBool = BoolStandard::tryFromMixed(true);
114+
115+
// invalid inputs
116+
$fromArray = BoolStandard::tryFromMixed(['x']);
117+
$fromNull = BoolStandard::tryFromMixed(null);
118+
119+
// stringable object
120+
$stringable = new class {
121+
public function __toString(): string
122+
{
123+
return 'yes';
124+
}
125+
};
126+
$fromStringable = BoolStandard::tryFromMixed($stringable);
127+
128+
expect($fromString)->toBeInstanceOf(BoolStandard::class)
129+
->and($fromString->value())->toBeTrue()
130+
->and($fromInt)->toBeInstanceOf(BoolStandard::class)
131+
->and($fromInt->value())->toBeFalse()
132+
->and($fromBool)->toBeInstanceOf(BoolStandard::class)
133+
->and($fromBool->value())->toBeTrue()
134+
->and($fromStringable)->toBeInstanceOf(BoolStandard::class)
135+
->and($fromStringable->value())->toBeTrue()
136+
->and($fromArray)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class)
137+
->and($fromNull)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class);
138+
});

tests/Unit/Bool/FalseStandardTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,34 @@
6969
expect((string) $f)->toBe('false')
7070
->and($f->__toString())->toBe('false');
7171
});
72+
73+
it('tryFromMixed handles various inputs returning FalseStandard or Undefined', function (): void {
74+
// valid inputs
75+
$fromString = FalseStandard::tryFromMixed('no');
76+
$fromInt = FalseStandard::tryFromMixed(0);
77+
$fromBool = FalseStandard::tryFromMixed(false);
78+
79+
// invalid inputs
80+
$fromArray = FalseStandard::tryFromMixed(['x']);
81+
$fromNull = FalseStandard::tryFromMixed(null);
82+
83+
// stringable object
84+
$stringable = new class {
85+
public function __toString(): string
86+
{
87+
return 'off';
88+
}
89+
};
90+
$fromStringable = FalseStandard::tryFromMixed($stringable);
91+
92+
expect($fromString)->toBeInstanceOf(FalseStandard::class)
93+
->and($fromString->value())->toBeFalse()
94+
->and($fromInt)->toBeInstanceOf(FalseStandard::class)
95+
->and($fromInt->value())->toBeFalse()
96+
// bool(false) is converted to empty string by convertMixedToString and is not accepted -> Undefined
97+
->and($fromBool)->toBeInstanceOf(Undefined::class)
98+
->and($fromStringable)->toBeInstanceOf(FalseStandard::class)
99+
->and($fromStringable->value())->toBeFalse()
100+
->and($fromArray)->toBeInstanceOf(Undefined::class)
101+
->and($fromNull)->toBeInstanceOf(Undefined::class);
102+
});

tests/Unit/Bool/TrueStandardTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,34 @@
6969
expect((string) $t)->toBe('true')
7070
->and($t->__toString())->toBe('true');
7171
});
72+
73+
it('tryFromMixed handles various inputs returning TrueStandard or Undefined', function (): void {
74+
// valid inputs
75+
$fromString = TrueStandard::tryFromMixed('yes');
76+
$fromInt = TrueStandard::tryFromMixed(1);
77+
$fromBool = TrueStandard::tryFromMixed(true);
78+
79+
// invalid inputs
80+
$fromArray = TrueStandard::tryFromMixed(['x']);
81+
$fromNull = TrueStandard::tryFromMixed(null);
82+
83+
// stringable object
84+
$stringable = new class {
85+
public function __toString(): string
86+
{
87+
return 'on';
88+
}
89+
};
90+
$fromStringable = TrueStandard::tryFromMixed($stringable);
91+
92+
expect($fromString)->toBeInstanceOf(TrueStandard::class)
93+
->and($fromString->value())->toBeTrue()
94+
->and($fromInt)->toBeInstanceOf(TrueStandard::class)
95+
->and($fromInt->value())->toBeTrue()
96+
->and($fromBool)->toBeInstanceOf(TrueStandard::class)
97+
->and($fromBool->value())->toBeTrue()
98+
->and($fromStringable)->toBeInstanceOf(TrueStandard::class)
99+
->and($fromStringable->value())->toBeTrue()
100+
->and($fromArray)->toBeInstanceOf(Undefined::class)
101+
->and($fromNull)->toBeInstanceOf(Undefined::class);
102+
});

tests/Unit/DateTime/DateTimeAtomTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,27 @@
141141
it('jsonSerialize returns string', function (): void {
142142
expect(DateTimeAtom::tryFromString('2025-01-02T03:04:05+00:00')->jsonSerialize())->toBeString();
143143
});
144+
145+
it('tryFromMixed handles valid ATOM strings and invalid mixed inputs', function (): void {
146+
// valid string
147+
$ok = DateTimeAtom::tryFromMixed('2025-01-02T03:04:05+00:00');
148+
149+
// invalid types
150+
$badArr = DateTimeAtom::tryFromMixed(['x']);
151+
$badNull = DateTimeAtom::tryFromMixed(null);
152+
153+
// stringable object
154+
$stringable = new class {
155+
public function __toString(): string
156+
{
157+
return '2025-01-02T03:04:05+00:00';
158+
}
159+
};
160+
$okStr = DateTimeAtom::tryFromMixed($stringable);
161+
162+
expect($ok)->toBeInstanceOf(DateTimeAtom::class)
163+
->and($ok->toString())->toBe('2025-01-02T03:04:05+00:00')
164+
->and($okStr)->toBeInstanceOf(DateTimeAtom::class)
165+
->and($badArr)->toBeInstanceOf(Undefined::class)
166+
->and($badNull)->toBeInstanceOf(Undefined::class);
167+
});

tests/Unit/DateTime/DateTimeRFC3339ExtendedTest.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,14 @@
115115
});
116116

117117
it('DateTimeRFC3339Extended::tryFromString returns value for valid RFC3339_EXTENDED string', function (): void {
118-
$s = '2025-01-02T03:04:05.123456+00:00';
118+
// DATE_RFC3339_EXTENDED uses milliseconds precision (3 digits)
119+
$s = '2025-01-02T03:04:05.123+00:00';
119120
$v = DateTimeRFC3339Extended::tryFromString($s);
120121

121122
expect($v)
122-
->toBeInstanceOf(Undefined::class);
123+
->toBeInstanceOf(DateTimeRFC3339Extended::class)
124+
->and($v->toString())
125+
->toBe($s);
123126
});
124127

125128
it('DateTimeRFC3339Extended::tryFromString returns Undefined for invalid string', function (): void {
@@ -138,3 +141,27 @@
138141
expect((string) $vo)->toBe('2025-01-02T03:04:05.123+00:00')
139142
->and($vo->__toString())->toBe('2025-01-02T03:04:05.123+00:00');
140143
});
144+
145+
it('tryFromMixed handles valid RFC3339_EXTENDED strings and invalid mixed inputs', function (): void {
146+
// valid string
147+
$ok = DateTimeRFC3339Extended::tryFromMixed('2025-01-02T03:04:05.000+00:00');
148+
149+
// invalid types
150+
$badArr = DateTimeRFC3339Extended::tryFromMixed(['x']);
151+
$badNull = DateTimeRFC3339Extended::tryFromMixed(null);
152+
153+
// stringable object
154+
$stringable = new class {
155+
public function __toString(): string
156+
{
157+
return '2025-01-02T03:04:05.000+00:00';
158+
}
159+
};
160+
$okStr = DateTimeRFC3339Extended::tryFromMixed($stringable);
161+
162+
expect($ok)->toBeInstanceOf(DateTimeRFC3339Extended::class)
163+
->and($ok->toString())->toBe('2025-01-02T03:04:05.000+00:00')
164+
->and($okStr)->toBeInstanceOf(DateTimeRFC3339Extended::class)
165+
->and($badArr)->toBeInstanceOf(Undefined::class)
166+
->and($badNull)->toBeInstanceOf(Undefined::class);
167+
});

tests/Unit/DateTime/DateTimeRFC3339Test.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,27 @@
140140
it('jsonSerialize returns string', function (): void {
141141
expect(DateTimeRFC3339::tryFromString('2025-01-02T03:04:05+00:00')->jsonSerialize())->toBeString();
142142
});
143+
144+
it('tryFromMixed handles valid RFC3339 strings and invalid mixed inputs', function (): void {
145+
// valid string
146+
$ok = DateTimeRFC3339::tryFromMixed('2025-01-02T03:04:05+00:00');
147+
148+
// invalid types
149+
$badArr = DateTimeRFC3339::tryFromMixed(['x']);
150+
$badNull = DateTimeRFC3339::tryFromMixed(null);
151+
152+
// stringable object
153+
$stringable = new class {
154+
public function __toString(): string
155+
{
156+
return '2025-01-02T03:04:05+00:00';
157+
}
158+
};
159+
$okStr = DateTimeRFC3339::tryFromMixed($stringable);
160+
161+
expect($ok)->toBeInstanceOf(DateTimeRFC3339::class)
162+
->and($ok->toString())->toBe('2025-01-02T03:04:05+00:00')
163+
->and($okStr)->toBeInstanceOf(DateTimeRFC3339::class)
164+
->and($badArr)->toBeInstanceOf(Undefined::class)
165+
->and($badNull)->toBeInstanceOf(Undefined::class);
166+
});

tests/Unit/DateTime/DateTimeW3CTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,27 @@
140140
expect((string) $vo)->toBe('2025-01-02T03:04:05+00:00')
141141
->and($vo->__toString())->toBe('2025-01-02T03:04:05+00:00');
142142
});
143+
144+
it('tryFromMixed handles valid W3C/RFC3339 strings and invalid mixed inputs', function (): void {
145+
// valid string
146+
$ok = DateTimeW3C::tryFromMixed('2025-01-02T03:04:05+00:00');
147+
148+
// invalid types
149+
$badArr = DateTimeW3C::tryFromMixed(['x']);
150+
$badNull = DateTimeW3C::tryFromMixed(null);
151+
152+
// stringable object
153+
$stringable = new class {
154+
public function __toString(): string
155+
{
156+
return '2025-01-02T03:04:05+00:00';
157+
}
158+
};
159+
$okStr = DateTimeW3C::tryFromMixed($stringable);
160+
161+
expect($ok)->toBeInstanceOf(DateTimeW3C::class)
162+
->and($ok->toString())->toBe('2025-01-02T03:04:05+00:00')
163+
->and($okStr)->toBeInstanceOf(DateTimeW3C::class)
164+
->and($badArr)->toBeInstanceOf(Undefined::class)
165+
->and($badNull)->toBeInstanceOf(Undefined::class);
166+
});

tests/Unit/DateTime/Timestamp/TimestampMillisecondsTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,28 @@
136136
expect($vo->toString())->toBe('0')
137137
->and($vo->value()->format('U.u'))->toBe('0.000000');
138138
});
139+
140+
it('tryFromMixed handles valid numeric strings/ints and invalid mixed inputs', function (): void {
141+
// valid inputs
142+
$fromString = TimestampMilliseconds::tryFromMixed('1732445696123');
143+
$fromInt = TimestampMilliseconds::tryFromMixed(1732445696123);
144+
145+
// invalid inputs
146+
$fromArray = TimestampMilliseconds::tryFromMixed(['x']);
147+
$fromNull = TimestampMilliseconds::tryFromMixed(null);
148+
149+
// stringable object
150+
$stringable = new class {
151+
public function __toString(): string
152+
{
153+
return '1732445696123';
154+
}
155+
};
156+
$fromStringable = TimestampMilliseconds::tryFromMixed($stringable);
157+
158+
expect($fromString)->toBeInstanceOf(TimestampMilliseconds::class)
159+
->and($fromInt)->toBeInstanceOf(TimestampMilliseconds::class)
160+
->and($fromStringable)->toBeInstanceOf(TimestampMilliseconds::class)
161+
->and($fromArray)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class)
162+
->and($fromNull)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class);
163+
});

tests/Unit/DateTime/Timestamp/TimestampSecondsTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,28 @@
135135
expect((string) $vo)->toBe('1735787045')
136136
->and($vo->__toString())->toBe('1735787045');
137137
});
138+
139+
it('tryFromMixed handles valid numeric strings/ints and invalid mixed inputs', function (): void {
140+
// valid inputs
141+
$fromString = TimestampSeconds::tryFromMixed('1735787045');
142+
$fromInt = TimestampSeconds::tryFromMixed(1735787045);
143+
144+
// invalid inputs
145+
$fromArray = TimestampSeconds::tryFromMixed(['x']);
146+
$fromNull = TimestampSeconds::tryFromMixed(null);
147+
148+
// stringable object
149+
$stringable = new class {
150+
public function __toString(): string
151+
{
152+
return '1735787045';
153+
}
154+
};
155+
$fromStringable = TimestampSeconds::tryFromMixed($stringable);
156+
157+
expect($fromString)->toBeInstanceOf(TimestampSeconds::class)
158+
->and($fromInt)->toBeInstanceOf(TimestampSeconds::class)
159+
->and($fromStringable)->toBeInstanceOf(TimestampSeconds::class)
160+
->and($fromArray)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class)
161+
->and($fromNull)->toBeInstanceOf(PhpTypedValues\Undefined\Alias\Undefined::class);
162+
});

tests/Unit/Integer/IntegerNonNegativeTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,31 @@
136136
it('jsonSerialize returns native int', function (): void {
137137
expect(IntegerNonNegative::fromInt(11)->jsonSerialize())->toBe(11);
138138
});
139+
140+
it('tryFromMixed returns instance for integer-like inputs and Undefined otherwise', function (): void {
141+
$okInt = IntegerNonNegative::tryFromMixed(0);
142+
$okStr = IntegerNonNegative::tryFromMixed('12');
143+
$badNeg = IntegerNonNegative::tryFromMixed(-1);
144+
$badFloatish = IntegerNonNegative::tryFromMixed('1.0');
145+
$badArr = IntegerNonNegative::tryFromMixed(['x']);
146+
$badNull = IntegerNonNegative::tryFromMixed(null);
147+
148+
$stringable = new class implements Stringable {
149+
public function __toString(): string
150+
{
151+
return '7';
152+
}
153+
};
154+
$okStringable = IntegerNonNegative::tryFromMixed($stringable);
155+
156+
expect($okInt)->toBeInstanceOf(IntegerNonNegative::class)
157+
->and($okInt->value())->toBe(0)
158+
->and($okStr)->toBeInstanceOf(IntegerNonNegative::class)
159+
->and($okStr->value())->toBe(12)
160+
->and($okStringable)->toBeInstanceOf(IntegerNonNegative::class)
161+
->and($okStringable->value())->toBe(7)
162+
->and($badNeg)->toBeInstanceOf(Undefined::class)
163+
->and($badFloatish)->toBeInstanceOf(Undefined::class)
164+
->and($badArr)->toBeInstanceOf(Undefined::class)
165+
->and($badNull)->toBeInstanceOf(Undefined::class);
166+
});

0 commit comments

Comments
 (0)