@@ -8,23 +8,93 @@ import Web3Core
88@testable import web3swift
99
1010final class BIP44Tests : LocalTestCase {
11+ private var mockTransactionChecker : MockTransactionChecker !
12+
13+ override func setUpWithError( ) throws {
14+ try super. setUpWithError ( )
15+ mockTransactionChecker = MockTransactionChecker ( )
16+ }
17+
18+ override func tearDownWithError( ) throws {
19+ try super. tearDownWithError ( )
20+ mockTransactionChecker = nil
21+ }
1122
23+ //MARK: - warns false
24+
1225 func testDeriveNoWarn( ) async throws {
1326 let rootNode = try rootNode ( )
1427
15- let childNode = try await rootNode. derive ( path: " m/44'/60'/8096'/0/1 " , warns: false )
28+ let childNode = try await rootNode. derive ( path: " m/44'/60'/8096'/0/1 " , warns: false , transactionChecker : mockTransactionChecker )
1629
1730 XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 035785d4918449c87892371c0f9ccf6e4eda40a7fb0f773f1254c064d3bba64026 " )
1831 }
19-
20- func testAccountZeroCanBeDerived( ) async throws {
32+
33+ //MARK: - warns true
34+
35+ func testDeriveInvalidPath( ) async throws {
2136 let rootNode = try rootNode ( )
2237
23- let childNode = try await rootNode. derive ( path: " m/44'/60'/0'/0/255 " , warns: true )
38+ let childNode = try ? await rootNode. derive ( path: " " , warns: true , transactionChecker: mockTransactionChecker)
39+
40+ XCTAssertNil ( childNode)
41+ }
42+
43+ func testAccountZeroCanBeDerivedAlways( ) async throws {
44+ let rootNode = try rootNode ( )
45+
46+ let childNode = try await rootNode. derive ( path: " m/44'/60'/0'/0/255 " , warns: true , transactionChecker: mockTransactionChecker)
2447
2548 XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 0262fba1af8f149258123265318114066decf50d16c1222a9d657b7de2296c2734 " )
2649 }
2750
51+ func testAccountOneWithoutTransactionsInAccountZeroWarns( ) async throws {
52+ do {
53+ let rootNode = try rootNode ( )
54+ let path = " m/44'/60'/1'/0/0 "
55+ mockTransactionChecker. results = false . times ( n: 20 )
56+
57+ let _ = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
58+
59+ XCTFail ( " Child must not be created usign warns true for the path: \( path) " )
60+ } catch BIP44Error . warning {
61+ XCTAssertTrue ( true )
62+ }
63+ }
64+
65+ func testAccountOneWithTransactionsInAccountZeroNotWarns( ) async throws {
66+ do {
67+ let rootNode = try rootNode ( )
68+ let path = " m/44'/60'/1'/0/0 "
69+ var results = false . times ( n: 19 )
70+ results. append ( true )
71+ mockTransactionChecker. results = results
72+
73+ let childNode = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
74+
75+ XCTAssertEqual ( try XCTUnwrap ( childNode) . publicKey. toHexString ( ) , " 036cd8f1bad46fa7caf7a80d48528b90db2a3b7a5c9a18d74d61b286e03850abf4 " )
76+ } catch BIP44Error . warning {
77+ XCTFail ( " BIP44Error.warning must not be thrown " )
78+ }
79+ }
80+
81+ func testAccountTwoWithTransactionsInAccountZeroButNotInOneWarns( ) async throws {
82+ do {
83+ let rootNode = try rootNode ( )
84+ let path = " m/44'/60'/2'/0/0 "
85+ var results : Array < Bool > = . init( )
86+ results. append ( true )
87+ results. append ( contentsOf: false . times ( n: 20 ) )
88+ mockTransactionChecker. results = results
89+
90+ let _ = try await rootNode. derive ( path: path, warns: true , transactionChecker: mockTransactionChecker)
91+
92+ XCTFail ( " Child must not be created usign warns true for the path: \( path) " )
93+ } catch BIP44Error . warning {
94+ XCTAssertTrue ( true )
95+ }
96+ }
97+
2898 // MARK: - private
2999
30100 private func rootNode( ) throws -> HDNode {
@@ -33,3 +103,23 @@ final class BIP44Tests: LocalTestCase {
33103 return try XCTUnwrap ( HDNode ( seed: seed) )
34104 }
35105}
106+
107+ extension Bool {
108+ func times( n: Int ) -> Array < Bool > {
109+ var array : Array < Bool > = . init( )
110+ ( 0 ..< n) . forEach { _ in
111+ array. append ( self )
112+ }
113+ return array
114+ }
115+ }
116+
117+ private final class MockTransactionChecker : TransactionChecker {
118+ var addresses : [ String ] = . init( )
119+ var results : [ Bool ] = . init( )
120+
121+ func hasTransactions( address: String ) async throws -> Bool {
122+ addresses. append ( address)
123+ return results. removeFirst ( )
124+ }
125+ }
0 commit comments