mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 00:29:09 -05:00
feat(std/node): support hex/base64 encoding in fs.readFile/fs.writeFile (#6512)
This commit is contained in:
parent
aeadf8189a
commit
a216bd06fc
6 changed files with 148 additions and 55 deletions
|
@ -61,7 +61,11 @@ export function getEncoding(
|
||||||
|
|
||||||
export function checkEncoding(encoding: Encodings | null): Encodings | null {
|
export function checkEncoding(encoding: Encodings | null): Encodings | null {
|
||||||
if (!encoding) return null;
|
if (!encoding) return null;
|
||||||
if (encoding === "utf8" || encoding === "utf-8") {
|
|
||||||
|
encoding = encoding.toLowerCase() as Encodings;
|
||||||
|
if (["utf8", "hex", "base64"].includes(encoding)) return encoding;
|
||||||
|
|
||||||
|
if (encoding === "utf-8") {
|
||||||
return "utf8";
|
return "utf8";
|
||||||
}
|
}
|
||||||
if (encoding === "binary") {
|
if (encoding === "binary") {
|
||||||
|
@ -70,16 +74,9 @@ export function checkEncoding(encoding: Encodings | null): Encodings | null {
|
||||||
// node -e "require('fs').readFile('../world.txt', 'buffer', console.log)"
|
// node -e "require('fs').readFile('../world.txt', 'buffer', console.log)"
|
||||||
}
|
}
|
||||||
|
|
||||||
const notImplementedEncodings = [
|
const notImplementedEncodings = ["utf16le", "latin1", "ascii", "ucs2"];
|
||||||
"utf16le",
|
|
||||||
"latin1",
|
|
||||||
"base64",
|
|
||||||
"hex",
|
|
||||||
"ascii",
|
|
||||||
"ucs2",
|
|
||||||
];
|
|
||||||
|
|
||||||
if (notImplementedEncodings.includes(encoding)) {
|
if (notImplementedEncodings.includes(encoding as string)) {
|
||||||
notImplemented(`"${encoding}" encoding`);
|
notImplemented(`"${encoding}" encoding`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,37 @@ Deno.test("readFileEncodeUtf8Success", async function () {
|
||||||
res(data);
|
res(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEquals(typeof data, "string");
|
assertEquals(typeof data, "string");
|
||||||
assertEquals(data as string, "hello world");
|
assertEquals(data as string, "hello world");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeHexSuccess", async function () {
|
||||||
|
const data = await new Promise((res, rej) => {
|
||||||
|
readFile(testData, { encoding: "hex" }, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
rej(err);
|
||||||
|
}
|
||||||
|
res(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "68656c6c6f20776f726c64");
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeBase64Success", async function () {
|
||||||
|
const data = await new Promise((res, rej) => {
|
||||||
|
readFile(testData, { encoding: "base64" }, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
rej(err);
|
||||||
|
}
|
||||||
|
res(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "aGVsbG8gd29ybGQ=");
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test("readFileEncodingAsString", async function () {
|
Deno.test("readFileEncodingAsString", async function () {
|
||||||
const data = await new Promise((res, rej) => {
|
const data = await new Promise((res, rej) => {
|
||||||
readFile(testData, "utf8", (err, data) => {
|
readFile(testData, "utf8", (err, data) => {
|
||||||
|
@ -60,6 +86,18 @@ Deno.test("readFileEncodeUtf8Success", function () {
|
||||||
assertEquals(data as string, "hello world");
|
assertEquals(data as string, "hello world");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeHexSuccess", function () {
|
||||||
|
const data = readFileSync(testData, { encoding: "hex" });
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "68656c6c6f20776f726c64");
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeBase64Success", function () {
|
||||||
|
const data = readFileSync(testData, { encoding: "base64" });
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "aGVsbG8gd29ybGQ=");
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test("readFileEncodeAsString", function () {
|
Deno.test("readFileEncodeAsString", function () {
|
||||||
const data = readFileSync(testData, "utf8");
|
const data = readFileSync(testData, "utf8");
|
||||||
assertEquals(typeof data, "string");
|
assertEquals(typeof data, "string");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { notImplemented } from "../_utils.ts";
|
import { notImplemented } from "../_utils.ts";
|
||||||
import { fromFileUrl } from "../path.ts";
|
import { fromFileUrl } from "../path.ts";
|
||||||
|
import { Buffer } from "../buffer.ts";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Encodings,
|
Encodings,
|
||||||
|
@ -40,8 +41,7 @@ export function writeFile(
|
||||||
const encoding = checkEncoding(getEncoding(options)) || "utf8";
|
const encoding = checkEncoding(getEncoding(options)) || "utf8";
|
||||||
const openOptions = getOpenOptions(flag || "w");
|
const openOptions = getOpenOptions(flag || "w");
|
||||||
|
|
||||||
if (typeof data === "string" && encoding === "utf8")
|
if (typeof data === "string") data = Buffer.from(data, encoding);
|
||||||
data = new TextEncoder().encode(data) as Uint8Array;
|
|
||||||
|
|
||||||
const isRid = typeof pathOrRid === "number";
|
const isRid = typeof pathOrRid === "number";
|
||||||
let file;
|
let file;
|
||||||
|
@ -87,8 +87,7 @@ export function writeFileSync(
|
||||||
const encoding = checkEncoding(getEncoding(options)) || "utf8";
|
const encoding = checkEncoding(getEncoding(options)) || "utf8";
|
||||||
const openOptions = getOpenOptions(flag || "w");
|
const openOptions = getOpenOptions(flag || "w");
|
||||||
|
|
||||||
if (typeof data === "string" && encoding === "utf8")
|
if (typeof data === "string") data = Buffer.from(data, encoding);
|
||||||
data = new TextEncoder().encode(data) as Uint8Array;
|
|
||||||
|
|
||||||
const isRid = typeof pathOrRid === "number";
|
const isRid = typeof pathOrRid === "number";
|
||||||
let file;
|
let file;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
assertThrows,
|
assertThrows,
|
||||||
} from "../../testing/asserts.ts";
|
} from "../../testing/asserts.ts";
|
||||||
import { writeFile, writeFileSync } from "./_fs_writeFile.ts";
|
import { writeFile, writeFileSync } from "./_fs_writeFile.ts";
|
||||||
|
import { TextEncodings } from "./_fs_common.ts";
|
||||||
import * as path from "../../path/mod.ts";
|
import * as path from "../../path/mod.ts";
|
||||||
|
|
||||||
const testDataDir = path.resolve(path.join("node", "_fs", "testdata"));
|
const testDataDir = path.resolve(path.join("node", "_fs", "testdata"));
|
||||||
|
@ -73,43 +74,18 @@ Deno.test(
|
||||||
function testUnsupportedEncoding() {
|
function testUnsupportedEncoding() {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
() => {
|
() => {
|
||||||
writeFile("some/path", "some data", "hex", () => {});
|
writeFile("some/path", "some data", "utf16le", () => {});
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
`Not implemented: "hex" encoding`
|
`Not implemented: "utf16le" encoding`
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThrows(
|
assertThrows(
|
||||||
() => {
|
() => {
|
||||||
writeFileSync("some/path", "some data", "hex");
|
writeFileSync("some/path", "some data", "utf16le");
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
`Not implemented: "hex" encoding`
|
`Not implemented: "utf16le" encoding`
|
||||||
);
|
|
||||||
|
|
||||||
assertThrows(
|
|
||||||
() => {
|
|
||||||
writeFile(
|
|
||||||
"some/path",
|
|
||||||
"some data",
|
|
||||||
{
|
|
||||||
encoding: "base64",
|
|
||||||
},
|
|
||||||
() => {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
Error,
|
|
||||||
`Not implemented: "base64" encoding`
|
|
||||||
);
|
|
||||||
|
|
||||||
assertThrows(
|
|
||||||
() => {
|
|
||||||
writeFileSync("some/path", "some data", {
|
|
||||||
encoding: "base64",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
Error,
|
|
||||||
`Not implemented: "base64" encoding`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -152,6 +128,36 @@ Deno.test(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"Data is written to correct file encodings",
|
||||||
|
async function testCorrectWriteUsingDifferentEncodings() {
|
||||||
|
const encodings = [
|
||||||
|
["hex", "68656c6c6f20776f726c64"],
|
||||||
|
["HEX", "68656c6c6f20776f726c64"],
|
||||||
|
["base64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["BASE64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["utf8", "hello world"],
|
||||||
|
["utf-8", "hello world"],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [encoding, value] of encodings) {
|
||||||
|
const res = await new Promise((resolve) => {
|
||||||
|
writeFile(
|
||||||
|
"_fs_writeFile_test_file.txt",
|
||||||
|
value,
|
||||||
|
encoding as TextEncodings,
|
||||||
|
resolve
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await Deno.readFile("_fs_writeFile_test_file.txt");
|
||||||
|
await Deno.remove("_fs_writeFile_test_file.txt");
|
||||||
|
assertEquals(res, null);
|
||||||
|
assertEquals(decoder.decode(data), "hello world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Deno.test("Path can be an URL", async function testCorrectWriteUsingURL() {
|
Deno.test("Path can be an URL", async function testCorrectWriteUsingURL() {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
Deno.build.os === "windows"
|
Deno.build.os === "windows"
|
||||||
|
@ -234,6 +240,29 @@ Deno.test(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"Data is written to correct file encodings",
|
||||||
|
function testCorrectWriteSyncUsingDifferentEncodings() {
|
||||||
|
const encodings = [
|
||||||
|
["hex", "68656c6c6f20776f726c64"],
|
||||||
|
["HEX", "68656c6c6f20776f726c64"],
|
||||||
|
["base64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["BASE64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["utf8", "hello world"],
|
||||||
|
["utf-8", "hello world"],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [encoding, value] of encodings) {
|
||||||
|
const file = "_fs_writeFileSync_test_file";
|
||||||
|
writeFileSync(file, value, encoding as TextEncodings);
|
||||||
|
|
||||||
|
const data = Deno.readFileSync(file);
|
||||||
|
Deno.removeSync(file);
|
||||||
|
assertEquals(decoder.decode(data), "hello world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
"Data is written synchronously to correct file",
|
"Data is written synchronously to correct file",
|
||||||
function testCorrectWriteSyncUsingPath() {
|
function testCorrectWriteSyncUsingPath() {
|
||||||
|
|
|
@ -34,6 +34,18 @@ Deno.test("readFileStringObjectSuccess", async function () {
|
||||||
assertEquals(data, "hello world");
|
assertEquals(data, "hello world");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeHexSuccess", async function () {
|
||||||
|
const data: string = await readFile(testData, { encoding: "hex" });
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "68656c6c6f20776f726c64");
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("readFileEncodeBase64Success", async function () {
|
||||||
|
const data: string = await readFile(testData, { encoding: "base64" });
|
||||||
|
assertEquals(typeof data, "string");
|
||||||
|
assertEquals(data as string, "aGVsbG8gd29ybGQ=");
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test("readFileStringSuccess", async function () {
|
Deno.test("readFileStringSuccess", async function () {
|
||||||
const data: string = await readFile(testData, "utf8");
|
const data: string = await readFile(testData, "utf8");
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
assertThrowsAsync,
|
assertThrowsAsync,
|
||||||
} from "../../../testing/asserts.ts";
|
} from "../../../testing/asserts.ts";
|
||||||
import { writeFile } from "./_fs_writeFile.ts";
|
import { writeFile } from "./_fs_writeFile.ts";
|
||||||
|
import { TextEncodings } from "../_fs_common.ts";
|
||||||
|
|
||||||
const decoder = new TextDecoder("utf-8");
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
|
||||||
|
@ -35,19 +36,10 @@ Deno.test(
|
||||||
function testUnsupportedEncoding() {
|
function testUnsupportedEncoding() {
|
||||||
assertThrowsAsync(
|
assertThrowsAsync(
|
||||||
async () => {
|
async () => {
|
||||||
await writeFile("some/path", "some data", "hex");
|
await writeFile("some/path", "some data", "utf16le");
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
`Not implemented: "hex" encoding`
|
`Not implemented: "utf16le" encoding`
|
||||||
);
|
|
||||||
assertThrowsAsync(
|
|
||||||
async () => {
|
|
||||||
await writeFile("some/path", "some data", {
|
|
||||||
encoding: "base64",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
Error,
|
|
||||||
`Not implemented: "base64" encoding`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -85,6 +77,32 @@ Deno.test(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"Data is written to correct file encodings",
|
||||||
|
async function testCorrectWritePromiseUsingDifferentEncodings() {
|
||||||
|
const encodings = [
|
||||||
|
["hex", "68656c6c6f20776f726c64"],
|
||||||
|
["HEX", "68656c6c6f20776f726c64"],
|
||||||
|
["base64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["BASE64", "aGVsbG8gd29ybGQ="],
|
||||||
|
["utf8", "hello world"],
|
||||||
|
["utf-8", "hello world"],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const [encoding, value] of encodings) {
|
||||||
|
await writeFile(
|
||||||
|
"_fs_writeFile_test_file.txt",
|
||||||
|
value,
|
||||||
|
encoding as TextEncodings
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = await Deno.readFile("_fs_writeFile_test_file.txt");
|
||||||
|
await Deno.remove("_fs_writeFile_test_file.txt");
|
||||||
|
assertEquals(decoder.decode(data), "hello world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Deno.test("Mode is correctly set", async function testCorrectFileMode() {
|
Deno.test("Mode is correctly set", async function testCorrectFileMode() {
|
||||||
if (Deno.build.os === "windows") return;
|
if (Deno.build.os === "windows") return;
|
||||||
const filename = "_fs_writeFile_test_file.txt";
|
const filename = "_fs_writeFile_test_file.txt";
|
||||||
|
|
Loading…
Reference in a new issue