| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 607ac90 commit ff58854
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2463,8 +2463,10 @@ changes: | |||
| 2463 | 2463 | * `callback` {Function} | |
| 2464 | 2464 | * `err` {Error} | |
| 2465 | 2465 | ||
| 2466 | - Asynchronously creates a directory. No arguments other than a possible exception | ||
| 2467 | - are given to the completion callback. | ||
| 2466 | + Asynchronously creates a directory. | ||
| 2467 | + | ||
| 2468 | + The callback is given a possible exception and, if `recursive` is `true`, the | ||
| 2469 | + first folder path created, `(err, [path])`. | ||
| 2468 | 2470 | ||
| 2469 | 2471 | The optional `options` argument can be an integer specifying mode (permission | |
| 2470 | 2472 | and sticky bits), or an object with a `mode` property and a `recursive` | |
@@ -2508,8 +2510,10 @@ changes: | |||
| 2508 | 2510 | * `options` {Object|integer} | |
| 2509 | 2511 | * `recursive` {boolean} **Default:** `false` | |
| 2510 | 2512 | * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. | |
| 2513 | + * Returns: {string|undefined} | ||
| 2511 | 2514 | ||
| 2512 | - Synchronously creates a directory. Returns `undefined`. | ||
| 2515 | + Synchronously creates a directory. Returns `undefined`, or if `recursive` is | ||
| 2516 | + `true`, the first folder path created. | ||
| 2513 | 2517 | This is the synchronous version of [`fs.mkdir()`][]. | |
| 2514 | 2518 | ||
| 2515 | 2519 | See also: mkdir(2). | |
@@ -4815,8 +4819,8 @@ added: v10.0.0 | |||
| 4815 | 4819 | * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. | |
| 4816 | 4820 | * Returns: {Promise} | |
| 4817 | 4821 | ||
| 4818 | - Asynchronously creates a directory then resolves the `Promise` with no | ||
| 4819 | - arguments upon success. | ||
| 4822 | + Asynchronously creates a directory then resolves the `Promise` with either no | ||
| 4823 | + arguments, or the first folder path created if `recursive` is `true`. | ||
| 4820 | 4824 | ||
| 4821 | 4825 | The optional `options` argument can be an integer specifying mode (permission | |
| 4822 | 4826 | and sticky bits), or an object with a `mode` property and a `recursive` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -855,10 +855,13 @@ function mkdirSync(path, options) { | |||
| 855 | 855 | throw new ERR_INVALID_ARG_TYPE('recursive', 'boolean', recursive); | |
| 856 | 856 | ||
| 857 | 857 | const ctx = { path }; | |
| 858 | - binding.mkdir(pathModule.toNamespacedPath(path), | ||
| 859 | - parseMode(mode, 'mode', 0o777), recursive, undefined, | ||
| 860 | - ctx); | ||
| 858 | + const result = binding.mkdir(pathModule.toNamespacedPath(path), | ||
| 859 | + parseMode(mode, 'mode', 0o777), recursive, | ||
| 860 | + undefined, ctx); | ||
| 861 | 861 | handleErrorFromBinding(ctx); | |
| 862 | + if (recursive) { | ||
| 863 | + return result; | ||
| 864 | + } | ||
| 862 | 865 | } | |
| 863 | 866 | ||
| 864 | 867 | function readdir(path, options, callback) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -107,9 +107,9 @@ void V8ProfilerConnection::V8ProfilerSessionDelegate::SendMessageToFrontend( | |||
| 107 | 107 | } | |
| 108 | 108 | ||
| 109 | 109 | static bool EnsureDirectory(const std::string& directory, const char* type) { | |
| 110 | - uv_fs_t req; | ||
| 111 | - int ret = fs::MKDirpSync(nullptr, &req, directory, 0777, nullptr); | ||
| 112 | - uv_fs_req_cleanup(&req); | ||
| 110 | + fs::FSReqWrapSync req_wrap_sync; | ||
| 111 | + int ret = fs::MKDirpSync(nullptr, &req_wrap_sync.req, directory, 0777, | ||
| 112 | + nullptr); | ||
| 113 | 113 | if (ret < 0 && ret != UV_EEXIST) { | |
| 114 | 114 | char err_buf[128]; | |
| 115 | 115 | uv_err_name_r(ret, err_buf, sizeof(err_buf)); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,6 +21,12 @@ void FSContinuationData::PushPath(const std::string& path) { | |||
| 21 | 21 | paths_.push_back(path); | |
| 22 | 22 | } | |
| 23 | 23 | ||
| 24 | + void FSContinuationData::MaybeSetFirstPath(const std::string& path) { | ||
| 25 | + if (first_path_.empty()) { | ||
| 26 | + first_path_ = path; | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | + | ||
| 24 | 30 | std::string FSContinuationData::PopPath() { | |
| 25 | 31 | CHECK_GT(paths_.size(), 0); | |
| 26 | 32 | std::string path = std::move(paths_.back()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -586,6 +586,43 @@ void AfterOpenFileHandle(uv_fs_t* req) { | |||
| 586 | 586 | } | |
| 587 | 587 | } | |
| 588 | 588 | ||
| 589 | + // Reverse the logic applied by path.toNamespacedPath() to create a | ||
| 590 | + // namespace-prefixed path. | ||
| 591 | + void FromNamespacedPath(std::string* path) { | ||
| 592 | + #ifdef _WIN32 | ||
| 593 | + if (path->compare(0, 8, "\\\\?\\UNC\\", 8) == 0) { | ||
| 594 | + *path = path->substr(8); | ||
| 595 | + path->insert(0, "\\\\"); | ||
| 596 | + } else if (path->compare(0, 4, "\\\\?\\", 4) == 0) { | ||
| 597 | + *path = path->substr(4); | ||
| 598 | + } | ||
| 599 | + #endif | ||
| 600 | + } | ||
| 601 | + | ||
| 602 | + void AfterMkdirp(uv_fs_t* req) { | ||
| 603 | + FSReqBase* req_wrap = FSReqBase::from_req(req); | ||
| 604 | + FSReqAfterScope after(req_wrap, req); | ||
| 605 | + | ||
| 606 | + MaybeLocal<Value> path; | ||
| 607 | + Local<Value> error; | ||
| 608 | + | ||
| 609 | + if (after.Proceed()) { | ||
| 610 | + if (!req_wrap->continuation_data()->first_path().empty()) { | ||
| 611 | + std::string first_path(req_wrap->continuation_data()->first_path()); | ||
| 612 | + FromNamespacedPath(&first_path); | ||
| 613 | + path = StringBytes::Encode(req_wrap->env()->isolate(), first_path.c_str(), | ||
| 614 | + req_wrap->encoding(), | ||
| 615 | + &error); | ||
| 616 | + if (path.IsEmpty()) | ||
| 617 | + req_wrap->Reject(error); | ||
| 618 | + else | ||
| 619 | + req_wrap->Resolve(path.ToLocalChecked()); | ||
| 620 | + } else { | ||
| 621 | + req_wrap->Resolve(Undefined(req_wrap->env()->isolate())); | ||
| 622 | + } | ||
| 623 | + } | ||
| 624 | + } | ||
| 625 | + | ||
| 589 | 626 | void AfterStringPath(uv_fs_t* req) { | |
| 590 | 627 | FSReqBase* req_wrap = FSReqBase::from_req(req); | |
| 591 | 628 | FSReqAfterScope after(req_wrap, req); | |
@@ -1213,18 +1250,25 @@ int MKDirpSync(uv_loop_t* loop, | |||
| 1213 | 1250 | const std::string& path, | |
| 1214 | 1251 | int mode, | |
| 1215 | 1252 | uv_fs_cb cb) { | |
| 1216 | - FSContinuationData continuation_data(req, mode, cb); | ||
| 1217 | - continuation_data.PushPath(std::move(path)); | ||
| 1253 | + FSReqWrapSync* req_wrap = ContainerOf(&FSReqWrapSync::req, req); | ||
| 1254 | + | ||
| 1255 | + // on the first iteration of algorithm, stash state information. | ||
| 1256 | + if (req_wrap->continuation_data() == nullptr) { | ||
| 1257 | + req_wrap->set_continuation_data( | ||
| 1258 | + std::make_unique<FSContinuationData>(req, mode, cb)); | ||
| 1259 | + req_wrap->continuation_data()->PushPath(std::move(path)); | ||
| 1260 | + } | ||
| 1218 | 1261 | ||
| 1219 | - while (continuation_data.paths().size() > 0) { | ||
| 1220 | - std::string next_path = continuation_data.PopPath(); | ||
| 1262 | + while (req_wrap->continuation_data()->paths().size() > 0) { | ||
| 1263 | + std::string next_path = req_wrap->continuation_data()->PopPath(); | ||
| 1221 | 1264 | int err = uv_fs_mkdir(loop, req, next_path.c_str(), mode, nullptr); | |
| 1222 | 1265 | while (true) { | |
| 1223 | 1266 | switch (err) { | |
| 1224 | 1267 | // Note: uv_fs_req_cleanup in terminal paths will be called by | |
| 1225 | 1268 | // ~FSReqWrapSync(): | |
| 1226 | 1269 | case 0: | |
| 1227 | - if (continuation_data.paths().size() == 0) { | ||
| 1270 | + req_wrap->continuation_data()->MaybeSetFirstPath(next_path); | ||
| 1271 | + if (req_wrap->continuation_data()->paths().size() == 0) { | ||
| 1228 | 1272 | return 0; | |
| 1229 | 1273 | } | |
| 1230 | 1274 | break; | |
@@ -1237,9 +1281,9 @@ int MKDirpSync(uv_loop_t* loop, | |||
| 1237 | 1281 | std::string dirname = next_path.substr(0, | |
| 1238 | 1282 | next_path.find_last_of(kPathSeparator)); | |
| 1239 | 1283 | if (dirname != next_path) { | |
| 1240 | - continuation_data.PushPath(std::move(next_path)); | ||
| 1241 | - continuation_data.PushPath(std::move(dirname)); | ||
| 1242 | - } else if (continuation_data.paths().size() == 0) { | ||
| 1284 | + req_wrap->continuation_data()->PushPath(std::move(next_path)); | ||
| 1285 | + req_wrap->continuation_data()->PushPath(std::move(dirname)); | ||
| 1286 | + } else if (req_wrap->continuation_data()->paths().size() == 0) { | ||
| 1243 | 1287 | err = UV_EEXIST; | |
| 1244 | 1288 | continue; | |
| 1245 | 1289 | } | |
@@ -1251,7 +1295,8 @@ int MKDirpSync(uv_loop_t* loop, | |||
| 1251 | 1295 | err = uv_fs_stat(loop, req, next_path.c_str(), nullptr); | |
| 1252 | 1296 | if (err == 0 && !S_ISDIR(req->statbuf.st_mode)) { | |
| 1253 | 1297 | uv_fs_req_cleanup(req); | |
| 1254 | - if (orig_err == UV_EEXIST && continuation_data.paths().size() > 0) { | ||
| 1298 | + if (orig_err == UV_EEXIST && | ||
| 1299 | + req_wrap->continuation_data()->paths().size() > 0) { | ||
| 1255 | 1300 | return UV_ENOTDIR; | |
| 1256 | 1301 | } | |
| 1257 | 1302 | return UV_EEXIST; | |
@@ -1296,8 +1341,10 @@ int MKDirpAsync(uv_loop_t* loop, | |||
| 1296 | 1341 | // FSReqAfterScope::~FSReqAfterScope() | |
| 1297 | 1342 | case 0: { | |
| 1298 | 1343 | if (req_wrap->continuation_data()->paths().size() == 0) { | |
| 1344 | + req_wrap->continuation_data()->MaybeSetFirstPath(path); | ||
| 1299 | 1345 | req_wrap->continuation_data()->Done(0); | |
| 1300 | 1346 | } else { | |
| 1347 | + req_wrap->continuation_data()->MaybeSetFirstPath(path); | ||
| 1301 | 1348 | uv_fs_req_cleanup(req); | |
| 1302 | 1349 | MKDirpAsync(loop, req, path.c_str(), | |
| 1303 | 1350 | req_wrap->continuation_data()->mode(), nullptr); | |
@@ -1360,6 +1407,25 @@ int MKDirpAsync(uv_loop_t* loop, | |||
| 1360 | 1407 | return err; | |
| 1361 | 1408 | } | |
| 1362 | 1409 | ||
| 1410 | + int CallMKDirpSync(Environment* env, const FunctionCallbackInfo<Value>& args, | ||
| 1411 | + FSReqWrapSync* req_wrap, const char* path, int mode) { | ||
| 1412 | + env->PrintSyncTrace(); | ||
| 1413 | + int err = MKDirpSync(env->event_loop(), &req_wrap->req, path, mode, | ||
| 1414 | + nullptr); | ||
| 1415 | + if (err < 0) { | ||
| 1416 | + v8::Local<v8::Context> context = env->context(); | ||
| 1417 | + v8::Local<v8::Object> ctx_obj = args[4].As<v8::Object>(); | ||
| 1418 | + v8::Isolate* isolate = env->isolate(); | ||
| 1419 | + ctx_obj->Set(context, | ||
| 1420 | + env->errno_string(), | ||
| 1421 | + v8::Integer::New(isolate, err)).Check(); | ||
| 1422 | + ctx_obj->Set(context, | ||
| 1423 | + env->syscall_string(), | ||
| 1424 | + OneByteString(isolate, "mkdir")).Check(); | ||
| 1425 | + } | ||
| 1426 | + return err; | ||
| 1427 | + } | ||
| 1428 | + | ||
| 1363 | 1429 | static void MKDir(const FunctionCallbackInfo<Value>& args) { | |
| 1364 | 1430 | Environment* env = Environment::GetCurrent(args); | |
| 1365 | 1431 | ||
@@ -1378,14 +1444,29 @@ static void MKDir(const FunctionCallbackInfo<Value>& args) { | |||
| 1378 | 1444 | FSReqBase* req_wrap_async = GetReqWrap(env, args[3]); | |
| 1379 | 1445 | if (req_wrap_async != nullptr) { // mkdir(path, mode, req) | |
| 1380 | 1446 | AsyncCall(env, req_wrap_async, args, "mkdir", UTF8, | |
| 1381 | - AfterNoArgs, mkdirp ? MKDirpAsync : uv_fs_mkdir, *path, mode); | ||
| 1447 | + mkdirp ? AfterMkdirp : AfterNoArgs, | ||
| 1448 | + mkdirp ? MKDirpAsync : uv_fs_mkdir, *path, mode); | ||
| 1382 | 1449 | } else { // mkdir(path, mode, undefined, ctx) | |
| 1383 | 1450 | CHECK_EQ(argc, 5); | |
| 1384 | 1451 | FSReqWrapSync req_wrap_sync; | |
| 1385 | 1452 | FS_SYNC_TRACE_BEGIN(mkdir); | |
| 1386 | 1453 | if (mkdirp) { | |
| 1387 | - SyncCall(env, args[4], &req_wrap_sync, "mkdir", | ||
| 1388 | - MKDirpSync, *path, mode); | ||
| 1454 | + int err = CallMKDirpSync(env, args, &req_wrap_sync, *path, mode); | ||
| 1455 | + if (err == 0 && | ||
| 1456 | + !req_wrap_sync.continuation_data()->first_path().empty()) { | ||
| 1457 | + Local<Value> error; | ||
| 1458 | + std::string first_path(req_wrap_sync.continuation_data()->first_path()); | ||
| 1459 | + FromNamespacedPath(&first_path); | ||
| 1460 | + MaybeLocal<Value> path = StringBytes::Encode(env->isolate(), | ||
| 1461 | + first_path.c_str(), | ||
| 1462 | + UTF8, &error); | ||
| 1463 | + if (path.IsEmpty()) { | ||
| 1464 | + Local<Object> ctx = args[4].As<Object>(); | ||
| 1465 | + ctx->Set(env->context(), env->error_string(), error).Check(); | ||
| 1466 | + return; | ||
| 1467 | + } | ||
| 1468 | + args.GetReturnValue().Set(path.ToLocalChecked()); | ||
| 1469 | + } | ||
| 1389 | 1470 | } else { | |
| 1390 | 1471 | SyncCall(env, args[4], &req_wrap_sync, "mkdir", | |
| 1391 | 1472 | uv_fs_mkdir, *path, mode); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,10 +19,13 @@ class FSContinuationData : public MemoryRetainer { | |||
| 19 | 19 | inline void PushPath(std::string&& path); | |
| 20 | 20 | inline void PushPath(const std::string& path); | |
| 21 | 21 | inline std::string PopPath(); | |
| 22 | + // Used by mkdirp to track the first path created: | ||
| 23 | + inline void MaybeSetFirstPath(const std::string& path); | ||
| 22 | 24 | inline void Done(int result); | |
| 23 | 25 | ||
| 24 | 26 | int mode() const { return mode_; } | |
| 25 | 27 | const std::vector<std::string>& paths() const { return paths_; } | |
| 28 | + const std::string& first_path() const { return first_path_; } | ||
| 26 | 29 | ||
| 27 | 30 | void MemoryInfo(MemoryTracker* tracker) const override; | |
| 28 | 31 | SET_MEMORY_INFO_NAME(FSContinuationData) | |
@@ -33,6 +36,7 @@ class FSContinuationData : public MemoryRetainer { | |||
| 33 | 36 | uv_fs_t* req_; | |
| 34 | 37 | int mode_; | |
| 35 | 38 | std::vector<std::string> paths_; | |
| 39 | + std::string first_path_; | ||
| 36 | 40 | }; | |
| 37 | 41 | ||
| 38 | 42 | class FSReqBase : public ReqWrap<uv_fs_t> { | |
@@ -306,8 +310,18 @@ class FSReqWrapSync { | |||
| 306 | 310 | ~FSReqWrapSync() { uv_fs_req_cleanup(&req); } | |
| 307 | 311 | uv_fs_t req; | |
| 308 | 312 | ||
| 313 | + FSContinuationData* continuation_data() const { | ||
| 314 | + return continuation_data_.get(); | ||
| 315 | + } | ||
| 316 | + void set_continuation_data(std::unique_ptr<FSContinuationData> data) { | ||
| 317 | + continuation_data_ = std::move(data); | ||
| 318 | + } | ||
| 319 | + | ||
| 309 | 320 | FSReqWrapSync(const FSReqWrapSync&) = delete; | |
| 310 | 321 | FSReqWrapSync& operator=(const FSReqWrapSync&) = delete; | |
| 322 | + | ||
| 323 | + private: | ||
| 324 | + std::unique_ptr<FSContinuationData> continuation_data_; | ||
| 311 | 325 | }; | |
| 312 | 326 | ||
| 313 | 327 | // TODO(addaleax): Currently, callers check the return value and assume | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -245,6 +245,100 @@ if (common.isMainThread && (common.isLinux || common.isOSX)) { | |||
| 245 | 245 | }); | |
| 246 | 246 | } | |
| 247 | 247 | ||
| 248 | + // `mkdirp` returns first folder created, when all folders are new. | ||
| 249 | + { | ||
| 250 | + const dir1 = nextdir(); | ||
| 251 | + const dir2 = nextdir(); | ||
| 252 | + const firstPathCreated = path.join(tmpdir.path, dir1); | ||
| 253 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 254 | + | ||
| 255 | + fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) { | ||
| 256 | + assert.strictEqual(err, null); | ||
| 257 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 258 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 259 | + assert.strictEqual(path, firstPathCreated); | ||
| 260 | + })); | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + // `mkdirp` returns first folder created, when last folder is new. | ||
| 264 | + { | ||
| 265 | + const dir1 = nextdir(); | ||
| 266 | + const dir2 = nextdir(); | ||
| 267 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 268 | + fs.mkdirSync(path.join(tmpdir.path, dir1)); | ||
| 269 | + fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) { | ||
| 270 | + assert.strictEqual(err, null); | ||
| 271 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 272 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 273 | + assert.strictEqual(path, pathname); | ||
| 274 | + })); | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + // `mkdirp` returns undefined, when no new folders are created. | ||
| 278 | + { | ||
| 279 | + const dir1 = nextdir(); | ||
| 280 | + const dir2 = nextdir(); | ||
| 281 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 282 | + fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), { recursive: true }); | ||
| 283 | + fs.mkdir(pathname, { recursive: true }, common.mustCall(function(err, path) { | ||
| 284 | + assert.strictEqual(err, null); | ||
| 285 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 286 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 287 | + assert.strictEqual(path, undefined); | ||
| 288 | + })); | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + // `mkdirp.sync` returns first folder created, when all folders are new. | ||
| 292 | + { | ||
| 293 | + const dir1 = nextdir(); | ||
| 294 | + const dir2 = nextdir(); | ||
| 295 | + const firstPathCreated = path.join(tmpdir.path, dir1); | ||
| 296 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 297 | + const p = fs.mkdirSync(pathname, { recursive: true }); | ||
| 298 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 299 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 300 | + assert.strictEqual(p, firstPathCreated); | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + // `mkdirp.sync` returns first folder created, when last folder is new. | ||
| 304 | + { | ||
| 305 | + const dir1 = nextdir(); | ||
| 306 | + const dir2 = nextdir(); | ||
| 307 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 308 | + fs.mkdirSync(path.join(tmpdir.path, dir1), { recursive: true }); | ||
| 309 | + const p = fs.mkdirSync(pathname, { recursive: true }); | ||
| 310 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 311 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 312 | + assert.strictEqual(p, pathname); | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + // `mkdirp.sync` returns undefined, when no new folders are created. | ||
| 316 | + { | ||
| 317 | + const dir1 = nextdir(); | ||
| 318 | + const dir2 = nextdir(); | ||
| 319 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 320 | + fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), { recursive: true }); | ||
| 321 | + const p = fs.mkdirSync(pathname, { recursive: true }); | ||
| 322 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 323 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 324 | + assert.strictEqual(p, undefined); | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | + // `mkdirp.promises` returns first folder created, when all folders are new. | ||
| 328 | + { | ||
| 329 | + const dir1 = nextdir(); | ||
| 330 | + const dir2 = nextdir(); | ||
| 331 | + const firstPathCreated = path.join(tmpdir.path, dir1); | ||
| 332 | + const pathname = path.join(tmpdir.path, dir1, dir2); | ||
| 333 | + async function testCase() { | ||
| 334 | + const p = await fs.promises.mkdir(pathname, { recursive: true }); | ||
| 335 | + assert.strictEqual(fs.existsSync(pathname), true); | ||
| 336 | + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); | ||
| 337 | + assert.strictEqual(p, firstPathCreated); | ||
| 338 | + } | ||
| 339 | + testCase(); | ||
| 340 | + } | ||
| 341 | + | ||
| 248 | 342 | // Keep the event loop alive so the async mkdir() requests | |
| 249 | 343 | // have a chance to run (since they don't ref the event loop). | |
| 250 | 344 | process.nextTick(() => {}); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments