1import * as std from "std"; 2import * as os from "os"; 3 4function assert(actual, expected, message) { 5 if (arguments.length == 1) 6 expected = true; 7 8 if (actual === expected) 9 return; 10 11 if (actual !== null && expected !== null 12 && typeof actual == 'object' && typeof expected == 'object' 13 && actual.toString() === expected.toString()) 14 return; 15 16 throw Error("assertion failed: got |" + actual + "|" + 17 ", expected |" + expected + "|" + 18 (message ? " (" + message + ")" : "")); 19} 20 21// load more elaborate version of assert if available 22try { std.loadScript("test_assert.js"); } catch(e) {} 23 24/*----------------*/ 25 26function test_printf() 27{ 28 assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc"); 29 assert(std.sprintf("%010d", 123), "0000000123"); 30 assert(std.sprintf("%x", -2), "fffffffe"); 31 assert(std.sprintf("%lx", -2), "fffffffffffffffe"); 32 assert(std.sprintf("%10.1f", 2.1), " 2.1"); 33 assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13"); 34 assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff"); 35} 36 37function test_file1() 38{ 39 var f, len, str, size, buf, ret, i, str1; 40 41 f = std.tmpfile(); 42 str = "hello world\n"; 43 f.puts(str); 44 45 f.seek(0, std.SEEK_SET); 46 str1 = f.readAsString(); 47 assert(str1 === str); 48 49 f.seek(0, std.SEEK_END); 50 size = f.tell(); 51 assert(size === str.length); 52 53 f.seek(0, std.SEEK_SET); 54 55 buf = new Uint8Array(size); 56 ret = f.read(buf.buffer, 0, size); 57 assert(ret === size); 58 for(i = 0; i < size; i++) 59 assert(buf[i] === str.charCodeAt(i)); 60 61 f.close(); 62} 63 64function test_file2() 65{ 66 var f, str, i, size; 67 f = std.tmpfile(); 68 str = "hello world\n"; 69 size = str.length; 70 for(i = 0; i < size; i++) 71 f.putByte(str.charCodeAt(i)); 72 f.seek(0, std.SEEK_SET); 73 for(i = 0; i < size; i++) { 74 assert(str.charCodeAt(i) === f.getByte()); 75 } 76 assert(f.getByte() === -1); 77 f.close(); 78} 79 80function test_getline() 81{ 82 var f, line, line_count, lines, i; 83 84 lines = ["hello world", "line 1", "line 2" ]; 85 f = std.tmpfile(); 86 for(i = 0; i < lines.length; i++) { 87 f.puts(lines[i], "\n"); 88 } 89 90 f.seek(0, std.SEEK_SET); 91 assert(!f.eof()); 92 line_count = 0; 93 for(;;) { 94 line = f.getline(); 95 if (line === null) 96 break; 97 assert(line == lines[line_count]); 98 line_count++; 99 } 100 assert(f.eof()); 101 assert(line_count === lines.length); 102 103 f.close(); 104} 105 106function test_popen() 107{ 108 var str, f, fname = "tmp_file.txt"; 109 var content = "hello world"; 110 111 f = std.open(fname, "w"); 112 f.puts(content); 113 f.close(); 114 115 /* test loadFile */ 116 assert(std.loadFile(fname), content); 117 118 /* execute the 'cat' shell command */ 119 f = std.popen("cat " + fname, "r"); 120 str = f.readAsString(); 121 f.close(); 122 123 assert(str, content); 124 125 os.remove(fname); 126} 127 128function test_ext_json() 129{ 130 var expected, input, obj; 131 expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}'; 132 input = `{ "x":false, /*comments are allowed */ 133 "y":true, // also a comment 134 z2:null, // unquoted property names 135 "a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal 136 "s":"str",} // trailing comma in objects and arrays 137 `; 138 obj = std.parseExtJSON(input); 139 assert(JSON.stringify(obj), expected); 140} 141 142function test_os() 143{ 144 var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path; 145 146 assert(os.isatty(0)); 147 148 fdir = "test_tmp_dir"; 149 fname = "tmp_file.txt"; 150 fpath = fdir + "/" + fname; 151 link_path = fdir + "/test_link"; 152 153 os.remove(link_path); 154 os.remove(fpath); 155 os.remove(fdir); 156 157 err = os.mkdir(fdir, 0o755); 158 assert(err === 0); 159 160 fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC); 161 assert(fd >= 0); 162 163 buf = new Uint8Array(10); 164 for(i = 0; i < buf.length; i++) 165 buf[i] = i; 166 assert(os.write(fd, buf.buffer, 0, buf.length) === buf.length); 167 168 assert(os.seek(fd, 0, std.SEEK_SET) === 0); 169 buf2 = new Uint8Array(buf.length); 170 assert(os.read(fd, buf2.buffer, 0, buf2.length) === buf2.length); 171 172 for(i = 0; i < buf.length; i++) 173 assert(buf[i] == buf2[i]); 174 175 if (typeof BigInt !== "undefined") { 176 assert(os.seek(fd, BigInt(6), std.SEEK_SET), BigInt(6)); 177 assert(os.read(fd, buf2.buffer, 0, 1) === 1); 178 assert(buf[6] == buf2[0]); 179 } 180 181 assert(os.close(fd) === 0); 182 183 [files, err] = os.readdir(fdir); 184 assert(err, 0); 185 assert(files.indexOf(fname) >= 0); 186 187 fdate = 10000; 188 189 err = os.utimes(fpath, fdate, fdate); 190 assert(err, 0); 191 192 [st, err] = os.stat(fpath); 193 assert(err, 0); 194 assert(st.mode & os.S_IFMT, os.S_IFREG); 195 assert(st.mtime, fdate); 196 197 err = os.symlink(fname, link_path); 198 assert(err === 0); 199 200 [st, err] = os.lstat(link_path); 201 assert(err, 0); 202 assert(st.mode & os.S_IFMT, os.S_IFLNK); 203 204 [buf, err] = os.readlink(link_path); 205 assert(err, 0); 206 assert(buf, fname); 207 208 assert(os.remove(link_path) === 0); 209 210 [buf, err] = os.getcwd(); 211 assert(err, 0); 212 213 [buf2, err] = os.realpath("."); 214 assert(err, 0); 215 216 assert(buf, buf2); 217 218 assert(os.remove(fpath) === 0); 219 220 fd = os.open(fpath, os.O_RDONLY); 221 assert(fd < 0); 222 223 assert(os.remove(fdir) === 0); 224} 225 226function test_os_exec() 227{ 228 var ret, fds, pid, f, status; 229 230 ret = os.exec(["true"]); 231 assert(ret, 0); 232 233 ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false }); 234 assert(ret, 1); 235 236 fds = os.pipe(); 237 pid = os.exec(["sh", "-c", "echo $FOO"], { 238 stdout: fds[1], 239 block: false, 240 env: { FOO: "hello" }, 241 } ); 242 assert(pid >= 0); 243 os.close(fds[1]); /* close the write end (as it is only in the child) */ 244 f = std.fdopen(fds[0], "r"); 245 assert(f.getline(), "hello"); 246 assert(f.getline(), null); 247 f.close(); 248 [ret, status] = os.waitpid(pid, 0); 249 assert(ret, pid); 250 assert(status & 0x7f, 0); /* exited */ 251 assert(status >> 8, 0); /* exit code */ 252 253 pid = os.exec(["cat"], { block: false } ); 254 assert(pid >= 0); 255 os.kill(pid, os.SIGQUIT); 256 [ret, status] = os.waitpid(pid, 0); 257 assert(ret, pid); 258 assert(status & 0x7f, os.SIGQUIT); 259} 260 261function test_timer() 262{ 263 var th, i; 264 265 /* just test that a timer can be inserted and removed */ 266 th = []; 267 for(i = 0; i < 3; i++) 268 th[i] = os.setTimeout(function () { }, 1000); 269 for(i = 0; i < 3; i++) 270 os.clearTimeout(th[i]); 271} 272 273test_printf(); 274test_file1(); 275test_file2(); 276test_getline(); 277test_popen(); 278test_os(); 279test_os_exec(); 280test_timer(); 281test_ext_json(); 282