Last active
November 26, 2019 04:53
-
-
Save scytacki/6d891ca6ab3d72ab05e094fe0ecc20c1 to your computer and use it in GitHub Desktop.
examples of let like behavior in jest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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