forked from loafle/openapi-generator-original
[Slim4] Add object support to Data Mocker (#4853)
* [Slim4] Add new method to Mocker interface * [Slim4] Add tests and implement mockObject method * [Slim4] Accept items as object in mockArray method * [Slim4] Add test for array of objects * [Slim4] Refresh samples * [Slim4] Remove abandoned debug comment * [Slim4] Improve tests code coverage
This commit is contained in:
parent
3959530465
commit
04ac754d3e
@ -34,6 +34,7 @@
|
||||
namespace {{mockPackage}};
|
||||
|
||||
use {{mockPackage}}\{{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}} as IMocker;
|
||||
use StdClass;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
@ -82,6 +83,13 @@ final class OpenApiDataMocker implements IMocker
|
||||
$maxItems = $options['maxItems'] ?? null;
|
||||
$uniqueItems = $options['uniqueItems'] ?? false;
|
||||
return $this->mockArray($items, $minItems, $maxItems, $uniqueItems);
|
||||
case IMocker::DATA_TYPE_OBJECT:
|
||||
$properties = $options['properties'] ?? null;
|
||||
$minProperties = $options['minProperties'] ?? 0;
|
||||
$maxProperties = $options['maxProperties'] ?? null;
|
||||
$additionalProperties = $options['additionalProperties'] ?? null;
|
||||
$required = $options['required'] ?? null;
|
||||
return $this->mockObject($properties, $minProperties, $maxProperties, $additionalProperties, $required);
|
||||
default:
|
||||
throw new InvalidArgumentException('"dataType" must be one of ' . implode(', ', [
|
||||
IMocker::DATA_TYPE_INTEGER,
|
||||
@ -89,6 +97,7 @@ final class OpenApiDataMocker implements IMocker
|
||||
IMocker::DATA_TYPE_STRING,
|
||||
IMocker::DATA_TYPE_BOOLEAN,
|
||||
IMocker::DATA_TYPE_ARRAY,
|
||||
IMocker::DATA_TYPE_OBJECT,
|
||||
]));
|
||||
}
|
||||
}
|
||||
@ -220,10 +229,10 @@ final class OpenApiDataMocker implements IMocker
|
||||
* Shortcut to mock array type
|
||||
* Equivalent to mockData(DATA_TYPE_ARRAY);
|
||||
*
|
||||
* @param array $items Array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
* @param object|array $items Object or assoc array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
@ -239,8 +248,12 @@ final class OpenApiDataMocker implements IMocker
|
||||
$minSize = 0;
|
||||
$maxSize = \PHP_INT_MAX;
|
||||
|
||||
if (is_array($items) === false || array_key_exists('type', $items) === false) {
|
||||
throw new InvalidArgumentException('"items" must be assoc array with "type" key');
|
||||
if (
|
||||
(is_array($items) === false && is_object($items) === false)
|
||||
|| (is_array($items) && array_key_exists('type', $items) === false)
|
||||
|| (is_object($items) && isset($items->type) === false)
|
||||
) {
|
||||
new InvalidArgumentException('"items" must be object or assoc array with "type" key');
|
||||
}
|
||||
|
||||
if ($minItems !== null) {
|
||||
@ -260,9 +273,9 @@ final class OpenApiDataMocker implements IMocker
|
||||
$maxSize = $maxItems;
|
||||
}
|
||||
|
||||
$dataType = $items['type'];
|
||||
$dataFormat = $items['format'] ?? null;
|
||||
$options = $this->extractSchemaProperties($items);
|
||||
$dataType = $options['type'];
|
||||
$dataFormat = $options['format'] ?? null;
|
||||
|
||||
// always genarate smallest possible array to avoid huge JSON responses
|
||||
$arrSize = ($maxSize < 1) ? $maxSize : max($minSize, 1);
|
||||
@ -273,17 +286,104 @@ final class OpenApiDataMocker implements IMocker
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Extract OAS properties from array or object.
|
||||
* Shortcut to mock object type.
|
||||
* Equivalent to mockData(DATA_TYPE_OBJECT);
|
||||
*
|
||||
* @param array $arr Processed array
|
||||
* @param object|array $properties Object or array of described properties
|
||||
* @param int|null $minProperties (optional) An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxProperties (optional) An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword.
|
||||
* @param bool|object|array|null $additionalProperties (optional) If "additionalProperties" is true, validation always succeeds.
|
||||
* If "additionalProperties" is false, validation succeeds only if the instance is an object and all properties on the instance were covered by "properties" and/or "patternProperties".
|
||||
* If "additionalProperties" is an object, validate the value as a schema to all of the properties that weren't validated by "properties" nor "patternProperties".
|
||||
* @param array|null $required (optional) This array MUST have at least one element. Elements of this array must be strings, and MUST be unique.
|
||||
* An object instance is valid if its property set contains all elements in this array value.
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function mockObject(
|
||||
$properties,
|
||||
$minProperties = 0,
|
||||
$maxProperties = null,
|
||||
$additionalProperties = null,
|
||||
$required = null
|
||||
) {
|
||||
$obj = new StdClass();
|
||||
|
||||
if (is_object($properties) === false && is_array($properties) === false) {
|
||||
throw new InvalidArgumentException('The value of "properties" must be an array or object');
|
||||
}
|
||||
|
||||
foreach ($properties as $propName => $propValue) {
|
||||
if (is_object($propValue) === false && is_array($propValue) === false) {
|
||||
throw new InvalidArgumentException('Each value of "properties" must be an array or object');
|
||||
}
|
||||
}
|
||||
|
||||
if ($minProperties !== null) {
|
||||
if (is_integer($minProperties) === false || $minProperties < 0) {
|
||||
throw new InvalidArgumentException('"minProperties" must be an integer. This integer must be greater than, or equal to, 0');
|
||||
}
|
||||
}
|
||||
|
||||
if ($maxProperties !== null) {
|
||||
if (is_integer($maxProperties) === false || $maxProperties < 0) {
|
||||
throw new InvalidArgumentException('"maxProperties" must be an integer. This integer must be greater than, or equal to, 0.');
|
||||
}
|
||||
if ($maxProperties < $minProperties) {
|
||||
throw new InvalidArgumentException('"maxProperties" value cannot be less than "minProperties"');
|
||||
}
|
||||
}
|
||||
|
||||
if ($additionalProperties !== null) {
|
||||
if (is_bool($additionalProperties) === false && is_object($additionalProperties) === false && is_array($additionalProperties) === false) {
|
||||
throw new InvalidArgumentException('The value of "additionalProperties" must be a boolean or object or array.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($required !== null) {
|
||||
if (
|
||||
is_array($required) === false
|
||||
|| count($required) > count(array_unique($required))
|
||||
) {
|
||||
throw new InvalidArgumentException('The value of "required" must be an array. Elements of this array must be unique.');
|
||||
}
|
||||
foreach ($required as $requiredPropName) {
|
||||
if (is_string($requiredPropName) === false) {
|
||||
throw new InvalidArgumentException('Elements of "required" array must be strings');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($properties as $propName => $propValue) {
|
||||
$options = $this->extractSchemaProperties($propValue);
|
||||
$dataType = $options['type'];
|
||||
$dataFormat = $options['dataFormat'] ?? null;
|
||||
$obj->$propName = $this->mock($dataType, $dataFormat, $options);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Extract OAS properties from array or object.
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array|object $val Processed array or object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extractSchemaProperties($arr)
|
||||
private function extractSchemaProperties($val)
|
||||
{
|
||||
$props = [];
|
||||
$props = [
|
||||
'type' => null,
|
||||
'format' => null,
|
||||
];
|
||||
foreach (
|
||||
[
|
||||
'type',
|
||||
'format',
|
||||
'minimum',
|
||||
'maximum',
|
||||
'exclusiveMinimum',
|
||||
@ -304,8 +404,10 @@ final class OpenApiDataMocker implements IMocker
|
||||
'example',
|
||||
] as $propName
|
||||
) {
|
||||
if (array_key_exists($propName, $arr)) {
|
||||
$props[$propName] = $arr[$propName];
|
||||
if (is_array($val) && array_key_exists($propName, $val)) {
|
||||
$props[$propName] = $val[$propName];
|
||||
} elseif (is_object($val) && isset($val->$propName)) {
|
||||
$props[$propName] = $val->$propName;
|
||||
}
|
||||
}
|
||||
return $props;
|
||||
@ -313,6 +415,7 @@ final class OpenApiDataMocker implements IMocker
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
|
@ -63,6 +63,9 @@ interface {{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}}
|
||||
/** @var string DATA_TYPE_ARRAY */
|
||||
public const DATA_TYPE_ARRAY = 'array';
|
||||
|
||||
/** @var string DATA_TYPE_OBJECT */
|
||||
public const DATA_TYPE_OBJECT = 'object';
|
||||
|
||||
/** @var string DATA_FORMAT_INT32 Signed 32 bits */
|
||||
public const DATA_FORMAT_INT32 = 'int32';
|
||||
|
||||
@ -194,10 +197,10 @@ interface {{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}}
|
||||
* Shortcut to mock array type
|
||||
* Equivalent to mockData(DATA_TYPE_ARRAY);
|
||||
*
|
||||
* @param array $items Array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
* @param object|array $items Object or assoc array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
@ -209,5 +212,30 @@ interface {{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}}
|
||||
$maxItems = null,
|
||||
$uniqueItems = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Shortcut to mock object type.
|
||||
* Equivalent to mockData(DATA_TYPE_OBJECT);
|
||||
*
|
||||
* @param object|array $properties Object or array of described properties
|
||||
* @param int|null $minProperties (optional) An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxProperties (optional) An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword.
|
||||
* @param bool|object|array|null $additionalProperties (optional) If "additionalProperties" is true, validation always succeeds.
|
||||
* If "additionalProperties" is false, validation succeeds only if the instance is an object and all properties on the instance were covered by "properties" and/or "patternProperties".
|
||||
* If "additionalProperties" is an object, validate the value as a schema to all of the properties that weren't validated by "properties" nor "patternProperties".
|
||||
* @param array|null $required (optional) This array MUST have at least one element. Elements of this array must be strings, and MUST be unique.
|
||||
* An object instance is valid if its property set contains all elements in this array value.
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function mockObject(
|
||||
$properties,
|
||||
$minProperties = 0,
|
||||
$maxProperties = null,
|
||||
$additionalProperties = null,
|
||||
$required = null
|
||||
);
|
||||
}
|
||||
{{/apiInfo}}
|
||||
|
@ -37,6 +37,7 @@ use {{mockPackage}}\OpenApiDataMocker;
|
||||
use {{mockPackage}}\{{interfaceNamePrefix}}OpenApiDataMocker{{interfaceNameSuffix}} as IMocker;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Constraint\IsType;
|
||||
use StdClass;
|
||||
|
||||
/**
|
||||
* OpenApiDataMockerTest Class Doc Comment
|
||||
@ -55,7 +56,8 @@ class OpenApiDataMockerTest extends TestCase
|
||||
public function testMockCorrectArguments($dataType, $dataFormat, $options, $expectedType)
|
||||
{
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$this->assertInternalType($expectedType, $mocker->mock($dataType));
|
||||
$data = $mocker->mock($dataType, $dataFormat, $options);
|
||||
$this->assertInternalType($expectedType, $data);
|
||||
}
|
||||
|
||||
public function provideMockCorrectArguments()
|
||||
@ -65,6 +67,39 @@ class OpenApiDataMockerTest extends TestCase
|
||||
[IMocker::DATA_TYPE_NUMBER, null, null, IsType::TYPE_FLOAT],
|
||||
[IMocker::DATA_TYPE_STRING, null, null, IsType::TYPE_STRING],
|
||||
[IMocker::DATA_TYPE_BOOLEAN, null, null, IsType::TYPE_BOOL],
|
||||
[IMocker::DATA_TYPE_ARRAY, null, [
|
||||
'items' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
], IsType::TYPE_ARRAY],
|
||||
[IMocker::DATA_TYPE_OBJECT, null, [
|
||||
'properties' => [
|
||||
'username' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
],
|
||||
], IsType::TYPE_OBJECT],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::mock
|
||||
* @dataProvider provideMockInvalidArguments
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage "dataType" must be one of integer, number, string, boolean, array, object
|
||||
*/
|
||||
public function testMockInvalidArguments($dataType, $dataFormat, $options)
|
||||
{
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$data = $mocker->mock($dataType, $dataFormat, $options);
|
||||
}
|
||||
|
||||
public function provideMockInvalidArguments()
|
||||
{
|
||||
return [
|
||||
['foobar', null, null],
|
||||
[3.14, null, null],
|
||||
[null, null, null],
|
||||
];
|
||||
}
|
||||
|
||||
@ -440,28 +475,54 @@ class OpenApiDataMockerTest extends TestCase
|
||||
$this->assertContainsOnly($expectedItemsType, $arr, true);
|
||||
}
|
||||
|
||||
$dataFormat = $items['dataFormat'] ?? null;
|
||||
if (is_array($items)) {
|
||||
$dataType = $items['type'];
|
||||
$dataFormat = $items['dataFormat'] ?? null;
|
||||
|
||||
// items field numeric properties
|
||||
$minimum = $items['minimum'] ?? null;
|
||||
$maximum = $items['maximum'] ?? null;
|
||||
$exclusiveMinimum = $items['exclusiveMinimum'] ?? null;
|
||||
$exclusiveMaximum = $items['exclusiveMaximum'] ?? null;
|
||||
// items field numeric properties
|
||||
$minimum = $items['minimum'] ?? null;
|
||||
$maximum = $items['maximum'] ?? null;
|
||||
$exclusiveMinimum = $items['exclusiveMinimum'] ?? null;
|
||||
$exclusiveMaximum = $items['exclusiveMaximum'] ?? null;
|
||||
|
||||
// items field string properties
|
||||
$minLength = $items['minLength'] ?? null;
|
||||
$maxLength = $items['maxLength'] ?? null;
|
||||
$enum = $items['enum'] ?? null;
|
||||
$pattern = $items['pattern'] ?? null;
|
||||
// items field string properties
|
||||
$minLength = $items['minLength'] ?? null;
|
||||
$maxLength = $items['maxLength'] ?? null;
|
||||
$enum = $items['enum'] ?? null;
|
||||
$pattern = $items['pattern'] ?? null;
|
||||
|
||||
// items field array properties
|
||||
$subItems = $items['items'] ?? null;
|
||||
$subMinItems = $items['minItems'] ?? null;
|
||||
$subMaxItems = $items['maxItems'] ?? null;
|
||||
$subUniqueItems = $items['uniqueItems'] ?? null;
|
||||
// items field array properties
|
||||
$subItems = $items['items'] ?? null;
|
||||
$subMinItems = $items['minItems'] ?? null;
|
||||
$subMaxItems = $items['maxItems'] ?? null;
|
||||
$subUniqueItems = $items['uniqueItems'] ?? null;
|
||||
} else {
|
||||
// is object
|
||||
$dataType = $items->type;
|
||||
$dataFormat = $items->dataFormat ?? null;
|
||||
|
||||
// items field numeric properties
|
||||
$minimum = $items->minimum ?? null;
|
||||
$maximum = $items->maximum ?? null;
|
||||
$exclusiveMinimum = $items->exclusiveMinimum ?? null;
|
||||
$exclusiveMaximum = $items->exclusiveMaximum ?? null;
|
||||
|
||||
// items field string properties
|
||||
$minLength = $items->minLength ?? null;
|
||||
$maxLength = $items->maxLength ?? null;
|
||||
$enum = $items->enum ?? null;
|
||||
$pattern = $items->pattern ?? null;
|
||||
|
||||
// items field array properties
|
||||
$subItems = $items->items ?? null;
|
||||
$subMinItems = $items->minItems ?? null;
|
||||
$subMaxItems = $items->maxItems ?? null;
|
||||
$subUniqueItems = $items->uniqueItems ?? null;
|
||||
}
|
||||
|
||||
|
||||
foreach ($arr as $item) {
|
||||
switch ($items['type']) {
|
||||
switch ($dataType) {
|
||||
case IMocker::DATA_TYPE_INTEGER:
|
||||
$this->internalAssertNumber($item, $minimum, $maximum, $exclusiveMinimum, $exclusiveMaximum);
|
||||
break;
|
||||
@ -486,13 +547,15 @@ class OpenApiDataMockerTest extends TestCase
|
||||
$intItems = ['type' => IMocker::DATA_TYPE_INTEGER, 'minimum' => 5, 'maximum' => 10];
|
||||
$floatItems = ['type' => IMocker::DATA_TYPE_NUMBER, 'minimum' => -32.4, 'maximum' => 88.6, 'exclusiveMinimum' => true, 'exclusiveMaximum' => true];
|
||||
$strItems = ['type' => IMocker::DATA_TYPE_STRING, 'minLength' => 20, 'maxLength' => 50];
|
||||
$boolItems = ['type' => IMocker::DATA_TYPE_BOOLEAN];
|
||||
$arrayItems = ['type' => IMocker::DATA_TYPE_ARRAY, 'items' => ['type' => IMocker::DATA_TYPE_STRING, 'minItems' => 3, 'maxItems' => 10]];
|
||||
$boolItems = (object) ['type' => IMocker::DATA_TYPE_BOOLEAN];
|
||||
$arrayItems = (object) ['type' => IMocker::DATA_TYPE_ARRAY, 'items' => ['type' => IMocker::DATA_TYPE_STRING, 'minItems' => 3, 'maxItems' => 10]];
|
||||
$objectItems = (object) ['type' => IMocker::DATA_TYPE_OBJECT, 'properties' => (object)['username' => ['type' => IMocker::DATA_TYPE_STRING]]];
|
||||
$expectedInt = IsType::TYPE_INT;
|
||||
$expectedFloat = IsType::TYPE_FLOAT;
|
||||
$expectedStr = IsType::TYPE_STRING;
|
||||
$expectedBool = IsType::TYPE_BOOL;
|
||||
$expectedArray = IsType::TYPE_ARRAY;
|
||||
$expectedObject = IsType::TYPE_OBJECT;
|
||||
|
||||
return [
|
||||
'empty array' => [
|
||||
@ -531,6 +594,9 @@ class OpenApiDataMockerTest extends TestCase
|
||||
'array of one array of strings' => [
|
||||
$arrayItems, null, null, false, $expectedArray, 1,
|
||||
],
|
||||
'array of one object' => [
|
||||
$objectItems, null, null, false, $expectedObject, 1
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -583,5 +649,125 @@ class OpenApiDataMockerTest extends TestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMockObjectCorrectArguments
|
||||
* @covers ::mockObject
|
||||
*/
|
||||
public function testMockObjectWithCorrectArguments(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required,
|
||||
$expectedKeys
|
||||
) {
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$obj = $mocker->mockObject(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required
|
||||
);
|
||||
|
||||
$this->assertInternalType(IsType::TYPE_OBJECT, $obj);
|
||||
$this->assertSame($expectedKeys, array_keys(get_object_vars($obj)));
|
||||
}
|
||||
|
||||
public function provideMockObjectCorrectArguments()
|
||||
{
|
||||
$additionProps = [
|
||||
'extra' => [
|
||||
'type' => IMocker::DATA_TYPE_STRING,
|
||||
],
|
||||
];
|
||||
return [
|
||||
'empty object' => [
|
||||
[], 1, 10, true, null, [],
|
||||
],
|
||||
'empty object from StdClass' => [
|
||||
new StdClass(), 1, 5, false, null, [],
|
||||
],
|
||||
'object with username property' => [
|
||||
[
|
||||
'username' => [
|
||||
'type' => IMocker::DATA_TYPE_STRING,
|
||||
],
|
||||
], 0, 5, $additionProps, null, ['username'],
|
||||
],
|
||||
'object with foobar property' => [
|
||||
(object) [
|
||||
'foobar' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
], 1, 1, (object) $additionProps, null, ['foobar'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMockObjectInvalidArguments
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @covers ::mockObject
|
||||
*/
|
||||
public function testMockObjectWithInvalidArguments(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required
|
||||
) {
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$obj = $mocker->mockObject($properties, $minProperties, $maxProperties, $additionalProperties, $required);
|
||||
}
|
||||
|
||||
public function provideMockObjectInvalidArguments()
|
||||
{
|
||||
return [
|
||||
'properties cannot be null' => [
|
||||
null, 0, 10, false, null,
|
||||
],
|
||||
'properties cannot be a string' => [
|
||||
'foobar', 0, 10, false, null,
|
||||
],
|
||||
'minProperties is not integer' => [
|
||||
[], 3.12, null, false, null,
|
||||
],
|
||||
'minProperties is negative' => [
|
||||
[], -10, null, false, null,
|
||||
],
|
||||
'minProperties is not number' => [
|
||||
[], '1', null, false, null,
|
||||
],
|
||||
'maxProperties is not integer' => [
|
||||
[], null, 3.12, false, null,
|
||||
],
|
||||
'maxProperties is negative' => [
|
||||
[], null, -10, false, null,
|
||||
],
|
||||
'maxProperties is not number' => [
|
||||
[], null, 'foobaz', false, null,
|
||||
],
|
||||
'maxProperties less than minProperties' => [
|
||||
[], 5, 2, false, null,
|
||||
],
|
||||
'additionalProperties is not object|array|boolean' => [
|
||||
[], null, null, 'foobar', null,
|
||||
],
|
||||
'required is object, not array' => [
|
||||
[], null, null, null, new StdClass(),
|
||||
],
|
||||
'required is not array' => [
|
||||
[], null, null, null, 'foobar',
|
||||
],
|
||||
'required array with duplicates' => [
|
||||
[], null, null, null, ['username', 'username'],
|
||||
],
|
||||
'required array of non-strings' => [
|
||||
[], null, null, null, [1, 2, 3],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
{{/apiInfo}}
|
||||
|
@ -26,6 +26,7 @@
|
||||
namespace OpenAPIServer\Mock;
|
||||
|
||||
use OpenAPIServer\Mock\OpenApiDataMockerInterface as IMocker;
|
||||
use StdClass;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
@ -74,6 +75,13 @@ final class OpenApiDataMocker implements IMocker
|
||||
$maxItems = $options['maxItems'] ?? null;
|
||||
$uniqueItems = $options['uniqueItems'] ?? false;
|
||||
return $this->mockArray($items, $minItems, $maxItems, $uniqueItems);
|
||||
case IMocker::DATA_TYPE_OBJECT:
|
||||
$properties = $options['properties'] ?? null;
|
||||
$minProperties = $options['minProperties'] ?? 0;
|
||||
$maxProperties = $options['maxProperties'] ?? null;
|
||||
$additionalProperties = $options['additionalProperties'] ?? null;
|
||||
$required = $options['required'] ?? null;
|
||||
return $this->mockObject($properties, $minProperties, $maxProperties, $additionalProperties, $required);
|
||||
default:
|
||||
throw new InvalidArgumentException('"dataType" must be one of ' . implode(', ', [
|
||||
IMocker::DATA_TYPE_INTEGER,
|
||||
@ -81,6 +89,7 @@ final class OpenApiDataMocker implements IMocker
|
||||
IMocker::DATA_TYPE_STRING,
|
||||
IMocker::DATA_TYPE_BOOLEAN,
|
||||
IMocker::DATA_TYPE_ARRAY,
|
||||
IMocker::DATA_TYPE_OBJECT,
|
||||
]));
|
||||
}
|
||||
}
|
||||
@ -212,10 +221,10 @@ final class OpenApiDataMocker implements IMocker
|
||||
* Shortcut to mock array type
|
||||
* Equivalent to mockData(DATA_TYPE_ARRAY);
|
||||
*
|
||||
* @param array $items Array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
* @param object|array $items Object or assoc array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
@ -231,8 +240,12 @@ final class OpenApiDataMocker implements IMocker
|
||||
$minSize = 0;
|
||||
$maxSize = \PHP_INT_MAX;
|
||||
|
||||
if (is_array($items) === false || array_key_exists('type', $items) === false) {
|
||||
throw new InvalidArgumentException('"items" must be assoc array with "type" key');
|
||||
if (
|
||||
(is_array($items) === false && is_object($items) === false)
|
||||
|| (is_array($items) && array_key_exists('type', $items) === false)
|
||||
|| (is_object($items) && isset($items->type) === false)
|
||||
) {
|
||||
new InvalidArgumentException('"items" must be object or assoc array with "type" key');
|
||||
}
|
||||
|
||||
if ($minItems !== null) {
|
||||
@ -252,9 +265,9 @@ final class OpenApiDataMocker implements IMocker
|
||||
$maxSize = $maxItems;
|
||||
}
|
||||
|
||||
$dataType = $items['type'];
|
||||
$dataFormat = $items['format'] ?? null;
|
||||
$options = $this->extractSchemaProperties($items);
|
||||
$dataType = $options['type'];
|
||||
$dataFormat = $options['format'] ?? null;
|
||||
|
||||
// always genarate smallest possible array to avoid huge JSON responses
|
||||
$arrSize = ($maxSize < 1) ? $maxSize : max($minSize, 1);
|
||||
@ -265,17 +278,104 @@ final class OpenApiDataMocker implements IMocker
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Extract OAS properties from array or object.
|
||||
* Shortcut to mock object type.
|
||||
* Equivalent to mockData(DATA_TYPE_OBJECT);
|
||||
*
|
||||
* @param array $arr Processed array
|
||||
* @param object|array $properties Object or array of described properties
|
||||
* @param int|null $minProperties (optional) An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxProperties (optional) An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword.
|
||||
* @param bool|object|array|null $additionalProperties (optional) If "additionalProperties" is true, validation always succeeds.
|
||||
* If "additionalProperties" is false, validation succeeds only if the instance is an object and all properties on the instance were covered by "properties" and/or "patternProperties".
|
||||
* If "additionalProperties" is an object, validate the value as a schema to all of the properties that weren't validated by "properties" nor "patternProperties".
|
||||
* @param array|null $required (optional) This array MUST have at least one element. Elements of this array must be strings, and MUST be unique.
|
||||
* An object instance is valid if its property set contains all elements in this array value.
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function mockObject(
|
||||
$properties,
|
||||
$minProperties = 0,
|
||||
$maxProperties = null,
|
||||
$additionalProperties = null,
|
||||
$required = null
|
||||
) {
|
||||
$obj = new StdClass();
|
||||
|
||||
if (is_object($properties) === false && is_array($properties) === false) {
|
||||
throw new InvalidArgumentException('The value of "properties" must be an array or object');
|
||||
}
|
||||
|
||||
foreach ($properties as $propName => $propValue) {
|
||||
if (is_object($propValue) === false && is_array($propValue) === false) {
|
||||
throw new InvalidArgumentException('Each value of "properties" must be an array or object');
|
||||
}
|
||||
}
|
||||
|
||||
if ($minProperties !== null) {
|
||||
if (is_integer($minProperties) === false || $minProperties < 0) {
|
||||
throw new InvalidArgumentException('"minProperties" must be an integer. This integer must be greater than, or equal to, 0');
|
||||
}
|
||||
}
|
||||
|
||||
if ($maxProperties !== null) {
|
||||
if (is_integer($maxProperties) === false || $maxProperties < 0) {
|
||||
throw new InvalidArgumentException('"maxProperties" must be an integer. This integer must be greater than, or equal to, 0.');
|
||||
}
|
||||
if ($maxProperties < $minProperties) {
|
||||
throw new InvalidArgumentException('"maxProperties" value cannot be less than "minProperties"');
|
||||
}
|
||||
}
|
||||
|
||||
if ($additionalProperties !== null) {
|
||||
if (is_bool($additionalProperties) === false && is_object($additionalProperties) === false && is_array($additionalProperties) === false) {
|
||||
throw new InvalidArgumentException('The value of "additionalProperties" must be a boolean or object or array.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($required !== null) {
|
||||
if (
|
||||
is_array($required) === false
|
||||
|| count($required) > count(array_unique($required))
|
||||
) {
|
||||
throw new InvalidArgumentException('The value of "required" must be an array. Elements of this array must be unique.');
|
||||
}
|
||||
foreach ($required as $requiredPropName) {
|
||||
if (is_string($requiredPropName) === false) {
|
||||
throw new InvalidArgumentException('Elements of "required" array must be strings');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($properties as $propName => $propValue) {
|
||||
$options = $this->extractSchemaProperties($propValue);
|
||||
$dataType = $options['type'];
|
||||
$dataFormat = $options['dataFormat'] ?? null;
|
||||
$obj->$propName = $this->mock($dataType, $dataFormat, $options);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Extract OAS properties from array or object.
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param array|object $val Processed array or object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extractSchemaProperties($arr)
|
||||
private function extractSchemaProperties($val)
|
||||
{
|
||||
$props = [];
|
||||
$props = [
|
||||
'type' => null,
|
||||
'format' => null,
|
||||
];
|
||||
foreach (
|
||||
[
|
||||
'type',
|
||||
'format',
|
||||
'minimum',
|
||||
'maximum',
|
||||
'exclusiveMinimum',
|
||||
@ -296,8 +396,10 @@ final class OpenApiDataMocker implements IMocker
|
||||
'example',
|
||||
] as $propName
|
||||
) {
|
||||
if (array_key_exists($propName, $arr)) {
|
||||
$props[$propName] = $arr[$propName];
|
||||
if (is_array($val) && array_key_exists($propName, $val)) {
|
||||
$props[$propName] = $val[$propName];
|
||||
} elseif (is_object($val) && isset($val->$propName)) {
|
||||
$props[$propName] = $val->$propName;
|
||||
}
|
||||
}
|
||||
return $props;
|
||||
@ -305,6 +407,7 @@ final class OpenApiDataMocker implements IMocker
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
|
@ -55,6 +55,9 @@ interface OpenApiDataMockerInterface
|
||||
/** @var string DATA_TYPE_ARRAY */
|
||||
public const DATA_TYPE_ARRAY = 'array';
|
||||
|
||||
/** @var string DATA_TYPE_OBJECT */
|
||||
public const DATA_TYPE_OBJECT = 'object';
|
||||
|
||||
/** @var string DATA_FORMAT_INT32 Signed 32 bits */
|
||||
public const DATA_FORMAT_INT32 = 'int32';
|
||||
|
||||
@ -186,10 +189,10 @@ interface OpenApiDataMockerInterface
|
||||
* Shortcut to mock array type
|
||||
* Equivalent to mockData(DATA_TYPE_ARRAY);
|
||||
*
|
||||
* @param array $items Array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
* @param object|array $items Object or assoc array of described items
|
||||
* @param int|null $minItems (optional) An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxItems (optional) An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword
|
||||
* @param bool|null $uniqueItems (optional) If it has boolean value true, the instance validates successfully if all of its elements are unique
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
@ -201,4 +204,29 @@ interface OpenApiDataMockerInterface
|
||||
$maxItems = null,
|
||||
$uniqueItems = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Shortcut to mock object type.
|
||||
* Equivalent to mockData(DATA_TYPE_OBJECT);
|
||||
*
|
||||
* @param object|array $properties Object or array of described properties
|
||||
* @param int|null $minProperties (optional) An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the value of this keyword.
|
||||
* @param int|null $maxProperties (optional) An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value of this keyword.
|
||||
* @param bool|object|array|null $additionalProperties (optional) If "additionalProperties" is true, validation always succeeds.
|
||||
* If "additionalProperties" is false, validation succeeds only if the instance is an object and all properties on the instance were covered by "properties" and/or "patternProperties".
|
||||
* If "additionalProperties" is an object, validate the value as a schema to all of the properties that weren't validated by "properties" nor "patternProperties".
|
||||
* @param array|null $required (optional) This array MUST have at least one element. Elements of this array must be strings, and MUST be unique.
|
||||
* An object instance is valid if its property set contains all elements in this array value.
|
||||
*
|
||||
* @throws \InvalidArgumentException when invalid arguments passed
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function mockObject(
|
||||
$properties,
|
||||
$minProperties = 0,
|
||||
$maxProperties = null,
|
||||
$additionalProperties = null,
|
||||
$required = null
|
||||
);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ use OpenAPIServer\Mock\OpenApiDataMocker;
|
||||
use OpenAPIServer\Mock\OpenApiDataMockerInterface as IMocker;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Constraint\IsType;
|
||||
use StdClass;
|
||||
|
||||
/**
|
||||
* OpenApiDataMockerTest Class Doc Comment
|
||||
@ -47,7 +48,8 @@ class OpenApiDataMockerTest extends TestCase
|
||||
public function testMockCorrectArguments($dataType, $dataFormat, $options, $expectedType)
|
||||
{
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$this->assertInternalType($expectedType, $mocker->mock($dataType));
|
||||
$data = $mocker->mock($dataType, $dataFormat, $options);
|
||||
$this->assertInternalType($expectedType, $data);
|
||||
}
|
||||
|
||||
public function provideMockCorrectArguments()
|
||||
@ -57,6 +59,39 @@ class OpenApiDataMockerTest extends TestCase
|
||||
[IMocker::DATA_TYPE_NUMBER, null, null, IsType::TYPE_FLOAT],
|
||||
[IMocker::DATA_TYPE_STRING, null, null, IsType::TYPE_STRING],
|
||||
[IMocker::DATA_TYPE_BOOLEAN, null, null, IsType::TYPE_BOOL],
|
||||
[IMocker::DATA_TYPE_ARRAY, null, [
|
||||
'items' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
], IsType::TYPE_ARRAY],
|
||||
[IMocker::DATA_TYPE_OBJECT, null, [
|
||||
'properties' => [
|
||||
'username' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
],
|
||||
], IsType::TYPE_OBJECT],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::mock
|
||||
* @dataProvider provideMockInvalidArguments
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage "dataType" must be one of integer, number, string, boolean, array, object
|
||||
*/
|
||||
public function testMockInvalidArguments($dataType, $dataFormat, $options)
|
||||
{
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$data = $mocker->mock($dataType, $dataFormat, $options);
|
||||
}
|
||||
|
||||
public function provideMockInvalidArguments()
|
||||
{
|
||||
return [
|
||||
['foobar', null, null],
|
||||
[3.14, null, null],
|
||||
[null, null, null],
|
||||
];
|
||||
}
|
||||
|
||||
@ -432,28 +467,54 @@ class OpenApiDataMockerTest extends TestCase
|
||||
$this->assertContainsOnly($expectedItemsType, $arr, true);
|
||||
}
|
||||
|
||||
$dataFormat = $items['dataFormat'] ?? null;
|
||||
if (is_array($items)) {
|
||||
$dataType = $items['type'];
|
||||
$dataFormat = $items['dataFormat'] ?? null;
|
||||
|
||||
// items field numeric properties
|
||||
$minimum = $items['minimum'] ?? null;
|
||||
$maximum = $items['maximum'] ?? null;
|
||||
$exclusiveMinimum = $items['exclusiveMinimum'] ?? null;
|
||||
$exclusiveMaximum = $items['exclusiveMaximum'] ?? null;
|
||||
// items field numeric properties
|
||||
$minimum = $items['minimum'] ?? null;
|
||||
$maximum = $items['maximum'] ?? null;
|
||||
$exclusiveMinimum = $items['exclusiveMinimum'] ?? null;
|
||||
$exclusiveMaximum = $items['exclusiveMaximum'] ?? null;
|
||||
|
||||
// items field string properties
|
||||
$minLength = $items['minLength'] ?? null;
|
||||
$maxLength = $items['maxLength'] ?? null;
|
||||
$enum = $items['enum'] ?? null;
|
||||
$pattern = $items['pattern'] ?? null;
|
||||
// items field string properties
|
||||
$minLength = $items['minLength'] ?? null;
|
||||
$maxLength = $items['maxLength'] ?? null;
|
||||
$enum = $items['enum'] ?? null;
|
||||
$pattern = $items['pattern'] ?? null;
|
||||
|
||||
// items field array properties
|
||||
$subItems = $items['items'] ?? null;
|
||||
$subMinItems = $items['minItems'] ?? null;
|
||||
$subMaxItems = $items['maxItems'] ?? null;
|
||||
$subUniqueItems = $items['uniqueItems'] ?? null;
|
||||
// items field array properties
|
||||
$subItems = $items['items'] ?? null;
|
||||
$subMinItems = $items['minItems'] ?? null;
|
||||
$subMaxItems = $items['maxItems'] ?? null;
|
||||
$subUniqueItems = $items['uniqueItems'] ?? null;
|
||||
} else {
|
||||
// is object
|
||||
$dataType = $items->type;
|
||||
$dataFormat = $items->dataFormat ?? null;
|
||||
|
||||
// items field numeric properties
|
||||
$minimum = $items->minimum ?? null;
|
||||
$maximum = $items->maximum ?? null;
|
||||
$exclusiveMinimum = $items->exclusiveMinimum ?? null;
|
||||
$exclusiveMaximum = $items->exclusiveMaximum ?? null;
|
||||
|
||||
// items field string properties
|
||||
$minLength = $items->minLength ?? null;
|
||||
$maxLength = $items->maxLength ?? null;
|
||||
$enum = $items->enum ?? null;
|
||||
$pattern = $items->pattern ?? null;
|
||||
|
||||
// items field array properties
|
||||
$subItems = $items->items ?? null;
|
||||
$subMinItems = $items->minItems ?? null;
|
||||
$subMaxItems = $items->maxItems ?? null;
|
||||
$subUniqueItems = $items->uniqueItems ?? null;
|
||||
}
|
||||
|
||||
|
||||
foreach ($arr as $item) {
|
||||
switch ($items['type']) {
|
||||
switch ($dataType) {
|
||||
case IMocker::DATA_TYPE_INTEGER:
|
||||
$this->internalAssertNumber($item, $minimum, $maximum, $exclusiveMinimum, $exclusiveMaximum);
|
||||
break;
|
||||
@ -478,13 +539,15 @@ class OpenApiDataMockerTest extends TestCase
|
||||
$intItems = ['type' => IMocker::DATA_TYPE_INTEGER, 'minimum' => 5, 'maximum' => 10];
|
||||
$floatItems = ['type' => IMocker::DATA_TYPE_NUMBER, 'minimum' => -32.4, 'maximum' => 88.6, 'exclusiveMinimum' => true, 'exclusiveMaximum' => true];
|
||||
$strItems = ['type' => IMocker::DATA_TYPE_STRING, 'minLength' => 20, 'maxLength' => 50];
|
||||
$boolItems = ['type' => IMocker::DATA_TYPE_BOOLEAN];
|
||||
$arrayItems = ['type' => IMocker::DATA_TYPE_ARRAY, 'items' => ['type' => IMocker::DATA_TYPE_STRING, 'minItems' => 3, 'maxItems' => 10]];
|
||||
$boolItems = (object) ['type' => IMocker::DATA_TYPE_BOOLEAN];
|
||||
$arrayItems = (object) ['type' => IMocker::DATA_TYPE_ARRAY, 'items' => ['type' => IMocker::DATA_TYPE_STRING, 'minItems' => 3, 'maxItems' => 10]];
|
||||
$objectItems = (object) ['type' => IMocker::DATA_TYPE_OBJECT, 'properties' => (object)['username' => ['type' => IMocker::DATA_TYPE_STRING]]];
|
||||
$expectedInt = IsType::TYPE_INT;
|
||||
$expectedFloat = IsType::TYPE_FLOAT;
|
||||
$expectedStr = IsType::TYPE_STRING;
|
||||
$expectedBool = IsType::TYPE_BOOL;
|
||||
$expectedArray = IsType::TYPE_ARRAY;
|
||||
$expectedObject = IsType::TYPE_OBJECT;
|
||||
|
||||
return [
|
||||
'empty array' => [
|
||||
@ -523,6 +586,9 @@ class OpenApiDataMockerTest extends TestCase
|
||||
'array of one array of strings' => [
|
||||
$arrayItems, null, null, false, $expectedArray, 1,
|
||||
],
|
||||
'array of one object' => [
|
||||
$objectItems, null, null, false, $expectedObject, 1
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -575,4 +641,124 @@ class OpenApiDataMockerTest extends TestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMockObjectCorrectArguments
|
||||
* @covers ::mockObject
|
||||
*/
|
||||
public function testMockObjectWithCorrectArguments(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required,
|
||||
$expectedKeys
|
||||
) {
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$obj = $mocker->mockObject(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required
|
||||
);
|
||||
|
||||
$this->assertInternalType(IsType::TYPE_OBJECT, $obj);
|
||||
$this->assertSame($expectedKeys, array_keys(get_object_vars($obj)));
|
||||
}
|
||||
|
||||
public function provideMockObjectCorrectArguments()
|
||||
{
|
||||
$additionProps = [
|
||||
'extra' => [
|
||||
'type' => IMocker::DATA_TYPE_STRING,
|
||||
],
|
||||
];
|
||||
return [
|
||||
'empty object' => [
|
||||
[], 1, 10, true, null, [],
|
||||
],
|
||||
'empty object from StdClass' => [
|
||||
new StdClass(), 1, 5, false, null, [],
|
||||
],
|
||||
'object with username property' => [
|
||||
[
|
||||
'username' => [
|
||||
'type' => IMocker::DATA_TYPE_STRING,
|
||||
],
|
||||
], 0, 5, $additionProps, null, ['username'],
|
||||
],
|
||||
'object with foobar property' => [
|
||||
(object) [
|
||||
'foobar' => [
|
||||
'type' => IMocker::DATA_TYPE_INTEGER,
|
||||
],
|
||||
], 1, 1, (object) $additionProps, null, ['foobar'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideMockObjectInvalidArguments
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @covers ::mockObject
|
||||
*/
|
||||
public function testMockObjectWithInvalidArguments(
|
||||
$properties,
|
||||
$minProperties,
|
||||
$maxProperties,
|
||||
$additionalProperties,
|
||||
$required
|
||||
) {
|
||||
$mocker = new OpenApiDataMocker();
|
||||
$obj = $mocker->mockObject($properties, $minProperties, $maxProperties, $additionalProperties, $required);
|
||||
}
|
||||
|
||||
public function provideMockObjectInvalidArguments()
|
||||
{
|
||||
return [
|
||||
'properties cannot be null' => [
|
||||
null, 0, 10, false, null,
|
||||
],
|
||||
'properties cannot be a string' => [
|
||||
'foobar', 0, 10, false, null,
|
||||
],
|
||||
'minProperties is not integer' => [
|
||||
[], 3.12, null, false, null,
|
||||
],
|
||||
'minProperties is negative' => [
|
||||
[], -10, null, false, null,
|
||||
],
|
||||
'minProperties is not number' => [
|
||||
[], '1', null, false, null,
|
||||
],
|
||||
'maxProperties is not integer' => [
|
||||
[], null, 3.12, false, null,
|
||||
],
|
||||
'maxProperties is negative' => [
|
||||
[], null, -10, false, null,
|
||||
],
|
||||
'maxProperties is not number' => [
|
||||
[], null, 'foobaz', false, null,
|
||||
],
|
||||
'maxProperties less than minProperties' => [
|
||||
[], 5, 2, false, null,
|
||||
],
|
||||
'additionalProperties is not object|array|boolean' => [
|
||||
[], null, null, 'foobar', null,
|
||||
],
|
||||
'required is object, not array' => [
|
||||
[], null, null, null, new StdClass(),
|
||||
],
|
||||
'required is not array' => [
|
||||
[], null, null, null, 'foobar',
|
||||
],
|
||||
'required array with duplicates' => [
|
||||
[], null, null, null, ['username', 'username'],
|
||||
],
|
||||
'required array of non-strings' => [
|
||||
[], null, null, null, [1, 2, 3],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user