[njs] Added fs.Dirent, fs.readdir() and friends.
Dmitry Volyntsev
xeioex at nginx.com
Tue Jun 9 16:48:21 UTC 2020
details: https://hg.nginx.org/njs/rev/b33402f10e82
branches:
changeset: 1429:b33402f10e82
user: Artem S. Povalyukhin <artem.povaluhin at gmail.com>
date: Sun May 31 08:45:41 2020 +0300
description:
Added fs.Dirent, fs.readdir() and friends.
This closes #254 issue on Github.
diffstat:
src/njs_builtin.c | 1 +
src/njs_fs.c | 415 +++++++++++++++++++++++++++++++++++++++++++++
src/njs_fs.h | 1 +
src/njs_vm.h | 3 +-
src/test/njs_unit_test.c | 41 ++++
test/js/fs_promises_007.js | 231 +++++++++++++++++++++++++
test/njs_expect_test.exp | 14 +-
7 files changed, 696 insertions(+), 10 deletions(-)
diffs (839 lines):
diff -r 724dedc6be18 -r b33402f10e82 src/njs_builtin.c
--- a/src/njs_builtin.c Tue Jun 09 12:56:56 2020 +0000
+++ b/src/njs_builtin.c Sun May 31 08:45:41 2020 +0300
@@ -73,6 +73,7 @@ static const njs_object_type_init_t *con
/* Hidden types. */
+ &njs_dirent_type_init,
&njs_hash_type_init,
&njs_hmac_type_init,
&njs_typed_array_type_init,
diff -r 724dedc6be18 -r b33402f10e82 src/njs_fs.c
--- a/src/njs_fs.c Tue Jun 09 12:56:56 2020 +0000
+++ b/src/njs_fs.c Sun May 31 08:45:41 2020 +0300
@@ -7,6 +7,31 @@
#include <njs_main.h>
+#include <dirent.h>
+
+#if (NJS_SOLARIS)
+
+#define DT_DIR 0
+#define DT_REG 0
+#define DT_CHR 0
+#define DT_LNK 0
+#define DT_BLK 0
+#define DT_FIFO 0
+#define DT_SOCK 0
+#define NJS_DT_INVALID 0xffffffff
+
+#define njs_dentry_type(_dentry) \
+ (NJS_DT_INVALID)
+
+#else
+
+#define NJS_DT_INVALID 0xffffffff
+
+#define njs_dentry_type(_dentry) \
+ ((_dentry)->d_type)
+
+#endif
+
#define njs_fs_magic(calltype, mode) \
(((mode) << 2) | calltype)
@@ -53,6 +78,8 @@ static njs_fs_encoding_t njs_fs_encoding
static njs_int_t njs_fs_add_event(njs_vm_t *vm, const njs_value_t *callback,
const njs_value_t *args, njs_uint_t nargs);
+static njs_int_t njs_fs_dirent_create(njs_vm_t *vm, njs_value_t *name,
+ njs_value_t *type, njs_value_t *retval);
static njs_fs_entry_t njs_flags_table[] = {
{ njs_str("r"), O_RDONLY },
@@ -895,6 +922,163 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *
static njs_int_t
+njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t calltype)
+{
+ DIR *dir;
+ u_char *d_name;
+ size_t size;
+ ssize_t length;
+ njs_int_t ret;
+ const char *dir_path;
+ njs_value_t encoding, types, ename, etype, retval, *path, *callback,
+ *options, *value;
+ njs_array_t *results;
+ struct dirent *entry;
+ njs_fs_encoding_t enc;
+
+ static const njs_value_t string_encoding = njs_string("encoding");
+ static const njs_value_t string_types = njs_string("withFileTypes");
+
+ path = njs_arg(args, nargs, 1);
+ ret = njs_fs_path_arg(vm, &dir_path, path, &njs_str_value("path"));
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ callback = NULL;
+ options = njs_arg(args, nargs, 2);
+
+ if (njs_slow_path(calltype == NJS_FS_CALLBACK)) {
+ callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
+ if (!njs_is_function(callback)) {
+ njs_type_error(vm, "\"callback\" must be a function");
+ return NJS_ERROR;
+ }
+ if (options == callback) {
+ options = njs_value_arg(&njs_value_undefined);
+ }
+ }
+
+ njs_set_false(&types);
+ njs_set_undefined(&encoding);
+
+ switch (options->type) {
+ case NJS_STRING:
+ encoding = *options;
+ break;
+
+ case NJS_UNDEFINED:
+ break;
+
+ default:
+ if (!njs_is_object(options)) {
+ njs_type_error(vm, "Unknown options type: \"%s\" "
+ "(a string or object required)",
+ njs_type_string(options->type));
+ return NJS_ERROR;
+ }
+
+ ret = njs_value_property(vm, options, njs_value_arg(&string_encoding),
+ &encoding);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ ret = njs_value_property(vm, options, njs_value_arg(&string_types),
+ &types);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+ }
+
+ enc = njs_fs_encoding(vm, &encoding);
+ if (njs_slow_path(enc == NJS_FS_ENC_INVALID)) {
+ return NJS_ERROR;
+ }
+
+ results = njs_array_alloc(vm, 1, 0, NJS_ARRAY_SPARE);
+ if (njs_slow_path(results == NULL)) {
+ return NJS_ERROR;
+ }
+
+ njs_set_array(&retval, results);
+
+ dir = opendir(dir_path);
+ if (njs_slow_path(dir == NULL)) {
+ ret = njs_fs_error(vm, "opendir", strerror(errno), path, errno,
+ &retval);
+ goto done;
+ }
+
+ for ( ;; ) {
+ errno = 0;
+ entry = readdir(dir);
+ if (njs_slow_path(entry == NULL)) {
+ if (errno != 0) {
+ ret = njs_fs_error(vm, "readdir", strerror(errno), path, errno,
+ &retval);
+ }
+
+ goto done;
+ }
+
+ d_name = (u_char *) entry->d_name;
+
+ size = njs_strlen(d_name);
+ length = njs_utf8_length(d_name, size);
+ if (njs_slow_path(length < 0)) {
+ length = 0;
+ }
+
+ if ((length == 1 && d_name[0] == '.')
+ || (length == 2 && (d_name[0] == '.' && d_name[1] == '.')))
+ {
+ continue;
+ }
+
+ if (njs_fast_path(!njs_is_true(&types))) {
+ ret = njs_array_string_add(vm, results, d_name, size, length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ goto done;
+ }
+
+ continue;
+ }
+
+ ret = njs_string_new(vm, &ename, d_name, size, length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ goto done;
+ }
+
+ njs_set_number(&etype, njs_dentry_type(entry));
+
+ value = njs_array_push(vm, results);
+ if (njs_slow_path(value == NULL)) {
+ goto done;
+ }
+
+ ret = njs_fs_dirent_create(vm, &ename, &etype, value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ goto done;
+ }
+ }
+
+done:
+
+ if (dir != NULL) {
+ (void) closedir(dir);
+ }
+
+ if (ret == NJS_OK) {
+ return njs_fs_result(vm, &retval, calltype, callback, 2);
+ }
+
+ return NJS_ERROR;
+}
+
+
+static njs_int_t
njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data)
{
u_char *p, *end, *start;
@@ -1231,6 +1415,205 @@ memory_error:
}
+static njs_int_t
+njs_fs_dirent_create(njs_vm_t *vm, njs_value_t *name, njs_value_t *type,
+ njs_value_t *retval)
+{
+ njs_int_t ret;
+ njs_object_t *object;
+
+ static const njs_value_t string_name = njs_string("name");
+ static const njs_value_t string_type = njs_string("type");
+
+ object = njs_object_alloc(vm);
+ if (njs_slow_path(object == NULL)) {
+ return NJS_ERROR;
+ }
+
+ object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FS_DIRENT].object;
+
+ njs_set_object(retval, object);
+
+ ret = njs_value_property_set(vm, retval, njs_value_arg(&string_name),
+ name);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ /* TODO: use a private symbol as a key. */
+ ret = njs_value_property_set(vm, retval, njs_value_arg(&string_type),
+ type);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ return NJS_OK;
+}
+
+
+static njs_int_t
+njs_dirent_constructor(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t unused)
+{
+ if (njs_slow_path(!vm->top_frame->ctor)) {
+ njs_type_error(vm, "the Dirent constructor must be called with new");
+ return NJS_ERROR;
+ }
+
+ return njs_fs_dirent_create(vm, njs_arg(args, nargs, 1),
+ njs_arg(args, nargs, 2), &vm->retval);
+}
+
+
+static const njs_object_prop_t njs_dirent_constructor_properties[] =
+{
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("Dirent"),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 2.0),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("prototype"),
+ .value = njs_prop_handler(njs_object_prototype_create),
+ },
+};
+
+
+const njs_object_init_t njs_dirent_constructor_init = {
+ njs_dirent_constructor_properties,
+ njs_nitems(njs_dirent_constructor_properties),
+};
+
+
+static njs_int_t
+njs_fs_dirent_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t testtype)
+{
+ njs_int_t ret;
+ njs_value_t type, *this;
+
+ static const njs_value_t string_type = njs_string("type");
+
+ this = njs_argument(args, 0);
+
+ ret = njs_value_property(vm, this, njs_value_arg(&string_type), &type);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ if (njs_slow_path(njs_is_number(&type)
+ && (njs_number(&type) == NJS_DT_INVALID)))
+ {
+ njs_internal_error(vm, "dentry type is not supported on this platform");
+ return NJS_ERROR;
+ }
+
+ njs_set_boolean(&vm->retval,
+ njs_is_number(&type) && testtype == njs_number(&type));
+
+ return NJS_OK;
+}
+
+
+static const njs_object_prop_t njs_dirent_prototype_properties[] =
+{
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
+ .value = njs_string("Dirent"),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("constructor"),
+ .value = njs_prop_handler(njs_object_prototype_create_constructor),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isDirectory"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_DIR),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isFile"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_REG),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isBlockDevice"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_BLK),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_long_string("isCharacterDevice"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_CHR),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isSymbolicLink"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_LNK),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isFIFO"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_FIFO),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("isSocket"),
+ .value = njs_native_function2(njs_fs_dirent_test, 0, DT_SOCK),
+ .writable = 1,
+ .configurable = 1,
+ },
+};
+
+
+const njs_object_init_t njs_dirent_prototype_init = {
+ njs_dirent_prototype_properties,
+ njs_nitems(njs_dirent_prototype_properties),
+};
+
+
+const njs_object_type_init_t njs_dirent_type_init = {
+ .constructor = njs_native_ctor(njs_dirent_constructor, 2, 0),
+ .prototype_props = &njs_dirent_prototype_init,
+ .constructor_props = &njs_dirent_constructor_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
+};
+
+
static const njs_object_prop_t njs_fs_promises_properties[] =
{
{
@@ -1293,6 +1676,14 @@ static const njs_object_prop_t njs_fs_p
{
.type = NJS_PROPERTY,
+ .name = njs_string("readdir"),
+ .value = njs_native_function2(njs_fs_readdir, 0, NJS_FS_PROMISE),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
.name = njs_string("symlink"),
.value = njs_native_function2(njs_fs_symlink, 0, NJS_FS_PROMISE),
.writable = 1,
@@ -1399,6 +1790,14 @@ static const njs_object_prop_t njs_fs_o
{
.type = NJS_PROPERTY,
+ .name = njs_string("Dirent"),
+ .value = _njs_native_function(njs_dirent_constructor, 2, 1, 0),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
.name = njs_string("access"),
.value = njs_native_function2(njs_fs_access, 0, NJS_FS_CALLBACK),
.writable = 1,
@@ -1560,6 +1959,22 @@ static const njs_object_prop_t njs_fs_o
.writable = 1,
.configurable = 1,
},
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("readdir"),
+ .value = njs_native_function2(njs_fs_readdir, 0, NJS_FS_CALLBACK),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("readdirSync"),
+ .value = njs_native_function2(njs_fs_readdir, 0, NJS_FS_DIRECT),
+ .writable = 1,
+ .configurable = 1,
+ },
};
diff -r 724dedc6be18 -r b33402f10e82 src/njs_fs.h
--- a/src/njs_fs.h Tue Jun 09 12:56:56 2020 +0000
+++ b/src/njs_fs.h Sun May 31 08:45:41 2020 +0300
@@ -10,5 +10,6 @@
extern const njs_object_init_t njs_fs_object_init;
+extern const njs_object_type_init_t njs_dirent_type_init;
#endif /* _NJS_FS_H_INCLUDED_ */
diff -r 724dedc6be18 -r b33402f10e82 src/njs_vm.h
--- a/src/njs_vm.h Tue Jun 09 12:56:56 2020 +0000
+++ b/src/njs_vm.h Sun May 31 08:45:41 2020 +0300
@@ -92,8 +92,9 @@ typedef enum {
NJS_OBJ_TYPE_PROMISE,
NJS_OBJ_TYPE_ARRAY_BUFFER,
+ NJS_OBJ_TYPE_FS_DIRENT,
+#define NJS_OBJ_TYPE_HIDDEN_MIN (NJS_OBJ_TYPE_FS_DIRENT)
NJS_OBJ_TYPE_CRYPTO_HASH,
-#define NJS_OBJ_TYPE_HIDDEN_MIN (NJS_OBJ_TYPE_CRYPTO_HASH)
NJS_OBJ_TYPE_CRYPTO_HMAC,
NJS_OBJ_TYPE_TYPED_ARRAY,
#define NJS_OBJ_TYPE_HIDDEN_MAX (NJS_OBJ_TYPE_TYPED_ARRAY + 1)
diff -r 724dedc6be18 -r b33402f10e82 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Jun 09 12:56:56 2020 +0000
+++ b/src/test/njs_unit_test.c Sun May 31 08:45:41 2020 +0300
@@ -16371,12 +16371,20 @@ static njs_unit_test_t njs_test[] =
"'writeFileSync',"
"'appendFile',"
"'appendFileSync',"
+ "'rename',"
+ "'renameSync',"
"'symlink',"
"'symlinkSync',"
"'unlink',"
"'unlinkSync',"
"'realpath',"
"'realpathSync',"
+ "'mkdir',"
+ "'mkdirSync',"
+ "'rmdir',"
+ "'rmdirSync',"
+ "'readdir',"
+ "'readdirSync',"
"],"
"test = (fname) =>"
"[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
@@ -16399,9 +16407,13 @@ static njs_unit_test_t njs_test[] =
"'readFile',"
"'writeFile',"
"'appendFile',"
+ "'rename',"
"'symlink',"
"'unlink',"
"'realpath',"
+ "'mkdir',"
+ "'rmdir',"
+ "'readdir',"
"];"
"func.every((x) => typeof fs[x] == 'function')"),
njs_str("true")},
@@ -16423,6 +16435,35 @@ static njs_unit_test_t njs_test[] =
"items.every((x) => typeof fsc[x] == 'number')"),
njs_str("true")},
+ /* require('fs').Dirent */
+
+ { njs_str("var fs = require('fs');"
+ "typeof fs.Dirent"),
+ njs_str("function") },
+
+ { njs_str("var fs = require('fs');"
+ "fs.Dirent('file', 123)"),
+ njs_str("TypeError: the Dirent constructor must be called with new") },
+
+ { njs_str("var fs = require('fs');"
+ "var e = new fs.Dirent('file', 123); [e.name, e.type]"),
+ njs_str("file,123") },
+
+ { njs_str("var "
+ "fs = require('fs'),"
+ "e = new fs.Dirent('file', 0),"
+ "func = ["
+ "'isDirectory',"
+ "'isFile',"
+ "'isBlockDevice',"
+ "'isCharacterDevice',"
+ "'isSymbolicLink',"
+ "'isFIFO',"
+ "'isSocket',"
+ "];"
+ "func.every((x) => typeof e[x] == 'function')"),
+ njs_str("true")},
+
/* require('crypto').createHash() */
{ njs_str("var h = require('crypto').createHash('sha1');"
diff -r 724dedc6be18 -r b33402f10e82 test/js/fs_promises_007.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/fs_promises_007.js Sun May 31 08:45:41 2020 +0300
@@ -0,0 +1,231 @@
+var fs = require('fs');
+var fsp = fs.promises;
+var dname = './build/test/fs_promises_007';
+var dname_utf8 = './build/test/fs_promises_αβγ_007';
+var fname = (d) => d + '/fs_promises_007_file';
+var lname = (d) => d + '/fs_promises_007_link';
+var cname = (d) => d + '/fs_promises_αβγ_007_dir';
+
+
+var dir_test = [cname(''), lname(''), fname('')].map((x) => x.substring(1));
+var match = (entry) => {
+ var idx = dir_test.indexOf(entry.name);
+
+ try {
+ switch(idx) {
+ case 0:
+ return entry.isDirectory();
+ case 1:
+ return entry.isSymbolicLink();
+ case 2:
+ return entry.isFile();
+ default:
+ return false;
+ }
+ } catch (e) {
+ if (e.name == 'InternalError') {
+ return true;
+ }
+
+ throw e;
+ }
+};
+
+
+var testSync = () => new Promise((resolve, reject) => {
+ try {
+ try { fs.rmdirSync(cname(dname)); } catch (e) {}
+ try { fs.rmdirSync(cname(dname_utf8)); } catch (e) {}
+ try { fs.unlinkSync(lname(dname)); } catch (e) {}
+ try { fs.unlinkSync(lname(dname_utf8)); } catch (e) {}
+ try { fs.unlinkSync(fname(dname)); } catch (e) {}
+ try { fs.unlinkSync(fname(dname_utf8)); } catch (e) {}
+ try { fs.rmdirSync(dname); } catch (e) {}
+ try { fs.rmdirSync(dname_utf8); } catch (e) {}
+
+ try {
+ fs.readdirSync(dname);
+ throw new Error('fs.readdirSync - error 0');
+
+ } catch (e) {
+ if (e.code != 'ENOENT') {
+ // njs: e.syscall == 'opendir'
+ // node: e.syscall == 'scandir'
+ throw e;
+ }
+ }
+
+ fs.mkdirSync(dname);
+ fs.mkdirSync(dname_utf8);
+ fs.writeFileSync(fname(dname), fname(dname));
+ fs.writeFileSync(fname(dname_utf8), fname(dname_utf8));
+ fs.symlinkSync(fname('.'), lname(dname));
+ fs.symlinkSync(fname('.'), lname(dname_utf8));
+ fs.mkdirSync(cname(dname));
+ fs.mkdirSync(cname(dname_utf8));
+
+ var dir = fs.readdirSync(dname);
+ var dir_utf8 = fs.readdirSync(dname_utf8);
+ if (dir.length != dir_utf8.length || dir.length != 3) {
+ throw new Error('fs.readdirSync - error 1');
+ }
+
+ var test = dir.filter((x) => !dir_test.includes(x));
+ if (test.length != 0) {
+ throw new Error('fs.readdirSync - error 2');
+ }
+
+ var test = dir_utf8.filter((x) => !dir_test.includes(x));
+ if (test.length != 0) {
+ throw new Error('fs.readdirSync - error 3');
+ }
+
+ var dir = fs.readdirSync(dname, { withFileTypes: true });
+ var dir_utf8 = fs.readdirSync(dname_utf8, { withFileTypes: true });
+ if (dir.length != dir_utf8.length || dir.length != 3) {
+ throw new Error('fs.readdirSync - error 4');
+ }
+
+ var test = dir.filter((x) => !match(x));
+ if (test.length != 0) {
+ throw new Error('fs.readdirSync - error 5');
+ }
+
+ var test = dir_utf8.filter((x) => !match(x));
+ if (test.length != 0) {
+ throw new Error('fs.readdirSync - error 6');
+ }
+
+ resolve();
+
+ } catch (e) {
+ reject(e);
+ }
+});
+
+
+var testCallback = () => new Promise((resolve, reject) => {
+ try {
+ try { fs.rmdirSync(cname(dname)); } catch (e) {}
+ try { fs.unlinkSync(lname(dname)); } catch (e) {}
+ try { fs.unlinkSync(fname(dname)); } catch (e) {}
+ try { fs.rmdirSync(dname); } catch (e) {}
+
+ fs.readdir(dname, (err, files) => {
+ if (!err || err.code != 'ENOENT') {
+ reject(new Error('fs.readdir - error 1'));
+ }
+
+ try {
+ fs.mkdirSync(dname);
+ fs.writeFileSync(fname(dname), fname(dname));
+ fs.symlinkSync(fname('.'), lname(dname));
+ fs.mkdirSync(cname(dname));
+
+ } catch (e) {
+ reject(e);
+ }
+
+ fs.readdir(dname, (err, dir) => {
+ if (err) {
+ reject(err);
+ }
+
+ if (dir.length != 3) {
+ reject(new Error('fs.readdir - error 2'));
+ }
+
+ var test = dir.filter((x) => !dir_test.includes(x));
+ if (test.length != 0) {
+ reject(new Error('fs.readdir - error 3'));
+ }
+
+ fs.readdir(dname, { withFileTypes: true }, (err, dir) => {
+ if (err) {
+ reject(err);
+ }
+
+ if (dir.length != 3) {
+ reject(new Error('fs.readdir - error 4'));
+ }
+
+ var test = dir.filter((x) => !match(x));
+ if (test.length != 0) {
+ reject(new Error('fs.readdir - error 5'));
+ }
+
+ resolve();
+ });
+ });
+ });
+
+ } catch (e) {
+ reject(e);
+ }
+});
+
+
+Promise.resolve()
+.then(testSync)
+.then(() => {
+ console.log('test fs.readdirSync');
+})
+.catch((e) => {
+ console.log('test fs.readdirSync failed', JSON.stringify(e));
+})
+
+.then(testCallback)
+.then(() => {
+ console.log('test fs.readdir');
+})
+.catch((e) => {
+ console.log('test fs.readdir failed', JSON.stringify(e));
+})
+
+.then(() => {
+ try { fs.rmdirSync(cname(dname)); } catch (e) {}
+ try { fs.unlinkSync(lname(dname)); } catch (e) {}
+ try { fs.unlinkSync(fname(dname)); } catch (e) {}
+ try { fs.rmdirSync(dname); } catch (e) {}
+})
+.then(() => fsp.readdir(dname)
+ .then(() => { throw new Error('fsp.readdir - error 1'); }))
+.catch((e) => {
+ if (e.code != 'ENOENT') {
+ throw e;
+ }
+})
+.then(() => {
+ fs.mkdirSync(dname);
+ fs.writeFileSync(fname(dname), fname(dname));
+ fs.symlinkSync(fname('.'), lname(dname));
+ fs.mkdirSync(cname(dname));
+})
+.then(() => fsp.readdir(dname))
+.then((dir) => {
+ if (dir.length != 3) {
+ throw new Error('fsp.readdir - error 2');
+ }
+
+ var test = dir.filter((x) => !dir_test.includes(x));
+ if (test.length != 0) {
+ throw new Error('fsp.readdir - error 3');
+ }
+})
+.then(() => fsp.readdir(dname, { withFileTypes: true }))
+.then((dir) => {
+ if (dir.length != 3) {
+ throw new Error('fsp.readdir - error 4');
+ }
+
+ var test = dir.filter((x) => !match(x));
+ if (test.length != 0) {
+ throw new Error('fsp.readdir - error 5');
+ }
+})
+.then(() => {
+ console.log('test fsp.readdir');
+})
+.catch((e) => {
+ console.log('test fsp.readdir failed', JSON.stringify(e));
+});
diff -r 724dedc6be18 -r b33402f10e82 test/njs_expect_test.exp
--- a/test/njs_expect_test.exp Tue Jun 09 12:56:56 2020 +0000
+++ b/test/njs_expect_test.exp Sun May 31 08:45:41 2020 +0300
@@ -459,15 +459,6 @@ njs_test {
"queue.toString()\r\n'0,1,2,3,4,5'"}
}
-# require('fs')
-
-njs_test {
- {"var fs = require('fs')\r\n"
- "undefined\r\n>> "}
- {"fs.read\t"
- "fs.read\a*File"}
-}
-
# require('fs').readFile()
njs_test {
@@ -1144,3 +1135,8 @@ njs_run {"./test/js/fs_promises_006.js"}
"test fs.renameSync
test fs.rename
test fsp.rename"
+
+njs_run {"./test/js/fs_promises_007.js"} \
+"test fs.readdirSync
+test fs.readdir
+test fsp.readdir"
More information about the nginx-devel
mailing list