Skip to content
This repository has been archived by the owner on Nov 11, 2017. It is now read-only.

Commit

Permalink
Merge pull request #9 from mpurland/number-string
Browse files Browse the repository at this point in the history
Allow bridging number to string. Fixed and added tests for optional binding.
  • Loading branch information
mpurland committed Dec 4, 2015
2 parents ee68eab + 36140ac commit c611aec
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 23 deletions.
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ struct User {
let latitude: Double
let longitude: Double
let admin: Bool

static func create(id: UInt64)(name: String)(age: Int)(tweets: [String])(profile: String)(balance: Double)(latitude: Double)(longitude: Double)(admin: Bool) -> User {
return User(id: id, name: name, age: age, tweets: tweets, profile: profile, balance: balance, latitude: latitude, longitude: longitude, admin: admin)
}
let optionalNickname: String?
}

extension User: FromJSON {
Expand All @@ -49,8 +46,9 @@ extension User: FromJSON {
let latitude: Double? = j <? "latitude"
let longitude: Double? = j <? "longitude"
let admin: Bool? = j <? "admin"
let optionalNickname: String?? = j <?? "optionalNickname"

return (User.create
return (curry(User.init)
<^> id
<*> name
<*> age
Expand All @@ -59,12 +57,28 @@ extension User: FromJSON {
<*> balance
<*> latitude
<*> longitude
<*> admin).toEither(.Custom("Could not create user"))
<*> admin
<*> optionalNickname).toEither(.Custom("Could not create user"))
}
}

extension User: Equatable {}

func == (lhs: User, rhs: User) -> Bool {
return lhs.id == rhs.id
&& lhs.name == rhs.name
&& lhs.age == rhs.age
&& lhs.tweets == rhs.tweets
&& lhs.profile == rhs.profile
&& lhs.balance == rhs.balance
&& lhs.latitude == rhs.latitude
&& lhs.longitude == rhs.longitude
&& lhs.admin == rhs.admin
&& lhs.optionalNickname == rhs.optionalNickname
}

extension User: Equatable {}

func == (lhs: User, rhs: User) -> Bool {
return lhs.id == rhs.id
&& lhs.name == rhs.name
Expand Down
4 changes: 3 additions & 1 deletion Tyro/Instances.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ extension String : FromJSON {
switch value {
case .String(let value):
return .Right(value)
case .Number(let value):
return .Right(value.stringValue)
default:
return .Left(.TypeMismatch("\(String.self)", "\(value.dynamicType.self)"))
}
Expand Down Expand Up @@ -201,4 +203,4 @@ extension Double : ToJSON {
public static func toJSON(value : Double) -> Either<JSONError, JSONValue> {
return .Right(.Number(NSNumber(double : value)))
}
}
}
6 changes: 3 additions & 3 deletions Tyro/JSONOperators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public func <? <B : JSONFormatterType> (lhs : B?, rhs : JSONKeypath) -> [String
}

public func <?? <B : JSONFormatterType> (lhs : B?, rhs : JSONKeypath) -> B.DecodedType?? {
return lhs <? rhs
return (lhs <? rhs) ?? nil
}

public func <?? <B : JSONFormatterType> (lhs : B?, rhs : JSONKeypath) -> [B.DecodedType]?? {
return lhs <? rhs
return (lhs <? rhs) ?? nil
}

public func <?? <B : JSONFormatterType> (lhs : B?, rhs : JSONKeypath) -> [String : B.DecodedType]?? {
return lhs <? rhs
return (lhs <? rhs) ?? nil
}

/// JSONValue decoding operators
Expand Down
1 change: 1 addition & 0 deletions Tyro/JSONValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extension JSONValue : JSONValueable {
public var string : Swift.String? {
switch self {
case .String(let value): return value
case .Number(let value): return value.stringValue
default: return nil
}
}
Expand Down
3 changes: 2 additions & 1 deletion TyroTests/JSONValueSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ func roundTrip<T : protocol<FromJSON, ToJSON>>(_ : T.Type, _ x : JSONValue) -> T

class JSONSpec : XCTestCase {
let frequentFliers : [Property] = [
forAll { (x : JSONValue) in roundTrip(Swift.String.self, x) },
// forAll { (x : JSONValue) in roundTrip(Swift.String.self, x) },
forAll { (x : JSONValue) in roundTrip(Bool.self, x) },

// forAll { (x : JSONValue) in roundTrip(Int.self, x) },
// forAll { (x : JSONValue) in roundTrip(Int8.self, x) },
// forAll { (x : JSONValue) in roundTrip(Int16.self, x) },
Expand Down
21 changes: 15 additions & 6 deletions TyroTests/TypesSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ class TypesFromJSONSpec : XCTestCase {
XCTAssert(stringFromObject == "This is a string")
}

func testStringInvalid() {
let jsonNotAString = "[1]"
let notAStringArray: [String]? = jsonNotAString.toJSON?.value()
XCTAssertNil(notAStringArray)
}

func testBool() {
let jsonBoolInArray = "[true,false]"
let boolInArray: [Bool]? = jsonBoolInArray.toJSON?.value()
Expand Down Expand Up @@ -223,6 +217,21 @@ class TypesFromJSONSpec : XCTestCase {
XCTAssertNotNil(pi)
XCTAssertEqualWithAccuracy(pi!, doublePI, accuracy: 1.0 / 1_000_000_000_000.0)
}

func testStringFromNumber() {
let json = "{\"id\":122585221112454722}"
let id: UInt64? = json.toJSON <? "id"
XCTAssertNotNil(id)

let idString: String? = json.toJSON <? "id"
XCTAssertNotNil(idString)
}

func testStringFromNumberArray() {
let jsonNotAString = "[1]"
let stringOfNumberArray: [String]? = jsonNotAString.toJSON?.value()
XCTAssert(stringOfNumberArray == ["1"])
}
}

class TypesToJSONSpec : XCTestCase {
Expand Down
12 changes: 6 additions & 6 deletions TyroTests/UserExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ struct User {
let latitude: Double
let longitude: Double
let admin: Bool

static func create(id: UInt64)(name: String)(age: Int)(tweets: [String])(profile: String)(balance: Double)(latitude: Double)(longitude: Double)(admin: Bool) -> User {
return User(id: id, name: name, age: age, tweets: tweets, profile: profile, balance: balance, latitude: latitude, longitude: longitude, admin: admin)
}
let optionalNickname: String?
}

extension User: FromJSON {
Expand All @@ -39,8 +36,9 @@ extension User: FromJSON {
let latitude: Double? = j <? "latitude"
let longitude: Double? = j <? "longitude"
let admin: Bool? = j <? "admin"
let optionalNickname: String?? = j <?? "optionalNickname"

return (User.create
return (curry(User.init)
<^> id
<*> name
<*> age
Expand All @@ -49,7 +47,8 @@ extension User: FromJSON {
<*> balance
<*> latitude
<*> longitude
<*> admin).toEither(.Custom("Could not create user"))
<*> admin
<*> optionalNickname).toEither(.Custom("Could not create user"))
}
}

Expand All @@ -65,6 +64,7 @@ func == (lhs: User, rhs: User) -> Bool {
&& lhs.latitude == rhs.latitude
&& lhs.longitude == rhs.longitude
&& lhs.admin == rhs.admin
&& lhs.optionalNickname == rhs.optionalNickname
}

func == (lhs: User?, rhs: User?) -> Bool {
Expand Down
12 changes: 12 additions & 0 deletions TyroTests/UserSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Swiftz

class UserSpec : XCTestCase {
let userJson = "{\"id\": 103622342330925644, \"name\": \"Matthew Purland\", \"age\": 30, \"tweets\": [\"Hello from Tyro\"], \"attributes\": {\"profile\": \"Test Profile\"}, \"balance\": 102.30, \"admin\": true, \"latitude\": 31.75, \"longitude\": 31.75}"
let userJsonWithNickname = "{\"id\": 103622342330925644, \"name\": \"Matthew Purland\", \"age\": 30, \"tweets\": [\"Hello from Tyro\"], \"attributes\": {\"profile\": \"Test Profile\"}, \"balance\": 102.30, \"admin\": true, \"latitude\": 31.75, \"longitude\": 31.75, \"optionalNickname\":\"mpurland\"}"
let userJsonWithoutLongitude = "{\"id\": 103622342330925644, \"name\": \"Matthew\", \"age\": 30, \"tweets\": [\"Hello from Tyro\"], \"attributes\": {\"profile\": \"Test Profile\"}, \"balance\": 102.30, \"admin\": true, \"latitude\": 31.75}"

func testDecodeUserEither() {
Expand All @@ -32,6 +33,17 @@ class UserSpec : XCTestCase {
XCTAssert(user?.admin == true)
XCTAssert(user?.latitude == 31.75)
XCTAssert(user?.longitude == 31.75)
XCTAssert(user?.optionalNickname == nil)

let userWithNickname: User? = userJsonWithNickname.toJSON?.value()
XCTAssertNotNil(userWithNickname)
XCTAssert(userWithNickname?.optionalNickname == "mpurland")

let nickname1: String?? = userJson.toJSON <?? "optionalNickname"
XCTAssert(nickname1! == nil)

let nickname2: String?? = userJsonWithNickname.toJSON <?? "optionalNickname"
XCTAssert(nickname2! == "mpurland")
}

func testDecodeUsers() {
Expand Down

0 comments on commit c611aec

Please sign in to comment.