Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0a759fe
Create PR
SOHELAHMED7 Jul 10, 2025
d40a157
Add dependency
SOHELAHMED7 Aug 21, 2025
b240bad
Setup mock web server lib
SOHELAHMED7 Aug 21, 2025
1833ef6
Attempt to fix failing CI for Windows
SOHELAHMED7 Aug 22, 2025
f1b10c6
Attempt 2
SOHELAHMED7 Aug 22, 2025
7398f5d
Run again
SOHELAHMED7 Aug 23, 2025
7bb4ca8
again
SOHELAHMED7 Aug 23, 2025
21632e2
Add test
SOHELAHMED7 Aug 23, 2025
f780954
Attempt to fix Windows CI
SOHELAHMED7 Aug 23, 2025
a09b8bc
Check if CI for Windows runs without this particular test
SOHELAHMED7 Aug 23, 2025
76c43d1
Attempt
SOHELAHMED7 Aug 25, 2025
c6a07f1
Attempt 2
SOHELAHMED7 Aug 25, 2025
2d58a22
Attempt 3
SOHELAHMED7 Aug 25, 2025
52372c7
Replace mockwebserver lib with custom implemention for Windows support
SOHELAHMED7 Aug 25, 2025
241df9f
Use `setUpBeforeClass()`
SOHELAHMED7 Aug 26, 2025
c5fd30e
Attempt using nohup/start-process instead of donatj/mock-webserver
SOHELAHMED7 Aug 26, 2025
9c8ba08
Fix for windows
SOHELAHMED7 Aug 26, 2025
c03bbf5
Fix for windows - attempt 2
SOHELAHMED7 Aug 26, 2025
1697bef
Fix for windows - attempt 3
SOHELAHMED7 Aug 26, 2025
40e6da0
Cleanup
SOHELAHMED7 Aug 26, 2025
0f69e6b
Polish
SOHELAHMED7 Aug 26, 2025
0c1fdb3
Discard redundant stdout messages
SOHELAHMED7 Aug 28, 2025
ad507a5
Add comment
SOHELAHMED7 Aug 28, 2025
7c62d7d
Discard redundant stdout messages - attempt 2
SOHELAHMED7 Aug 28, 2025
d5c690a
Discard redundant stdout messages - attempt 3
SOHELAHMED7 Aug 28, 2025
b91e163
Discard redundant stdout messages - attempt 4
SOHELAHMED7 Aug 28, 2025
cad33f0
Discard redundant stdout messages - attempt 5
SOHELAHMED7 Aug 28, 2025
c91f9a5
Revert
SOHELAHMED7 Aug 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions tests/data/issue/236/base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

openapi: 3.0.0
info:
title: Link Example
version: 1.0.0
components:
schemas:
Pet:
$ref: definitions.yaml#/Pet
Dog:
$ref: ##ABSOLUTEPATH##/definitions.yaml#/Dog
paths:
'/pet':
get:
responses:
200:
description: return a pet
12 changes: 12 additions & 0 deletions tests/data/issue/236/definitions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

Pet:
type: object
properties:
id:
type: integer
format: int64
Dog:
type: object
properties:
name:
type: string
50 changes: 34 additions & 16 deletions tests/spec/ReferenceTest.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<?php

use cebe\openapi\Reader;
use cebe\openapi\ReferenceContext;
use cebe\openapi\spec\Example;
use cebe\openapi\spec\OpenApi;
use cebe\openapi\spec\Parameter;
use cebe\openapi\spec\Reference;
use cebe\openapi\spec\RequestBody;
use cebe\openapi\spec\Response;
use cebe\openapi\spec\Schema;
use cebe\openapi\spec\Example;

/**
* @covers \cebe\openapi\spec\Reference
Expand Down Expand Up @@ -66,7 +67,7 @@ public function testResolveInDocument()
$this->assertInstanceOf(Reference::class, $petResponse->content['application/json']->examples['frog']);
$this->assertInstanceOf(Reference::class, $openapi->paths->getPath('/pet/1')->get->responses['200']);

$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));
$openapi->resolveReferences(new ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));

$this->assertInstanceOf(Schema::class, $refSchema = $petResponse->content['application/json']->schema);
$this->assertInstanceOf(Example::class, $refExample = $petResponse->content['application/json']->examples['frog']);
Expand Down Expand Up @@ -125,7 +126,7 @@ public function testResolveCyclicReferenceInDocument()
$this->assertInstanceOf(Reference::class, $response->content['application/json']->examples['frog']);

// $this->expectException(\cebe\openapi\exceptions\UnresolvableReferenceException::class);
$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));
$openapi->resolveReferences(new ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));

$this->assertInstanceOf(Schema::class, $petItems = $openapi->components->schemas['Pet']->properties['id']->items);
$this->assertInstanceOf(Schema::class, $refSchema = $response->content['application/json']->schema);
Expand Down Expand Up @@ -160,7 +161,7 @@ public function testResolveFile()
$this->assertInstanceOf(Reference::class, $petItems = $openapi->components->schemas['Pet']);
$this->assertInstanceOf(Reference::class, $petItems = $openapi->components->schemas['Dog']);

$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, $file));
$openapi->resolveReferences(new ReferenceContext($openapi, $file));

$this->assertInstanceOf(Schema::class, $petItems = $openapi->components->schemas['Pet']);
$this->assertInstanceOf(Schema::class, $petItems = $openapi->components->schemas['Dog']);
Expand Down Expand Up @@ -189,7 +190,7 @@ public function testResolveFileInSubdir()
$this->assertInstanceOf(Reference::class, $openapi->components->schemas['Dog']);
$this->assertInstanceOf(Reference::class, $openapi->components->parameters['Parameter.PetId']);

$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, $file));
$openapi->resolveReferences(new ReferenceContext($openapi, $file));

$this->assertInstanceOf(Schema::class, $openapi->components->schemas['Pet']);
$this->assertInstanceOf(Schema::class, $openapi->components->schemas['Dog']);
Expand Down Expand Up @@ -233,7 +234,21 @@ public function testResolveFileInSubdirWithMultipleRelativePaths()

public function testResolveFileHttp()
{
$file = 'https://raw.githubusercontent.com/cebe/php-openapi/290389bbd337cf4d70ecedfd3a3d886715e19552/tests/spec/data/reference/base.yaml';
$host = 'localhost:8787'; # create mock web server to avoid calling real GitHub URL and rate limit hit
// $file = 'https://raw.githubusercontent.com/cebe/php-openapi/290389bbd337cf4d70ecedfd3a3d886715e19552/tests/spec/data/reference/base.yaml';
if (stripos(PHP_OS_FAMILY, 'Windows') !== false) {
$cmd = 'powershell -Command "Start-Process php -ArgumentList \'-S '.$host.'\' -NoNewWindow"';
$res = popen($cmd, "r");
} else {
exec('nohup php -S '.$host.' > /dev/null 2>&1 &');
}
// ENH: turn off the server
// ENH: avoid displaying stdout in CI while starting the server
sleep(2);

// $path = '/cebe/php-openapi/290389bbd337cf4d70ecedfd3a3d886715e19552/tests/spec/data/reference/base.yaml';
$path = '/tests/data/issue/236/base.yaml';
$file = 'http://' . $host . $path;
/** @var $openapi OpenApi */
$openapi = Reader::readFromYaml(str_replace('##ABSOLUTEPATH##', dirname($file), file_get_contents($file)));

Expand All @@ -244,12 +259,16 @@ public function testResolveFileHttp()
$this->assertInstanceOf(Reference::class, $petItems = $openapi->components->schemas['Pet']);
$this->assertInstanceOf(Reference::class, $petItems = $openapi->components->schemas['Dog']);

$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, $file));
$openapi->resolveReferences(new ReferenceContext($openapi, $file));

$this->assertInstanceOf(Schema::class, $petItems = $openapi->components->schemas['Pet']);
$this->assertInstanceOf(Schema::class, $petItems = $openapi->components->schemas['Dog']);
$this->assertArrayHasKey('id', $openapi->components->schemas['Pet']->properties);
$this->assertArrayHasKey('name', $openapi->components->schemas['Dog']->properties);

if (isset($res) && is_resource($petItems)) {
pclose($res);
}
}

public function testResolvePaths()
Expand Down Expand Up @@ -312,7 +331,7 @@ enum:

YAML;
$openapi = Reader::readFromYaml($schema);
$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, $this->createFileUri(__DIR__ . '/data/reference/definitions.yaml')));
$openapi->resolveReferences(new ReferenceContext($openapi, $this->createFileUri(__DIR__ . '/data/reference/definitions.yaml')));

$this->assertTrue(isset($openapi->components->schemas['Pet']));
$this->assertEquals(['One', 'Two'], $openapi->components->schemas['Pet']->properties['typeA']->enum);
Expand Down Expand Up @@ -354,7 +373,7 @@ public function testTransitiveReference()
YAML;

$openapi = Reader::readFromYaml($schema);
$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));
$openapi->resolveReferences(new ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));

$this->assertTrue(isset($openapi->components->schemas['City']));
$this->assertTrue(isset($openapi->components->schemas['Named']));
Expand Down Expand Up @@ -393,7 +412,7 @@ public function testTransitiveReferenceToFile()
YAML;

$openapi = Reader::readFromYaml($schema);
$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, $this->createFileUri(__DIR__ . '/data/reference/definitions.yaml')));
$openapi->resolveReferences(new ReferenceContext($openapi, $this->createFileUri(__DIR__ . '/data/reference/definitions.yaml')));

$this->assertTrue(isset($openapi->components->schemas['Dog']));
$this->assertEquals('object', $openapi->components->schemas['Dog']->type);
Expand Down Expand Up @@ -431,12 +450,12 @@ public function testTransitiveReferenceCyclic()
$this->expectException(\cebe\openapi\exceptions\UnresolvableReferenceException::class);
$this->expectExceptionMessage('Cyclic reference detected on a Reference Object.');

$openapi->resolveReferences(new \cebe\openapi\ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));
$openapi->resolveReferences(new ReferenceContext($openapi, 'file:///tmp/openapi.yaml'));
}

public function testTransitiveReferenceOverTwoFiles()
{
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/structure.yaml', OpenApi::class, \cebe\openapi\ReferenceContext::RESOLVE_MODE_INLINE);
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/structure.yaml', OpenApi::class, ReferenceContext::RESOLVE_MODE_INLINE);

$yaml = \cebe\openapi\Writer::writeToYaml($openapi);

Expand Down Expand Up @@ -471,7 +490,7 @@ public function testTransitiveReferenceOverTwoFiles()

public function testReferencedCommonParamsInReferencedPath()
{
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/ReferencedCommonParamsInReferencedPath.yml', OpenApi::class, \cebe\openapi\ReferenceContext::RESOLVE_MODE_INLINE);
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/ReferencedCommonParamsInReferencedPath.yml', OpenApi::class, ReferenceContext::RESOLVE_MODE_INLINE);
$yaml = \cebe\openapi\Writer::writeToYaml($openapi);
$expected = <<<YAML
openapi: 3.0.0
Expand Down Expand Up @@ -536,7 +555,7 @@ enum:

public function testResolveRelativePathInline()
{
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/openapi_models.yaml', OpenApi::class, \cebe\openapi\ReferenceContext::RESOLVE_MODE_INLINE);
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/openapi_models.yaml', OpenApi::class, ReferenceContext::RESOLVE_MODE_INLINE);

$yaml = \cebe\openapi\Writer::writeToYaml($openapi);

Expand Down Expand Up @@ -589,7 +608,7 @@ public function testResolveRelativePathInline()

public function testResolveRelativePathAll()
{
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/openapi_models.yaml', OpenApi::class, \cebe\openapi\ReferenceContext::RESOLVE_MODE_ALL);
$openapi = Reader::readFromYamlFile(__DIR__ . '/data/reference/openapi_models.yaml', OpenApi::class, ReferenceContext::RESOLVE_MODE_ALL);

$yaml = \cebe\openapi\Writer::writeToYaml($openapi);

Expand Down Expand Up @@ -656,5 +675,4 @@ public function testResolveRelativePathAll()
$this->assertEquals($expected, $yaml, $yaml);
}
}

}
Loading