Skip to content

Instantly share code, notes, and snippets.

@scytacki
Last active November 26, 2019 04:53
Show Gist options
  • Save scytacki/6d891ca6ab3d72ab05e094fe0ecc20c1 to your computer and use it in GitHub Desktop.
Save scytacki/6d891ca6ab3d72ab05e094fe0ecc20c1 to your computer and use it in GitHub Desktop.
examples of let like behavior in jest
// For a more complete version of this look at given: https://github.com/tatyshev/given2/
// it supports more options and has more checks, but is also much bigger than this
// 15 line approach.
const c = {};
// Approach #1 add properties to a variable `c`
// these use a getter that gets replaced after being called the first time
// In theory this can be used with the global object, but that means your test would be adding
// properties to the global namespace
// This approach hasn't been tested well though. I kind of think it doesn't work as expected since the
// beforeEach here might not know its context. I'm not sure how Jest keeps track of the context. It does seem to work
// though. So perhaps Jest builds up a tree of blocks and has an internal context that the beforeEach call addes to.
function set(name, computeValue) {
beforeEach(() => {
Object.defineProperty(c, name, {
configurable: true,
get: () => {
delete c[name];
return c[name] = computeValue();
}
});
});
afterEach(() => {
delete c[name];
});
}
// Approach #2, use a simple memoization function
// this would be used like `let variable = mem(() => value);`
// In this case overriding a variable later requires putting it in a beforeEach block
// it seems Jest evaluates all of the describe blocks before running the first it block
// this makes sense. But it means any overrides will be called and then modify the variable
// before it is actually used.
// because of this the set approach above seems best
function mem(computeValue) {
let computed = false;
let value;
return () => {
if(computed) {
return value
} else {
computed = true;
return value = computeValue();
}
}
}
describe("<NumericTextField /> minValue prop", () => {
let props = mem(() => ({}));
let wrapper = mem(() => shallow(<NumericTextField {...props()}/>));
// set("wrapper", () => shallow(<NumericTextField {...c.props}/>) );
// set("props", () => ({}) );
describe("default behavior with no configuration", () => {
it("should not allow non-numeric values, and default to 0", () => {
wrapper().find("input").simulate("change", { target: { value: "x" } });
wrapper().find("input").simulate("blur", {});
expect(wrapper().state("value")).toBe(0);
});
it("will allow values greater than 0", () => {
c.wrapper.find("input").simulate("change", { target: { value: "5" } });
c.wrapper.find("input").simulate("blur", {});
expect(c.wrapper.state("value")).toBe(5);
});
it("will allow an in-range decimal value. Truncates to integer", () => {
c.wrapper.find("input").simulate("change", { target: { value: "2.6" } });
c.wrapper.find("input").simulate("blur", {});
expect(c.wrapper.state("value")).toBe(2);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment