Skip to content

Commit 04772b5

Browse files
committed
Initial work and unit test.
1 parent 5f5aa1e commit 04772b5

File tree

3 files changed

+101
-2
lines changed

3 files changed

+101
-2
lines changed

src/definitions.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export class DefinitionRegistry {
120120
this.currentPath = [];
121121
this.client = client;
122122
this.#gatherDefinitions(map);
123+
this.#expandInheritanceChains();
123124
this.#expandReferences();
124125
}
125126

@@ -302,6 +303,7 @@ export class DefinitionRegistry {
302303
this.referenceStack = [];
303304
for (const [filepath, values] of collection.data.entries()) {
304305
for (const [key, value] of values.entries()) {
306+
console.log(key);
305307
this.currentPath.push(key);
306308
let expanded = this.#expand(value, key, filepath);
307309
collection.data.get(filepath)!.set(key, expanded);
@@ -417,9 +419,12 @@ export class DefinitionRegistry {
417419
this.data.securityDefinitions.add(path, name, data);
418420
}
419421
}
422+
}
423+
424+
#expandInheritanceChains() {
420425
// ensure each base class has a list of derived classes for use
421426
// when interpretting allOf.
422-
for (const [ref, set] of this.polymorphicMap.entries()) {
427+
for (const [ref, derived_set] of this.polymorphicMap.entries()) {
423428
const refResult = parseReference(ref);
424429
if (!refResult) {
425430
throw new Error(`Could not parse reference: ${ref}`);
@@ -429,7 +434,17 @@ export class DefinitionRegistry {
429434
this.logUnresolvedReference(ref);
430435
continue;
431436
}
432-
baseClass["$derivedClasses"] = Array.from(set);
437+
// check if refKey also has derived classes and combine them
438+
for (const derived of derived_set) {
439+
const derivedRef = parseReference(derived)!.expandedRef;
440+
const match = this.polymorphicMap.get(derivedRef);
441+
if (match !== undefined) {
442+
for (const item of match) {
443+
derived_set.add(item);
444+
}
445+
}
446+
}
447+
baseClass["$derivedClasses"] = Array.from(derived_set);
433448
}
434449
}
435450

test/definition-registry.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,24 @@ it("should ignore example references", async () => {
158158
expect(ref.includes("examples")).toBe(false);
159159
}
160160
});
161+
162+
it("expands inheritance chains", async () => {
163+
const config: DiffClientConfig = {
164+
lhs: ["test/files/inheritanceChain.json"],
165+
rhs: ["test/files/inheritanceChain.json"],
166+
args: {},
167+
rules: getApplicableRules({}),
168+
};
169+
const client = await TestableDiffClient.create(config);
170+
client.parse();
171+
const [parser, _] = client.getParsers();
172+
const defRegistry = getDefinitionRegistry(parser).getCollection(
173+
RegistryKind.Definition
174+
);
175+
let filePath = Object.keys(defRegistry)[0];
176+
let quad = defRegistry[filePath].get("Quadrilateral");
177+
let expected_properties = ["length", "width", "sides", "name"];
178+
for (const prop of expected_properties) {
179+
expect(quad.properties).toHaveProperty(prop);
180+
}
181+
});

test/files/inheritanceChain.json

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"title": "(title)",
5+
"version": "0000-00-00",
6+
"x-typespec-generated": [
7+
{
8+
"emitter": "@azure-tools/typespec-autorest"
9+
}
10+
]
11+
},
12+
"schemes": ["https"],
13+
"produces": ["application/json"],
14+
"consumes": ["application/json"],
15+
"tags": [],
16+
"paths": {},
17+
"definitions": {
18+
"Polygon": {
19+
"type": "object",
20+
"properties": {
21+
"sides": {
22+
"type": "integer",
23+
"format": "int16"
24+
}
25+
},
26+
"required": ["sides"],
27+
"allOf": [
28+
{
29+
"$ref": "#/definitions/Shape"
30+
}
31+
]
32+
},
33+
"Quadrilateral": {
34+
"type": "object",
35+
"properties": {
36+
"length": {
37+
"type": "integer",
38+
"format": "int16"
39+
},
40+
"width": {
41+
"type": "integer",
42+
"format": "int16"
43+
}
44+
},
45+
"required": ["length", "width"],
46+
"allOf": [
47+
{
48+
"$ref": "#/definitions/Polygon"
49+
}
50+
]
51+
},
52+
"Shape": {
53+
"type": "object",
54+
"properties": {
55+
"name": {
56+
"type": "string"
57+
}
58+
},
59+
"required": ["name"]
60+
}
61+
},
62+
"parameters": {}
63+
}

0 commit comments

Comments
 (0)