diff --git a/src/utils/index.ts b/src/utils/index.ts index 1f26910e..0502dbb5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -118,10 +118,6 @@ Array.prototype.compact_push = function(item: T | null | undefined) { if (item) this.push(item) } -Array.prototype.compact_unshift = function(item: T | null | undefined) { - if (item) this.unshift(item) -} - export function flatmap(t: T | undefined | null, body: (t: T) => S | undefined, opts?: {rescue?: boolean}): NonNullable | undefined { try { if (t) return body(t) ?? undefined @@ -139,19 +135,6 @@ export async function async_flatmap(t: Promise, body } } -export function pivot(input: E[], body: (e: E) => ['L', L] | ['R', R]): [L[], R[]] { - const rv = { - 'L': [] as L[], - 'R': [] as R[] - } - for (const e of input) { - const [side, value] = body(e) - // deno-lint-ignore no-explicit-any - rv[side].push(value as any) - } - return [rv['L'], rv['R']] -} - declare global { interface Promise { swallow(err?: unknown): Promise @@ -179,24 +162,11 @@ Promise.prototype.swallow = function(gristle?: unknown) { }) } -export async function attempt(body: () => Promise, opts: {swallow: unknown}): Promise { - try { - return await body() - } catch (err) { - if (err !== opts.swallow) throw err - } -} - ///////////////////////////////////////////////////////////////////////// misc import TeaError, { UsageError, panic } from "./error.ts" export { TeaError, UsageError, panic } export * as error from "./error.ts" -// deno-lint-ignore no-explicit-any -export function tuplize(...elements: T) { - return elements -} - ///////////////////////////////////////////////////////////////////////// pkgs export * as pkg from "./pkg.ts" diff --git a/src/vendor/Path.ts b/src/vendor/Path.ts index 2e382a53..a11cd11f 100644 --- a/src/vendor/Path.ts +++ b/src/vendor/Path.ts @@ -340,9 +340,15 @@ export default class Path { return Deno.readTextFile(this.string) } - readLines(): AsyncIterableIterator { + async *readLines(): AsyncIterableIterator { const fd = Deno.openSync(this.string) - return readLines(fd) + try { + for await (const line of readLines(fd)) + yield line + } + finally { + fd.close() + } } //FIXME like, we don’t want a hard dependency in the published library diff --git a/tests/unit/path.test.ts b/tests/unit/path.test.ts new file mode 100644 index 00000000..4c8fa13c --- /dev/null +++ b/tests/unit/path.test.ts @@ -0,0 +1,84 @@ +import Path from "path"; +import { assert, assertEquals, assertFalse, assertThrows } from "deno/testing/asserts.ts" + +Deno.test("test Path", async test => { + await test.step("creating files", () => { + assertEquals(new Path("/a/b/c").components(), ["", "a", "b", "c"]) + assertEquals(new Path("/a/b/c").split(), [new Path("/a/b"), "c"]) + + const tmp = Path.mktmp({prefix: "tea-"}) + assert(tmp.isEmpty()) + + const child = tmp.join("a/b/c") + assertFalse(child.parent().isDirectory()) + child.mkparent() + assert(child.parent().isDirectory()) + + assertThrows(() => child.readlink()) // not found + assertFalse(child.isReadableFile()) + child.touch() + assert(child.isReadableFile()) + + assert(child.in(tmp)) + assertFalse(tmp.isEmpty()) + assertEquals(child.readlink(), child) // not a link + }) + + await test.step("write and read", async () => { + const tmp = Path.mktmp({prefix: "tea-"}) + + const data = tmp.join("test.dat") + data.write({text: "hello\nworld"}) + + const lines = await asyncIterToArray(data.readLines()) + assertEquals(lines, ["hello", "world"]) + + // will throw with no force flag + assertThrows(() => data.write({ json: { hello: "world" } })) + + data.write({ json: { hello: "world" }, force: true }) + assertEquals(await data.readJSON(), { hello: "world" }) + }) + + await test.step("test walk", async () => { + const tmp = Path.mktmp({prefix: "tea-"}) + + const a = tmp.join("a").mkdir() + a.join("a1").touch() + a.join("a2").touch() + + const b = tmp.join("b").mkdir() + b.join("b1").touch() + b.join("b2").touch() + + const c = tmp.join("c").mkdir() + c.join("c1").touch() + c.join("c2").touch() + + const walked = (await asyncIterToArray(tmp.walk())) + .map(([path, entry]) => { + return {name: path.basename(), isDir: entry.isDirectory} + }) + .sort((a, b) => a.name.localeCompare(b.name)) + + assertEquals(walked, [ + { name: "a", isDir: true}, + { name: "a1", isDir: false}, + { name: "a2", isDir: false}, + { name: "b", isDir: true}, + { name: "b1", isDir: false}, + { name: "b2", isDir: false}, + { name: "c", isDir: true}, + { name: "c1", isDir: false}, + { name: "c2", isDir: false}, + ]) + }) +}) + +async function asyncIterToArray (iter: AsyncIterable){ + const result = []; + for await(const i of iter) { + result.push(i); + } + return result; +}