Skip to content

Commit

Permalink
Don't generate inline schemas when allOf only contains a single sch…
Browse files Browse the repository at this point in the history
…ema (#278)

* Update TestSpec to include a scenario where allOf is used to change a referenced schemas nullability or description

* Update inlineSchema extension on Schema to ignore allOf groups where there is only a single child schema

* Update generated fixtures to match expected results after patch

* Update CHANGELOG.md

* Update TestSpec to include example demonstrated in #267
  • Loading branch information
liamnichols authored Aug 5, 2021
1 parent 76d42a6 commit 1a01b5f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 44 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

### Fixed
- Fixed sporadic crashes due to malformed URLs #268 @marcelvoss
- Fixed generation of inline types for `allOf` #267
- Fixed generation of inline types for `allOf` #267 @nicholascross, @liamnichols

## 4.4.0

Expand Down
2 changes: 1 addition & 1 deletion Sources/SwagGenKit/SwaggerExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ extension Schema {
case let .group(group):
if group.discriminator != nil {
return self
} else if case .all = group.type {
} else if case .all = group.type, group.schemas.count > 1 {
return self
}
default: break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,35 @@ public class UserSubclass: User {

public var age: Int?

public init(id: Int? = nil, name: String? = nil, age: Int? = nil) {
/** last error reported to user object, or null if they have not seen an error. */
public var lastError: ErrorType?

public init(id: Int? = nil, name: String? = nil, age: Int? = nil, lastError: ErrorType? = nil) {
self.age = age
self.lastError = lastError
super.init(id: id, name: name)
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)

age = try container.decodeIfPresent("age")
lastError = try container.decodeIfPresent("last_error")
try super.init(from: decoder)
}

public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)

try container.encodeIfPresent(age, forKey: "age")
try container.encodeIfPresent(lastError, forKey: "last_error")
try super.encode(to: encoder)
}

override public func isEqual(to object: Any?) -> Bool {
guard let object = object as? UserSubclass else { return false }
guard self.age == object.age else { return false }
guard self.lastError == object.lastError else { return false }
return super.isEqual(to: object)
}
}
109 changes: 68 additions & 41 deletions Specs/TestSpec/generated/Swift/Sources/Models/Zoo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,12 @@ public class Zoo: APIModel {

public var inlineAnimals: [InlineAnimals]?

public var manager: Manager?

public var oneOfDog: Dog?

public var schemaAnimals: [SingleAnimal]?

public class AllOfDog: Dog {

public override init(animal: String? = nil, barks: Bool? = nil) {
super.init(animal: animal, barks: barks)
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
}

public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
}

override public func isEqual(to object: Any?) -> Bool {
guard object is AllOfDog else { return false }
return super.isEqual(to: object)
}
}

public class InlineAnimal: Animal {

public override init(animal: String? = nil) {
super.init(animal: animal)
}

public required init(from decoder: Decoder) throws {
try super.init(from: decoder)
}

public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
}

override public func isEqual(to object: Any?) -> Bool {
guard object is InlineAnimal else { return false }
return super.isEqual(to: object)
}
}

public enum InlineAnimals: Codable, Equatable {
case cat(Cat)
case dog(Dog)
Expand Down Expand Up @@ -87,11 +49,73 @@ public class Zoo: APIModel {
}
}

public init(allOfDog: Dog? = nil, anyOfDog: Dog? = nil, inlineAnimal: Animal? = nil, inlineAnimals: [InlineAnimals]? = nil, oneOfDog: Dog? = nil, schemaAnimals: [SingleAnimal]? = nil) {
public class Manager: User {

public var value: Value?

public class Value: APIModel {

public var id: String

public init(id: String) {
self.id = id
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)

id = try container.decode("id")
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)

try container.encode(id, forKey: "id")
}

public func isEqual(to object: Any?) -> Bool {
guard let object = object as? Value else { return false }
guard self.id == object.id else { return false }
return true
}

public static func == (lhs: Value, rhs: Value) -> Bool {
return lhs.isEqual(to: rhs)
}
}

public init(id: Int? = nil, name: String? = nil, value: Value? = nil) {
self.value = value
super.init(id: id, name: name)
}

public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)

value = try container.decodeIfPresent("value")
try super.init(from: decoder)
}

public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)

try container.encodeIfPresent(value, forKey: "value")
try super.encode(to: encoder)
}

override public func isEqual(to object: Any?) -> Bool {
guard let object = object as? Manager else { return false }
guard self.value == object.value else { return false }
return super.isEqual(to: object)
}
}

public init(allOfDog: Dog? = nil, anyOfDog: Dog? = nil, inlineAnimal: Animal? = nil, inlineAnimals: [InlineAnimals]? = nil, manager: Manager? = nil, oneOfDog: Dog? = nil, schemaAnimals: [SingleAnimal]? = nil) {
self.allOfDog = allOfDog
self.anyOfDog = anyOfDog
self.inlineAnimal = inlineAnimal
self.inlineAnimals = inlineAnimals
self.manager = manager
self.oneOfDog = oneOfDog
self.schemaAnimals = schemaAnimals
}
Expand All @@ -103,6 +127,7 @@ public class Zoo: APIModel {
anyOfDog = try container.decodeIfPresent("anyOfDog")
inlineAnimal = try container.decodeIfPresent("inlineAnimal")
inlineAnimals = try container.decodeArrayIfPresent("inlineAnimals")
manager = try container.decodeIfPresent("manager")
oneOfDog = try container.decodeIfPresent("oneOfDog")
schemaAnimals = try container.decodeArrayIfPresent("schemaAnimals")
}
Expand All @@ -114,6 +139,7 @@ public class Zoo: APIModel {
try container.encodeIfPresent(anyOfDog, forKey: "anyOfDog")
try container.encodeIfPresent(inlineAnimal, forKey: "inlineAnimal")
try container.encodeIfPresent(inlineAnimals, forKey: "inlineAnimals")
try container.encodeIfPresent(manager, forKey: "manager")
try container.encodeIfPresent(oneOfDog, forKey: "oneOfDog")
try container.encodeIfPresent(schemaAnimals, forKey: "schemaAnimals")
}
Expand All @@ -124,6 +150,7 @@ public class Zoo: APIModel {
guard self.anyOfDog == object.anyOfDog else { return false }
guard self.inlineAnimal == object.inlineAnimal else { return false }
guard self.inlineAnimals == object.inlineAnimals else { return false }
guard self.manager == object.manager else { return false }
guard self.oneOfDog == object.oneOfDog else { return false }
guard self.schemaAnimals == object.schemaAnimals else { return false }
return true
Expand Down
16 changes: 16 additions & 0 deletions Specs/TestSpec/spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ components:
properties:
age:
type: integer
last_error:
allOf:
- $ref: "#/components/schemas/Error"
nullable: true
description: last error reported to user object, or null if they have not seen an error.
UserReference:
$ref: "#/components/schemas/User"
ModelWithAdditionalProperties:
Expand Down Expand Up @@ -332,6 +337,17 @@ components:
allOfDog:
allOf:
- $ref: '#/components/schemas/Dog'
manager:
allOf:
- $ref: "#/components/schemas/User"
- properties:
value:
type: object
required:
- id
properties:
id:
type: string
SingleAnimal:
oneOf:
- $ref: "#/components/schemas/Cat"
Expand Down

0 comments on commit 1a01b5f

Please sign in to comment.