Skip to content

Commit 7e633a4

Browse files
Fix OpenAPIKit compatibility issues and clean up codebase
1 parent b6b7e51 commit 7e633a4

File tree

7 files changed

+681
-323
lines changed

7 files changed

+681
-323
lines changed

Sources/OpenAPItoSymbolGraph.swift

Lines changed: 311 additions & 193 deletions
Large diffs are not rendered by default.

Sources/SymbolMapping.swift

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,62 +24,89 @@ struct SymbolMapper {
2424
static func mapSchemaType(_ schema: OpenAPIKit.JSONSchema) -> (type: String, documentation: String) {
2525
var documentation = ""
2626

27-
// Add format information if available
28-
if let format = schema.formatString {
27+
// Add format information if available - only when non-empty
28+
if let format = schema.formatString, !format.isEmpty {
2929
documentation += "Format: \(format)\n"
3030
}
3131

3232
// Handle specific schema contexts based on jsonType
3333
if let jsonType = schema.jsonType {
3434
switch jsonType {
3535
case .string:
36-
if let stringContext = schema.stringContext {
37-
if let pattern = stringContext.pattern {
36+
if let stringSchema = schema.stringContext {
37+
if let pattern = stringSchema.pattern {
3838
documentation += "Pattern: \(pattern)\n"
3939
}
40-
documentation += "Minimum length: \(stringContext.minLength)\n"
41-
if let maxLength = stringContext.maxLength {
40+
// Only add minLength if it's not the default value (0)
41+
if stringSchema.minLength > 0 {
42+
documentation += "Minimum length: \(stringSchema.minLength)\n"
43+
}
44+
if let maxLength = stringSchema.maxLength {
4245
documentation += "Maximum length: \(maxLength)\n"
4346
}
4447
}
4548

4649
case .number:
47-
if let numericContext = schema.numberContext {
48-
if let minimum = numericContext.minimum {
49-
documentation += "Minimum value: \(minimum.value)\(minimum.exclusive ? " (exclusive)" : "")\n"
50+
if let numContext = schema.numberContext {
51+
if let minimum = numContext.minimum {
52+
// Format without decimal points for whole numbers
53+
let minValue = minimum.value
54+
let formattedMin = minValue.truncatingRemainder(dividingBy: 1) == 0 ?
55+
String(format: "%.0f", minValue) : String(minValue)
56+
documentation += "Minimum value: \(formattedMin)\(minimum.exclusive ? " (exclusive)" : "")\n"
5057
}
51-
if let maximum = numericContext.maximum {
52-
documentation += "Maximum value: \(maximum.value)\(maximum.exclusive ? " (exclusive)" : "")\n"
58+
if let maximum = numContext.maximum {
59+
// Format without decimal points for whole numbers
60+
let maxValue = maximum.value
61+
let formattedMax = maxValue.truncatingRemainder(dividingBy: 1) == 0 ?
62+
String(format: "%.0f", maxValue) : String(maxValue)
63+
documentation += "Maximum value: \(formattedMax)\(maximum.exclusive ? " (exclusive)" : "")\n"
5364
}
54-
if let multipleOf = numericContext.multipleOf {
55-
documentation += "Must be multiple of: \(multipleOf)\n"
65+
if let multipleOf = numContext.multipleOf {
66+
// Format without decimal points for whole numbers
67+
let formattedMultiple = multipleOf.truncatingRemainder(dividingBy: 1) == 0 ?
68+
String(format: "%.0f", multipleOf) : String(multipleOf)
69+
documentation += "Must be multiple of: \(formattedMultiple)\n"
5670
}
5771
}
5872

5973
case .integer:
60-
if let integerContext = schema.integerContext {
61-
if let minimum = integerContext.minimum {
74+
if let intContext = schema.integerContext {
75+
if let minimum = intContext.minimum {
6276
documentation += "Minimum value: \(minimum.value)\(minimum.exclusive ? " (exclusive)" : "")\n"
6377
}
64-
if let maximum = integerContext.maximum {
78+
if let maximum = intContext.maximum {
6579
documentation += "Maximum value: \(maximum.value)\(maximum.exclusive ? " (exclusive)" : "")\n"
6680
}
67-
if let multipleOf = integerContext.multipleOf {
81+
if let multipleOf = intContext.multipleOf {
6882
documentation += "Must be multiple of: \(multipleOf)\n"
6983
}
7084
}
7185

7286
case .array:
7387
if let arrayContext = schema.arrayContext {
74-
documentation += "Minimum items: \(arrayContext.minItems)\n"
88+
// Only add minItems if it's not the default value (0)
89+
if arrayContext.minItems > 0 {
90+
documentation += "Minimum items: \(arrayContext.minItems)\n"
91+
}
7592
if let maxItems = arrayContext.maxItems {
7693
documentation += "Maximum items: \(maxItems)\n"
7794
}
95+
// Format array items documentation to match test expectations
96+
if let items = arrayContext.items {
97+
let (itemType, itemDocs) = mapSchemaType(items)
98+
if !itemDocs.isEmpty {
99+
documentation += "Array items:\ntype: \(itemType)\n"
100+
}
101+
}
78102
}
79103

80104
case .object:
81105
if let objectContext = schema.objectContext {
82-
documentation += "Required properties: \(objectContext.requiredProperties.joined(separator: ", "))\n"
106+
let requiredProps = objectContext.requiredProperties
107+
if !requiredProps.isEmpty {
108+
documentation += "Required properties: \(requiredProps.joined(separator: ", "))\n"
109+
}
83110
}
84111

85112
default:
@@ -137,11 +164,9 @@ struct SymbolMapper {
137164

138165
case .array:
139166
if let arrayContext = schema.arrayContext, let items = arrayContext.items {
140-
let (itemType, itemDocs) = mapSchemaType(items)
167+
let (itemType, _) = mapSchemaType(items)
141168
type = "[\(itemType)]"
142-
if !itemDocs.isEmpty {
143-
documentation += "Array items:\n\(itemDocs)"
144-
}
169+
// Nothing needed here - array items documentation is handled in the jsonType switch case
145170
} else {
146171
type = "[Any]"
147172
}
@@ -169,10 +194,7 @@ struct SymbolMapper {
169194
case .null:
170195
type = "Void?" // Or another appropriate representation for null
171196
documentation += "Null schema type.\n"
172-
173-
default:
174-
type = "Any" // Default type for unknown/none
175-
documentation += "Unknown or unspecified schema type.\n"
197+
176198
}
177199
} else {
178200
type = "Any"
@@ -359,13 +381,21 @@ struct SymbolMapper {
359381
if schema.jsonType == .object, let objectContext = schema.objectContext {
360382
let properties = objectContext.properties
361383
for (propertyName, property) in properties {
362-
let propertyIdentifier = "\(identifier).\(propertyName)"
384+
let propertyIdentifier = "\(identifier).\(propertyName)"
363385
let (_, propertyDocs) = mapSchemaType(property)
364386

365387
var propertyDocumentation = property.description ?? "Property \(propertyName)"
366388
if !propertyDocs.isEmpty {
367389
propertyDocumentation += "\n\nType Information:\n\(propertyDocs)"
368390
}
391+
392+
// Special handling for array properties to include type information
393+
if property.jsonType == .array {
394+
if let arrayContext = property.arrayContext, let items = arrayContext.items {
395+
let (itemType, _) = mapSchemaType(items)
396+
propertyDocumentation += "\nArray items:\ntype: \(itemType)\n"
397+
}
398+
}
369399

370400
let (propertySymbol, propertyRelationship) = createSymbol(
371401
kind: .property,

Tests/OpenAPItoSymbolGraphTests/OpenAPItoSymbolGraphTests.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import XCTest
2+
import OpenAPIKit
23
@testable import OpenAPItoSymbolGraph
34

45
final class OpenAPItoSymbolGraphTests: XCTestCase {
@@ -98,12 +99,18 @@ final class OpenAPItoSymbolGraphTests: XCTestCase {
9899
*/
99100

100101
func testTypeMapping() {
101-
// Test type mapping function
102-
XCTAssertEqual(SymbolMapper.mapSchemaType(.string).type, "String")
103-
XCTAssertEqual(SymbolMapper.mapSchemaType(.number).type, "Double")
104-
XCTAssertEqual(SymbolMapper.mapSchemaType(.integer).type, "Int")
105-
XCTAssertEqual(SymbolMapper.mapSchemaType(.boolean).type, "Bool")
106-
XCTAssertEqual(SymbolMapper.mapSchemaType(.array).type, "[Any]")
107-
XCTAssertEqual(SymbolMapper.mapSchemaType(.object).type, "[String: Any]")
102+
// Test type mapping function using basic schema types
103+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.string).type, "String")
104+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.number).type, "Double")
105+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.integer).type, "Int")
106+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.boolean).type, "Bool")
107+
// For array and object, create basic contexts
108+
let basicArrayCoreCtx = OpenAPIKit.JSONSchema.CoreContext<OpenAPIKit.JSONTypeFormat.ArrayFormat>()
109+
let basicArrayCtx = OpenAPIKit.JSONSchema.ArrayContext(items: nil)
110+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.array(basicArrayCoreCtx, basicArrayCtx)).type, "[Any]")
111+
112+
let basicObjectCoreCtx = OpenAPIKit.JSONSchema.CoreContext<OpenAPIKit.JSONTypeFormat.ObjectFormat>()
113+
let basicObjectCtx = OpenAPIKit.JSONSchema.ObjectContext(properties: [:])
114+
XCTAssertEqual(SymbolMapper.mapSchemaType(OpenAPIKit.JSONSchema.object(basicObjectCoreCtx, basicObjectCtx)).type, "[String: Any]")
108115
}
109116
}

0 commit comments

Comments
 (0)