Skip to content

Commit d22ddfe

Browse files
authored
Forward schema warnings to diagnostics (#174)
Forward schema warnings to diagnostics ### Motivation OpenAPIKit emits warnings about parsed `JSONSchema` objects that could be helpful to adopters when debugging issues. Today, we are ignoring them. ### Modifications This PR forwards them into the diagnostics collector as warnings. ### Result When a schema is malformed in a way that OpenAPIKit still manages to parse it, but has issues, adopters will see these issues emitted as all other diagnostics we emit. ### Test Plan Added a unit test. Reviewed by: gjcairo Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #174
1 parent cb41d40 commit d22ddfe

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateSchema.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ extension FileTranslator {
7474

7575
let value = schema.value
7676

77+
// Attach any warnings from the parsed schema as a diagnostic.
78+
for warning in schema.warnings {
79+
diagnostics.emit(
80+
.warning(
81+
message: "Schema warning: \(warning.description)",
82+
context: [
83+
"codingPath": warning.codingPathString ?? "<none>",
84+
"contextString": warning.contextString ?? "<none>",
85+
"subjectName": warning.subjectName ?? "<none>",
86+
]
87+
)
88+
)
89+
}
90+
7791
// If this type maps to a referenceable schema, define a typealias
7892
if let builtinType = try typeMatcher.tryMatchReferenceableType(for: schema) {
7993
let typealiasDecl = try translateTypealias(

Tests/OpenAPIGeneratorCoreTests/TestUtilities.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,14 @@ func newTypeName(swiftFQName: String, jsonFQName: String) throws -> TypeName {
189189
.map(TypeName.Component.init)
190190
)
191191
}
192+
193+
/// A diagnostic collector that accumulates all received diagnostics into
194+
/// an array.
195+
final class AccumulatingDiagnosticCollector: DiagnosticCollector {
196+
197+
private(set) var diagnostics: [Diagnostic] = []
198+
199+
func emit(_ diagnostic: Diagnostic) {
200+
diagnostics.append(diagnostic)
201+
}
202+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftOpenAPIGenerator open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
import XCTest
15+
import OpenAPIKit30
16+
import Yams
17+
@testable import _OpenAPIGeneratorCore
18+
19+
class Test_translateSchemas: Test_Core {
20+
21+
func testSchemaWarningsForwardedToGeneratorDiagnostics() throws {
22+
let typeName = TypeName(swiftKeyPath: ["Foo"])
23+
24+
let schemaWithWarnings = try YAMLDecoder()
25+
.decode(
26+
JSONSchema.self,
27+
from: #"""
28+
type: string
29+
items:
30+
type: integer
31+
"""#
32+
)
33+
34+
let cases: [(JSONSchema, [String])] = [
35+
(.string, []),
36+
37+
(
38+
schemaWithWarnings,
39+
[
40+
"warning: Schema warning: Inconsistency encountered when parsing `OpenAPI Schema`: Found schema attributes not consistent with the type specified: string. Specifically, attributes for these other types: [\"array\"]. [context: codingPath=, contextString=, subjectName=OpenAPI Schema]"
41+
]
42+
),
43+
]
44+
45+
for (schema, diagnosticDescriptions) in cases {
46+
let collector = AccumulatingDiagnosticCollector()
47+
let translator = makeTranslator(diagnostics: collector)
48+
_ = try translator.translateSchema(
49+
typeName: typeName,
50+
schema: schema,
51+
overrides: .none
52+
)
53+
XCTAssertEqual(collector.diagnostics.map(\.description), diagnosticDescriptions)
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)