Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
romalytvynenko committed Mar 31, 2024
1 parent 215b30f commit a71b627
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 40 deletions.
11 changes: 10 additions & 1 deletion src/Infer/Scope/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Dedoc\Scramble\Support\Type\ArrayItemType_;
use Dedoc\Scramble\Support\Type\ArrayType;
use Dedoc\Scramble\Support\Type\CallableStringType;
use Dedoc\Scramble\Support\Type\KeyedArrayType;
use Dedoc\Scramble\Support\Type\ObjectType;
use Dedoc\Scramble\Support\Type\Reference\AbstractReferenceType;
use Dedoc\Scramble\Support\Type\Reference\CallableCallReferenceType;
Expand Down Expand Up @@ -218,7 +219,15 @@ private function getArgsTypes(array $args)
return [$arg->name ? $arg->name->name : $index => $type];
}

if (! $type instanceof ArrayType) {
if (! $type instanceof ArrayType && ! $type instanceof KeyedArrayType) {
return [$arg->name ? $arg->name->name : $index => $type]; // falling back, but not sure if we should. Maybe some DTO is needed to represent unpacked arg type?
}

if ($type instanceof ArrayType) {
/*
* For example, when passing something that is array, but shape is unknown
* $a = foo(...array_keys($bar));
*/
return [$arg->name ? $arg->name->name : $index => $type]; // falling back, but not sure if we should. Maybe some DTO is needed to represent unpacked arg type?
}

Expand Down
45 changes: 14 additions & 31 deletions src/Support/InferExtensions/ArrayKeysReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
use Dedoc\Scramble\Infer\Extensions\FunctionReturnTypeExtension;
use Dedoc\Scramble\Support\Type\ArrayItemType_;
use Dedoc\Scramble\Support\Type\ArrayType;
use Dedoc\Scramble\Support\Type\IntegerType;
use Dedoc\Scramble\Support\Type\StringType;
use Dedoc\Scramble\Support\Type\KeyedArrayType;
use Dedoc\Scramble\Support\Type\Type;
use Dedoc\Scramble\Support\Type\TypeHelper;
use Dedoc\Scramble\Support\Type\Union;

class ArrayKeysReturnTypeExtension implements FunctionReturnTypeExtension
{
Expand All @@ -23,41 +21,26 @@ public function getFunctionReturnType(FunctionCallEvent $event): ?Type
{
$argType = $event->getArg('array', 0);

if (! $argType instanceof ArrayType) {
if (
! $argType instanceof ArrayType
&& ! $argType instanceof KeyedArrayType
) {
return null;
}

$keys = collect($argType->items)->map(fn (ArrayItemType_ $item) => $item->key);

// assuming it is a list for now
if ($keys->count() === 1) {
return new ArrayType([
new ArrayItemType_(
key: null,
value: Union::wrap([
new StringType(),
new IntegerType(),
])
),
]);
if ($argType instanceof ArrayType) {
return new ArrayType(value: $argType->key);
}

$numIndex = 0;

return new ArrayType(
array_map(function ($key) use (&$numIndex) {
if ($key === null || is_numeric($key)) {
return new ArrayItemType_(
key: null,
value: TypeHelper::createTypeFromValue($numIndex++),
);
}

$index = 0;
return new KeyedArrayType(array_map(
function (ArrayItemType_ $item) use (&$index) {
return new ArrayItemType_(
key: null,
value: TypeHelper::createTypeFromValue($key),
value: TypeHelper::createTypeFromValue($item->key === null ? $index++ : $item->key),
);
}, $keys->toArray())
);
},
$argType->items,
));
}
}
6 changes: 5 additions & 1 deletion src/Support/Type/TypeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public static function createTypeFromValue(mixed $value)
}

if (is_array($value)) {
return new ArrayType(
return new KeyedArrayType(
collect($value)
->map(function ($value, $key) {
return new ArrayItemType_(
Expand All @@ -158,6 +158,10 @@ public static function createTypeFromValue(mixed $value)
);
}

if (is_null($value)) {
return new NullType;
}

return null; // @todo: object
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Infer/Services/ConstFetchTypeGetterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
it('gets const type from array value', function () {
$type = (new ConstFetchTypeGetter)(new GlobalScope, ConstFetchTypeGetterTest_Foo::class, 'ARRAY');

expect($type->toString())->toBe('array{0: string(foo), 1: string(bar)}');
expect($type->toString())->toBe('list{string(foo), string(bar)}');
});
class ConstFetchTypeGetterTest_Foo
{
Expand Down
2 changes: 1 addition & 1 deletion tests/Infer/Services/ReferenceTypeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@

$type = getStatementType('(new ReferenceTypeResolverTest_Bar)->test()');

expect($type->toString())->toBe('array{0: array{0: string(bar), 1: int(21)}, 1: array{0: string(foo), 1: int(21)}}');
expect($type->toString())->toBe('list{list{string(bar), int(21)}, list{string(foo), int(21)}}');
});
class ReferenceTypeResolverTest_Foo
{
Expand Down
6 changes: 3 additions & 3 deletions tests/InferExtensions/RuleExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

expect($type->toString())->toBe($expectedType);
})->with([
['Illuminate\Validation\Rule::in(...["values" => ["foo", "bar"]])', 'Illuminate\Validation\Rules\In<array{0: string(foo), 1: string(bar)}>'],
['Illuminate\Validation\Rule::in(values: ["foo", "bar"])', 'Illuminate\Validation\Rules\In<array{0: string(foo), 1: string(bar)}>'],
['Illuminate\Validation\Rule::in(["foo", "bar"])', 'Illuminate\Validation\Rules\In<array{0: string(foo), 1: string(bar)}>'],
['Illuminate\Validation\Rule::in(...["values" => ["foo", "bar"]])', 'Illuminate\Validation\Rules\In<list{string(foo), string(bar)}>'],
['Illuminate\Validation\Rule::in(values: ["foo", "bar"])', 'Illuminate\Validation\Rules\In<list{string(foo), string(bar)}>'],
['Illuminate\Validation\Rule::in(["foo", "bar"])', 'Illuminate\Validation\Rules\In<list{string(foo), string(bar)}>'],
]);
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
it('infers string array keys return type from literal string keys', function () {
$type = getStatementType('array_keys(["foo" => 1, "bar" => 2])', [new ArrayKeysReturnTypeExtension]);

expect($type->toString())->toBe('array{0: string(foo), 1: string(bar)}');
expect($type->toString())->toBe('list{string(foo), string(bar)}');
});

it('infers all array keys return type from non-string keys', function () {
$type = getStatementType('array_keys([1, "foo", "bar" => 42])', [new ArrayKeysReturnTypeExtension]);

expect($type->toString())->toBe('array{0: int(0), 1: int(1), 2: string(bar)}');
expect($type->toString())->toBe('list{int(0), int(1), string(bar)}');
});

0 comments on commit a71b627

Please sign in to comment.