Repository: swagger-api/swagger-parser
Pull request #726 (2018-05-29 08:16:24)

fixing relative references
refs #727 


Patch:
diff --git a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
index 5e312ec2..26c0b5b4 100644
--- a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
+++ b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java
@@ -143,7 +143,9 @@ public class SwaggerConverter implements SwaggerParserExtension {
             openAPI.setExternalDocs(convert(swagger.getExternalDocs()));
         }
 
-        openAPI.setInfo(convert(swagger.getInfo()));
+        if (swagger.getInfo() != null) {
+            openAPI.setInfo(convert(swagger.getInfo()));
+        }
 
         openAPI.setServers(convert(swagger.getSchemes(), swagger.getHost(), swagger.getBasePath()));
 
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java
index 0e6c3312..a7dcca31 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java
@@ -203,6 +203,17 @@ public class OpenAPIDeserializer {
         return openAPI;
     }
 
+    public String mungedRef(String refString) {
+        // Ref: IETF RFC 3966, Section 5.2.2
+        if (!refString.contains(":") &&   // No scheme
+                !refString.startsWith("#") && // Path is not empty
+                !refString.startsWith("/") && // Path is not absolute
+                refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension)
+            return "./" + refString;
+        }
+        return null;
+    }
+
     public Map<String,Object> getExtensions(ObjectNode node){
 
         Map<String,Object> extensions = new LinkedHashMap<>();
@@ -531,8 +542,13 @@ public class OpenAPIDeserializer {
             JsonNode ref = obj.get("$ref");
 
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                pathItem.set$ref(ref.asText());
-                return pathItem.$ref((ref.asText()));
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    pathItem.set$ref(mungedRef);
+                }else{
+                    pathItem.set$ref(ref.textValue());
+                }
+                return pathItem;
             } else if (ref.getNodeType().equals(JsonNodeType.OBJECT)) {
                 ObjectNode node = (ObjectNode) ref;
 
@@ -1005,8 +1021,14 @@ public class OpenAPIDeserializer {
         JsonNode ref = linkNode.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                link.set$ref(ref.asText());
-                return link.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    link.set$ref(mungedRef);
+                }else{
+                    link.set$ref(ref.textValue());
+                }
+
+                return link;
             } else {
                 result.invalidType(location, "$ref", "string", linkNode);
                 return null;
@@ -1101,7 +1123,13 @@ public class OpenAPIDeserializer {
                 if (ref != null) {
                     if (ref.getNodeType().equals(JsonNodeType.STRING)) {
                         PathItem pathItem = new PathItem();
-                        return callback.addPathItem(name,pathItem.$ref(ref.asText()));
+                        String mungedRef = mungedRef(ref.textValue());
+                        if (mungedRef != null) {
+                            pathItem.set$ref(mungedRef);
+                        }else{
+                            pathItem.set$ref(ref.textValue());
+                        }
+                        return callback.addPathItem(name,pathItem);
                     } else {
                         result.invalidType(location, "$ref", "string", node);
                         return null;
@@ -1295,8 +1323,13 @@ public class OpenAPIDeserializer {
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
                 parameter = new Parameter();
-                parameter.set$ref(ref.asText());
-                return parameter.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    parameter.set$ref(mungedRef);
+                }else{
+                    parameter.set$ref(ref.textValue());
+                }
+                return parameter;
             } else {
                 result.invalidType(location, "$ref", "string", obj);
                 return null;
@@ -1451,8 +1484,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = headerNode.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                header.set$ref(ref.asText());
-                return header.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    header.set$ref(mungedRef);
+                }else{
+                    header.set$ref(ref.textValue());
+                }
+                return header;
             } else {
                 result.invalidType(location, "$ref", "string", headerNode);
                 return null;
@@ -1586,8 +1624,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = node.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                securityScheme.set$ref(ref.asText());
-                return securityScheme.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    securityScheme.set$ref(mungedRef);
+                }else{
+                    securityScheme.set$ref(ref.textValue());
+                }
+                return securityScheme;
             } else {
                 result.invalidType(location, "$ref", "string", node);
                 return null;
@@ -1892,8 +1935,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = node.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                schema.set$ref(ref.asText());
-                return schema.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    schema.set$ref(mungedRef);
+                }else{
+                    schema.set$ref(ref.asText());
+                }
+                return schema;
             } else {
                 result.invalidType(location, "$ref", "string", node);
                 return null;
@@ -2192,8 +2240,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = node.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                example.set$ref(ref.asText());
-                return example.$ref((ref.asText()));
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    example.set$ref(mungedRef);
+                }else{
+                    example.set$ref(ref.textValue());
+                }
+                return example;
             } else {
                 result.invalidType(location, "$ref", "string", node);
                 return null;
@@ -2303,8 +2356,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = node.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                 apiResponse.set$ref(ref.asText());
-                 return apiResponse.$ref((ref.asText()));
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    apiResponse.set$ref(mungedRef);
+                }else{
+                    apiResponse.set$ref(ref.textValue());
+                }
+                 return apiResponse;
             } else {
                 result.invalidType(location, "$ref", "string", node);
                 return null;
@@ -2528,8 +2586,13 @@ public class OpenAPIDeserializer {
         JsonNode ref = node.get("$ref");
         if (ref != null) {
             if (ref.getNodeType().equals(JsonNodeType.STRING)) {
-                body.set$ref(ref.asText());
-                return body.$ref(ref.asText());
+                String mungedRef = mungedRef(ref.textValue());
+                if (mungedRef != null) {
+                    body.set$ref(mungedRef);
+                }else{
+                    body.set$ref(ref.textValue());
+                }
+                return body;
             } else {
                 result.invalidType(location, "$ref", "string", node);
                 return null;
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java
index 5eb3f582..72ac186b 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/PathUtils.java
@@ -1,21 +1,36 @@
 package io.swagger.v3.parser.util;
 
 import java.net.URI;
+import java.net.URL;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
 public class PathUtils {
 
 
-    public static Path getParentDirectoryOfFile(String fileStr) {
-        final String fileScheme = "file:";
-        Path file;
-        fileStr = fileStr.replaceAll("\\\\","/");
-        if (fileStr.toLowerCase().startsWith(fileScheme)) {
-            file = Paths.get(URI.create(fileStr)).toAbsolutePath();
-        } else {
-            file = Paths.get(fileStr).toAbsolutePath();
+    public static Path getParentDirectoryOfFile(String location) {
+        Path file = null;
+        try {
+            location = location.replaceAll("\\\\","/");
+            final String fileScheme = "file:";
+            if (location.toLowerCase().startsWith(fileScheme)) {
+                file = Paths.get(URI.create(location)).toAbsolutePath();
+            } else {
+                file = Paths.get(location).toAbsolutePath();
+            }
+            if (!Files.exists(file)) {
+                URL url = PathUtils.class.getClassLoader().getResource(location);
+                file = Paths.get((URI.create(url.toExternalForm())));
+                return file.getParent();
+            }
+
+
+
+        } catch (Exception e) {
+            e.getMessage();
         }
+
         return file.toAbsolutePath().getParent();
     }
 }
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java
index 66380cea..9c0d8c31 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/RefUtils.java
@@ -49,7 +49,8 @@ public class RefUtils {
 
     public static RefFormat computeRefFormat(String ref) {
         RefFormat result = RefFormat.INTERNAL;
-        if(ref.startsWith("http")) {
+        ref = mungedRef(ref);
+        if(ref.startsWith("http")||ref.startsWith("https")) {
             result = RefFormat.URL;
         } else if(ref.startsWith("#/")) {
             result = RefFormat.INTERNAL;
@@ -60,6 +61,18 @@ public class RefUtils {
         return result;
     }
 
+    public static String mungedRef(String refString) {
+        // Ref: IETF RFC 3966, Section 5.2.2
+        if (!refString.contains(":") &&   // No scheme
+                !refString.startsWith("#") && // Path is not empty
+                !refString.startsWith("/") && // Path is not absolute
+                !refString.contains("$") &&
+                refString.indexOf(".") > 0) { // Path does not start with dot but contains "." (file extension)
+            return "./" + refString;
+        }
+        return refString;
+    }
+
 
     public static String readExternalUrlRef(String file, RefFormat refFormat, List<AuthorizationValue> auths,
                                             String rootPath) {
@@ -136,13 +149,11 @@ public class RefUtils {
             throw new RuntimeException("Ref is not external");
         }
 
-        String result;
+        String result = null;
 
         try {
             if (refFormat == RefFormat.URL) {
-
                 result = RemoteUrl.urlToString(file, auths);
-
             } else {
                 //its assumed to be a relative file ref
                 final Path pathToUse = parentDirectory.resolve(file).normalize();
@@ -150,13 +161,26 @@ public class RefUtils {
                 if(Files.exists(pathToUse)) {
                     result = IOUtils.toString(new FileInputStream(pathToUse.toFile()), "UTF-8");
                 } else {
+                    String url = file;
+                    if(url.contains("..")) {
+                        url = parentDirectory + url.substring(url.indexOf(".") + 2);
+                    }else{
+                        url = parentDirectory + url.substring(url.indexOf(".") + 1);
+                    }
+                    final Path pathToUse2 = parentDirectory.resolve(url).normalize();
+
+                    if(Files.exists(pathToUse2)) {
+                        result = IOUtils.toString(new FileInputStream(pathToUse2.toFile()), "UTF-8");
+                    }
+                }
+                if (result == null){
                     result = ClasspathHelper.loadFileFromClasspath(file);
                 }
 
+
             }
         } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException("Unable to load " + refFormat + " ref: " + file, e);
+            throw new RuntimeException("Unable to load " + refFormat + " ref: " + file + " path: "+parentDirectory, e);
         }
 
         return result;


Test patch:
diff --git a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
index 99381a72..f6cfc58f 100644
--- a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
+++ b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java
@@ -79,6 +79,7 @@ public class V2ConverterTest {
     private static final String ISSUE_673_YAML = "issue-673.yaml";
     private static final String ISSUE_676_JSON = "issue-676.json";
     private static final String ISSUE_708_YAML = "issue-708.yaml";
+    private static final String ISSUE_755_YAML = "issue-755.yaml";
     private static final String ISSUE_740_YAML = "issue-740.yaml";
     private static final String ISSUE_756_JSON = "issue-756.json";
     private static final String ISSUE_758_JSON = "issue-758.json";
@@ -86,6 +87,7 @@ public class V2ConverterTest {
     private static final String ISSUE_765_YAML = "issue-765.yaml";
     private static final String ISSUE_768_JSON = "issue-786.json";
 
+
     private static final String API_BATCH_PATH = "/api/batch/";
     private static final String PETS_PATH = "/pets";
     private static final String PET_FIND_BY_STATUS_PATH = "/pet/findByStatus";
@@ -704,12 +706,20 @@ public class V2ConverterTest {
         assertNotNull(result.getMessages());
     }
 
+    
     @Test(description = "OpenAPI v2 converter - Migrate minLength, maxLength and pattern of String property")
     public void testIssue786() throws Exception {
         final OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_768_JSON);
         assertNotNull(oas);
     }
 
+
+    @Test(description = "OpenAPI v2 converter - Conversion of a spec without a info section")
+    public void testIssue755() throws Exception {
+        final OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_755_YAML);
+        assertNotNull(oas);
+    }
+
     private OpenAPI getConvertedOpenAPIFromJsonFile(String file) throws IOException, URISyntaxException {
         SwaggerConverter converter = new SwaggerConverter();
         String swaggerAsString = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource(file).toURI())));
diff --git a/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml b/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml
new file mode 100644
index 00000000..083ba6ee
--- /dev/null
+++ b/modules/swagger-parser-v2-converter/src/test/resources/issue-755.yaml
@@ -0,0 +1,14 @@
+swagger: '2.0'
+host: petstore.swagger.io
+basePath: /v2
+schemes:
+  - http
+paths:
+  /ping:
+    post:
+      summary: test
+      description: 'test it'
+      operationId: pingOp
+      responses:
+        '200':
+          description: OK
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
index 92a7bd9f..145b3593 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
@@ -72,15 +72,25 @@ public class OpenAPIV3ParserTest {
         OpenAPIV3Parser parser = new OpenAPIV3Parser();
         ParseOptions options = new ParseOptions();
         options.setResolve(true);
-        options.setResolveCombinators(false);
-        options.setResolveFully(true);
 
-        String location = getClass().getResource("/odin.yaml").toString();
-        Assert.assertNotNull(location);
-        final SwaggerParseResult result = parser.readLocation(location, null, options);
+        final SwaggerParseResult result = parser.readLocation("src/test/resources/sample/SwaggerPetstore.yaml", null, options);
         Assert.assertNotNull(result.getOpenAPI());
         Assert.assertTrue(result.getMessages().isEmpty());
-        Assert.assertTrue(result.getOpenAPI().getPaths().get("/JTasker/startRun").getPost().getRequestBody().getContent().get("application/json").getSchema().getProperties().size() == 2);
+        Assert.assertNotNull(result.getOpenAPI().getPaths().get("/pets").getGet());
+    }
+
+    @Test
+    public void issueRelativeRefs2() throws Exception {
+        OpenAPIV3Parser parser = new OpenAPIV3Parser();
+        ParseOptions options = new ParseOptions();
+        options.setResolve(true);
+
+        final SwaggerParseResult result = parser.readLocation("src/test/resources/relative-upper-directory/swagger.yaml", null, options);
+        Assert.assertNotNull(result.getOpenAPI());
+        OpenAPI openAPI = result.getOpenAPI();
+        assertNotNull(openAPI.getPaths().get("/api/Address").getGet());
+        assertTrue(openAPI.getComponents().getSchemas().size() == 1);
+        assertNotNull(openAPI.getComponents().getSchemas().get("AddressEx"));
     }
 
     @Test
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/RefUtilsTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/RefUtilsTest.java
index 5463e98c..87d4b3ab 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/RefUtilsTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/RefUtilsTest.java
@@ -231,8 +231,10 @@ public class RefUtilsTest {
     public void testReadExternalRef_OnClasspath(@Mocked Files files,
                                                 @Mocked ClasspathHelper classpathHelper,
                                                 @Injectable final Path parentDirectory,
-                                                @Injectable final Path pathToUse) throws Exception {
+                                                @Injectable final Path pathToUse,
+                                                @Injectable final Path pathToUse2) throws Exception {
         final String filePath = "./path/to/file.json";
+        final String url = parentDirectory + "/path/to/file.json";
         final String expectedResult = "really good json";
 
         new StrictExpectations() {{
@@ -245,6 +247,14 @@ public class RefUtilsTest {
             times = 1;
             result = false;
 
+            parentDirectory.resolve(url).normalize();
+            times = 1;
+            result = pathToUse2;
+
+            Files.exists(pathToUse2);
+            times = 1;
+            result = false;
+
             ClasspathHelper.loadFileFromClasspath(filePath); times=1; result=expectedResult;
 
         }};
diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json
index c1f9b469..d85c4e56 100644
--- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json
+++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/purebred_pet.json
@@ -1,7 +1,7 @@
 {
   "allOf": [
     {
-      "$ref": "./pet.json"
+      "$ref": "pet.json"
     },
     {
       "type": "object",
@@ -11,12 +11,12 @@
           "sample": "Labrador"
         },
         "mother": {
-          "$ref": "./pet.json"
+          "$ref": "pet.json"
         },
         "siblings": {
           "type": "array",
           "items": {
-            "$ref": "./pet.json"
+            "$ref": "pet.json"
           }
         }
       }
diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json
index d5c22108..dfbbdc61 100644
--- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json
+++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/models/swagger.json
@@ -7,7 +7,7 @@
 	"components": {
 		"schemas": {
 			"record": {
-				"$ref": "./purebred_pet.json"
+				"$ref": "purebred_pet.json"
 			}
 		}
 	}
diff --git a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json
index a5bc7e96..295e41d3 100644
--- a/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json
+++ b/modules/swagger-parser-v3/src/test/resources/allOf-properties-ext-ref/swagger.json
@@ -7,7 +7,7 @@
 	"components": {
 		"schemas": {
 			"record": {
-				"$ref": "./models/purebred_pet.json"
+				"$ref": "models/purebred_pet.json"
 			}
 		}
 	}
diff --git a/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Paths/Address.yaml b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Paths/Address.yaml
new file mode 100644
index 00000000..9d9a282e
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Paths/Address.yaml
@@ -0,0 +1,66 @@
+get:
+  tags:
+    - Address
+  operationId: Address_Get
+  responses:
+    '200':
+      description: OK
+      content:
+        application/json:
+          schema:
+            type: array
+            items:
+              $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        text/json:
+          schema:
+            type: array
+            items:
+              $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        application/xml:
+          schema:
+            type: array
+            items:
+              $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        text/xml:
+          schema:
+            type: array
+            items:
+              $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+post:
+  tags:
+    - Address
+  operationId: Address_Post
+  responses:
+    '200':
+      description: OK
+      content:
+        application/json:
+          schema:
+            $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        text/json:
+          schema:
+            $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        application/xml:
+          schema:
+            $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+        text/xml:
+          schema:
+            $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+  requestBody:
+    content:
+      application/json:
+        schema:
+          $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+      text/json:
+        schema:
+          $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+      application/xml:
+        schema:
+          $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+      text/xml:
+        schema:
+          $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+      application/x-www-form-urlencoded:
+        schema:
+          $ref: "../Schemas/schema.yaml#/definitions/AddressEx"
+    required: true
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Schemas/schema.yaml b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Schemas/schema.yaml
new file mode 100644
index 00000000..cb3f00b7
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/Schemas/schema.yaml
@@ -0,0 +1,24 @@
+definitions:
+  AddressEx:
+    type: object
+    properties:
+      Type:
+        enum:
+        - Residential
+        - Business
+        type: string
+      Street:
+        type: string
+      City:
+        type: string
+      State:
+        type: string
+  Address:
+    type: object
+    properties:
+      Street:
+        type: string
+      City:
+        type: string
+      State:
+        type: string
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml
new file mode 100644
index 00000000..91e0edbc
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/relative-upper-directory/swagger.yaml
@@ -0,0 +1,11 @@
+openapi: 3.0.0
+servers:
+  - url: 'http://paeshin-w7/SwaggerTest'
+  - url: 'https://paeshin-w7/SwaggerTest'
+info:
+  version: v1
+  title: SwaggerTest
+  description: Service for Swagger and JSON schema testing
+paths:
+  /api/Address:
+    $ref: "Paths/Address.yaml"
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/sample/SwaggerPetstore.yaml b/modules/swagger-parser-v3/src/test/resources/sample/SwaggerPetstore.yaml
new file mode 100755
index 00000000..98c27939
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/sample/SwaggerPetstore.yaml
@@ -0,0 +1,63 @@
+openapi: "3.0.0"
+info:
+  version: 1.0.0
+  title: Swagger Petstore
+  description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
+  termsOfService: http://swagger.io/terms/
+  contact:
+    name: Swagger API Team
+    email: apiteam@swagger.io
+    url: http://swagger.io
+  license:
+    name: Apache 2.0
+    url: https://www.apache.org/licenses/LICENSE-2.0.html
+servers:
+  - url: http://petstore.swagger.io/api
+paths:
+  /pets:
+    $ref: 'pets.yaml'
+  /pets/{id}:
+    get:
+      description: Returns a user based on a single ID, if the user does not have access to the pet
+      operationId: find pet by id
+      parameters:
+        - name: id
+          in: path
+          description: ID of pet to fetch
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '200':
+          description: pet response
+          content:
+            application/json:
+              schema:
+                $ref: 'schema.yaml#/components/schemas/Pet'
+        default:
+          description: unexpected error
+          content:
+            application/json:
+              schema:
+                $ref: 'schema.yaml#/components/schemas/Error'
+    delete:
+      description: deletes a single pet based on the ID supplied
+      operationId: deletePet
+      parameters:
+        - name: id
+          in: path
+          description: ID of pet to delete
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '204':
+          description: pet deleted
+        default:
+          description: unexpected error
+          content:
+            application/json:
+              schema:
+                $ref: 'schema.yaml#/components/schemas/Error'
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/sample/pets.yaml b/modules/swagger-parser-v3/src/test/resources/sample/pets.yaml
new file mode 100755
index 00000000..5dd0f4d2
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/sample/pets.yaml
@@ -0,0 +1,62 @@
+get:
+  description: |
+    Returns all pets from the system that the user has access to
+    Nam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia.
+    
+    Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien.
+  operationId: findPets
+  parameters:
+    - name: tags
+      in: query
+      description: tags to filter by
+      required: false
+      style: form
+      schema: 
+        type: array
+        items:
+          type: string
+    - name: limit
+      in: query
+      description: maximum number of results to return
+      required: false
+      schema:
+        type: integer
+        format: int32
+  responses:
+    '200':
+      description: pet response
+      content:
+        application/json:
+           schema:
+              type: array
+              items:
+                $ref: 'schema.yaml#/components/schemas/Pet'
+    default:
+      description: unexpected error
+      content:
+        application/json:
+          schema:
+            $ref: 'schema.yaml#/components/schemas/Error'
+post:
+  description: Creates a new pet in the store.  Duplicates are allowed
+  operationId: addPet
+  requestBody:
+    description: Pet to add to the store
+    required: true
+    content:
+      application/json:
+        schema:
+          $ref: 'schema.yaml#/components/schemas/NewPet'
+  responses:
+    '200':
+      description: pet response
+      content:
+        application/json:
+          schema:
+            $ref: 'schema.yaml#/components/schemas/Pet'
+    default:
+      description: unexpected error
+      content:
+        application/json:
+          schema:
+            $ref: 'schema.yaml#/components/schemas/Error'
\ No newline at end of file
diff --git a/modules/swagger-parser-v3/src/test/resources/sample/schema.yaml b/modules/swagger-parser-v3/src/test/resources/sample/schema.yaml
new file mode 100755
index 00000000..a367d1b2
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/sample/schema.yaml
@@ -0,0 +1,31 @@
+components:
+  schemas:
+    Pet:
+      allOf:
+        - $ref: '#/components/schemas/NewPet'
+        - required:
+          - id
+          properties:
+            id:
+              type: integer
+              format: int64
+
+    NewPet:
+      required:
+        - name  
+      properties:
+        name:
+          type: string
+        tag:
+          type: string    
+
+    Error:
+      required:
+        - code
+        - message
+      properties:
+        code:
+          type: integer
+          format: int32
+        message:
+          type: string
\ No newline at end of file