diff options
author | Divya <hello@shortdiv.com> | 2020-04-28 00:35:20 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-28 01:35:20 -0400 |
commit | de751e5221cd2eafbdd9cddfb58b0619d74c0504 (patch) | |
tree | 10af8c5b70fc6b57f4a3247ec3367bf5847f195b /cli/js | |
parent | 2fc5878668d8f08ec6989d07e79125d640a73d43 (diff) |
fix(#4769) Adds readTextFile, writeTextFile, with sync counterparts (#4901)
Diffstat (limited to 'cli/js')
-rw-r--r-- | cli/js/deno.ts | 2 | ||||
-rw-r--r-- | cli/js/lib.deno.ns.d.ts | 37 | ||||
-rw-r--r-- | cli/js/read_text_file.ts | 18 | ||||
-rw-r--r-- | cli/js/tests/read_text_file_test.ts | 61 | ||||
-rw-r--r-- | cli/js/tests/unit_tests.ts | 2 | ||||
-rw-r--r-- | cli/js/tests/write_text_file_test.ts | 79 | ||||
-rw-r--r-- | cli/js/write_text_file.ts | 18 |
7 files changed, 217 insertions, 0 deletions
diff --git a/cli/js/deno.ts b/cli/js/deno.ts index 355000ac5..2efb6920a 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -99,6 +99,7 @@ export { kill } from "./ops/process.ts"; export { run, RunOptions, Process, ProcessStatus } from "./process.ts"; export { DirEntry, readdirSync, readdir } from "./ops/fs/read_dir.ts"; export { readFileSync, readFile } from "./read_file.ts"; +export { readTextFileSync, readTextFile } from "./read_text_file.ts"; export { readlinkSync, readlink } from "./ops/fs/read_link.ts"; export { realpathSync, realpath } from "./ops/fs/realpath.ts"; export { removeSync, remove, RemoveOptions } from "./ops/fs/remove.ts"; @@ -114,6 +115,7 @@ export { umask } from "./ops/fs/umask.ts"; export { utimeSync, utime } from "./ops/fs/utime.ts"; export { version } from "./version.ts"; export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts"; +export { writeTextFileSync, writeTextFile } from "./write_text_file.ts"; export const args: string[] = []; export { TestDefinition, test } from "./testing.ts"; diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index d33fde844..6d354d034 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -1276,6 +1276,25 @@ declare namespace Deno { * Requires `allow-read` and `allow-write` permission. */ export function rename(oldpath: string, newpath: string): Promise<void>; + /** Synchronously reads and returns the entire contents of a file as utf8 encoded string + * encoded string. Reading a directory returns an empty string. + * + * const data = Deno.readTextFileSync("hello.txt"); + * console.log(data); + * + * Requires `allow-read` permission. */ + export function readTextFileSync(path: string): string; + + /** Asynchronously reads and returns the entire contents of a file as a utf8 + * encoded string. Reading a directory returns an empty data array. + * + * const decoder = new TextDecoder("utf-8"); + * const data = Deno.readFileSync("hello.txt"); + * console.log(decoder.decode(data)); + * + * Requires `allow-read` permission. */ + export function readTextFile(path: string): Promise<string>; + /** Synchronously reads and returns the entire contents of a file as an array * of bytes. `TextDecoder` can be used to transform the bytes to string if * required. Reading a directory returns an empty data array. @@ -1598,6 +1617,24 @@ declare namespace Deno { options?: WriteFileOptions ): Promise<void>; + /** Synchronously write string `data` to the given `path`, by default creating a new file if needed, + * else overwriting. + * + * await Deno.writeTextFileSync("hello1.txt", "Hello world\n"); // overwrite "hello1.txt" or create it + * + * Requires `allow-write` permission, and `allow-read` if `options.create` is `false`. + */ + export function writeTextFileSync(path: string, data: string): void; + + /** Asynchronously write string `data` to the given `path`, by default creating a new file if needed, + * else overwriting. + * + * await Deno.writeTextFile("hello1.txt", "Hello world\n"); // overwrite "hello1.txt" or create it + * + * Requires `allow-write` permission, and `allow-read` if `options.create` is `false`. + */ + export function writeTextFile(path: string, data: string): Promise<void>; + /** **UNSTABLE**: Should not have same name as `window.location` type. */ interface Location { /** The full url for the module, e.g. `file://some/file.ts` or diff --git a/cli/js/read_text_file.ts b/cli/js/read_text_file.ts new file mode 100644 index 000000000..3423b26b8 --- /dev/null +++ b/cli/js/read_text_file.ts @@ -0,0 +1,18 @@ +import { open, openSync } from "./files.ts"; +import { readAll, readAllSync } from "./buffer.ts"; + +export function readTextFileSync(path: string): string { + const decoder = new TextDecoder(); + const file = openSync(path); + const content = readAllSync(file); + file.close(); + return decoder.decode(content); +} + +export async function readTextFile(path: string): Promise<string> { + const decoder = new TextDecoder(); + const file = await open(path); + const content = await readAll(file); + file.close(); + return decoder.decode(content); +} diff --git a/cli/js/tests/read_text_file_test.ts b/cli/js/tests/read_text_file_test.ts new file mode 100644 index 000000000..3e7493e4a --- /dev/null +++ b/cli/js/tests/read_text_file_test.ts @@ -0,0 +1,61 @@ +import { unitTest, assert, assertEquals } from "./test_util.ts"; + +unitTest({ perms: { read: true } }, function readTextFileSyncSuccess(): void { + const data = Deno.readTextFileSync("cli/tests/fixture.json"); + assert(data.length > 0); + const pkg = JSON.parse(data); + assertEquals(pkg.name, "deno"); +}); + +unitTest({ perms: { read: false } }, function readTextFileSyncPerm(): void { + let caughtError = false; + try { + Deno.readTextFileSync("cli/tests/fixture.json"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.PermissionDenied); + } + assert(caughtError); +}); + +unitTest({ perms: { read: true } }, function readTextFileSyncNotFound(): void { + let caughtError = false; + let data; + try { + data = Deno.readTextFileSync("bad_filename"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.NotFound); + } + assert(caughtError); + assert(data === undefined); +}); + +unitTest( + { perms: { read: true } }, + async function readTextFileSuccess(): Promise<void> { + const data = await Deno.readTextFile("cli/tests/fixture.json"); + assert(data.length > 0); + const pkg = JSON.parse(data); + assertEquals(pkg.name, "deno"); + } +); + +unitTest({ perms: { read: false } }, async function readTextFilePerm(): Promise< + void +> { + let caughtError = false; + try { + await Deno.readTextFile("cli/tests/fixture.json"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.PermissionDenied); + } + assert(caughtError); +}); + +unitTest({ perms: { read: true } }, function readTextFileSyncLoop(): void { + for (let i = 0; i < 256; i++) { + Deno.readTextFileSync("cli/tests/fixture.json"); + } +}); diff --git a/cli/js/tests/unit_tests.ts b/cli/js/tests/unit_tests.ts index 627832ca9..dd4abf116 100644 --- a/cli/js/tests/unit_tests.ts +++ b/cli/js/tests/unit_tests.ts @@ -44,6 +44,7 @@ import "./permissions_test.ts"; import "./process_test.ts"; import "./realpath_test.ts"; import "./read_dir_test.ts"; +import "./read_text_file_test.ts"; import "./read_file_test.ts"; import "./read_link_test.ts"; import "./remove_test.ts"; @@ -64,5 +65,6 @@ import "./url_test.ts"; import "./url_search_params_test.ts"; import "./utime_test.ts"; import "./write_file_test.ts"; +import "./write_text_file_test.ts"; import "./performance_test.ts"; import "./version_test.ts"; diff --git a/cli/js/tests/write_text_file_test.ts b/cli/js/tests/write_text_file_test.ts new file mode 100644 index 000000000..321189b0e --- /dev/null +++ b/cli/js/tests/write_text_file_test.ts @@ -0,0 +1,79 @@ +import { unitTest, assert, assertEquals } from "./test_util.ts"; + +unitTest( + { perms: { read: true, write: true } }, + function writeTextFileSyncSuccess(): void { + const filename = Deno.makeTempDirSync() + "/test.txt"; + Deno.writeTextFileSync(filename, "Hello"); + const dataRead = Deno.readTextFileSync(filename); + assertEquals("Hello", dataRead); + } +); + +unitTest({ perms: { write: true } }, function writeTextFileSyncFail(): void { + const filename = "/baddir/test.txt"; + // The following should fail because /baddir doesn't exist (hopefully). + let caughtError = false; + try { + Deno.writeTextFileSync(filename, "hello"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.NotFound); + } + assert(caughtError); +}); + +unitTest({ perms: { write: false } }, function writeTextFileSyncPerm(): void { + const filename = "/baddir/test.txt"; + // The following should fail due to no write permission + let caughtError = false; + try { + Deno.writeTextFileSync(filename, "Hello"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.PermissionDenied); + } + assert(caughtError); +}); + +unitTest( + { perms: { read: true, write: true } }, + async function writeTextFileSuccess(): Promise<void> { + const filename = Deno.makeTempDirSync() + "/test.txt"; + await Deno.writeTextFile(filename, "Hello"); + const dataRead = Deno.readTextFileSync(filename); + assertEquals("Hello", dataRead); + } +); + +unitTest( + { perms: { read: true, write: true } }, + async function writeTextFileNotFound(): Promise<void> { + const filename = "/baddir/test.txt"; + // The following should fail because /baddir doesn't exist (hopefully). + let caughtError = false; + try { + await Deno.writeTextFile(filename, "Hello"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.NotFound); + } + assert(caughtError); + } +); + +unitTest( + { perms: { write: false } }, + async function writeTextFilePerm(): Promise<void> { + const filename = "/baddir/test.txt"; + // The following should fail due to no write permission + let caughtError = false; + try { + await Deno.writeTextFile(filename, "Hello"); + } catch (e) { + caughtError = true; + assert(e instanceof Deno.errors.PermissionDenied); + } + assert(caughtError); + } +); diff --git a/cli/js/write_text_file.ts b/cli/js/write_text_file.ts new file mode 100644 index 000000000..d2a6575d7 --- /dev/null +++ b/cli/js/write_text_file.ts @@ -0,0 +1,18 @@ +import { open, openSync } from "./files.ts"; +import { writeAll, writeAllSync } from "./buffer.ts"; + +export function writeTextFileSync(path: string, data: string): void { + const file = openSync(path, { write: true, create: true, truncate: true }); + const enc = new TextEncoder(); + const contents = enc.encode(data); + writeAllSync(file, contents); + file.close(); +} + +export async function writeTextFile(path: string, data: string): Promise<void> { + const file = await open(path, { write: true, create: true, truncate: true }); + const enc = new TextEncoder(); + const contents = enc.encode(data); + await writeAll(file, contents); + file.close(); +} |