@@ -12,35 +12,43 @@ import XCTest
12
12
import class Foundation. Bundle
13
13
14
14
final class DealerTests : XCTestCase {
15
- func testExample( ) throws {
16
- // This is an example of a functional test case.
17
- // Use XCTAssert and related functions to verify your tests produce the correct
18
- // results.
19
-
20
- // Some of the APIs that we use below are available in macOS 10.13 and above.
21
- guard #available( macOS 10 . 13 , * ) else {
22
- return
23
- }
15
+ func testUsage( ) throws {
16
+ let ( status, output, error) = try execute ( with: [ " --help " ] )
17
+ XCTAssertEqual ( status, EXIT_SUCCESS)
18
+ XCTAssert ( output? . starts ( with: " OVERVIEW: Shuffles a deck of playing cards and deals a number of cards. " ) ?? false )
19
+ XCTAssertEqual ( error, " " )
20
+ }
24
21
25
- // Mac Catalyst won't have `Process`, but it is supported for executables.
26
- #if !targetEnvironment(macCatalyst)
22
+ func testDealOneCard( ) throws {
23
+ let ( status, output, error) = try execute ( with: [ " 1 " ] )
24
+ XCTAssertEqual ( status, EXIT_SUCCESS)
25
+ XCTAssertEqual ( output? . filter ( \. isPlayingCardSuit) . count, 1 )
27
26
28
- let dealerBinary = productsDirectory. appendingPathComponent ( " dealer " )
27
+ XCTAssertEqual ( error, " " )
28
+ }
29
29
30
- let process = Process ( )
31
- process. executableURL = dealerBinary
30
+ func testDealTenCards( ) throws {
31
+ let ( status, output, error) = try execute ( with: [ " 10 " ] )
32
+ XCTAssertEqual ( status, EXIT_SUCCESS)
33
+ XCTAssertEqual ( output? . filter ( \. isPlayingCardSuit) . count, 10 )
32
34
33
- let pipe = Pipe ( )
34
- process . standardOutput = pipe
35
+ XCTAssertEqual ( error , " " )
36
+ }
35
37
36
- try process. run ( )
37
- process. waitUntilExit ( )
38
+ func testDealThirteenCardsFourTimes( ) throws {
39
+ let ( status, output, error) = try execute ( with: [ " 13 " , " 13 " , " 13 " , " 13 " ] )
40
+ XCTAssertEqual ( status, EXIT_SUCCESS)
41
+ XCTAssertEqual ( output? . filter ( \. isPlayingCardSuit) . count, 52 )
42
+ XCTAssertEqual ( output? . filter ( \. isNewline) . count, 4 )
38
43
39
- let data = pipe . fileHandleForReading . readDataToEndOfFile ( )
40
- let output = String ( data : data , encoding : . utf8 )
44
+ XCTAssertEqual ( error , " " )
45
+ }
41
46
42
- XCTAssertNotEqual ( output, " " )
43
- #endif
47
+ func testDealOneHundredCards( ) throws {
48
+ let ( status, output, error) = try execute ( with: [ " 100 " ] )
49
+ XCTAssertNotEqual ( status, EXIT_SUCCESS)
50
+ XCTAssertEqual ( output, " " )
51
+ XCTAssertEqual ( error, " Error: Not enough cards \n " )
44
52
}
45
53
46
54
/// Returns path to the built products directory.
@@ -54,4 +62,42 @@ final class DealerTests: XCTestCase {
54
62
return Bundle . main. bundleURL
55
63
#endif
56
64
}
65
+
66
+ private func execute( with arguments: [ String ] = [ ] ) throws -> ( status: Int32 , output: String ? , error: String ? ) {
67
+ let process = Process ( )
68
+ process. executableURL = productsDirectory. appendingPathComponent ( " dealer " )
69
+ process. arguments = arguments
70
+
71
+ let outputPipe = Pipe ( )
72
+ process. standardOutput = outputPipe
73
+
74
+ let errorPipe = Pipe ( )
75
+ process. standardError = errorPipe
76
+
77
+ try process. run ( )
78
+ process. waitUntilExit ( )
79
+
80
+ let status = process. terminationStatus
81
+
82
+ let outputData = outputPipe. fileHandleForReading. readDataToEndOfFile ( )
83
+ let output = String ( data: outputData, encoding: . utf8)
84
+
85
+ let errorData = errorPipe. fileHandleForReading. readDataToEndOfFile ( )
86
+ let error = String ( data: errorData, encoding: . utf8)
87
+
88
+ return ( status, output, error)
89
+ }
90
+ }
91
+
92
+ // MARK: -
93
+
94
+ private extension Character {
95
+ var isPlayingCardSuit : Bool {
96
+ switch self {
97
+ case " ♠︎ " , " ♡ " , " ♢ " , " ♣︎ " :
98
+ return true
99
+ default :
100
+ return false
101
+ }
102
+ }
57
103
}
0 commit comments