Skip to content

Commit a45b58b

Browse files
committed
Remove obsolete trailing shape tests
The trailing shape specialization has been removed, so its metadata, size-limit, and eligibility tests no longer exercise distinct behavior. Keep the soundness regressions and representative fallback coverage, and reuse the flipped type in its assertion and diagnostic.
1 parent fbbb9b5 commit a45b58b

1 file changed

Lines changed: 3 additions & 173 deletions

File tree

tests/GenericStringArrayShapePrecisionAdversarialTest.php

Lines changed: 3 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,13 @@ public function testArrayFlipDoesNotAssumeWhichDuplicateValueWins(): void
105105
),
106106
]))->resolve();
107107
$nativeOutcome = self::constantArrayFromRuntime(['x' => 'later']);
108+
$flippedResult = $result->flipArray();
108109

109110
$this->assertTrue(
110-
$result->flipArray()->isSuperTypeOf($nativeOutcome)->yes(),
111+
$flippedResult->isSuperTypeOf($nativeOutcome)->yes(),
111112
sprintf(
112113
'Flipped inferred type %s must contain the native duplicate-value outcome %s.',
113-
$result->flipArray()->describe(VerbosityLevel::precise()),
114+
$flippedResult->describe(VerbosityLevel::precise()),
114115
$nativeOutcome->describe(VerbosityLevel::precise()),
115116
),
116117
);
@@ -238,68 +239,6 @@ public function testBoundaryCasesContainRepresentativeNativeMergeOutcomes(): voi
238239
}
239240
}
240241

241-
public function testUnusualAutoIndexStateIsNotRetainedInAConflictingShape(): void
242-
{
243-
$unusualShape = new ConstantArrayType(
244-
[new ConstantStringType('fixed')],
245-
[new StringType()],
246-
[7],
247-
);
248-
249-
$result = (new ArrayMergeType([
250-
new ArrayType(new StringType(), new IntegerType()),
251-
$unusualShape,
252-
]))->resolve();
253-
254-
$runtimeOutcome = self::constantArrayFromRuntime(['fixed' => 'shape']);
255-
$this->assertTrue(
256-
$result->isSuperTypeOf($runtimeOutcome)->yes(),
257-
'The unusual construction metadata must not exclude the visible array_merge result.',
258-
);
259-
260-
$constantArrays = $result->getConstantArrays();
261-
262-
if ([] === $constantArrays) {
263-
return;
264-
}
265-
266-
foreach ($constantArrays as $constantArray) {
267-
$this->assertSame(
268-
[0],
269-
$constantArray->getNextAutoIndexes(),
270-
'array_merge creates a new array whose first available integer offset is zero.',
271-
);
272-
}
273-
}
274-
275-
public function testLargeTrailingShapesUseConservativeFallback(): void
276-
{
277-
$firstShapeKeyTypes = [];
278-
$firstShapeValueTypes = [];
279-
280-
for ($i = 0; $i < 256; $i++) {
281-
$firstShapeKeyTypes[] = new ConstantStringType('first' . $i);
282-
$firstShapeValueTypes[] = new ConstantIntegerType($i);
283-
}
284-
285-
$result = (new ArrayMergeType([
286-
new ArrayType(new StringType(), new IntegerType()),
287-
new ConstantArrayType($firstShapeKeyTypes, $firstShapeValueTypes),
288-
new ConstantArrayType(
289-
[new ConstantStringType('first0'), new ConstantStringType('last')],
290-
[new ConstantStringType('overwritten'), new ConstantStringType('tail')],
291-
),
292-
]))->resolve();
293-
294-
$this->assertSame([], $result->getConstantArrays());
295-
$this->assertTrue(TypeCombinator::union(
296-
new IntegerType(),
297-
new ConstantStringType('overwritten'),
298-
new ConstantStringType('tail'),
299-
)->equals($result->getIterableValueType()));
300-
$this->assertTrue($result->hasOffsetValueType(new ConstantStringType('first0'))->maybe());
301-
}
302-
303242
public function testMultipleTrailingShapesRemainBroadAndContainNativeOutcome(): void
304243
{
305244
$runtimeShapes = [
@@ -338,115 +277,6 @@ public function testMultipleTrailingShapesRemainBroadAndContainNativeOutcome():
338277
)->yes());
339278
}
340279

341-
public function testDisqualifiedThirdOperandForcesConservativeFallback(): void
342-
{
343-
$generic = new ArrayType(new StringType(), new IntegerType());
344-
$validShape = new ConstantArrayType(
345-
[new ConstantStringType('fixed')],
346-
[new StringType()],
347-
);
348-
$optionalShape = new ConstantArrayType(
349-
[new ConstantStringType('fixed')],
350-
[new BooleanType()],
351-
[0],
352-
[0],
353-
);
354-
$integerShape = new ConstantArrayType(
355-
[new ConstantIntegerType(7)],
356-
[new BooleanType()],
357-
[8],
358-
);
359-
$canonicalIntegerStringShape = new ConstantArrayType(
360-
[new ConstantStringType('7')],
361-
[new BooleanType()],
362-
);
363-
$otherShape = new ConstantArrayType(
364-
[new ConstantStringType('other')],
365-
[new BooleanType()],
366-
);
367-
$unusualAutoIndexShape = new ConstantArrayType(
368-
[new ConstantStringType('other')],
369-
[new BooleanType()],
370-
[7],
371-
);
372-
373-
/**
374-
* @var array<string, array{
375-
* non-empty-list<Type>,
376-
* non-empty-list<array<int|string, bool|int|string>>
377-
* }> $scenarios
378-
*/
379-
$scenarios = [
380-
'optional keys' => [
381-
[$generic, $validShape, $optionalShape],
382-
[['dynamic' => 1], ['fixed' => 'shape'], []],
383-
],
384-
'integer keys' => [
385-
[$generic, $validShape, $integerShape],
386-
[['dynamic' => 1], ['fixed' => 'shape'], [7 => true]],
387-
],
388-
'canonical integer string keys' => [
389-
[$generic, $validShape, $canonicalIntegerStringShape],
390-
[['dynamic' => 1], ['fixed' => 'shape'], [7 => true]],
391-
],
392-
'shape unions' => [
393-
[$generic, $validShape, new UnionType([$validShape, $otherShape])],
394-
[['dynamic' => 1], ['fixed' => 'shape'], ['other' => true]],
395-
],
396-
'shape intersections' => [
397-
[$generic, $validShape, new IntersectionType([$otherShape, new NonEmptyArrayType()])],
398-
[['dynamic' => 1], ['fixed' => 'shape'], ['other' => true]],
399-
],
400-
'generic operands after shapes' => [
401-
[$generic, $validShape, new ArrayType(new StringType(), new BooleanType())],
402-
[['dynamic' => 1], ['fixed' => 'shape'], ['fixed' => true]],
403-
],
404-
'empty shapes' => [
405-
[$generic, $validShape, ConstantArrayTypeBuilder::createEmpty()->getArray()],
406-
[['dynamic' => 1], ['fixed' => 'shape'], []],
407-
],
408-
'unusual auto-index metadata' => [
409-
[$generic, $validShape, $unusualAutoIndexShape],
410-
[['dynamic' => 1], ['fixed' => 'shape'], ['other' => true]],
411-
],
412-
];
413-
414-
if (self::supportsUnsealedShapes()) {
415-
$unsealedShape = new ConstantArrayType(
416-
[new ConstantStringType('other')],
417-
[new BooleanType()],
418-
[0],
419-
[],
420-
TrinaryLogic::createNo(),
421-
[new StringType(), new BooleanType()],
422-
);
423-
$scenarios['unsealed shapes'] = [
424-
[$generic, $validShape, $unsealedShape],
425-
[['dynamic' => 1], ['fixed' => 'shape'], ['other' => true, 'extra' => false]],
426-
];
427-
}
428-
429-
foreach ($scenarios as $name => [$declaredTypes, $runtimeOperands]) {
430-
$result = (new ArrayMergeType($declaredTypes))->resolve();
431-
$this->assertSame(
432-
[],
433-
$result->getConstantArrays(),
434-
sprintf('Scenario %s must retain the prior conservative fallback.', $name),
435-
);
436-
437-
$runtimeOutcome = self::constantArrayFromRuntime(array_merge(...$runtimeOperands));
438-
$this->assertTrue(
439-
$result->isSuperTypeOf($runtimeOutcome)->yes(),
440-
sprintf(
441-
'Scenario %s inferred %s, which excludes native result %s.',
442-
$name,
443-
$result->describe(VerbosityLevel::precise()),
444-
$runtimeOutcome->describe(VerbosityLevel::precise()),
445-
),
446-
);
447-
}
448-
}
449-
450280
private static function supportsUnsealedShapes(): bool
451281
{
452282
return self::hasOptionalMethod(ConstantArrayTypeBuilder::createEmpty(), 'makeUnsealed');

0 commit comments

Comments
 (0)