Skip to content

Commit

Permalink
Merge branch 'vNext' into php-84-upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah authored Jan 18, 2025
2 parents 9ca60a3 + d5e61eb commit 4674c2d
Show file tree
Hide file tree
Showing 16 changed files with 52 additions and 39 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Lint

on:
push:
branches: [master]
branches: [master, vNext]
pull_request:

jobs:
Expand All @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
php:
- 8.1
- 8.3

name: Lint code (PHP ${{ matrix.php }})

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Tests

on:
push:
branches: [master, v4]
branches: [master, vNext]
pull_request:

jobs:
Expand All @@ -11,11 +11,14 @@ jobs:
strategy:
matrix:
php:
- '8.4'
- '8.3'
- '8.2'
- '8.1'
deps:
- highest
include:
- {php: '8.1', deps: lowest}
- {php: '8.1', deps: dingo}

name: Tests (PHP ${{ matrix.php }} - ${{ matrix.deps }})
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Removed

# 4.39.0 (31 December 2024)
## Added
- Correctly list required fields for nested objects in OpenAPI spec [#905](https://github.com/knuckleswtf/scribe/pull/905)
- Cursor pagination support in API responses (`cursorPaginate`/`paginate=cursor`) [#917](https://github.com/knuckleswtf/scribe/pull/917)

## Fixed
- Fixed type error when attempting to parse Request::validate [#925](https://github.com/knuckleswtf/scribe/pull/925)
- Don't render empty responses as string "null" in OpenAPI spec [#911](https://github.com/knuckleswtf/scribe/pull/911)
- Correctly replace `apiDescriptionUrl`for `external_laravel` (Eelements theme) [#906](https://github.com/knuckleswtf/scribe/pull/906)
- Cast form data values to strings in Postman collection [#926](https://github.com/knuckleswtf/scribe/pull/926)

## Modified
- Resolve PHP 8.4 deprecations [#929](https://github.com/knuckleswtf/scribe/pull/929)

# 4.38.0 (18 October 2024)
## Fixed
- Elements theme: Fix display of boolean examples [#887](https://github.com/knuckleswtf/scribe/pull/887)
Expand Down
2 changes: 1 addition & 1 deletion composer.lowest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=8.0",
"php": ">=8.1",
"ext-fileinfo": "*",
"ext-json": "*",
"ext-pdo": "*",
Expand Down
4 changes: 2 additions & 2 deletions config/scribe.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
// Options: query, body, basic, bearer, header (for custom header)
'in' => 'bearer',

// The name of the auth parameter (eg token, key, apiKey) or header (eg Authorization, Api-Key).
// The name of the auth parameter (e.g. token, key, apiKey) or header (e.g. Authorization, Api-Key).
'name' => 'key',

// The value of the parameter to be used by Scribe to authenticate response calls.
Expand Down Expand Up @@ -189,7 +189,7 @@
'last_updated' => 'Last updated: {date:F j, Y}',

'examples' => [
// Set this to any number (eg. 1234) to generate the same example values for parameters on each run,
// Set this to any number (e.g. 1234) to generate the same example values for parameters on each run,
'faker_seed' => null,

// With API resources and transformers, Scribe tries to generate example models to use in your API responses.
Expand Down
6 changes: 2 additions & 4 deletions src/Attributes/GenericParam.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@ protected function getEnumValues(): array
return $this->enum;
}

if (function_exists('enum_exists') && enum_exists($this->enum)
&& method_exists($this->enum, 'tryFrom')
) {
if (enum_exists($this->enum) && method_exists($this->enum, 'tryFrom')) {
return array_map(
// $case->value only exists on BackedEnums, not UnitEnums
// method_exists($enum, 'tryFrom') implies $enum instanceof BackedEnum
// method_exists($enum, 'tryFrom') implies the enum is a BackedEnum
// @phpstan-ignore-next-line
fn ($case) => $case->value,
$this->enum::cases()
Expand Down
4 changes: 2 additions & 2 deletions src/Extracting/ParsesValidationRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,15 @@ protected function parseRule($rule, array &$parameterData, bool $independentOnly
return true;
}

if (function_exists('enum_exists') && $rule instanceof \Illuminate\Validation\Rules\Enum) {
if ($rule instanceof \Illuminate\Validation\Rules\Enum) {
$reflection = new \ReflectionClass($rule);
$property = $reflection->getProperty('type');
$property->setAccessible(true);
$type = $property->getValue($rule);

if (enum_exists($type) && method_exists($type, 'tryFrom')) {
// $case->value only exists on BackedEnums, not UnitEnums
// method_exists($enum, 'tryFrom') implies $enum instanceof BackedEnum
// method_exists($enum, 'tryFrom') implies the enum is a BackedEnum
// @phpstan-ignore-next-line
$cases = array_map(fn ($case) => $case->value, $type::cases());
$parameterData['type'] = gettype($cases[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ public static function find(Node $node)

if (
$expr instanceof Node\Expr\StaticCall
&& in_array((string) $expr->class, ['Request', \Illuminate\Support\Facades\Request::class])
&& $expr->class instanceof Node\Name
&& in_array($expr->class->name, ['Request', \Illuminate\Support\Facades\Request::class])
) {
if ($expr->name->name == "validate") {
if ($expr->name->name === "validate") {
return $expr->args[0]->value;
}

if ($expr->name->name == "validateWithBag") {
if ($expr->name->name === "validateWithBag") {
return $expr->args[1]->value;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/Extracting/Strategies/GetFromInlineValidatorBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,11 @@ public function lookForInlineValidationRules(ClassMethod $methodAst): array
}
// Try to extract Enum rule
else if (
function_exists('enum_exists') &&
($enum = $this->extractEnumClassFromArrayItem($arrayItem)) &&
enum_exists($enum) && method_exists($enum, 'tryFrom')
) {
// $case->value only exists on BackedEnums, not UnitEnums
// method_exists($enum, 'tryFrom') implies $enum instanceof BackedEnum
// method_exists($enum, 'tryFrom') implies the enum is a BackedEnum
// @phpstan-ignore-next-line
$rulesList[] = 'in:' . implode(',', array_map(fn ($case) => $case->value, $enum::cases()));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Scribe.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Scribe
{
public const VERSION = '4.38.0';
public const VERSION = '4.39.0';

/**
* Specify a callback that will be executed just before a response call is made
Expand Down
2 changes: 1 addition & 1 deletion src/Writing/PostmanCollectionWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ protected function getFormDataParams(array $paramsKeyValue, ?string $key = null,
if (!is_array($value)) {
$body[] = [
'key' => $index,
'value' => $value,
'value' => (string) $value,
'type' => 'text',
'description' => $paramsFullDetails[$index]->description ?? '',
];
Expand Down
5 changes: 0 additions & 5 deletions tests/Fixtures/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -704,19 +704,14 @@ public function withEnumRule(Request $request)
]);
}

/**
* Can only run on PHP 8.1
public function withInjectedEnumAndModel(Category $category, TestUser $user)
{
return null;
}
*/
}

/**
enum Category: string
{
case Fruits = 'fruits';
case People = 'people';
}
*/
12 changes: 12 additions & 0 deletions tests/GenerateDocumentation/OutputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ private function generate_with_paths($configName, $intermediateOutputDirectory =
/** @test */
public function generated_postman_collection_file_is_correct()
{
if (phpversion() < 8.3) {
// See https://github.com/FakerPHP/Faker/issues/694
$this->markTestSkipped('Faker seeding changed in PHP 8.3');
return;
}

RouteFacade::post('/api/withBodyParametersAsArray', [TestController::class, 'withBodyParametersAsArray']);
RouteFacade::post('/api/withFormDataParams', [TestController::class, 'withFormDataParams']);
RouteFacade::post('/api/withBodyParameters', [TestController::class, 'withBodyParameters']);
Expand Down Expand Up @@ -205,6 +211,12 @@ public function generated_postman_collection_file_is_correct()
/** @test */
public function generated_openapi_spec_file_is_correct()
{
if (phpversion() < 8.3) {
// See https://github.com/FakerPHP/Faker/issues/694
$this->markTestSkipped('Faker seeding changed in PHP 8.3');
return;
}

RouteFacade::post('/api/withBodyParametersAsArray', [TestController::class, 'withBodyParametersAsArray']);
RouteFacade::post('/api/withFormDataParams', [TestController::class, 'withFormDataParams']);
RouteFacade::get('/api/withResponseTag', [TestController::class, 'withResponseTag']);
Expand Down
4 changes: 0 additions & 4 deletions tests/Strategies/GetFromInlineValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,6 @@ public function respects_query_params_comment()
/** @test */
public function can_fetch_inline_enum_rules()
{
if (phpversion() < 8.1) {
$this->markTestSkipped('Enums are only supported in PHP 8.1 or later');
}

$endpoint = $this->endpoint(function (ExtractedEndpointData $e) {
$e->method = new \ReflectionMethod(TestController::class, 'withEnumRule');
});
Expand Down
9 changes: 4 additions & 5 deletions tests/Strategies/UrlParameters/GetFromLaravelAPITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,23 @@ class GetFromLaravelAPITest extends BaseLaravelTest
/** @test */
public function can_infer_type_from_model_binding()
{
$endpoint = $this->endpointForRoute("users/{id}", TestController::class, 'withInjectedModel');
// Can only run on PHP 8.1
// $endpoint = $this->endpointForRoute("categories/{category}/users/{id}/", TestController::class, 'withInjectedEnumAndModel');
// $endpoint = $this->endpointForRoute("users/{id}", TestController::class, 'withInjectedModel');
$endpoint = $this->endpointForRoute("categories/{category}/users/{id}/", TestController::class, 'withInjectedEnumAndModel');
$results = $this->fetch($endpoint);

$this->assertArraySubset([
"name" => "id",
"description" => "The ID of the user.",
"required" => true,
"type" => "integer",
], $results['id']);/*
], $results['id']);
$this->assertArraySubset([
"name" => "category",
"description" => "The category.",
"required" => true,
"type" => "string",
"example" => \Knuckles\Scribe\Tests\Fixtures\Category::cases()[0]->value,
], $results['category']);*/
], $results['category']);
$this->assertIsInt($results['id']['example']);
}

Expand Down
8 changes: 2 additions & 6 deletions tests/Unit/ValidationRuleParsingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function can_parse_supported_rules(array $ruleset, array $customInfo, arr
Schema::create('users', function ($table) {
$table->id();
});

$results = $this->strategy->parse($ruleset, $customInfo);

$parameterName = array_keys($ruleset)[0];
Expand All @@ -57,7 +57,7 @@ public function can_parse_supported_rules(array $ruleset, array $customInfo, arr

// Validate that the generated values actually pass validation (for rules where we can generate some data)
if (is_string($ruleset[$parameterName]) && str_contains($ruleset[$parameterName], "exists")) return;

$exampleData = [$parameterName => $results[$parameterName]['example']];
$validator = Validator::make($exampleData, $ruleset);
try {
Expand Down Expand Up @@ -552,10 +552,6 @@ public function can_parse_custom_rule_classes()
/** @test */
public function can_parse_enum_rules()
{
if (phpversion() < 8.1) {
$this->markTestSkipped('Enums are only supported in PHP 8.1 or later');
}

$results = $this->strategy->parse([
'enum' => [
'required',
Expand Down

0 comments on commit 4674c2d

Please sign in to comment.