Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with comparing CGPoint using XCTAssertEqual in Xcode 5.1

Tags:

xcode

ios

xctest

I just upgraded to XCode 5.1 and am seeing a compilation error in my unit tests for code like this:

CGPoint p1 = CGPointMake(1,2);
CGPoint p2 = CGPointMake(2,3);
XCTAssertEqual(p1, p2, @"Points not equal");

This is the error message:

Invalid operands to binary expression ('typeof (p1)' (aka 'struct CGPoint') and 'typeof (p2)' (aka 'struct CGPoint'))

The same code worked in previous versions of XCode. Is the code incorrect, or is this a bug in the latest XCode?

Update

The error is triggered by the XCTAssertEqual macro doing a != on the two variables. As these are structs this is not allowed. Did the macro change from 5.0 to 5.1, or did the compiler allow comparison of structs before?

Update 2

The code can be fixed by changing too

XCTAssertEqualObjects([NSValue valueWithCGPoint:p1],
                      [NSValue valueWithCGPoint:p2],
                      @"Points not equal");

I would still like to know what caused this to start failing. (Unfortunately the old version of xcode is removed by installing the new one).

like image 877
combinatorial Avatar asked Mar 10 '14 22:03

combinatorial


2 Answers

The functionally of this macro was changed in Xcode 5.1 to allow comparison of scalar values but removing support for nonscalar types like the struct CGPoint.

From the release notes The XCTAssertEqual macro (formerly STAssertEquals using OCUnit) correctly compares scalar values of different types without casting, for example, int andNSInteger. It can no longer accept nonscalar types, such as structs, for comparison. (14435933)

like image 148
adamwalz Avatar answered Oct 22 '22 01:10

adamwalz


That test code:

XCTAssertEqual(p1, p2, @"Points not equal"); ) 

...definitely compiles fine in Xcode 5.0.1 (5A2034a). In 5.0.1, XCTAssertEqual evaluates to _XCTPrimitiveAssertEqual, which is not doing a !=. It's encoding the primitives into NSValues via value:withObjCType:, then comparing via isEqualToValue:.

Another option would be to use something like:

XCTAssertTrue( NSEqualPoints( NSPointFromCGPoint( p1 ), NSPointFromCGPoint( p2) ), 
    @"Points not equal" );
like image 28
zpasternack Avatar answered Oct 22 '22 02:10

zpasternack