quickjs/tests/test_std.js

308 lines
7.1 KiB
JavaScript
Raw Permalink Normal View History

#! (shebang test)
2020-09-07 00:53:08 +08:00
import * as std from "std";
import * as os from "os";
function assert(actual, expected, message) {
if (arguments.length == 1)
expected = true;
if (actual === expected)
return;
if (actual !== null && expected !== null
&& typeof actual == 'object' && typeof expected == 'object'
&& actual.toString() === expected.toString())
return;
throw Error("assertion failed: got |" + actual + "|" +
", expected |" + expected + "|" +
(message ? " (" + message + ")" : ""));
}
// load more elaborate version of assert if available
try { std.loadScript("test_assert.js"); } catch(e) {}
/*----------------*/
function test_printf()
{
assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc");
2020-09-07 01:07:30 +08:00
assert(std.sprintf("%010d", 123), "0000000123");
assert(std.sprintf("%x", -2), "fffffffe");
assert(std.sprintf("%lx", -2), "fffffffffffffffe");
assert(std.sprintf("%10.1f", 2.1), " 2.1");
assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13");
assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff");
2020-09-07 00:53:08 +08:00
}
function test_file1()
{
var f, len, str, size, buf, ret, i, str1;
f = std.tmpfile();
str = "hello world\n";
f.puts(str);
f.seek(0, std.SEEK_SET);
str1 = f.readAsString();
assert(str1 === str);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
f.seek(0, std.SEEK_END);
size = f.tell();
assert(size === str.length);
f.seek(0, std.SEEK_SET);
buf = new Uint8Array(size);
ret = f.read(buf.buffer, 0, size);
assert(ret === size);
for(i = 0; i < size; i++)
assert(buf[i] === str.charCodeAt(i));
f.close();
}
function test_file2()
{
var f, str, i, size;
f = std.tmpfile();
str = "hello world\n";
size = str.length;
for(i = 0; i < size; i++)
f.putByte(str.charCodeAt(i));
f.seek(0, std.SEEK_SET);
for(i = 0; i < size; i++) {
assert(str.charCodeAt(i) === f.getByte());
}
assert(f.getByte() === -1);
f.close();
}
function test_getline()
{
var f, line, line_count, lines, i;
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
lines = ["hello world", "line 1", "line 2" ];
f = std.tmpfile();
for(i = 0; i < lines.length; i++) {
f.puts(lines[i], "\n");
}
f.seek(0, std.SEEK_SET);
assert(!f.eof());
line_count = 0;
for(;;) {
line = f.getline();
if (line === null)
break;
assert(line == lines[line_count]);
line_count++;
}
assert(f.eof());
assert(line_count === lines.length);
f.close();
}
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
function test_popen()
{
var str, f, fname = "tmp_file.txt";
var content = "hello world";
f = std.open(fname, "w");
f.puts(content);
f.close();
2020-09-07 01:02:03 +08:00
/* test loadFile */
assert(std.loadFile(fname), content);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
/* execute the 'cat' shell command */
f = std.popen("cat " + fname, "r");
str = f.readAsString();
f.close();
assert(str, content);
os.remove(fname);
}
2020-09-07 01:07:30 +08:00
function test_ext_json()
{
var expected, input, obj;
expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}';
input = `{ "x":false, /*comments are allowed */
"y":true, // also a comment
z2:null, // unquoted property names
"a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal
"s":"str",} // trailing comma in objects and arrays
`;
obj = std.parseExtJSON(input);
assert(JSON.stringify(obj), expected);
}
2020-09-07 00:53:08 +08:00
function test_os()
{
var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path;
const stdinIsTTY = !os.exec(["/bin/sh", "-c", "test -t 0"], { usePath: false });
assert(os.isatty(0), stdinIsTTY, `isatty(STDIN)`);
2020-09-07 00:53:08 +08:00
fdir = "test_tmp_dir";
fname = "tmp_file.txt";
fpath = fdir + "/" + fname;
link_path = fdir + "/test_link";
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
os.remove(link_path);
os.remove(fpath);
os.remove(fdir);
err = os.mkdir(fdir, 0o755);
assert(err === 0);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC);
assert(fd >= 0);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
buf = new Uint8Array(10);
for(i = 0; i < buf.length; i++)
buf[i] = i;
assert(os.write(fd, buf.buffer, 0, buf.length) === buf.length);
2020-09-07 01:02:03 +08:00
assert(os.seek(fd, 0, std.SEEK_SET) === 0);
2020-09-07 00:53:08 +08:00
buf2 = new Uint8Array(buf.length);
assert(os.read(fd, buf2.buffer, 0, buf2.length) === buf2.length);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
for(i = 0; i < buf.length; i++)
assert(buf[i] == buf2[i]);
2024-02-10 23:18:11 +08:00
2020-09-07 01:02:03 +08:00
if (typeof BigInt !== "undefined") {
assert(os.seek(fd, BigInt(6), std.SEEK_SET), BigInt(6));
assert(os.read(fd, buf2.buffer, 0, 1) === 1);
assert(buf[6] == buf2[0]);
}
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
assert(os.close(fd) === 0);
[files, err] = os.readdir(fdir);
assert(err, 0);
assert(files.indexOf(fname) >= 0);
fdate = 10000;
err = os.utimes(fpath, fdate, fdate);
assert(err, 0);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
[st, err] = os.stat(fpath);
assert(err, 0);
assert(st.mode & os.S_IFMT, os.S_IFREG);
assert(st.mtime, fdate);
err = os.symlink(fname, link_path);
assert(err === 0);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
[st, err] = os.lstat(link_path);
assert(err, 0);
assert(st.mode & os.S_IFMT, os.S_IFLNK);
[buf, err] = os.readlink(link_path);
assert(err, 0);
assert(buf, fname);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
assert(os.remove(link_path) === 0);
[buf, err] = os.getcwd();
assert(err, 0);
[buf2, err] = os.realpath(".");
assert(err, 0);
assert(buf, buf2);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
assert(os.remove(fpath) === 0);
fd = os.open(fpath, os.O_RDONLY);
assert(fd < 0);
assert(os.remove(fdir) === 0);
}
function test_os_exec()
{
var ret, fds, pid, f, status;
ret = os.exec(["true"]);
assert(ret, 0);
ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false });
assert(ret, 1);
2024-02-10 23:18:11 +08:00
2020-09-07 00:53:08 +08:00
fds = os.pipe();
2020-09-07 01:04:20 +08:00
pid = os.exec(["sh", "-c", "echo $FOO"], {
stdout: fds[1],
block: false,
env: { FOO: "hello" },
} );
2020-09-07 00:53:08 +08:00
assert(pid >= 0);
os.close(fds[1]); /* close the write end (as it is only in the child) */
f = std.fdopen(fds[0], "r");
assert(f.getline(), "hello");
assert(f.getline(), null);
f.close();
[ret, status] = os.waitpid(pid, 0);
assert(ret, pid);
assert(status & 0x7f, 0); /* exited */
assert(status >> 8, 0); /* exit code */
pid = os.exec(["cat"], { block: false } );
assert(pid >= 0);
os.kill(pid, os.SIGTERM);
2020-09-07 00:53:08 +08:00
[ret, status] = os.waitpid(pid, 0);
assert(ret, pid);
assert(status !== 0, true, `expect nonzero exit code (got ${status})`);
assert(status & 0x7f, os.SIGTERM);
2020-09-07 00:53:08 +08:00
}
function test_timer()
{
var th, i;
/* just test that a timer can be inserted and removed */
th = [];
for(i = 0; i < 3; i++)
th[i] = os.setTimeout(function () { }, 1000);
for(i = 0; i < 3; i++)
os.clearTimeout(th[i]);
}
/* test closure variable handling when freeing asynchronous
function */
function test_async_gc()
{
(async function run () {
let obj = {}
2024-02-10 23:18:11 +08:00
let done = () => {
obj
std.gc();
}
2024-02-10 23:18:11 +08:00
Promise.resolve().then(done)
2024-02-10 23:18:11 +08:00
const p = new Promise(() => {})
2024-02-10 23:18:11 +08:00
await p
})();
}
2020-09-07 00:53:08 +08:00
test_printf();
test_file1();
test_file2();
test_getline();
test_popen();
test_os();
test_os_exec();
test_timer();
2020-09-07 01:07:30 +08:00
test_ext_json();
test_async_gc();