From 700b0757620eae34ff5cc9430d66b896a389660c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Wed, 11 Oct 2023 18:13:25 +0200 Subject: [PATCH] Some text encoding tests. --- .../NBKDoubleWidth+Text.swift | 410 ++++++++++-------- 1 file changed, 223 insertions(+), 187 deletions(-) diff --git a/Tests/NBKDoubleWidthKitTests/NBKDoubleWidth+Text.swift b/Tests/NBKDoubleWidthKitTests/NBKDoubleWidth+Text.swift index 05902e35..efdd964a 100644 --- a/Tests/NBKDoubleWidthKitTests/NBKDoubleWidth+Text.swift +++ b/Tests/NBKDoubleWidthKitTests/NBKDoubleWidth+Text.swift @@ -54,99 +54,99 @@ final class NBKDoubleWidthTestsOnTextAsInt256: XCTestCase { } //=------------------------------------------------------------------------= - // MARK: Tests x Decode + // MARK: Tests x Decoding //=------------------------------------------------------------------------= func testDecodingRadix02() { - NBKAssertDecodeText(T.min, 02, "-1" + String(repeating: "0", count: T.bitWidth / 1 - 1)) - NBKAssertDecodeText(T.max, 02, String(repeating: "1", count: T.bitWidth / 1 - 1)) + NBKAssertDecodingText(T.min, 02, "-1" + String(repeating: "0", count: T.bitWidth / 1 - 1)) + NBKAssertDecodingText(T.max, 02, String(repeating: "1", count: T.bitWidth / 1 - 1)) } func testDecodingRadix03() { - NBKAssertDecodeText(T.min, 03, "-21221122120" + + NBKAssertDecodingText(T.min, 03, "-21221122120" + "12222212211110210202220000022211002111211122012220" + "12122202101121021220012201000100012101202122101020" + "20010111121211022111102111220220201211121011101022" ) - NBKAssertDecodeText(T.max, 03, "21221122120" + + NBKAssertDecodingText(T.max, 03, "21221122120" + "12222212211110210202220000022211002111211122012220" + "12122202101121021220012201000100012101202122101020" + "20010111121211022111102111220220201211121011101021" ) } func testDecodingRadix04() { - NBKAssertDecodeText(T.min, 04, "-2" + String(repeating: "0", count: T.bitWidth / 2 - 1)) - NBKAssertDecodeText(T.max, 04, "1" + String(repeating: "3", count: T.bitWidth / 2 - 1)) + NBKAssertDecodingText(T.min, 04, "-2" + String(repeating: "0", count: T.bitWidth / 2 - 1)) + NBKAssertDecodingText(T.max, 04, "1" + String(repeating: "3", count: T.bitWidth / 2 - 1)) } func testDecodingRadix08() { - NBKAssertDecodeText(T.min, 08, "-1" + String(repeating: "0", count: 85)) - NBKAssertDecodeText(T.max, 08, String(repeating: "7", count: 85)) + NBKAssertDecodingText(T.min, 08, "-1" + String(repeating: "0", count: 85)) + NBKAssertDecodingText(T.max, 08, String(repeating: "7", count: 85)) } func testDecodingRadix10() { - NBKAssertDecodeText(T.min, 10, "-57896044618658097711785492504343953926634992332820282019728792003956564819968") - NBKAssertDecodeText(T.max, 10, "57896044618658097711785492504343953926634992332820282019728792003956564819967") + NBKAssertDecodingText(T.min, 10, "-57896044618658097711785492504343953926634992332820282019728792003956564819968") + NBKAssertDecodingText(T.max, 10, "57896044618658097711785492504343953926634992332820282019728792003956564819967") } func testDecodingRadix16() { - NBKAssertDecodeText(T.min, 16, "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) - NBKAssertDecodeText(T.max, 16, "7" + String(repeating: "f", count: T.bitWidth / 4 - 1)) + NBKAssertDecodingText(T.min, 16, "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) + NBKAssertDecodingText(T.max, 16, "7" + String(repeating: "f", count: T.bitWidth / 4 - 1)) } func testDecodingRadix32() { - NBKAssertDecodeText(T.min, 32, "-1" + String(repeating: "0", count: 51)) - NBKAssertDecodeText(T.max, 32, String(repeating: "v", count: 51)) + NBKAssertDecodingText(T.min, 32, "-1" + String(repeating: "0", count: 51)) + NBKAssertDecodingText(T.max, 32, String(repeating: "v", count: 51)) } func testDecodingRadix36() { - NBKAssertDecodeText(T.min, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8") - NBKAssertDecodeText(T.max, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu7") + NBKAssertDecodingText(T.min, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8") + NBKAssertDecodingText(T.max, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu7") } func testDecodingRadixLiteralAsNumber() { - NBKAssertDecodeText(T( 33), 36, "0x") - NBKAssertDecodeText(T( 24), 36, "0o") - NBKAssertDecodeText(T( 11), 36, "0b") + NBKAssertDecodingText(T( 33), 36, "0x") + NBKAssertDecodingText(T( 24), 36, "0o") + NBKAssertDecodingText(T( 11), 36, "0b") - NBKAssertDecodeText(T( 33), 36, "+0x") - NBKAssertDecodeText(T( 24), 36, "+0o") - NBKAssertDecodeText(T( 11), 36, "+0b") + NBKAssertDecodingText(T( 33), 36, "+0x") + NBKAssertDecodingText(T( 24), 36, "+0o") + NBKAssertDecodingText(T( 11), 36, "+0b") - NBKAssertDecodeText(T(-33), 36, "-0x") - NBKAssertDecodeText(T(-24), 36, "-0o") - NBKAssertDecodeText(T(-11), 36, "-0b") + NBKAssertDecodingText(T(-33), 36, "-0x") + NBKAssertDecodingText(T(-24), 36, "-0o") + NBKAssertDecodingText(T(-11), 36, "-0b") } func testDecodingRadixLiteralAsRadixReturnsNil() { - NBKAssertDecodeText(T?.none, 10, "0x10") - NBKAssertDecodeText(T?.none, 10, "0o10") - NBKAssertDecodeText(T?.none, 10, "0b10") + NBKAssertDecodingText(T?.none, 10, "0x10") + NBKAssertDecodingText(T?.none, 10, "0o10") + NBKAssertDecodingText(T?.none, 10, "0b10") - NBKAssertDecodeText(T?.none, 10, "+0x10") - NBKAssertDecodeText(T?.none, 10, "+0o10") - NBKAssertDecodeText(T?.none, 10, "+0b10") + NBKAssertDecodingText(T?.none, 10, "+0x10") + NBKAssertDecodingText(T?.none, 10, "+0o10") + NBKAssertDecodingText(T?.none, 10, "+0b10") - NBKAssertDecodeText(T?.none, 10, "-0x10") - NBKAssertDecodeText(T?.none, 10, "-0o10") - NBKAssertDecodeText(T?.none, 10, "-0b10") + NBKAssertDecodingText(T?.none, 10, "-0x10") + NBKAssertDecodingText(T?.none, 10, "-0o10") + NBKAssertDecodingText(T?.none, 10, "-0b10") } func testDecodingStringsWithAndWithoutSign() { - NBKAssertDecodeText(T( 1234567890), 10, "1234567890") - NBKAssertDecodeText(T( 1234567890), 10, "+1234567890") - NBKAssertDecodeText(T(-1234567890), 10, "-1234567890") + NBKAssertDecodingText(T( 1234567890), 10, "1234567890") + NBKAssertDecodingText(T( 1234567890), 10, "+1234567890") + NBKAssertDecodingText(T(-1234567890), 10, "-1234567890") } func testDecodingStrategyIsCaseInsensitive() { - NBKAssertDecodeText(T(0xabcdef), 16, "abcdef") - NBKAssertDecodeText(T(0xABCDEF), 16, "ABCDEF") - NBKAssertDecodeText(T(0xaBcDeF), 16, "aBcDeF") - NBKAssertDecodeText(T(0xAbCdEf), 16, "AbCdEf") + NBKAssertDecodingText(T(0xabcdef), 16, "abcdef") + NBKAssertDecodingText(T(0xABCDEF), 16, "ABCDEF") + NBKAssertDecodingText(T(0xaBcDeF), 16, "aBcDeF") + NBKAssertDecodingText(T(0xAbCdEf), 16, "AbCdEf") } func testDecodingUnalignedStringsIsOK() { - NBKAssertDecodeText(T(1), 10, "1") - NBKAssertDecodeText(T(1), 16, "1") + NBKAssertDecodingText(T(1), 10, "1") + NBKAssertDecodingText(T(1), 16, "1") } func testDecodingPrefixingZerosHasNoEffect() { @@ -154,32 +154,32 @@ final class NBKDoubleWidthTestsOnTextAsInt256: XCTestCase { let one = String(repeating: "0", count: T.bitWidth) + "1" for radix in 02 ... 36 { - NBKAssertDecodeText(T(0), radix, zero) - NBKAssertDecodeText(T(1), radix, one ) + NBKAssertDecodingText(T(0), radix, zero) + NBKAssertDecodingText(T(1), radix, one ) } } func testDecodingInvalidCharactersReturnsNil() { - NBKAssertDecodeText(T?.none, 16, "/") - NBKAssertDecodeText(T?.none, 16, "G") + NBKAssertDecodingText(T?.none, 16, "/") + NBKAssertDecodingText(T?.none, 16, "G") - NBKAssertDecodeText(T?.none, 10, "/") - NBKAssertDecodeText(T?.none, 10, ":") + NBKAssertDecodingText(T?.none, 10, "/") + NBKAssertDecodingText(T?.none, 10, ":") - NBKAssertDecodeText(T?.none, 10, String(repeating: "1", count: 19) + "/") - NBKAssertDecodeText(T?.none, 10, String(repeating: "1", count: 19) + ":") + NBKAssertDecodingText(T?.none, 10, String(repeating: "1", count: 19) + "/") + NBKAssertDecodingText(T?.none, 10, String(repeating: "1", count: 19) + ":") } func testDecodingStringsWithoutDigitsReturnsNil() { - NBKAssertDecodeText(T?.none, 10, "") - NBKAssertDecodeText(T?.none, 10, "+") - NBKAssertDecodeText(T?.none, 10, "-") - NBKAssertDecodeText(T?.none, 10, "~") + NBKAssertDecodingText(T?.none, 10, "") + NBKAssertDecodingText(T?.none, 10, "+") + NBKAssertDecodingText(T?.none, 10, "-") + NBKAssertDecodingText(T?.none, 10, "~") - NBKAssertDecodeText(T?.none, 16, "") - NBKAssertDecodeText(T?.none, 16, "+") - NBKAssertDecodeText(T?.none, 16, "-") - NBKAssertDecodeText(T?.none, 16, "~") + NBKAssertDecodingText(T?.none, 16, "") + NBKAssertDecodingText(T?.none, 16, "+") + NBKAssertDecodingText(T?.none, 16, "-") + NBKAssertDecodingText(T?.none, 16, "~") } func testDecodingValuesOutsideOfRepresentableRangeReturnsNil() { @@ -187,70 +187,88 @@ final class NBKDoubleWidthTestsOnTextAsInt256: XCTestCase { let negative = "-" + String(repeating: "1", count: T.bitWidth) for radix in 02 ... 36 { - NBKAssertDecodeText(T?.none, radix, positive) - NBKAssertDecodeText(T?.none, radix, negative) + NBKAssertDecodingText(T?.none, radix, positive) + NBKAssertDecodingText(T?.none, radix, negative) } - NBKAssertDecodeText(T?.none, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu9" ) // - 01 - NBKAssertDecodeText(T?.none, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu80") // * 36 - NBKAssertDecodeText(T?.none, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8" ) // + 01 - NBKAssertDecodeText(T?.none, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu70") // * 36 + NBKAssertDecodingText(T?.none, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu9" ) // - 01 + NBKAssertDecodingText(T?.none, 36, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu80") // * 36 + NBKAssertDecodingText(T?.none, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8" ) // + 01 + NBKAssertDecodingText(T?.none, 36, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu70") // * 36 } //=------------------------------------------------------------------------= - // MARK: Tests x Encode + // MARK: Tests x Encoding //=------------------------------------------------------------------------= func testEncodingRadix02() { - NBKAssertEncodeText(T.min, 02, false, "-1" + String(repeating: "0", count: T.bitWidth / 1 - 1)) - NBKAssertEncodeText(T.max, 02, false, String(repeating: "1", count: T.bitWidth / 1 - 1)) + NBKAssertEncodingText(T.min, 02, false, "-1" + String(repeating: "0", count: T.bitWidth / 1 - 1)) + NBKAssertEncodingText(T.max, 02, false, String(repeating: "1", count: T.bitWidth / 1 - 1)) } func testEncodingRadix03() { - NBKAssertEncodeText(T.min, 03, false, "-21221122120" + - "12222212211110210202220000022211002111211122012220" + - "12122202101121021220012201000100012101202122101020" + - "20010111121211022111102111220220201211121011101022" ) - NBKAssertEncodeText(T.max, 03, false, "21221122120" + - "12222212211110210202220000022211002111211122012220" + - "12122202101121021220012201000100012101202122101020" + - "20010111121211022111102111220220201211121011101021" ) + NBKAssertEncodingText(T.min, 03, false, + /*--------------------------*/"-212211221201222221221111021020222" + + "0000022211002111211122012220121222021011210212200122010001000121" + + "0120212210102020010111121211022111102111220220201211121011101022" ) + NBKAssertEncodingText(T.max, 03, false, + /*---------------------------*/"212211221201222221221111021020222" + + "0000022211002111211122012220121222021011210212200122010001000121" + + "0120212210102020010111121211022111102111220220201211121011101021" ) } func testEncodingRadix04() { - NBKAssertEncodeText(T.min, 04, false, "-2" + String(repeating: "0", count: T.bitWidth / 2 - 1)) - NBKAssertEncodeText(T.max, 04, false, "1" + String(repeating: "3", count: T.bitWidth / 2 - 1)) + NBKAssertEncodingText(T.min, 04, false, "-2" + String(repeating: "0", count: T.bitWidth / 2 - 1)) + NBKAssertEncodingText(T.max, 04, false, "1" + String(repeating: "3", count: T.bitWidth / 2 - 1)) } func testEncodingRadix08() { - NBKAssertEncodeText(T.min, 08, false, "-1" + String(repeating: "0", count: 85)) - NBKAssertEncodeText(T.max, 08, false, String(repeating: "7", count: 85)) + NBKAssertEncodingText(T.min, 08, false, "-1" + String(repeating: "0", count: 85)) + NBKAssertEncodingText(T.max, 08, false, String(repeating: "7", count: 85)) } func testEncodingRadix10() { - NBKAssertEncodeText(T.min, 10, false, "-57896044618658097711785492504343953926634992332820282019728792003956564819968") - NBKAssertEncodeText(T.max, 10, false, "57896044618658097711785492504343953926634992332820282019728792003956564819967") + NBKAssertEncodingText(T.min, 10, false, "-57896044618658097711785492504343953926634992332820282019728792003956564819968") + NBKAssertEncodingText(T.max, 10, false, "57896044618658097711785492504343953926634992332820282019728792003956564819967") } func testEncodingRadix16() { - NBKAssertEncodeText(T.min, 16, false, "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) - NBKAssertEncodeText(T.min, 16, true , "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) - NBKAssertEncodeText(T.max, 16, false, "7" + String(repeating: "f", count: T.bitWidth / 4 - 1)) - NBKAssertEncodeText(T.max, 16, true , "7" + String(repeating: "F", count: T.bitWidth / 4 - 1)) + NBKAssertEncodingText(T.min, 16, false, "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) + NBKAssertEncodingText(T.min, 16, true , "-8" + String(repeating: "0", count: T.bitWidth / 4 - 1)) + NBKAssertEncodingText(T.max, 16, false, "7" + String(repeating: "f", count: T.bitWidth / 4 - 1)) + NBKAssertEncodingText(T.max, 16, true , "7" + String(repeating: "F", count: T.bitWidth / 4 - 1)) } func testEncodingRadix32() { - NBKAssertEncodeText(T.min, 32, false, "-1" + String(repeating: "0", count: 51)) - NBKAssertEncodeText(T.min, 32, true , "-1" + String(repeating: "0", count: 51)) - NBKAssertEncodeText(T.max, 32, false, String(repeating: "v", count: 51)) - NBKAssertEncodeText(T.max, 32, true , String(repeating: "V", count: 51)) + NBKAssertEncodingText(T.min, 32, false, "-1" + String(repeating: "0", count: 51)) + NBKAssertEncodingText(T.min, 32, true , "-1" + String(repeating: "0", count: 51)) + NBKAssertEncodingText(T.max, 32, false, String(repeating: "v", count: 51)) + NBKAssertEncodingText(T.max, 32, true , String(repeating: "V", count: 51)) } func testEncodingRadix36() { - NBKAssertEncodeText(T.min, 36, false, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8") - NBKAssertEncodeText(T.min, 36, true , "-36UKV65J19B11MBVJYFUI963V4MY01KRTH19G3R3BK1OJLRWU8") - NBKAssertEncodeText(T.max, 36, false, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu7") - NBKAssertEncodeText(T.max, 36, true , "36UKV65J19B11MBVJYFUI963V4MY01KRTH19G3R3BK1OJLRWU7") + NBKAssertEncodingText(T.min, 36, false, "-36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu8") + NBKAssertEncodingText(T.min, 36, true , "-36UKV65J19B11MBVJYFUI963V4MY01KRTH19G3R3BK1OJLRWU8") + NBKAssertEncodingText(T.max, 36, false, "36ukv65j19b11mbvjyfui963v4my01krth19g3r3bk1ojlrwu7") + NBKAssertEncodingText(T.max, 36, true , "36UKV65J19B11MBVJYFUI963V4MY01KRTH19G3R3BK1OJLRWU7") + } + + func testEncodingNearRadixPowers() { + self.continueAfterFailure = false + let alphabet = Array("0123456789abcdefghijklmnopqrstuvwxyz") + for radix in 2 ... 36 { + + var power = T(radix) + let top: Character = alphabet[radix - 1] + + for exponent in 1 ..< Int.max { + NBKAssertEncodingText(power - 1, radix, false, String(repeating: top, count: exponent)) + NBKAssertEncodingText(power, radix, false, "1" + String(repeating: "0", count: exponent)) + NBKAssertEncodingText(power + 1, radix, false, "1" + String(repeating: "0", count: exponent - 1) + "1") + + guard !power.multiplyReportingOverflow(by: T.Digit(radix)) else { break } + } + } } } @@ -289,87 +307,87 @@ final class NBKDoubleWidthTestsOnTextAsUInt256: XCTestCase { } //=------------------------------------------------------------------------= - // MARK: Tests x Decode + // MARK: Tests x Decoding //=------------------------------------------------------------------------= func testDecodingRadix02() { - NBKAssertDecodeText(T.min, 02, "0") - NBKAssertDecodeText(T.max, 02, String(repeating: "1", count: T.bitWidth / 1)) + NBKAssertDecodingText(T.min, 02, "0") + NBKAssertDecodingText(T.max, 02, String(repeating: "1", count: T.bitWidth / 1)) } func testDecodingRadix03() { - NBKAssertDecodeText(T.min, 03, "0" ) - NBKAssertDecodeText(T.max, 03, "120220022011" + - "02222202122221121112210000122122012000200021102211" + - "02022111210012120210102102000200101210112021202111" + - "10021000020122121222212000211211110200012022202120" ) + NBKAssertDecodingText(T.min, 03, "0") + NBKAssertDecodingText(T.max, 03, + /*--------------------------*/"1202200220110222220212222112111221" + + "0000122122012000200021102211020221112100121202101021020002001012" + + "1011202120211110021000020122121222212000211211110200012022202120" ) } func testDecodingRadix04() { - NBKAssertDecodeText(T.min, 04, "0") - NBKAssertDecodeText(T.max, 04, String(repeating: "3", count: T.bitWidth / 2)) + NBKAssertDecodingText(T.min, 04, "0") + NBKAssertDecodingText(T.max, 04, String(repeating: "3", count: T.bitWidth / 2)) } func testDecodingRadix08() { - NBKAssertDecodeText(T.min, 08, "0") - NBKAssertDecodeText(T.max, 08, "1" + String(repeating: "7", count: 85)) + NBKAssertDecodingText(T.min, 08, "0") + NBKAssertDecodingText(T.max, 08, "1" + String(repeating: "7", count: 85)) } func testDecodingRadix10() { - NBKAssertDecodeText(T.min, 10, "0") - NBKAssertDecodeText(T.max, 10, "115792089237316195423570985008687907853269984665640564039457584007913129639935") + NBKAssertDecodingText(T.min, 10, "0") + NBKAssertDecodingText(T.max, 10, "115792089237316195423570985008687907853269984665640564039457584007913129639935") } func testDecodingRadix16() { - NBKAssertDecodeText(T.min, 16, "0") - NBKAssertDecodeText(T.max, 16, String(repeating: "f", count: T.bitWidth / 4)) + NBKAssertDecodingText(T.min, 16, "0") + NBKAssertDecodingText(T.max, 16, String(repeating: "f", count: T.bitWidth / 4)) } func testDecodingRadix32() { - NBKAssertDecodeText(T.min, 32, "0") - NBKAssertDecodeText(T.max, 32, "1" + String(repeating: "v", count: 51)) + NBKAssertDecodingText(T.min, 32, "0") + NBKAssertDecodingText(T.max, 32, "1" + String(repeating: "v", count: 51)) } func testDecodingRadix36() { - NBKAssertDecodeText(T.min, 36, "0") - NBKAssertDecodeText(T.max, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof") + NBKAssertDecodingText(T.min, 36, "0") + NBKAssertDecodingText(T.max, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof") } func testDecodingRadixLiteralAsNumber() { - NBKAssertDecodeText(T(33), 36, "0x") - NBKAssertDecodeText(T(24), 36, "0o") - NBKAssertDecodeText(T(11), 36, "0b") + NBKAssertDecodingText(T(33), 36, "0x") + NBKAssertDecodingText(T(24), 36, "0o") + NBKAssertDecodingText(T(11), 36, "0b") - NBKAssertDecodeText(T(33), 36, "+0x") - NBKAssertDecodeText(T(24), 36, "+0o") - NBKAssertDecodeText(T(11), 36, "+0b") + NBKAssertDecodingText(T(33), 36, "+0x") + NBKAssertDecodingText(T(24), 36, "+0o") + NBKAssertDecodingText(T(11), 36, "+0b") } func testDecodingRadixLiteralAsRadixReturnsNil() { - NBKAssertDecodeText(T?.none, 10, "0x10") - NBKAssertDecodeText(T?.none, 10, "0o10") - NBKAssertDecodeText(T?.none, 10, "0b10") + NBKAssertDecodingText(T?.none, 10, "0x10") + NBKAssertDecodingText(T?.none, 10, "0o10") + NBKAssertDecodingText(T?.none, 10, "0b10") - NBKAssertDecodeText(T?.none, 10, "+0x10") - NBKAssertDecodeText(T?.none, 10, "+0o10") - NBKAssertDecodeText(T?.none, 10, "+0b10") + NBKAssertDecodingText(T?.none, 10, "+0x10") + NBKAssertDecodingText(T?.none, 10, "+0o10") + NBKAssertDecodingText(T?.none, 10, "+0b10") } func testDecodingStringsWithAndWithoutSign() { - NBKAssertDecodeText(T(1234567890), 10, "1234567890") - NBKAssertDecodeText(T(1234567890), 10, "+1234567890") + NBKAssertDecodingText(T(1234567890), 10, "1234567890") + NBKAssertDecodingText(T(1234567890), 10, "+1234567890") } func testDecodingStrategyIsCaseInsensitive() { - NBKAssertDecodeText(T(0xabcdef), 16, "abcdef") - NBKAssertDecodeText(T(0xABCDEF), 16, "ABCDEF") - NBKAssertDecodeText(T(0xaBcDeF), 16, "aBcDeF") - NBKAssertDecodeText(T(0xAbCdEf), 16, "AbCdEf") + NBKAssertDecodingText(T(0xabcdef), 16, "abcdef") + NBKAssertDecodingText(T(0xABCDEF), 16, "ABCDEF") + NBKAssertDecodingText(T(0xaBcDeF), 16, "aBcDeF") + NBKAssertDecodingText(T(0xAbCdEf), 16, "AbCdEf") } func testDecodingUnalignedStringsIsOK() { - NBKAssertDecodeText(T(1), 10, "1") - NBKAssertDecodeText(T(1), 16, "1") + NBKAssertDecodingText(T(1), 10, "1") + NBKAssertDecodingText(T(1), 16, "1") } func testDecodingPrefixingZerosHasNoEffect() { @@ -377,32 +395,32 @@ final class NBKDoubleWidthTestsOnTextAsUInt256: XCTestCase { let one = String(repeating: "0", count: T.bitWidth) + "1" for radix in 02 ... 36 { - NBKAssertDecodeText(T(0), radix, zero) - NBKAssertDecodeText(T(1), radix, one ) + NBKAssertDecodingText(T(0), radix, zero) + NBKAssertDecodingText(T(1), radix, one ) } } func testDecodingInvalidCharactersReturnsNil() { - NBKAssertDecodeText(T?.none, 16, "/") - NBKAssertDecodeText(T?.none, 16, "G") + NBKAssertDecodingText(T?.none, 16, "/") + NBKAssertDecodingText(T?.none, 16, "G") - NBKAssertDecodeText(T?.none, 10, "/") - NBKAssertDecodeText(T?.none, 10, ":") + NBKAssertDecodingText(T?.none, 10, "/") + NBKAssertDecodingText(T?.none, 10, ":") - NBKAssertDecodeText(T?.none, 10, String(repeating: "1", count: 19) + "/") - NBKAssertDecodeText(T?.none, 10, String(repeating: "1", count: 19) + ":") + NBKAssertDecodingText(T?.none, 10, String(repeating: "1", count: 19) + "/") + NBKAssertDecodingText(T?.none, 10, String(repeating: "1", count: 19) + ":") } func testDecodingStringsWithoutDigitsReturnsNil() { - NBKAssertDecodeText(T?.none, 10, "") - NBKAssertDecodeText(T?.none, 10, "+") - NBKAssertDecodeText(T?.none, 10, "-") - NBKAssertDecodeText(T?.none, 10, "~") + NBKAssertDecodingText(T?.none, 10, "") + NBKAssertDecodingText(T?.none, 10, "+") + NBKAssertDecodingText(T?.none, 10, "-") + NBKAssertDecodingText(T?.none, 10, "~") - NBKAssertDecodeText(T?.none, 16, "") - NBKAssertDecodeText(T?.none, 16, "+") - NBKAssertDecodeText(T?.none, 16, "-") - NBKAssertDecodeText(T?.none, 16, "~") + NBKAssertDecodingText(T?.none, 16, "") + NBKAssertDecodingText(T?.none, 16, "+") + NBKAssertDecodingText(T?.none, 16, "-") + NBKAssertDecodingText(T?.none, 16, "~") } func testDecodingValuesOutsideOfRepresentableRangeReturnsNil() { @@ -410,65 +428,83 @@ final class NBKDoubleWidthTestsOnTextAsUInt256: XCTestCase { let negative = "-" + String(repeating: "1", count: 1) for radix in 02 ... 36 { - NBKAssertDecodeText(T?.none, radix, positive) - NBKAssertDecodeText(T?.none, radix, negative) + NBKAssertDecodingText(T?.none, radix, positive) + NBKAssertDecodingText(T?.none, radix, negative) } - NBKAssertDecodeText(T?.none, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtog" ) // + 01 - NBKAssertDecodeText(T?.none, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof0") // * 36 + NBKAssertDecodingText(T?.none, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtog" ) // + 01 + NBKAssertDecodingText(T?.none, 36, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof0") // * 36 } //=------------------------------------------------------------------------= - // MARK: Tests x Encode + // MARK: Tests x Encoding //=------------------------------------------------------------------------= func testEncodingRadix02() { - NBKAssertEncodeText(T.min, 02, false, "0") - NBKAssertEncodeText(T.max, 02, false, String(repeating: "1", count: T.bitWidth / 1)) + NBKAssertEncodingText(T.min, 02, false, "0") + NBKAssertEncodingText(T.max, 02, false, String(repeating: "1", count: T.bitWidth / 1)) } func testEncodingRadix03() { - NBKAssertEncodeText(T.min, 03, false, "0" ) - NBKAssertEncodeText(T.max, 03, false, "120220022011" + - "02222202122221121112210000122122012000200021102211" + - "02022111210012120210102102000200101210112021202111" + - "10021000020122121222212000211211110200012022202120" ) + NBKAssertEncodingText(T.min, 03, false, "0") + NBKAssertEncodingText(T.max, 03, false, + /*--------------------------*/"1202200220110222220212222112111221" + + "0000122122012000200021102211020221112100121202101021020002001012" + + "1011202120211110021000020122121222212000211211110200012022202120" ) } func testEncodingRadix04() { - NBKAssertEncodeText(T.min, 04, false, "0") - NBKAssertEncodeText(T.max, 04, false, String(repeating: "3", count: T.bitWidth / 2)) + NBKAssertEncodingText(T.min, 04, false, "0") + NBKAssertEncodingText(T.max, 04, false, String(repeating: "3", count: T.bitWidth / 2)) } func testEncodingRadix08() { - NBKAssertEncodeText(T.min, 08, false, "0") - NBKAssertEncodeText(T.max, 08, false, "1" + String(repeating: "7", count: 85)) + NBKAssertEncodingText(T.min, 08, false, "0") + NBKAssertEncodingText(T.max, 08, false, "1" + String(repeating: "7", count: 85)) } func testEncodingRadix10() { - NBKAssertEncodeText(T.min, 10, false, "0") - NBKAssertEncodeText(T.max, 10, false, "115792089237316195423570985008687907853269984665640564039457584007913129639935") + NBKAssertEncodingText(T.min, 10, false, "0") + NBKAssertEncodingText(T.max, 10, false, "115792089237316195423570985008687907853269984665640564039457584007913129639935") } func testEncodingRadix16() { - NBKAssertEncodeText(T.min, 16, false, "0") - NBKAssertEncodeText(T.min, 16, true , "0") - NBKAssertEncodeText(T.max, 16, false, String(repeating: "f", count: T.bitWidth / 4)) - NBKAssertEncodeText(T.max, 16, true , String(repeating: "F", count: T.bitWidth / 4)) + NBKAssertEncodingText(T.min, 16, false, "0") + NBKAssertEncodingText(T.min, 16, true , "0") + NBKAssertEncodingText(T.max, 16, false, String(repeating: "f", count: T.bitWidth / 4)) + NBKAssertEncodingText(T.max, 16, true , String(repeating: "F", count: T.bitWidth / 4)) } func testEncodingRadix32() { - NBKAssertEncodeText(T.min, 32, false, "0") - NBKAssertEncodeText(T.min, 32, true , "0") - NBKAssertEncodeText(T.max, 32, false, "1" + String(repeating: "v", count: 51)) - NBKAssertEncodeText(T.max, 32, true , "1" + String(repeating: "V", count: 51)) + NBKAssertEncodingText(T.min, 32, false, "0") + NBKAssertEncodingText(T.min, 32, true , "0") + NBKAssertEncodingText(T.max, 32, false, "1" + String(repeating: "v", count: 51)) + NBKAssertEncodingText(T.max, 32, true , "1" + String(repeating: "V", count: 51)) } func testEncodingRadix36() { - NBKAssertEncodeText(T.min, 36, false, "0") - NBKAssertEncodeText(T.min, 36, true , "0") - NBKAssertEncodeText(T.max, 36, false, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof") - NBKAssertEncodeText(T.max, 36, true , "6DP5QCB22IM238NR3WVP0IC7Q99W035JMY2IW7I6N43D37JTOF") + NBKAssertEncodingText(T.min, 36, false, "0") + NBKAssertEncodingText(T.min, 36, true , "0") + NBKAssertEncodingText(T.max, 36, false, "6dp5qcb22im238nr3wvp0ic7q99w035jmy2iw7i6n43d37jtof") + NBKAssertEncodingText(T.max, 36, true , "6DP5QCB22IM238NR3WVP0IC7Q99W035JMY2IW7I6N43D37JTOF") + } + + func testEncodingNearRadixPowers() { + self.continueAfterFailure = false + let alphabet = Array("0123456789abcdefghijklmnopqrstuvwxyz") + for radix in 2 ... 36 { + + var power = T(radix) + let top: Character = alphabet[radix - 1] + + for exponent in 1 ..< Int.max { + NBKAssertEncodingText(power - 1, radix, false, String(repeating: top, count: exponent)) + NBKAssertEncodingText(power, radix, false, "1" + String(repeating: "0", count: exponent)) + NBKAssertEncodingText(power + 1, radix, false, "1" + String(repeating: "0", count: exponent - 1) + "1") + + guard !power.multiplyReportingOverflow(by: T.Digit(radix)) else { break } + } + } } } @@ -508,10 +544,10 @@ final class NBKDoubleWidthTestsOnTextForEachRadixAsUInt256: XCTestCase { encoded.append(contentsOf: self.txt.suffix(1)) } - NBKAssertDecodeText(decoded, self.radix, txt) - NBKAssertDecodeText(decoded, self.radix, encoded) - NBKAssertEncodeText(decoded, self.radix, true, encoded.uppercased()) - NBKAssertEncodeText(decoded, self.radix, false, encoded.lowercased()) + NBKAssertDecodingText(decoded, self.radix, txt) + NBKAssertDecodingText(decoded, self.radix, encoded) + NBKAssertEncodingText(decoded, self.radix, true, encoded.uppercased()) + NBKAssertEncodingText(decoded, self.radix, false, encoded.lowercased()) } //=------------------------------------------------------------------------= @@ -1404,7 +1440,7 @@ file: StaticString = #file, line: UInt = #line) { XCTAssertEqual(T(description, radix: 10), integer, file: file, line: line) } -private func NBKAssertDecodeText( +private func NBKAssertDecodingText( _ integer: NBKDoubleWidth?, _ radix: Int, _ text: String, file: StaticString = #file, line: UInt = #line) { typealias T = NBKDoubleWidth @@ -1416,7 +1452,7 @@ file: StaticString = #file, line: UInt = #line) { XCTAssertEqual(T.init(text, radix: radix), integer, file: file, line: line) } -private func NBKAssertEncodeText( +private func NBKAssertEncodingText( _ integer: NBKDoubleWidth, _ radix: Int, _ uppercase: Bool, _ text: String, file: StaticString = #file, line: UInt = #line) { //=------------------------------------------=