Skip to content

Instantly share code, notes, and snippets.

@webbower
Last active May 1, 2020 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webbower/f2a8ec0ffb3a0e024941d548f12894fc to your computer and use it in GitHub Desktop.
Save webbower/f2a8ec0ffb3a0e024941d548f12894fc to your computer and use it in GitHub Desktop.
Simple, composable, instanced-enabled model factories
{
"name": "simple-model",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {},
"scripts": {
"start": "watch 'yarn run test' src",
"test": "tape -r esm src/*.test.js"
},
"devDependencies": {
"esm": "^3.2.25",
"tape": "^4.13.0",
"watch": "^1.0.2"
}
}
const createModel = (...factories) => {
const ctor = data => {
const factoryOutputs = factories.map(factory => factory(data));
const inst = Object.create(ctor.prototype);
Object.assign(inst, ...factoryOutputs);
return inst;
};
ctor.compose = (...newFactories) => {
return createModel(...factories.concat(newFactories));
};
ctor.prototype = { constructor: ctor };
return ctor;
};
export default createModel;
// const Link = ({ label, url }) => ({ label, url });
// const HasVisibility = ({ isVisible }) => ({ isVisible });
// const LinkWithVisibility = createModel(Link, HasVisibility);
import test from "tape";
import createModel from "./simple-model.js";
test("createModel(): creates a function", t => {
const actual = typeof createModel(() => {});
const expected = "function";
t.equal(actual, expected);
t.end();
});
test("createModel(): factory returns an object", t => {
const Factory = createModel(() => ({}));
const actual = typeof Factory({});
const expected = "object";
t.equal(actual, expected);
t.end();
});
test("createModel(): factory returns an object with expected fields", t => {
const Factory = createModel(({ foo }) => ({ foo }));
const actual = Factory({ foo: "foo", bar: "bar" });
const expected = { foo: "foo" };
t.deepEqual(actual, expected);
t.end();
});
test("createModel(): factory instances work with instanceof", t => {
const Factory = createModel(({ foo }) => ({ foo }));
const actual = Factory({ foo: "foo" }) instanceof Factory;
const expected = true;
t.equal(actual, expected);
t.end();
});
test("createModel(): multiple bare factory functions compose together", t => {
const Factory = createModel(
({ foo }) => ({ foo }),
({ bar }) => ({ bar })
);
const actual = Factory({ foo: "foo", bar: "bar", baz: "baz" });
const expected = { foo: "foo", bar: "bar" };
t.deepEqual(actual, expected);
t.end();
});
const Base = createModel(({ foo }) => ({ foo }));
test(".compose(): creates a function", t => {
const actual = typeof Base.compose(() => {});
const expected = "function";
t.equal(actual, expected);
t.end();
});
test(".compose(): factory returns an object", t => {
const Factory = Base.compose(() => {});
const actual = typeof Factory({});
const expected = "object";
t.equal(actual, expected);
t.end();
});
test(".compose(): factory returns an object with fields from all factories", t => {
const Factory = Base.compose(({ bar }) => ({ bar }));
const actual = Factory({ foo: "foo", bar: "bar", baz: "baz" });
const expected = { foo: "foo", bar: "bar" };
t.deepEqual(actual, expected);
t.end();
});
test(".compose(): factory instances work with instanceof", t => {
const Factory = Base.compose(({ bar }) => ({ bar }));
const actual = Factory({ foo: "foo", bar: "bar" }) instanceof Factory;
const expected = true;
t.equal(actual, expected);
t.end();
});
test(".compose().compose(): factory returns an object with fields from all factories", t => {
const Factory = Base.compose(({ bar }) => ({ bar })).compose(({ baz }) => ({
baz
}));
const actual = Factory({ foo: "foo", bar: "bar", baz: "baz", sneh: "sneh" });
const expected = { foo: "foo", bar: "bar", baz: "baz" };
t.deepEqual(actual, expected);
t.end();
});
test(".compose().compose(): factory instances work with instanceof", t => {
const Factory = Base.compose(({ bar }) => ({ bar })).compose(({ baz }) => ({
baz
}));
const actual =
Factory({ foo: "foo", bar: "bar", baz: "baz" }) instanceof Factory;
const expected = true;
t.equal(actual, expected);
t.end();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment