66// Copyright (c) 2015 TypeLift. All rights reserved.
77//
88
9- import XCTest
109import Swiftz
10+ import XCTest
11+ import SwiftCheck
12+
13+ let defaultError = NSError ( domain: " Swiftz " , code: - 1 , userInfo: nil )
14+
15+ struct ResultOf < A : Arbitrary > : Arbitrary , Printable {
16+ let getResult : Result < A >
17+
18+ init ( _ maybe : Result < A > ) {
19+ self . getResult = maybe
20+ }
21+
22+ var description : String {
23+ return " \( self . getResult) "
24+ }
25+
26+ private static func create( opt : Result < A > ) -> ResultOf < A > {
27+ return ResultOf ( opt)
28+ }
29+
30+ static func arbitrary( ) -> Gen < ResultOf < A > > {
31+ return Gen . frequency ( [
32+ ( 1 , Gen . pure ( ResultOf ( . Error( defaultError) ) ) ) ,
33+ ( 3 , liftM ( { ResultOf ( pure ( $0) ) } ) ( m1: A . arbitrary ( ) ) )
34+ ] )
35+ }
36+
37+ static func shrink( bl : ResultOf < A > ) -> [ ResultOf < A > ] {
38+ switch bl. getResult {
39+ case . Error( _) :
40+ return [ ]
41+ case let . Value( v) :
42+ return [ ResultOf ( . Error( defaultError) ) ] + A. shrink ( v. value) . map ( { ResultOf ( pure ( $0) ) } )
43+ }
44+ }
45+ }
46+
47+ func == < T : protocol < Arbitrary , Equatable > > ( lhs : ResultOf < T > , rhs : ResultOf < T > ) -> Bool {
48+ return lhs. getResult == rhs. getResult
49+ }
50+
51+ func != < T : protocol < Arbitrary , Equatable > > ( lhs : ResultOf < T > , rhs : ResultOf < T > ) -> Bool {
52+ return !( lhs == rhs)
53+ }
1154
1255class ResultSpec : XCTestCase {
13- func testResult( ) {
14- let divisionError = NSError ( domain: " DivisionDomain " , code: 1 , userInfo: nil )
15-
16- func divTwoEvenly( x: Int ) -> Result < Int > {
17- if x % 2 == 0 {
18- return Result . error ( divisionError)
19- } else {
20- return Result . value ( x / 2 )
21- }
56+ func testProperties( ) {
57+ property [ " There is an isomorphism between Either<NSError, A> and Result<A> " ] = forAll { ( l : ResultOf < Int > ) in
58+ return l. getResult == l. getResult. toEither ( ) . toResult ( identity)
59+ }
60+
61+ property [ " Results of Equatable elements obey reflexivity " ] = forAll { ( l : ResultOf < Int > ) in
62+ return l == l
63+ }
64+
65+ property [ " Results of Equatable elements obey symmetry " ] = forAll { ( x : ResultOf < Int > , y : ResultOf < Int > ) in
66+ return ( x == y) == ( y == x)
67+ }
68+
69+ property [ " Results of Equatable elements obey transitivity " ] = forAll { ( x : ResultOf < Int > , y : ResultOf < Int > , z : ResultOf < Int > ) in
70+ return ( x == y) && ( y == z) ==> ( x == z)
71+ }
72+
73+ property [ " Results of Equatable elements obey negation " ] = forAll { ( x : ResultOf < Int > , y : ResultOf < Int > ) in
74+ return ( x != y) == !( x == y)
75+ }
76+
77+ property [ " Result obeys the Functor identity law " ] = forAll { ( x : ResultOf < Int > ) in
78+ return ( identity <^> x. getResult) == identity ( x. getResult)
79+ }
80+
81+ property [ " Result obeys the Functor composition law " ] = forAll { ( f : ArrowOf < Int , Int > , g : ArrowOf < Int , Int > , x : ResultOf < Int > ) in
82+ return ( ( f. getArrow • g. getArrow) <^> x. getResult) == ( f. getArrow <^> ( g. getArrow <^> x. getResult) )
83+ }
84+
85+ property [ " Result obeys the Applicative identity law " ] = forAll { ( x : ResultOf < Int > ) in
86+ return ( pure ( identity) <*> x. getResult) == x. getResult
87+ }
88+
89+ property [ " Result obeys the first Applicative composition law " ] = forAll { ( fl : ResultOf < ArrowOf < Int8 , Int8 > > , gl : ResultOf < ArrowOf < Int8 , Int8 > > , x : ResultOf < Int8 > ) in
90+ let f = { $0. getArrow } <^> fl. getResult
91+ let g = { $0. getArrow } <^> gl. getResult
92+ return ( curry ( • ) <^> f <*> g <*> x. getResult) == ( f <*> ( g <*> x. getResult) )
93+ }
94+
95+ property [ " Result obeys the second Applicative composition law " ] = forAll { ( fl : ResultOf < ArrowOf < Int8 , Int8 > > , gl : ResultOf < ArrowOf < Int8 , Int8 > > , x : ResultOf < Int8 > ) in
96+ let f = { $0. getArrow } <^> fl. getResult
97+ let g = { $0. getArrow } <^> gl. getResult
98+ return ( pure ( curry ( • ) ) <*> f <*> g <*> x. getResult) == ( f <*> ( g <*> x. getResult) )
99+ }
100+
101+ property [ " Result obeys the Monad left identity law " ] = forAll { ( a : Int , fa : ArrowOf < Int , ResultOf < Int > > ) in
102+ let f = { $0. getResult } • fa. getArrow
103+ return ( pure ( a) >>- f) == f ( a)
104+ }
105+
106+ property [ " Result obeys the Monad right identity law " ] = forAll { ( m : ResultOf < Int > ) in
107+ return ( m. getResult >>- pure) == m. getResult
22108 }
23109
24- // fold
25- XCTAssert ( Result . error ( divisionError) . fold ( 0 , f: identity) == 0 )
26- XCTAssert ( Result . value ( 10 ) . fold ( 0 , f: identity) == 10 )
27-
28- let start = 17
29- let first : Result < Int > = divTwoEvenly ( start)
30- let prettyPrinted : Result < String > = { $0. description } <^> first
31- let snd = first >>- divTwoEvenly
32- XCTAssert ( prettyPrinted == Result . value ( " 8 " ) )
33- XCTAssert ( snd == . Error( divisionError) )
34-
35- let startResult : Result < Int > = pure ( start)
36- XCTAssert ( startResult == Result . value ( 17 ) )
37- let doubleResult : Result < Int -> Int > = pure ( { $0 * 2 } )
38- XCTAssert ( ( doubleResult <*> startResult) == Result . value ( 34 ) , " test ap: (result, result) " )
39- let noF : Result < Int -> Int > = . Error( divisionError)
40- let noX : Result < Int > = snd
41- XCTAssert ( ( noF <*> startResult) == . Error( divisionError) , " test ap: (error, result) " )
42- XCTAssert ( ( doubleResult <*> noX) == . Error( divisionError) , " test ap: (result, error) " )
43- XCTAssert ( ( noF <*> noX) == . Error( divisionError) , " test ap: (error, error) " )
44-
45- // special constructor
46- XCTAssert ( Result ( divisionError, 1 ) == . Error( divisionError) , " special Result cons error " )
47- XCTAssert ( Result ( nil , 1 ) == Result . value ( 1 ) , " special Result cons value " )
110+ property [ " Result obeys the Monad associativity law " ] = forAll { ( fa : ArrowOf < Int , ResultOf < Int > > , ga : ArrowOf < Int , ResultOf < Int > > , m : ResultOf < Int > ) in
111+ let f = { $0. getResult } • fa. getArrow
112+ let g = { $0. getResult } • ga. getArrow
113+ return ( ( m. getResult >>- f) >>- g) == ( m. getResult >>- { x in f ( x) >>- g } )
114+ }
48115 }
49116
50117 func testResultFrom( ) {
@@ -62,17 +129,4 @@ class ResultSpec : XCTestCase {
62129 XCTAssertTrue ( ( throwableFunction !! - 1 ) == Result . error ( e) , " " )
63130 XCTAssertTrue ( ( throwableFunction !! 1 ) == Result . value ( " 1 " ) , " " )
64131 }
65-
66- func testEitherResult( ) {
67- // tests:
68- // - either -> result
69- // - result -> either
70-
71- let resultOne : Result < Int > = Result . value ( 1 )
72- let eitherOne : Either < NSError , Int > = resultOne. toEither ( )
73- let resultAgain : Result < Int > = eitherOne. toResult ( identity)
74- XCTAssert ( resultOne == resultAgain)
75-
76- let typeinfworkplz = Result . Value ( Box ( 1 ) ) . toEither ( ) . toResult ( identity)
77- }
78132}
0 commit comments