Skip to content

Commit 9d3755d

Browse files
authored
Merge pull request #152 from cebe/fix-array-value-found-but-an-object-is-required
Fix OpenAPI v3.0 Schema Violation: Array value found, but an object is required
2 parents 352848b + 1bd42dd commit 9d3755d

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,21 @@ install: composer.lock yarn.lock
4141
$(DOCKER_PHP) composer install --prefer-dist --no-interaction --no-progress --ansi
4242
$(DOCKER_NODE) yarn install
4343

44-
test:
44+
test: unit test-recursion.json test-recursion2.yaml test-empty-maps.json
45+
46+
unit:
4547
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) vendor/bin/phpunit --verbose --colors=always $(TESTCASE)
46-
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/recursion.json
47-
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/recursion2.yaml
48+
49+
# test specific JSON files in tests/spec/data/
50+
# e.g. test-recursion will run validation on tests/spec/data/recursion.json
51+
test-%: tests/spec/data/%
52+
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate $<
4853

4954
lint: install
5055
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/reference/playlist.json
5156
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/recursion.json
5257
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/recursion2.yaml
58+
$(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) bin/php-openapi validate tests/spec/data/empty-maps.json
5359
$(DOCKER_NODE) yarn run speccy lint tests/spec/data/reference/playlist.json
5460
$(DOCKER_NODE) yarn run speccy lint tests/spec/data/recursion.json
5561

src/SpecBaseObject.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,23 @@ public function getSerializableData()
190190
if ($v instanceof SpecObjectInterface) {
191191
$data[$k] = $v->getSerializableData();
192192
} elseif (is_array($v)) {
193+
// test if php arrays should be represented as object in YAML/JSON
193194
$toObject = false;
194-
$j = 0;
195-
foreach ($v as $i => $d) {
196-
if ($j++ !== $i) {
197-
$toObject = true;
198-
}
199-
if ($d instanceof SpecObjectInterface) {
200-
$data[$k][$i] = $d->getSerializableData();
195+
if (!empty($v)) {
196+
// case 1: non-empty array should be an object if it does not contain
197+
// consecutive numeric keys
198+
$j = 0;
199+
foreach ($v as $i => $d) {
200+
if ($j++ !== $i) {
201+
$toObject = true;
202+
}
203+
if ($d instanceof SpecObjectInterface) {
204+
$data[$k][$i] = $d->getSerializableData();
205+
}
201206
}
207+
} elseif (isset($this->attributes()[$k]) && is_array($this->attributes()[$k]) && 2 === count($this->attributes()[$k])) {
208+
// case 2: Attribute type is an object (specified in attributes() by an array which specifies two items (key and value type)
209+
$toObject = true;
202210
}
203211
if ($toObject) {
204212
$data[$k] = (object) $data[$k];

tests/spec/data/empty-maps.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "test",
5+
"version": "1.0"
6+
},
7+
"paths": {
8+
"/products": {
9+
"description": "default",
10+
"get": {
11+
"responses": {
12+
"200": {
13+
"description": "Products",
14+
"headers": {},
15+
"content": {},
16+
"links": {}
17+
}
18+
}
19+
}
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)