Skip to content

Commit 31908df

Browse files
committed
Support enums without type - Close #6
1 parent d699f78 commit 31908df

File tree

2 files changed

+96
-3
lines changed

2 files changed

+96
-3
lines changed

src/Type/Type.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
1212

13+
use OpenCodeModeling\JsonSchemaToPhp\Exception\RuntimeException;
1314
use OpenCodeModeling\JsonSchemaToPhp\Shorthand\Shorthand;
1415

1516
final class Type
@@ -57,10 +58,38 @@ public static function fromDefinition(array $definition, ?string $name = null, a
5758
|| isset($definition['required']):
5859
$definition['type'] = ObjectType::type();
5960
break;
61+
case isset($definition['enum']):
62+
$enumType = '';
63+
64+
foreach ($definition['enum'] as $enumvalue) {
65+
$previousType = \gettype($enumvalue);
66+
67+
if ($enumType !== '' && $previousType !== $enumType) {
68+
throw new RuntimeException('Mixed enum types not supported');
69+
}
70+
$enumType = $previousType;
71+
}
72+
switch ($enumType) {
73+
case 'array':
74+
case 'string':
75+
case 'integer':
76+
case 'boolean':
77+
break;
78+
case 'float':
79+
case 'double':
80+
$enumType = 'number';
81+
break;
82+
default:
83+
throw new RuntimeException(
84+
\sprintf('The type "%s" is not supported in schema definition for "%s"', $enumType, $name)
85+
);
86+
}
87+
$definition['type'] = $enumType;
88+
break;
6089
case \count($definition) === 0:
6190
return new TypeSet(MixedType::fromDefinition($definition, $name));
6291
default:
63-
throw new \RuntimeException(\sprintf('The "type" is missing in schema definition for "%s"', $name));
92+
throw new RuntimeException(\sprintf('The "type" is missing in schema definition for "%s"', $name));
6493
}
6594
}
6695

@@ -113,14 +142,14 @@ public static function fromDefinition(array $definition, ?string $name = null, a
113142
$isNullable = true;
114143
break;
115144
default:
116-
throw new \RuntimeException(
145+
throw new RuntimeException(
117146
\sprintf('JSON schema type "%s" is not implemented', $definition['type'])
118147
);
119148
}
120149
}
121150

122151
if (\count($types) === 0) {
123-
throw new \RuntimeException('Could not determine type of JSON schema');
152+
throw new RuntimeException('Could not determine type of JSON schema');
124153
}
125154

126155
$typeSet = new TypeSet(...$types);

tests/Type/TypeTest.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/json-schema-to-php for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/json-schema-to-php/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/json-schema-to-php/blob/master/LICENSE.md MIT License
7+
*/
8+
29
declare(strict_types=1);
310

411
namespace OpenCodeModelingTest\JsonSchemaToPhp\Type;
512

13+
use OpenCodeModeling\JsonSchemaToPhp\Type\IntegerType;
14+
use OpenCodeModeling\JsonSchemaToPhp\Type\NumberType;
615
use OpenCodeModeling\JsonSchemaToPhp\Type\ObjectType;
16+
use OpenCodeModeling\JsonSchemaToPhp\Type\StringType;
717
use OpenCodeModeling\JsonSchemaToPhp\Type\Type;
818
use PHPUnit\Framework\TestCase;
919

@@ -27,4 +37,58 @@ public function it_supports_shorthand_definition(): void
2737
$this->assertEquals('Person', $type->name());
2838
$this->assertEquals('Person', $type->title());
2939
}
40+
41+
/**
42+
* @test
43+
*/
44+
public function it_supports_string_enums_without_type(): void
45+
{
46+
$typeSet = Type::fromShorthand(['contentLanguage' => 'enum|de-DE|en-US'], 'Content');
47+
48+
$this->assertCount(1, $typeSet);
49+
50+
/** @var ObjectType $type */
51+
$type = $typeSet->first();
52+
53+
$this->assertInstanceOf(ObjectType::class, $type);
54+
$this->assertArrayHasKey('contentLanguage', $type->properties());
55+
56+
$contentLanguage = $type->properties()['contentLanguage'];
57+
/** @var StringType $contentLanguageType */
58+
$contentLanguageType = $contentLanguage->first();
59+
$this->assertInstanceOf(StringType::class, $contentLanguageType);
60+
$this->assertSame(['de-DE', 'en-US'], $contentLanguageType->enum());
61+
}
62+
63+
/**
64+
* @test
65+
*/
66+
public function it_supports_int_enums_without_type(): void
67+
{
68+
$typeSet = Type::fromDefinition(['enum' => [10, 20]], 'Content');
69+
70+
$this->assertCount(1, $typeSet);
71+
72+
/** @var IntegerType $type */
73+
$type = $typeSet->first();
74+
75+
$this->assertInstanceOf(IntegerType::class, $type);
76+
$this->assertSame([10, 20], $type->enum());
77+
}
78+
79+
/**
80+
* @test
81+
*/
82+
public function it_supports_float_enums_without_type(): void
83+
{
84+
$typeSet = Type::fromDefinition(['enum' => [10.10, 20.20]], 'Content');
85+
86+
$this->assertCount(1, $typeSet);
87+
88+
/** @var NumberType $type */
89+
$type = $typeSet->first();
90+
91+
$this->assertInstanceOf(NumberType::class, $type);
92+
$this->assertSame([10.10, 20.20], $type->enum());
93+
}
3094
}

0 commit comments

Comments
 (0)