scanner_test+test.ha (5227B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use bytes; 5 use encoding::utf8; 6 use io; 7 use memio; 8 use strings; 9 use types; 10 11 @test fn read_byte() void = { 12 let buf = memio::fixed([1, 3, 3, 7]); 13 14 assert(read_byte(&buf) as u8 == 1); 15 assert(read_byte(&buf) as u8 == 3); 16 assert(read_byte(&buf) as u8 == 3); 17 assert(read_byte(&buf) as u8 == 7); 18 assert(read_byte(&buf) is io::EOF); 19 }; 20 21 @test fn read_tok() void = { 22 let buf = memio::fixed([1, 3, 4, 5, 3, 7]); 23 24 let tok = read_tok(&buf, 4) as []u8; 25 defer free(tok); 26 assert(bytes::equal(tok, [1, 3])); 27 28 let tok = read_tok(&buf, 7) as []u8; 29 defer free(tok); 30 assert(bytes::equal(tok, [5, 3])); 31 32 assert(read_tok(&buf, 1) is io::EOF); 33 }; 34 35 @test fn read_line() void = { 36 let helloworld = strings::toutf8("hello\nworld"); 37 let buf = memio::fixed(helloworld); 38 39 let line = read_line(&buf) as []u8; 40 defer free(line); 41 assert(bytes::equal(line, strings::toutf8("hello"))); 42 43 let line = read_line(&buf) as []u8; 44 defer free(line); 45 assert(bytes::equal(line, strings::toutf8("world"))); 46 47 assert(read_line(&buf) is io::EOF); 48 }; 49 50 @test fn read_rune() void = { 51 let in = memio::fixed([ 52 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 53 0xAB, 0xE3, 0x81, 0xA1, 0xE3, 0x81, 0xAF, 0x00, 54 ]); 55 56 const expected: [_](rune | utf8::invalid | io::EOF | io::error) = [ 57 'こ', 'ん', 'に', 'ち', 'は', '\0', io::EOF, 58 ]; 59 for (let i = 0z; i < len(expected); i += 1) { 60 let want = expected[i]; 61 62 match (read_rune(&in)) { 63 case let r: rune => 64 assert(want is rune && want as rune == r); 65 case io::EOF => 66 assert(want is io::EOF); 67 case => 68 abort(); 69 }; 70 }; 71 }; 72 73 @test fn scan_rune() void = { 74 let in = memio::fixed(strings::toutf8("hello")); 75 let scanner = newscanner(&in, 32); 76 defer finish(&scanner); 77 78 const expected: [_](rune | utf8::invalid | io::EOF | io::error) = [ 79 'h', 'e', 'l', 'l', 'o', io::EOF, 80 ]; 81 for (let i = 0z; i < len(expected); i += 1) { 82 let want = expected[i]; 83 84 match (scan_rune(&scanner)) { 85 case let r: rune => 86 assert(want is rune && want as rune == r); 87 case io::EOF => 88 assert(want is io::EOF); 89 case => 90 abort(); 91 }; 92 }; 93 }; 94 95 @test fn scan_rune_cutoff() void = { 96 let in = memio::fixed([ 97 'a', 0xE3, 98 ]); 99 let scanner = newscanner(&in, 32); 100 defer finish(&scanner); 101 102 const expected: [_](rune | utf8::invalid | io::EOF | io::error) = [ 103 'a', utf8::invalid, 104 ]; 105 for (let i = 0z; i < len(expected); i += 1) { 106 let want = expected[i]; 107 108 match (scan_rune(&scanner)) { 109 case let r: rune => 110 assert(want is rune && want as rune == r); 111 case io::EOF => 112 assert(want is io::EOF); 113 case utf8::invalid => 114 assert(want is utf8::invalid); 115 case => 116 abort(); 117 }; 118 }; 119 }; 120 121 @test fn scan_byte() void = { 122 let in = memio::fixed([1, 2, 3]); 123 let scanner = newscanner(&in, 3); 124 defer finish(&scanner); 125 126 assert(scan_byte(&scanner) as u8 == 1); 127 assert(scan_byte(&scanner) as u8 == 2); 128 assert(scan_byte(&scanner) as u8 == 3); 129 assert(scan_byte(&scanner) is io::EOF); 130 }; 131 132 @test fn scan_read() void = { 133 const expected: [_]u8 = [ 134 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 135 ]; 136 let in = memio::fixed(expected); 137 138 let scanner = newscanner(&in, 2); 139 defer finish(&scanner); 140 let result = io::drain(&scanner)!; 141 defer free(result); 142 assert(bytes::equal(expected, result)); 143 }; 144 145 @test fn scan_unread() void = { 146 const expected: str = " I will not repeat \nDone!\n"; 147 let in = memio::fixed(strings::toutf8(expected)); 148 149 let scanner = newscanner(&in, 32); 150 defer finish(&scanner); 151 152 let b = scan_byte(&scanner) as u8; 153 unread(&scanner, [b]); 154 155 let b = scan_rune(&scanner) as rune; 156 unread(&scanner, utf8::encoderune(b)!); 157 158 let l = scan_line(&scanner)! as const str; 159 assert(l == " I will not repeat "); 160 161 unread(&scanner, strings::toutf8("\n")); 162 unread(&scanner, strings::toutf8(l)); 163 let l = scan_line(&scanner)! as const str; 164 assert(l == " I will not repeat "); 165 166 unread(&scanner, strings::toutf8("\n")); 167 unread(&scanner, strings::toutf8(strings::trim(l))); 168 let l = scan_line(&scanner)! as const str; 169 assert(l == "I will not repeat"); 170 171 unread(&scanner, strings::toutf8("See?\n")); 172 let l = scan_line(&scanner)! as const str; 173 assert(l == "See?"); 174 175 let b = scan_rune(&scanner) as rune; 176 unreadrune(&scanner, b); 177 unreadrune(&scanner, ' '); 178 unread(&scanner, strings::toutf8("I'm")); 179 let l = scan_line(&scanner)! as const str; 180 assert(l == "I'm Done!"); 181 182 assert(scan_line(&scanner) is io::EOF); 183 }; 184 185 @test fn scan_uncomplete_line() void = { 186 let buf = memio::dynamic(); 187 let scan = newscanner(&buf); 188 189 assert(scan_line(&scan) is io::EOF); 190 191 io::write(&buf, strings::toutf8("hello"))!; 192 io::seek(&buf, 0, io::whence::SET)!; 193 194 assert(scan_line(&scan) is io::EOF); 195 196 io::write(&buf, strings::toutf8("\n"))!; 197 io::seek(&buf, -1, io::whence::CUR)!; 198 199 let line = scan_line(&scan) as const str; 200 assert(strings::compare(line, "hello") == 0); 201 }; 202 203 @test fn greedy_scan_uncomplete_line() void = { 204 let buf = memio::dynamic(); 205 let scan = newscanner(&buf, types::SIZE_MAX, scan_options::EOF_GREEDY); 206 207 assert(scan_line(&scan) is io::EOF); 208 209 io::write(&buf, strings::toutf8("hello"))!; 210 io::seek(&buf, 0, io::whence::SET)!; 211 212 let line = scan_line(&scan) as const str; 213 assert(strings::compare(line, "hello") == 0); 214 };