Skip to content

Commit

Permalink
Node polyfill for fs.chown and fs.close (#4377)
Browse files Browse the repository at this point in the history
  • Loading branch information
cknight authored Mar 15, 2020
1 parent 6cc40b0 commit a159165
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 0 deletions.
37 changes: 37 additions & 0 deletions std/node/_fs/_fs_chown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

import { CallbackWithError } from "./_fs_common.ts";

/**
* TODO: Also accept 'path' parameter as a Node polyfill Buffer or URL type once these
* are implemented. See https://github.com/denoland/deno/issues/3403
*/
export function chown(
path: string,
uid: number,
gid: number,
callback: CallbackWithError
): void {
new Promise(async (resolve, reject) => {
try {
await Deno.chown(path, uid, gid);
resolve();
} catch (err) {
reject(err);
}
})
.then(() => {
callback();
})
.catch(err => {
callback(err);
});
}

/**
* TODO: Also accept 'path' parameter as a Node polyfill Buffer or URL type once these
* are implemented. See https://github.com/denoland/deno/issues/3403
*/
export function chownSync(path: string, uid: number, gid: number): void {
Deno.chownSync(path, uid, gid);
}
50 changes: 50 additions & 0 deletions std/node/_fs/_fs_chown_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
const { test } = Deno;
import { fail, assertEquals } from "../../testing/asserts.ts";
import { chown, chownSync } from "./_fs_chown.ts";

if (Deno.build.os !== "win") {
//chown is difficult to test. Best we can do is set the existing user id/group id again
test({
name: "ASYNC: setting existing uid/gid works as expected (non-Windows)",
async fn() {
const tempFile: string = await Deno.makeTempFile();
const originalUserId: number | null = (await Deno.lstat(tempFile)).uid;
const originalGroupId: number | null = (await Deno.lstat(tempFile)).gid;
await new Promise((resolve, reject) => {
chown(tempFile, originalUserId!, originalGroupId!, err => {
if (err) reject(err);
else resolve();
});
})
.then(() => {
const newUserId: number | null = Deno.lstatSync(tempFile).uid;
const newGroupId: number | null = Deno.lstatSync(tempFile).gid;
assertEquals(newUserId, originalUserId);
assertEquals(newGroupId, originalGroupId);
})
.catch(() => {
fail();
})
.finally(() => {
Deno.removeSync(tempFile);
});
}
});

test({
name: "SYNC: setting existing uid/gid works as expected (non-Windows)",
fn() {
const tempFile: string = Deno.makeTempFileSync();
const originalUserId: number | null = Deno.lstatSync(tempFile).uid;
const originalGroupId: number | null = Deno.lstatSync(tempFile).gid;
chownSync(tempFile, originalUserId!, originalGroupId!);

const newUserId: number | null = Deno.lstatSync(tempFile).uid;
const newGroupId: number | null = Deno.lstatSync(tempFile).gid;
assertEquals(newUserId, originalUserId);
assertEquals(newGroupId, originalGroupId);
Deno.removeSync(tempFile);
}
});
}
24 changes: 24 additions & 0 deletions std/node/_fs/_fs_close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

import { CallbackWithError } from "./_fs_common.ts";

export function close(fd: number, callback: CallbackWithError): void {
new Promise(async (resolve, reject) => {
try {
Deno.close(fd);
resolve();
} catch (err) {
reject(err);
}
})
.then(() => {
callback();
})
.catch(err => {
callback(err);
});
}

export function closeSync(fd: number): void {
Deno.close(fd);
}
42 changes: 42 additions & 0 deletions std/node/_fs/_fs_close_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
const { test } = Deno;
import { fail, assert } from "../../testing/asserts.ts";
import { close, closeSync } from "./_fs_close.ts";

test({
name: "ASYNC: File is closed",
async fn() {
const tempFile: string = await Deno.makeTempFile();
const file: Deno.File = await Deno.open(tempFile);

assert(Deno.resources()[file.rid]);
await new Promise((resolve, reject) => {
close(file.rid, err => {
if (err) reject();
else resolve();
});
})
.then(async () => {
assert(!Deno.resources()[file.rid]);
})
.catch(() => {
fail("No error expected");
})
.finally(async () => {
await Deno.remove(tempFile);
});
}
});

test({
name: "SYNC: File is closed",
fn() {
const tempFile: string = Deno.makeTempFileSync();
const file: Deno.File = Deno.openSync(tempFile);

assert(Deno.resources()[file.rid]);
closeSync(file.rid);
assert(!Deno.resources()[file.rid]);
Deno.removeSync(tempFile);
}
});
2 changes: 2 additions & 0 deletions std/node/querystring.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

interface ParseOptions {
decodeURIComponent?: (string: string) => string;
maxKeys?: number;
Expand Down

0 comments on commit a159165

Please sign in to comment.