railsish
v0.9.0
Published
Rails-like blank and presence helpers, with related property access methods
Downloads
9
Maintainers
Readme
import { strict: assert } from "assert";
import { isPresent, isBlank } from "railsish";
// It treats empty or invalid values as blank...
assert(isBlank([]), "an empty array is blank");
assert(isBlank({}), "an empty object is blank");
assert(isBlank(new Date("2020-03-32")), "an invalid date is blank");
assert(isBlank(NaN), "NaN is blank");
assert(isBlank("\n\t "), "a string containing only whitespace is blank");
// But there's a special case: 0 is present!
assert(isPresent(0), "0 is present");
import { strict: assert } from "assert";
import { getPresent } from "railsish";
assert.equal(getPresent({ foo: { bar: { baz: null } } }, "foo.bar.baz", "quux"), "quux", "it will return a default value");
import { strict: assert } from "assert";
import { getPresentNumber, getPresentString } from "railsish";
assert.equal(getPresentNumber({ foo: "-3.14" }, "foo"), -3.14, "fetching a numeric string will cast it");
assert.equal(getPresentString({ foo: "\t" }, "foo", "default"), "default", "whitespace-only strings are not present");
import { booleanize } from "railsish";
booleanize(0) === false
booleanize("0") == false
// an empty object
booleanize({}) === false
// an empty array
booleanize([]) === false
booleanize(new Int8Array()) === false
// an empty string
booleanize("") === false
// a string that's only whitespace
booleanize(" ") === false
// special string handling: the following are case-insensitive
booleanize("F") === false
booleanize("n") === false
booleanize("no") === false
booleanize("nil") === false
booleanize("NULL") === false
booleanize("FALSE") === false
import { strict: assert } from "assert";
import { getBoolean } from "railsish";
assert.fail(getBoolean({ foo: [] }, "foo"), "it will booleanize the value at a given path");
booleanize(0) === false
booleanize("0") == false
// an empty object
booleanize({}) === false
// an empty array
booleanize([]) === false
booleanize(new Int8Array()) === false
// an empty string
booleanize("") === false
// a string that's only whitespace
booleanize(" ") === false
// special string handling: the following are case-insensitive
booleanize("F") === false
booleanize("n") === false
booleanize("no") === false
booleanize("nil") === false
booleanize("NULL") === false
booleanize("FALSE") === false
import { getPresentArray }
const response = {
foo: {
bar: {
baz: {
quux: []
}
}
}
};
// instead of this:
function extractDeepValue(value) {
if (value && value.foo) {
if (value.foo.bar) {
if (value.foo.bar.baz) {
if (Array.isArray(value.foo.bar.baz.quux) && value.foo.bar.baz.quux.length > 0) {
return value;
}
}
}
}
return ["default"];
};
extractDeepValue(response, ["default"]);
// you can just:
getPresentArray(response, "foo.bar.baz.quux", ["default"]);
import { getPresentArray } from "railsish";
const NO_TAGS_SELECTED = Symbol("NO_TAGS");
const getSelectedTags = (config) => getPresentArray(config, "user.selected.tags", NO_TAGS_SELECTED);
// A contrived express handler
export async function renderSelectedTags(req, res) {
const tags = getSelectedTags(req.user.config);
if (tags === NO_TAGS_SELECTED) {
// take the user to a
return res.json({
error: "User needs to select tags",
code: "SELECT_TAGS_FIRST"
}).status(400);
}
const tagResponse = await myDB.getTags(tags);
res.json(tagResponse);
}
// It'll booleanize a deeply-nested value
getBoolean({ foo: { bar: [] } }, "foo.bar") === false;
getPresentString({ foo: "\t" }, "foo", "default") === "default";
isPresentObject({}) === false
isPresentObject({ foo: "bar" }) === true
isPresentObject([]) === false
isPresentObject(new Foo()) === false
isPresentObject(Object.create(null)) === false
isBlankObject({}) === true
isBlankObject({ foo: "bar" }) === false
isBlankObject([]) === false
isBlankObject(new Foo()) === false
isBlankObject(Object.create(null)) === false
import { install as installRailsishMatchers } from "railsish/jest-matchers"
installRailsishMatchers(expect)
describe("some tests", () => {
it("returns a present response", () => {
expect(myLibrary.doSomething()).toBePresent();
});
it("returns something blank", () => {
expect(anonymousRequest.getCurrentUser()).toBeBlank();
});
it("implements foo", () => {
expect({ foo: () => "bar" }).toRespondTo("foo");
});
});
// in a file called by "setupFilesAfterEnv":
import { install } from "railsish/jest-matchers"
install(expect);
expect(0).toBePresent();
expect([]).not.toBePresent();
expect(false).not.toBePresent();
expect("some string").toBePresent();
expect({}).not.toBePresent();
expect({ foo: "bar" }).toBePresent();
expect
expect(0).not.toBeBlank();
expect([]).toBeBlank();
expect({}).toBeBlank();
expect(NaN).toBeBlank();
expect(Infinity).not.toBeBlank();
expect("\t\n\t").toBeBlank();
expect("some text").toBooleanizeAs(true);
expect([]).toBooleanizeAs(false);
expect("some text").toBooleanizeTrue();
expect([]).not.toBooleanizeTrue();
expect("some text").not.toBooleanizeFalse();
expect([]).toBooleanizeFalse();
expect(new Date()).toRespondTo("toISOString");
expect({ foo: { bar: { baz: () => "quux" } } }).toRespondToPath("foo.bar.baz");