v0.0.11: Added unit-tests, solved the key={...} problem, updated the build/watch configuration of CSX to be able to build minified and non-minified bundle outputs, as well as a CJS version of lib/ (for consuming in Node-environment, like Jest). The previous tests were renamed to examples, and should still need to be updated.
This commit is contained in:
215
jest/render/basic-render.test.js
Normal file
215
jest/render/basic-render.test.js
Normal file
@@ -0,0 +1,215 @@
|
||||
import { render } from "@cerxes/csx";
|
||||
import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("Basic elements", () => {
|
||||
test("Single element", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<textarea />
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<textarea></textarea>`
|
||||
);
|
||||
});
|
||||
|
||||
test("With text-contents", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div>Simple test</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<div>Simple test</div>`
|
||||
);
|
||||
});
|
||||
|
||||
// TODO once added: fragments
|
||||
});
|
||||
|
||||
describe("Native Attributes", () => {
|
||||
test("Button-type", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<button type="submit">Save</button>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<button type="submit">Save</button>`
|
||||
);
|
||||
});
|
||||
|
||||
test("Image-src", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<img src="/some-image.jpg"/>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<img src="/some-image.jpg">`
|
||||
);
|
||||
});
|
||||
|
||||
// We're testing for native functionality of class here, not className
|
||||
test("Class", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="some-class"/>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<div class="some-class"></div>`
|
||||
);
|
||||
});
|
||||
|
||||
// We're testing for native functionality of style here, which should always directly set style as an attribute
|
||||
// when passed in as a string
|
||||
test("Style", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div style="width: 10em"/>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<div style="width: 10em"></div>`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Basic Events", () => {
|
||||
test("Click-event", async () => {
|
||||
let clicked = false;
|
||||
let clickHandler = (ev)=>{
|
||||
clicked = true;
|
||||
|
||||
// TODO test on properties that should be on a native click event
|
||||
};
|
||||
/** @type {HTMLButtonElement} */
|
||||
let button = render(<button type="submit" onClick={clickHandler}>Save</button>);
|
||||
|
||||
document.body.append(button);
|
||||
button.click();
|
||||
expect(clicked).toBe(true);
|
||||
document.body.removeChild(button);
|
||||
});
|
||||
|
||||
test("Focus-event", async () => {
|
||||
// This test exists just to have a second event to test, ideally we would have used two-part word event
|
||||
// like focusin, but unfortunatily, it does not seem to be working. (probably JSDOM related?)
|
||||
let focused = false;
|
||||
let focusHandler = (ev)=>{
|
||||
focused = true;
|
||||
};
|
||||
/** @type {HTMLButtonElement} */
|
||||
let input = render(<input type="text" onFocus={focusHandler}/>);
|
||||
|
||||
document.body.append(input);
|
||||
input.focus();
|
||||
expect(focused).toBe(true);
|
||||
document.body.removeChild(input);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Children", () => {
|
||||
test("3 levels", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
<button type="submit">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe(
|
||||
`<div class="container"><button type="submit">Save</button></div>`
|
||||
);
|
||||
});
|
||||
|
||||
test("Multiple children", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
<h1>Title</h1>
|
||||
<p>
|
||||
Contents
|
||||
</p>
|
||||
<button type="submit">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`<h1>Title</h1>`,
|
||||
`<p>Contents</p>`,
|
||||
`<button type="submit">Save</button>`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
});
|
||||
|
||||
test("Prerendered element", async () => {
|
||||
let element = render(<h1>Title</h1>);
|
||||
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
{element}
|
||||
</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`<h1>Title</h1>`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
});
|
||||
|
||||
test("Prerendered text", async () => {
|
||||
// TODO: CSX doesn't support fragments yet (<>I am text</>)
|
||||
let text = document.createTextNode(`I am text!`);
|
||||
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
{text}
|
||||
</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`I am text!`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
});
|
||||
|
||||
test("Nulls are ignored", async () => {
|
||||
expect(
|
||||
testContainer(
|
||||
render(
|
||||
<div class="container">
|
||||
<h1>Title</h1>
|
||||
{null}
|
||||
<button>Save</button>
|
||||
</div>
|
||||
)
|
||||
).innerHTML
|
||||
).toBe([
|
||||
`<div class="container">`,
|
||||
`<h1>Title</h1>`,
|
||||
`<button>Save</button>`,
|
||||
`</div>`
|
||||
].join(''));
|
||||
});
|
||||
});
|
||||
61
jest/render/key-property.test.js
Normal file
61
jest/render/key-property.test.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { render } from "@cerxes/csx";
|
||||
import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("Key-property tests", () => {
|
||||
test("Keyed list", async () => {
|
||||
let renderedIndexes = [];
|
||||
let initIndexes = [0, 1, 2, 3];
|
||||
|
||||
let makeSpec = (targetList, indexes)=>(
|
||||
<ul>
|
||||
{
|
||||
indexes.map(index => (
|
||||
<li id={`li_${index}`} key={index} ref={(el) => targetList[ index ] = el}>
|
||||
{index}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
|
||||
let initialVSpec = makeSpec(renderedIndexes, initIndexes);
|
||||
|
||||
let rendered = render(initialVSpec);
|
||||
let container = testContainer(rendered);
|
||||
|
||||
expect(container.innerHTML).toBe(
|
||||
[
|
||||
`<ul>`,
|
||||
...initIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
|
||||
`</ul>`
|
||||
].join('')
|
||||
);
|
||||
|
||||
expect(renderedIndexes.length).toBe(4);
|
||||
for(let rendered of renderedIndexes){
|
||||
expect(rendered).not.toBeUndefined();
|
||||
}
|
||||
|
||||
let reorderedIndexes = [3,2,1,0];
|
||||
let rerenderedIndexes = renderedIndexes.slice();
|
||||
let updatedVSpec = makeSpec(rerenderedIndexes, reorderedIndexes);
|
||||
render(updatedVSpec, {host: rendered, old: initialVSpec});// Is this host right? it seems inconsistent and the source of our bug (as it is probably also misused in custom-elements)
|
||||
|
||||
// Updated
|
||||
expect(container.innerHTML).toBe(
|
||||
[
|
||||
`<ul>`,
|
||||
...reorderedIndexes.map(index=>`<li id="${`li_${index}`}">${index}</li>`),
|
||||
`</ul>`
|
||||
].join('')
|
||||
);
|
||||
|
||||
// Validate that items were merely re-arranged and not re-created
|
||||
expect(rerenderedIndexes.length).toBe(4);
|
||||
for(let i=0; i<4; ++i){
|
||||
let initRendered = renderedIndexes[i];
|
||||
let reorderedRendered = rerenderedIndexes[i];
|
||||
expect(initRendered === reorderedRendered).toBe(true); // These should've remained the same
|
||||
}
|
||||
});
|
||||
});
|
||||
17
jest/render/ref-property.test.js
Normal file
17
jest/render/ref-property.test.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { render, Host } from "@cerxes/csx";
|
||||
import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("Ref-property tests", () => {
|
||||
test("Simple ref", async () => {
|
||||
let targetVar = null;
|
||||
let refHandler = (el)=>targetVar = el;
|
||||
let container = testContainer(render(<div id="test-div" ref={refHandler}/>));
|
||||
|
||||
expect(container.innerHTML).toBe(
|
||||
`<div id="test-div"></div>`
|
||||
);
|
||||
|
||||
expect(targetVar).not.toBe(null);
|
||||
expect(targetVar.id).toBe('test-div')
|
||||
});
|
||||
});
|
||||
44
jest/render/render-opts.test.js
Normal file
44
jest/render/render-opts.test.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import { render, Host } from "@cerxes/csx";
|
||||
import { testContainer } from "../utils/test-container";
|
||||
|
||||
describe("Basic render-options", () => {
|
||||
test("opts.host", async () => {
|
||||
let startElement = render(<div />);
|
||||
let container = testContainer([startElement]);
|
||||
|
||||
render(<Host style="width: 10em">Contents</Host>, {host: startElement});
|
||||
|
||||
expect(container.innerHTML).toBe(
|
||||
`<div style="width: 10em">Contents</div>`
|
||||
);
|
||||
});
|
||||
|
||||
test("opts.vnode", async () => {
|
||||
let container = testContainer();
|
||||
|
||||
let initialVSpec = (
|
||||
<Host>
|
||||
<h1>Initial title</h1>
|
||||
</Host>
|
||||
);
|
||||
|
||||
let updatedVSpec = (
|
||||
<Host>
|
||||
<h1>Updated title</h1>
|
||||
</Host>
|
||||
);
|
||||
render(initialVSpec, {host: container});
|
||||
|
||||
// Initial
|
||||
expect(container.innerHTML).toBe(
|
||||
`<h1>Initial title</h1>`
|
||||
);
|
||||
|
||||
render(updatedVSpec, {host: container, old: initialVSpec});
|
||||
|
||||
// Updated
|
||||
expect(container.innerHTML).toBe(
|
||||
`<h1>Updated title</h1>`
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user