Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ deno add jsr:@bytebury/toolkit
## Sample Usage

```ts
import { average, isNoneOrWhitespace, title } from "@bytebury/toolkit";

function sayHelloTo(name: string): void {
if ((isWhitespace(name)) {
if (isNoneOrWhitespace(name)) {
console.log("Hello, Guest!");
} else {
console.log(`Hello, ${title(name)}!`);
Expand All @@ -47,3 +49,10 @@ function getAverageAge(): number {
return average(people.map(({ age }) => age)); // 5
}
```

## Naming Notes

Helpers such as `isWhitespace` and `isEmpty` are already `null` and `undefined`
safe. The more explicit `isNoneOrWhitespace`, `isNoneOrEmpty`,
`isNotNoneOrWhitespace`, and `isNotNoneOrEmpty` aliases are available when that
behavior should be visible at the call site.
46 changes: 23 additions & 23 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"name": "@bytebury/toolkit",
"version": "2.0.0",
"exports": {
".": "./mod.ts",
"./core": "./src/core.ts",
"./dates": "./src/dates.ts",
"./duration": "./src/duration.ts",
"./numbers": "./src/numbers.ts",
"./objects": "./src/objects.ts",
"./strings": "./src/strings.ts",
"./utility-types": "./src/utility_types.ts"
},
"tasks": {
"dev": "deno test --watch"
},
"license": "MIT",
"imports": {
"@std/assert": "jsr:@std/assert@1"
},
"compilerOptions": {
"lib": ["dom", "dom.iterable", "deno.ns"]
},
"exclude": ["deno.lock", "scripts/**", "npm/**"]
"name": "@bytebury/toolkit",
"version": "2.1.0",
"exports": {
".": "./mod.ts",
"./core": "./src/core.ts",
"./dates": "./src/dates.ts",
"./duration": "./src/duration.ts",
"./numbers": "./src/numbers.ts",
"./objects": "./src/objects.ts",
"./strings": "./src/strings.ts",
"./utility-types": "./src/utility_types.ts"
},
"tasks": {
"dev": "deno test --watch"
},
"license": "MIT",
"imports": {
"@std/assert": "jsr:@std/assert@1"
},
"compilerOptions": {
"lib": ["dom", "dom.iterable", "deno.ns"]
},
"exclude": ["deno.lock", "scripts/**", "npm/**"]
}
20 changes: 17 additions & 3 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export function reverse<T>(
): string | Set<T> | T[] {
if (typeof thing === "string") return thing.split("").reverse().join("");
if (thing instanceof Set) return new Set([...thing].reverse());
return thing.reverse();
return [...thing].reverse();
}

/**
Expand Down Expand Up @@ -220,6 +220,13 @@ export function isEmpty(thing: unknown): boolean {
return false;
}

/**
* Alias for `isEmpty`.
*/
export function isNoneOrEmpty(thing: unknown): boolean {
return isEmpty(thing);
}

/**
* Determines if the given thing is not empty.
*
Expand All @@ -240,6 +247,13 @@ export function isNotEmpty(thing: unknown): boolean {
return !isEmpty(thing);
}

/**
* Alias for `isNotEmpty`.
*/
export function isNotNoneOrEmpty(thing: unknown): boolean {
return isNotEmpty(thing);
}

/**
* Returns the distinct values from a list.
*
Expand Down Expand Up @@ -328,7 +342,7 @@ export function falsy(thing: unknown): boolean {
* isSome({}); // true
* ```
*/
export function isSome(thing: unknown): boolean {
export function isSome<T>(thing: T | null | undefined): thing is T {
return !isNone(thing);
}

Expand All @@ -343,7 +357,7 @@ export function isSome(thing: unknown): boolean {
* isNone(0); // false
* ```
*/
export function isNone(thing: unknown): boolean {
export function isNone(thing: unknown): thing is null | undefined {
return thing === null || thing === undefined;
}

Expand Down
51 changes: 50 additions & 1 deletion src/core_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import {
isEqual,
isEqualIgnoreCase,
isNone,
isNoneOrEmpty,
isNotEmpty,
isNotEqual,
isNotEqualIgnoreCase,
isNotNoneOrEmpty,
isSome,
last,
move,
Expand Down Expand Up @@ -169,7 +171,10 @@ Deno.test("reverse strings", () => {
});

Deno.test("reverse arrays", () => {
assertEquals(reverse([1, 2, 3]), [3, 2, 1]);
const list = [1, 2, 3];

assertEquals(reverse(list), [3, 2, 1]);
assertEquals(list, [1, 2, 3]);
});

Deno.test("reverse sets", () => {
Expand Down Expand Up @@ -205,6 +210,19 @@ Deno.test("isEmpty Set and Map", () => {
assertFalse(isEmpty(new Map([["key", "value"]])));
});

Deno.test("isNoneOrEmpty behavior", () => {
assert(isNoneOrEmpty(null));
assert(isNoneOrEmpty(undefined));
assert(isNoneOrEmpty(""));
assert(isNoneOrEmpty([]));
assert(isNoneOrEmpty({}));
assert(isNoneOrEmpty(new Set()));
assert(isNoneOrEmpty(new Map()));
assertFalse(isNoneOrEmpty(" "));
assertFalse(isNoneOrEmpty([1]));
assertFalse(isNoneOrEmpty({ foo: "bar" }));
});

Deno.test("isNotEmpty behavior", () => {
assertFalse(isNotEmpty(null));
assertFalse(isNotEmpty(""));
Expand All @@ -217,6 +235,19 @@ Deno.test("isNotEmpty behavior", () => {
assertFalse(isNotEmpty(new Set()));
});

Deno.test("isNotNoneOrEmpty behavior", () => {
assertFalse(isNotNoneOrEmpty(null));
assertFalse(isNotNoneOrEmpty(undefined));
assertFalse(isNotNoneOrEmpty(""));
assertFalse(isNotNoneOrEmpty([]));
assertFalse(isNotNoneOrEmpty({}));
assertFalse(isNotNoneOrEmpty(new Set()));
assertFalse(isNotNoneOrEmpty(new Map()));
assert(isNotNoneOrEmpty(" "));
assert(isNotNoneOrEmpty([1]));
assert(isNotNoneOrEmpty({ foo: "bar" }));
});

Deno.test("unique produces distinct values", () => {
assertEquals(unique([1, 2, 2, 3]), [1, 2, 3]);
assertEquals(unique(["a", "b", "a"]), ["a", "b"]);
Expand Down Expand Up @@ -305,6 +336,15 @@ Deno.test("isSome", () => {
assert(isSome([]));
});

Deno.test("isSome narrows the type", () => {
const value: string | null | undefined = "hello";

if (isSome(value)) {
const text: string = value;
assertStrictEquals(text.toUpperCase(), "HELLO");
}
});

Deno.test("isNone", () => {
assert(isNone(null));
assert(isNone(undefined));
Expand All @@ -316,6 +356,15 @@ Deno.test("isNone", () => {
assertFalse(isNone([]));
});

Deno.test("isNone narrows the type", () => {
const value: string | null | undefined = null;

if (isNone(value)) {
const none: null | undefined = value;
assertStrictEquals(none, null);
}
});

Deno.test("noop behavior", () => {
noop();
});
Expand Down
14 changes: 14 additions & 0 deletions src/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export function isWhitespace(text: string): boolean {
return trim(text).length === 0;
}

/**
* Alias for `isWhitespace`.
*/
export function isNoneOrWhitespace(text: string): boolean {
return isWhitespace(text);
}

/**
* Determines if the given text contains any non-whitespace characters.
*
Expand All @@ -35,6 +42,13 @@ export function isNotWhitespace(text: string): boolean {
return !isWhitespace(text);
}

/**
* Alias for `isNotWhitespace`.
*/
export function isNotNoneOrWhitespace(text: string): boolean {
return isNotWhitespace(text);
}

/**
* Trims the whitespace from the beginning and the end. This is an
* alias for `.trim()`. Useful for when you're mapping over lists.
Expand Down
22 changes: 22 additions & 0 deletions src/strings_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert } from "@std/assert";
import {
camel,
isNoneOrWhitespace,
isNotNoneOrWhitespace,
isNotWhitespace,
isWhitespace,
kebab,
Expand All @@ -27,13 +29,33 @@ Deno.test("isWhitespace", () => {
assert(!isWhitespace("Hello"));
});

Deno.test("isNoneOrWhitespace", () => {
assert(isNoneOrWhitespace(" "));
assert(isNoneOrWhitespace(null as unknown as string));
assert(isNoneOrWhitespace(undefined as unknown as string));
assert(isNoneOrWhitespace(""));
assert(isNoneOrWhitespace("\t"));
assert(isNoneOrWhitespace("\n"));
assert(!isNoneOrWhitespace("Hello"));
});

Deno.test("isNotWhitespace", () => {
assert(!isNotWhitespace(" "));
assert(!isNotWhitespace("\t"));
assert(!isNotWhitespace("\n"));
assert(isNotWhitespace("Hello"));
});

Deno.test("isNotNoneOrWhitespace", () => {
assert(!isNotNoneOrWhitespace(" "));
assert(!isNotNoneOrWhitespace(null as unknown as string));
assert(!isNotNoneOrWhitespace(undefined as unknown as string));
assert(!isNotNoneOrWhitespace(""));
assert(!isNotNoneOrWhitespace("\t"));
assert(!isNotNoneOrWhitespace("\n"));
assert(isNotNoneOrWhitespace("Hello"));
});

Deno.test("trim", () => {
assert(trim(" Hello, World! ") === "Hello, World!");
assert(trim("\nHey\n\t") === "Hey");
Expand Down
Loading