-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from mattpolzin/feature/testing-comparisons
Feature/testing comparisons
- Loading branch information
Showing
22 changed files
with
1,477 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 11/5/19. | ||
// | ||
|
||
import JSONAPI | ||
|
||
public enum ArrayElementComparison: Equatable, CustomStringConvertible { | ||
case same | ||
case missing | ||
case differentTypes(String, String) | ||
case differentValues(String, String) | ||
case prebuilt(String) | ||
|
||
public init(sameTypeComparison: Comparison) { | ||
switch sameTypeComparison { | ||
case .same: | ||
self = .same | ||
case .different(let one, let two): | ||
self = .differentValues(one, two) | ||
case .prebuilt(let str): | ||
self = .prebuilt(str) | ||
} | ||
} | ||
|
||
public init(resourceObjectComparison: ResourceObjectComparison) { | ||
guard !resourceObjectComparison.isSame else { | ||
self = .same | ||
return | ||
} | ||
|
||
self = .prebuilt( | ||
resourceObjectComparison | ||
.differences | ||
.sorted { $0.key < $1.key } | ||
.map { "\($0.key): \($0.value)" } | ||
.joined(separator: ", ") | ||
) | ||
} | ||
|
||
public var description: String { | ||
switch self { | ||
case .same: | ||
return "same" | ||
case .missing: | ||
return "missing" | ||
case .differentTypes(let one, let two), | ||
.differentValues(let one, let two): | ||
return "\(one) ≠ \(two)" | ||
case .prebuilt(let description): | ||
return description | ||
} | ||
} | ||
|
||
public var rawValue: String { description } | ||
} | ||
|
||
extension Array { | ||
func compare(to other: Self, using compare: (Element, Element) -> ArrayElementComparison) -> [ArrayElementComparison] { | ||
let isSelfLonger = count >= other.count | ||
|
||
let longer = isSelfLonger ? self : other | ||
let shorter = isSelfLonger ? other : self | ||
|
||
return longer.indices.map { idx in | ||
guard shorter.indices.contains(idx) else { | ||
return .missing | ||
} | ||
|
||
let this = longer[idx] | ||
let other = shorter[idx] | ||
|
||
return compare(this, other) | ||
} | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
Sources/JSONAPITesting/Comparisons/AttributesCompare.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 11/3/19. | ||
// | ||
|
||
import JSONAPI | ||
|
||
extension Attributes { | ||
public func compare(to other: Self) -> [String: Comparison] { | ||
let mirror1 = Mirror(reflecting: self) | ||
let mirror2 = Mirror(reflecting: other) | ||
|
||
var comparisons = [String: Comparison]() | ||
|
||
for child in mirror1.children { | ||
guard let childLabel = child.label else { continue } | ||
|
||
let childDescription = attributeDescription(of: child.value) | ||
|
||
guard let otherChild = mirror2.children.first(where: { $0.label == childLabel }) else { | ||
comparisons[childLabel] = .different(childDescription, "missing") | ||
continue | ||
} | ||
|
||
if (attributesEqual(child.value, otherChild.value)) { | ||
comparisons[childLabel] = .same | ||
} else { | ||
let otherChildDescription = attributeDescription(of: otherChild.value) | ||
|
||
comparisons[childLabel] = .different(childDescription, otherChildDescription) | ||
} | ||
} | ||
|
||
return comparisons | ||
} | ||
} | ||
|
||
fileprivate func attributesEqual(_ one: Any, _ two: Any) -> Bool { | ||
guard let attr = one as? AbstractAttribute else { | ||
return false | ||
} | ||
|
||
return attr.equals(two) | ||
} | ||
|
||
fileprivate func attributeDescription(of thing: Any) -> String { | ||
return (thing as? AbstractAttribute)?.abstractDescription ?? String(describing: thing) | ||
} | ||
|
||
protocol AbstractAttribute { | ||
var abstractDescription: String { get } | ||
|
||
func equals(_ other: Any) -> Bool | ||
} | ||
|
||
extension Attribute: AbstractAttribute { | ||
var abstractDescription: String { String(describing: value) } | ||
|
||
func equals(_ other: Any) -> Bool { | ||
guard let attributeB = other as? Self else { | ||
return false | ||
} | ||
return abstractDescription == attributeB.abstractDescription | ||
} | ||
} | ||
|
||
extension TransformedAttribute: AbstractAttribute { | ||
var abstractDescription: String { String(describing: value) } | ||
|
||
func equals(_ other: Any) -> Bool { | ||
guard let attributeB = other as? Self else { | ||
return false | ||
} | ||
return abstractDescription == attributeB.abstractDescription | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// | ||
// Comparison.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 11/3/19. | ||
// | ||
|
||
public enum Comparison: Equatable, CustomStringConvertible { | ||
case same | ||
case different(String, String) | ||
case prebuilt(String) | ||
|
||
init<T: Equatable>(_ one: T, _ two: T) { | ||
guard one == two else { | ||
self = .different(String(describing: one), String(describing: two)) | ||
return | ||
} | ||
self = .same | ||
} | ||
|
||
init(reducing other: ArrayElementComparison) { | ||
switch other { | ||
case .same: | ||
self = .same | ||
case .differentTypes(let one, let two), | ||
.differentValues(let one, let two): | ||
self = .different(one, two) | ||
case .missing: | ||
self = .different("array length 1", "array length 2") | ||
case .prebuilt(let str): | ||
self = .prebuilt(str) | ||
} | ||
} | ||
|
||
public var description: String { | ||
switch self { | ||
case .same: | ||
return "same" | ||
case .different(let one, let two): | ||
return "\(one) ≠ \(two)" | ||
case .prebuilt(let str): | ||
return str | ||
} | ||
} | ||
|
||
public var rawValue: String { description } | ||
|
||
public var isSame: Bool { self == .same } | ||
} | ||
|
||
public typealias NamedDifferences = [String: String] | ||
|
||
public protocol PropertyComparable: CustomStringConvertible { | ||
var differences: NamedDifferences { get } | ||
} | ||
|
||
extension PropertyComparable { | ||
public var description: String { | ||
return differences | ||
.map { "(\($0): \($1))" } | ||
.sorted() | ||
.joined(separator: ", ") | ||
} | ||
|
||
public var rawValue: String { description } | ||
|
||
public var isSame: Bool { differences.isEmpty } | ||
} |
Oops, something went wrong.