reblend-testing-library
Version:
Simple and complete Reblendjs testing utilities that encourage good testing practices.
147 lines (145 loc) • 4.55 kB
JavaScript
;
var _reblendjs = require("reblendjs");
var _ = require("../");
test("cleans up the document", async () => {
const spy = jest.fn();
const divId = "my-div";
class Test extends _reblendjs.Reblend {
componentWillUnmount() {
expect(document.getElementById(divId)).toBeInTheDocument();
spy();
}
html() {
return _reblendjs.Reblend.construct.bind(this)("div", {
id: divId
});
}
}
await (0, _.render)(_reblendjs.Reblend.construct.bind(this)(Test, null));
await (0, _.cleanup)();
expect(document.body).toBeEmptyDOMElement();
expect(spy).toHaveBeenCalledTimes(1);
});
test("cleanup does not error when an element is not a child", async () => {
await (0, _.render)(_reblendjs.Reblend.construct.bind(this)("div", null), {
container: document.createElement("div")
});
await (0, _.cleanup)();
});
test("cleanup runs effect cleanup functions", async () => {
const spy = jest.fn();
//@reblendComponent
const Test = class
/* @Reblend: Transformed from function to class */
extends _reblendjs.Reblend {
static ELEMENT_NAME = "Test";
constructor() {
super();
}
async initState() {
_reblendjs.useEffect.bind(this)(() => spy);
}
async initProps() {
this.props = {};
}
async html() {
return;
}
};
await (0, _.render)(_reblendjs.Reblend.construct.bind(this)(Test, null));
await (0, _.cleanup)();
expect(spy).toHaveBeenCalledTimes(1);
});
describe("fake timers and missing act warnings", () => {
beforeEach(() => {
jest.resetAllMocks();
jest.spyOn(console, "error").mockImplementation(() => {
// assert messages explicitly
});
jest.useFakeTimers();
});
afterEach(() => {
jest.restoreAllMocks();
jest.useRealTimers();
});
test("cleanup does not flush microtasks", async () => {
const microTaskSpy = jest.fn();
//@reblendComponent
class Test extends _reblendjs.Reblend {
static ELEMENT_NAME = "Test";
constructor() {
super();
}
async initState() {
const [counter, setDeferredCounter] = _reblendjs.useState.bind(this)(1, "counter");
this.state.counter = counter;
this.state.setDeferredCounter = setDeferredCounter;
_reblendjs.useEffect.bind(this)(() => {
let cancelled = false;
Promise.resolve().then(() => {
microTaskSpy();
// eslint-disable-next-line jest/no-if, jest/no-conditional-in-test -- false positive
if (!cancelled) {
this.state.setDeferredCounter(this.state.counter);
}
});
return () => {
cancelled = true;
};
}, (() => [this.state.counter]).bind(this));
}
async initProps() {
this.props = {};
}
async html() {
return null;
}
}
/* @Reblend: Transformed from function to class */
await (0, _.render)(_reblendjs.Reblend.construct.bind(this)(Test, null));
await (0, _.cleanup)();
expect(microTaskSpy).toHaveBeenCalledTimes(1);
// console.error is mocked
// eslint-disable-next-line no-console
expect(console.error).toHaveBeenCalledTimes(0);
});
test("cleanup does not flush macrotasks", async () => {
const deferredStateUpdateSpy = jest.fn();
//@reblendComponent
class Test extends _reblendjs.Reblend {
static ELEMENT_NAME = "Test";
constructor() {
super();
}
async initState() {
const [counter, setDeferredCounter] = _reblendjs.useState.bind(this)(1, "counter");
this.state.counter = counter;
this.state.setDeferredCounter = setDeferredCounter;
_reblendjs.useEffect.bind(this)(() => {
let cancelled = false;
setTimeout(() => {
deferredStateUpdateSpy();
// eslint-disable-next-line jest/no-conditional-in-test -- false-positive
if (!cancelled) {
this.state.setDeferredCounter(this.state.counter);
}
}, 0);
return () => {
cancelled = true;
};
}, (() => [this.state.counter]).bind(this));
}
async initProps() {
this.props = {};
}
async html() {
return null;
}
}
/* @Reblend: Transformed from function to class */
await (0, _.render)(_reblendjs.Reblend.construct.bind(this)(Test, null));
jest.runAllTimers();
await (0, _.cleanup)();
expect(deferredStateUpdateSpy).toHaveBeenCalledTimes(1);
});
});