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

Predicate equal doesn't work as expected with NSObject #1082

Closed
1 task done
georgemp opened this issue Sep 6, 2023 · 1 comment
Closed
1 task done

Predicate equal doesn't work as expected with NSObject #1082

georgemp opened this issue Sep 6, 2023 · 1 comment

Comments

@georgemp
Copy link

georgemp commented Sep 6, 2023

  • I have read CONTRIBUTING and have done my best to follow them.

What did you do?

Create an NSObject (in Swift) that conforms to Comparable and implements isEqual(to: Any?).

import Cocoa

public class Tiger: NSObject {
    let id: Int
    let name: String

    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

extension Tiger {
    public override func isEqual(to object: Any?) -> Bool {
        guard let rhs = object as? Tiger else {
            return false
        }

        return self.id == rhs.id && self.name == rhs.name
    }
}

extension Tiger: Comparable {
    public static func < (lhs: Tiger, rhs: Tiger) -> Bool {
        return lhs.id < rhs.id
    }

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

Compared instances of the Tiger object using predicate equal

import XCTest
@testable import NimblePackage
import Nimble

final class NimblePackageTests: XCTestCase {
    func testExample() throws {
        let tiger1 = Tiger(id: 1, name: "Sher Khan")
        let tiger1Copy = Tiger(id: 1, name: "Sher Khan")
        let tiger2 = Tiger(id: 2, name: "Tigger")

        expect(tiger1 == tiger1Copy).to(beTrue()) //Passes
        expect(tiger1).to(equal(tiger1)) //Passes
        expect(tiger1).to(equal(tiger1Copy)) //Fails
        expect(tiger1 != tiger2).to(beTrue()) //Passes
    }
}

What did you expect to happen?

Expected the objects to be compared using the implementation of the Equatable protocol and to return true.

What actually happened instead?

Instead, they are compared by pointer to see if they are the same object and returns false.

Environment

List the software versions you're using:

  • Quick: ?.?.?
  • Nimble: 12.2.0
  • Xcode Version: 14.1
  • Swift Version: Xcode Default

Please also mention which package manager you used and its version. Delete the
other package managers in this list:

  • Swift Package Manager - Swift 5.7.1
@younata
Copy link
Member

younata commented Dec 12, 2024

Sorry, this is over a year old at this point.

In your sample code, you have an incorrect signature for NSObject's equal(_:) method. The signature you gave uses equal(to:), which generates a warning and, because it's the wrong signature, means that Nimble will call NSObject's equal(_:), which does pointer equality.

I wrote #1181 to demonstrate that Nimble is doing the right thing here. Please feel free to re-open this issue if I have anything wrong.

@younata younata closed this as completed Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants