krzysztofzablocki/Difference

Simple way to identify what is different between 2 instances of any type. Must have for TDD.

Swift

1,243

85 commits

updated May 8, 2025

See the code

README

Version License Platform

Difference

Better way to identify what's different between 2 instances.

Have you ever written tests? Usually they use equality asserts, e.g. XCTAssertEqual, what happens if the objects aren't equal? Xcode throws a wall of text at you:

This forces you to manually scan the text and try to figure out exactly what's wrong, what if instead you could just learn which property is different?

If you'd like to support my work and improve your engineering workflows, check out my SwiftyStack course

Installation

CocoaPods

Add pod 'Difference' to your Podfile.

Carthage

Add github "krzysztofzablocki/Difference" to your Cartfile.

SwiftPM

Add .package(url: "https://github.com/krzysztofzablocki/Difference.git", branch: "master") dependency in your Package manifest.

Using lldb

Write the following to see the difference between 2 instances:

po dumpDiff(expected, received)

Integrate with XCTest

Add this to your test target:

public func XCTAssertEqual<T: Equatable>(_ expected: @autoclosure () throws -> T, _ received: @autoclosure () throws -> T, file: StaticString = #filePath, line: UInt = #line) {
    do {
        let expected = try expected()
        let received = try received()
        XCTAssertTrue(expected == received, "Found difference for \n" + diff(expected, received).joined(separator: ", "), file: file, line: line)
    }
    catch {
        XCTFail("Caught error while testing: \(error)", file: file, line: line)
    }
}

Replace #filePath with #file if you're using Xcode 11 or earlier.

Integrate with Quick

Add this to your test target:

public func equalDiff<T: Equatable>(_ expectedValue: T?) -> Matcher<T> {
    return Matcher.define { actualExpression in
        let receivedValue = try actualExpression.evaluate()

        if receivedValue == nil {
            var message = ExpectationMessage.fail("")
            if let expectedValue = expectedValue {
                message = ExpectationMessage.expectedCustomValueTo("equal <\(expectedValue)>", actual: "nil")
            }
            return MatcherResult(status: .fail, message: message)
        }
        if expectedValue == nil {
            return MatcherResult(status: .fail, message: ExpectationMessage.fail("").appendedBeNilHint())
        }

        return MatcherResult(bool: receivedValue == expectedValue, message: ExpectationMessage.fail("Found difference for " + diff(expectedValue, receivedValue).joined(separator: ", ")))
    }
}

Write the following to see the difference between 2 instances: expect(received).to(equalDiff(expected))

Integrate with The Composable Architecture

If you are using The Composable Architecture nameLabels configuration to get a diff that's more appropiate for reducer instrumentation

diff(oldState, newState, indentationType: .pipe, nameLabels: .comparing)

You can use this function in your own variant of ReducerInstrumentation code based on this

That way your diffs will look more like this:

Received action:
  AppAction.home(.howTo(.setSelectedSlide))
State:
home:
|	selectedHowTo:
|	|	selectedSlide:
|	|	|	Current: 8mnkni91h4fe
|	|	|	Previous: exei4wpqsmdk
ios
macos
swift
testing
tvos
watchos

krzysztofzablocki/Difference

Simple way to identify what is different between 2 instances of any type. Must have for TDD.

Swift

1,243

85 commits

updated May 8, 2025

See the code

README

Version License Platform

Difference

Better way to identify what's different between 2 instances.

Have you ever written tests? Usually they use equality asserts, e.g. XCTAssertEqual, what happens if the objects aren't equal? Xcode throws a wall of text at you:

This forces you to manually scan the text and try to figure out exactly what's wrong, what if instead you could just learn which property is different?

If you'd like to support my work and improve your engineering workflows, check out my SwiftyStack course

Installation

CocoaPods

Add pod 'Difference' to your Podfile.

Carthage

Add github "krzysztofzablocki/Difference" to your Cartfile.

SwiftPM

Add .package(url: "https://github.com/krzysztofzablocki/Difference.git", branch: "master") dependency in your Package manifest.

Using lldb

Write the following to see the difference between 2 instances:

po dumpDiff(expected, received)

Integrate with XCTest

Add this to your test target:

public func XCTAssertEqual<T: Equatable>(_ expected: @autoclosure () throws -> T, _ received: @autoclosure () throws -> T, file: StaticString = #filePath, line: UInt = #line) {
    do {
        let expected = try expected()
        let received = try received()
        XCTAssertTrue(expected == received, "Found difference for \n" + diff(expected, received).joined(separator: ", "), file: file, line: line)
    }
    catch {
        XCTFail("Caught error while testing: \(error)", file: file, line: line)
    }
}

Replace #filePath with #file if you're using Xcode 11 or earlier.

Integrate with Quick

Add this to your test target:

public func equalDiff<T: Equatable>(_ expectedValue: T?) -> Matcher<T> {
    return Matcher.define { actualExpression in
        let receivedValue = try actualExpression.evaluate()

        if receivedValue == nil {
            var message = ExpectationMessage.fail("")
            if let expectedValue = expectedValue {
                message = ExpectationMessage.expectedCustomValueTo("equal <\(expectedValue)>", actual: "nil")
            }
            return MatcherResult(status: .fail, message: message)
        }
        if expectedValue == nil {
            return MatcherResult(status: .fail, message: ExpectationMessage.fail("").appendedBeNilHint())
        }

        return MatcherResult(bool: receivedValue == expectedValue, message: ExpectationMessage.fail("Found difference for " + diff(expectedValue, receivedValue).joined(separator: ", ")))
    }
}

Write the following to see the difference between 2 instances: expect(received).to(equalDiff(expected))

Integrate with The Composable Architecture

If you are using The Composable Architecture nameLabels configuration to get a diff that's more appropiate for reducer instrumentation

diff(oldState, newState, indentationType: .pipe, nameLabels: .comparing)

You can use this function in your own variant of ReducerInstrumentation code based on this

That way your diffs will look more like this:

Received action:
  AppAction.home(.howTo(.setSelectedSlide))
State:
home:
|	selectedHowTo:
|	|	selectedSlide:
|	|	|	Current: 8mnkni91h4fe
|	|	|	Previous: exei4wpqsmdk
ios
macos
swift
testing
tvos
watchos

Project health

Overall

3.3/10

Maintained

0/10

Code review

5/10
OpenSSF Scorecard

Significant stargazers

Yuta Saito

646 followers · starred Oct 2017

Kyle

892 followers · starred Aug 2025

Max Howell

7,873 followers · starred Jul 2020

Nikolai Vazquez

466 followers · starred Oct 2017