Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle ObjC enum cases when inside collections or deeply inside objects #32

68 changes: 20 additions & 48 deletions Sources/Difference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private struct Differ {
guard expectedMirror.children.count != 0, receivedMirror.children.count != 0 else {
if String(dumping: received) != String(dumping: expected) {
return handleChildless(expected, expectedMirror, received, receivedMirror, level)
} else if expectedMirror.unwrapped?.displayStyle == .enum {
} else if expectedMirror.displayStyle == .enum {
let expectedValue = enumIntValue(for: expected)
let receivedValue = enumIntValue(for: received)
if expectedValue != receivedValue {
Expand All @@ -79,6 +79,14 @@ private struct Differ {
return []
}

// Remove embedding of `some` for optional types, as it offers no value
guard expectedMirror.displayStyle != .optional else {
if let expectedUnwrapped = expectedMirror.firstChildenValue, let receivedUnwrapped = receivedMirror.firstChildenValue {
return diffLines(expectedUnwrapped, receivedUnwrapped, level: level)
}
return []
}

let hasDiffNumOfChildren = expectedMirror.children.count != receivedMirror.children.count
switch (expectedMirror.displayStyle, receivedMirror.displayStyle) {
case (.collection?, .collection?) where hasDiffNumOfChildren,
Expand Down Expand Up @@ -143,43 +151,15 @@ private struct Differ {
let lhs = zippedValues.0
let rhs = zippedValues.1
let childName = "\(expectedMirror.displayStyleDescriptor(index: index))\(lhs.label ?? ""):"
let leftDump = String(dumping: lhs.value)
if leftDump != String(dumping: rhs.value) {
// Remove embedding of `some` for optional types, as it offers no value
guard expectedMirror.displayStyle != .optional else {
let results = diffLines(lhs.value, rhs.value, level: level)
resultLines.append(contentsOf: results)
return
}
if Mirror(reflecting: lhs.value).displayStyle != nil {
let results = diffLines(lhs.value, rhs.value, level: level + 1)
if !results.isEmpty {
let line = Line(contents: childName,
indentationLevel: level,
canBeOrdered: true,
children: results
)
resultLines.append(line)
}
} else {
let children = generateExpectedReceiveLines(
String(describing: lhs.value),
String(describing: rhs.value),
level + 1
)
resultLines.append(Line(contents: childName, indentationLevel: level, canBeOrdered: true, children: children))
}
} else if Mirror(reflecting: lhs.value).unwrapped?.displayStyle == .enum {
let expectedValue = enumIntValue(for: lhs.value)
let receivedValue = enumIntValue(for: rhs.value)
if expectedValue != receivedValue {
let children = generateExpectedReceiveLines(
String(describing: expectedValue),
String(describing: receivedValue),
level + 1
)
resultLines.append(Line(contents: childName, indentationLevel: level, canBeOrdered: true, children: children))
}
let results = diffLines(lhs.value, rhs.value, level: level + 1)

if !results.isEmpty {
let line = Line(contents: childName,
indentationLevel: level,
canBeOrdered: true,
children: results
)
resultLines.append(line)
}
}
return resultLines
Expand Down Expand Up @@ -378,16 +358,8 @@ fileprivate extension Mirror {
}
}

var unwrapped: Mirror? {
guard displayStyle == .optional else {
return self
}
guard children.count != 0 else {
return nil
}

let (_, value) = children.first!
return Mirror(reflecting: value)
var firstChildenValue: Any? {
children.first?.value
}
}

Expand Down
58 changes: 57 additions & 1 deletion Tests/DifferenceTests/DifferenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fileprivate struct Person: Equatable {
let petAges: [String: Int]?
let favoriteFoods: Set<String>?
let objcEnum: ByteCountFormatter.CountStyle?
let elements: [CollectionElement]

init(
name: String = "Krzysztof",
Expand All @@ -28,7 +29,8 @@ fileprivate struct Person: Equatable {
pet: Pet? = .init(),
petAges: [String: Int]? = nil,
favoriteFoods: Set<String>? = nil,
objcEnum: ByteCountFormatter.CountStyle = .binary
objcEnum: ByteCountFormatter.CountStyle = .binary,
elements: [CollectionElement] = []
) {
self.name = name
self.age = age
Expand All @@ -37,6 +39,7 @@ fileprivate struct Person: Equatable {
self.petAges = petAges
self.favoriteFoods = favoriteFoods
self.objcEnum = objcEnum
self.elements = elements
}

struct Address: Equatable {
Expand Down Expand Up @@ -70,6 +73,16 @@ fileprivate struct Person: Equatable {
self.name = name
}
}

struct CollectionElement: Equatable {
let title: String
let objcEnum: ByteCountFormatter.CountStyle

init(title: String = "title", objcEnum: ByteCountFormatter.CountStyle) {
self.title = title
self.objcEnum = objcEnum
}
}
}

private enum State {
Expand Down Expand Up @@ -286,6 +299,47 @@ class DifferenceTests: XCTestCase {
)
}

func test_canFindObjCEnumDifferenceInArrayOfEnums() {
let expected = [
ByteCountFormatter.CountStyle.decimal,
ByteCountFormatter.CountStyle.decimal,
ByteCountFormatter.CountStyle.decimal,
]
let received = [
ByteCountFormatter.CountStyle.decimal,
ByteCountFormatter.CountStyle.binary,
ByteCountFormatter.CountStyle.decimal,
]
runTest(
expected: expected,
received: received,
expectedResults: ["Collection[1]:\n|\tReceived: 3\n|\tExpected: 2\n"]
)
}

func test_canFindObjCEnumDifferenceInArrayOfStructures() {
let expected = Person(
elements: [
Person.CollectionElement(title: "1", objcEnum: .decimal),
Person.CollectionElement(title: "2", objcEnum: .decimal),
Person.CollectionElement(title: "3", objcEnum: .decimal),
]
)
let received = Person(
elements: [
Person.CollectionElement(title: "1", objcEnum: .decimal),
Person.CollectionElement(title: "2", objcEnum: .binary),
Person.CollectionElement(title: "3", objcEnum: .decimal),
]
)
runTest(
expected: expected,
received: received,
expectedResults: ["elements:\n|\tCollection[1]:\n|\t|\tobjcEnum:\n|\t|\t|\tReceived: 3\n|\t|\t|\tExpected: 2\n"]
)
}


func test_cannotFindDifferenceWithSameSwiftEnum() {
runTest(
expected: State.loadedWithNoArguments,
Expand Down Expand Up @@ -323,5 +377,7 @@ extension DifferenceTests {
("test_canFindObjCEnumDifference", test_canFindObjCEnumDifference),
("test_cannotFindDifferenceWithSameSwiftEnum", test_cannotFindDifferenceWithSameSwiftEnum),
("test_cannotFindDifferenceWithSameObjects", test_cannotFindDifferenceWithSameObjects),
("test_canFindObjCEnumDifferenceInArrayOfEnums", test_canFindObjCEnumDifferenceInArrayOfEnums),
("test_canFindObjCEnumDifferenceInArrayOfStructures", test_canFindObjCEnumDifferenceInArrayOfStructures),
]
}