-
-
Save joemasilotti/da1c5a04bd6386c22d55 to your computer and use it in GitHub Desktop.
import CoreLocation | |
struct AddressFormatter { | |
private let placemark: Placemarkable | |
init(placemark: Placemarkable) { | |
self.placemark = placemark | |
} | |
func formattedAddress() -> String { | |
let nameOrAddress = placemark.name ?? placemark.thoroughfare | |
var city = placemark.locality | |
var state = placemark.administrativeArea | |
let zip = placemark.postalCode | |
var cityAndState: String? | |
if let presentCity = city, presentState = state { | |
cityAndState = "\(presentCity), \(presentState)" | |
city = nil | |
state = nil | |
} | |
let presentInfo = [nameOrAddress, city, state, cityAndState, zip].flatMap{$0} | |
return presentInfo.joinWithSeparator(" ") | |
} | |
} |
import XCTest | |
import CoreLocation | |
class AddressFormatterTests: XCTestCase { | |
var subject: AddressFormatter! | |
func test_WithAName_ReturnJustTheName() { | |
let placemark = MockPlacemarkable() | |
placemark.name = "St. Gambrinus Beer Shoppe" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "St. Gambrinus Beer Shoppe") | |
} | |
func test_WithoutANameButWithAnAddress_ReturnJustTheAddress() { | |
let placemark = MockPlacemarkable() | |
placemark.thoroughfare = "533 Atlantic Ave" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "533 Atlantic Ave") | |
} | |
func test_WithANameAndACity_ReturnBoth() { | |
let placemark = MockPlacemarkable() | |
placemark.name = "St. Gambrinus Beer Shoppe" | |
placemark.locality = "Brooklyn" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "St. Gambrinus Beer Shoppe Brooklyn") | |
} | |
func test_WithACityAndState_IncludesThemWithAComma() { | |
let placemark = MockPlacemarkable() | |
placemark.locality = "Brooklyn" | |
placemark.administrativeArea = "NY" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "Brooklyn, NY") | |
} | |
func test_WithAStateButNoCity_DoesNotIncludeAComma() { | |
let placemark = MockPlacemarkable() | |
placemark.administrativeArea = "NY" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "NY") | |
} | |
func test_WithAOptionalParameters_IncludesThem() { | |
let placemark = MockPlacemarkable() | |
placemark.thoroughfare = "533 Atlantic Ave" | |
placemark.locality = "Brooklyn" | |
placemark.administrativeArea = "NY" | |
placemark.postalCode = "11217" | |
subject = AddressFormatter(placemark: placemark) | |
XCTAssertEqual(subject.formattedAddress(), "533 Atlantic Ave Brooklyn, NY 11217") | |
} | |
} |
import Foundation | |
@objc class MockPlacemarkable: NSObject, Placemarkable { | |
var name: String? | |
var thoroughfare: String? | |
var administrativeArea: String? | |
var locality: String? | |
var postalCode: String? | |
} |
Do a test for placemark.name
too because in your formattedAddress()
function you test let nameOrAddress = placemark.name ?? placemark.thoroughfare
. You may also want to test what happens when you pass both name
and thoroughfare
in, just in case. The ??
operator shouldn't change, but if it does you will know.
Suggestion, since you seem to be using the same address (or parts of it) to test throughout, maybe consider abstracting them to variables at the top, or a expectedPlacemark
variable. This way, when you are testing, you set it to something that isn't changing (and prevent typos from occurring in the future). Also, means when you test the comparison, you just format the concatenation of two strings, instead of possibility of miss typing a full string.
@Aghassi thanks for the review!
Comment 1: Good idea pulling the placemark out to a let
variable. Fortunately, the code in setup
isn't needed. The class is recreated by XCTest for each test, so no pollution would occur.
Comment 2: The first test covers just name
, right? But I can definitely add a test that checks both, good point.
Comment 3: I like the idea of abstracting comparisons, but an expected placemark seems too heavy handed. Making the strings, however, be variables could be a good compromise.
In each of your tests you create this. I would save some code and instead do:
This way, we guarantee that we always have a placemark, and that it is never nil before a test. We also clean up the first line of all the tests by removing the
let placemark = MockPlacemarkable()