# The "eh... just about?" custom operator

Recently I’ve been writing a lot of model logic tests (oh tests = 😻, I’m a convert and will be talking to you about them at a party soon while you try desperately to catch anyone else’s eye and make your excuses). Anyway, there’s a bit of maths going on with `Double`s, which means I’m ending up with a lot of these checks:

``````XCTAssertEqualWithAccuracy(calculatedResult, niceRoundNumber, accuracy: 0.001,
"These should have been just about equal")
``````

These are just some tiny calculation differences (e.g. `50.00000000001` vs `50`) that are just cognitive noise - I don’t care about the accuracy and it’s a lot of overhead for a rough comparison. Sounds like a job for a custom operator:

``````infix operator ~ { associativity left precedence 130 }

public func ~(lhs: Double?, rhs: Double?) -> Bool {
switch (lhs, rhs) {
case (let left?, let right?):
let l = Double(round(accuracy * left)/accuracy)
let r = Double(round(accuracy * right)/accuracy)
return l == r
default:
return lhs == rhs
}
}

private let accuracy = 1000.0 // compare down to the thousandth

``````

And now my tests just look like:

``````XCTAssertTrue(calculatedResult ~ niceRoundNumber)
``````

which I find a lot easier to write and read back. 👍

### Update 28/03/16

Two things occured to me: firstly defining `!~` would be nice:

``````infix operator !~ { associativity left precedence 130 }

public func !~(lhs: Double?, rhs: Double?) -> Bool {
return !(lhs ~ rhs)
}
``````

And secondly, I remembered this fine article from Joe Masilotti about manually triggering test failures and capturing their context with default `#file` and `#line` arguments. So now I can write an `AssertMoreOrLessEqual` function to produce a default message in the same format as `XCTAssertEqual()`:

``````func AssertMoreOrLessEqual( lhs: Double?, _ rhs: Double?,
_ message: String? = nil,
file: String = #file, line: UInt = #line) {
if lhs !~ rhs {
let message = message ??
"AssertMoreOrLessEqual failed: \(lhs) is not more or less equal to \(rhs)"
self.recordFailureWithDescription(message,
inFile: file, atLine: line, expected: true)
}
}
``````

And now my tests look like:

🎉