Skip to content

Commit

Permalink
V1.4.2 - Fix Union Generation (#15)
Browse files Browse the repository at this point in the history
Fix union generation not evaluating possible regex statements
  • Loading branch information
BolZer authored Dec 20, 2022
1 parent e175f19 commit c8ea243
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cs_fix:
vendor/bin/php-cs-fixer fix ./
PHP_CS_FIXER_IGNORE_ENV=true vendor/bin/php-cs-fixer fix ./

lint:
./vendor/bin/psalm
Expand Down
27 changes: 25 additions & 2 deletions Service/GeneratorService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class GeneratorService
{
public function __construct(
private RouterInterface $router,
private readonly RouterInterface $router,
) {
}

Expand Down Expand Up @@ -262,6 +262,11 @@ private function isUnionRequirement(string $requirement): bool
return str_contains($requirement, '|');
}

private function isPhpRegexExpression(string $requirement): bool
{
return str_starts_with($requirement, '\\');
}

private function createRouteParamsMergeExpressionForDefaults(Route $route): string
{
if (!$route->getDefaults()) {
Expand All @@ -279,7 +284,25 @@ private function deriveUnionExpressionForTypescript(string $requirement): string
throw new \LogicException('At this point union parts must be greater than 2!');
}

return implode('|', array_map(static fn (string $matchFromBuffer) => sprintf("'%s'", $matchFromBuffer), $matches));
$transformedMatches = array_map(function ($match) {
if ($this->isDigitRequirement($match)) {
return 'number';
}

if ($this->isPhpRegexExpression($match)) {
return 'string';
}

return $match;
}, $matches);

return implode('|', array_map(function (string $matchFromBuffer) {
if ($matchFromBuffer === 'string' || $matchFromBuffer === 'number') {
return sprintf('%s', $matchFromBuffer);
}

return sprintf("'%s'", $matchFromBuffer);
}, $transformedMatches));
}

private function retrieveSchemeFromRoute(Route $route): string
Expand Down
10 changes: 9 additions & 1 deletion Tests/GenerateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ public function generationServiceDataProvider(): \Generator
$routeCollection->add('generate_route_with_long_requirement_as_union', new Route(
path: '/generate/{intent}/{documents}',
requirements: [
'intent' => 'new_email|email|print|printdebug|preview|preview_data|preview_text|gct.legalize'
'intent' => 'new_email|email|print|printdebug|preview|preview_data|preview_text|gct.legalize',
],
host: 'app.development.org',
schemes: 'https'
));
$routeCollection->add('generate_route_requirement_union_with_regex', new Route(
path: '/generate/{id}',
requirements: [
'id' => 'new|\d+',
],
host: 'app.development.org',
schemes: 'https'
Expand Down
3 changes: 2 additions & 1 deletion Tests/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const path_users_route_without_requirements_and_defaults = (): { relative
export const path_users_route_with_requirements = (): { relative: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', routeParams), queryParams), absolute: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', routeParams), queryParams)}};
export const path_users_route_with_requirements_and_defaults = (): { relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', {...{"locale":"en"}, ...routeParams}), queryParams), absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', {...{"locale":"en"}, ...routeParams}), queryParams)}};
export const path_users_route_with_requirements_and_null_defaults = (): { relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', {...{"locale":null}, ...routeParams}), queryParams), absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', {...{"locale":null}, ...routeParams}), queryParams)}};
export const path_generate_route_with_long_requirement_as_union = (): { relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{intent}/{documents}', routeParams), queryParams), absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{intent}/{documents}', routeParams), queryParams)}};
export const path_generate_route_with_long_requirement_as_union = (): { relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{intent}/{documents}', routeParams), queryParams), absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{intent}/{documents}', routeParams), queryParams)}};
export const path_generate_route_requirement_union_with_regex = (): { relative: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>) => string, absolute: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>) => string} => {return {relative: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{id}', routeParams), queryParams), absolute: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{id}', routeParams), queryParams)}};
3 changes: 2 additions & 1 deletion Tests/output_absolute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const path_users_route_without_requirements_and_defaults = (): { absolute
export const path_users_route_with_requirements = (): { absolute: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', routeParams), queryParams)}};
export const path_users_route_with_requirements_and_defaults = (): { absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', {...{"locale":"en"}, ...routeParams}), queryParams)}};
export const path_users_route_with_requirements_and_null_defaults = (): { absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/users/{id}/{locale}', {...{"locale":null}, ...routeParams}), queryParams)}};
export const path_generate_route_with_long_requirement_as_union = (): { absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{intent}/{documents}', routeParams), queryParams)}};
export const path_generate_route_with_long_requirement_as_union = (): { absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{intent}/{documents}', routeParams), queryParams)}};
export const path_generate_route_requirement_union_with_regex = (): { absolute: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>) => string} => {return {absolute: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('https://app.development.org/generate/{id}', routeParams), queryParams)}};
3 changes: 2 additions & 1 deletion Tests/output_relative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const path_users_route_without_requirements_and_defaults = (): { relative
export const path_users_route_with_requirements = (): { relative: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {id:number, locale:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', routeParams), queryParams), }};
export const path_users_route_with_requirements_and_defaults = (): { relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', {...{"locale":"en"}, ...routeParams}), queryParams), }};
export const path_users_route_with_requirements_and_null_defaults = (): { relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {id:number, locale?:'en'|'fr'}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/users/{id}/{locale}', {...{"locale":null}, ...routeParams}), queryParams), }};
export const path_generate_route_with_long_requirement_as_union = (): { relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{intent}/{documents}', routeParams), queryParams), }};
export const path_generate_route_with_long_requirement_as_union = (): { relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {intent:'new_email'|'email'|'print'|'printdebug'|'preview'|'preview_data'|'preview_text'|'gct.legalize', documents:string}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{intent}/{documents}', routeParams), queryParams), }};
export const path_generate_route_requirement_union_with_regex = (): { relative: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>) => string, } => {return {relative: (routeParams: {id:'new'|number}, queryParams?: Record<string, string>): string => appendQueryParams(replaceRouteParams('/generate/{id}', routeParams), queryParams), }};
6 changes: 6 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage:
status:
project:
default:
target: 90%
threshold: 1%

0 comments on commit c8ea243

Please sign in to comment.