als-component
Version:
lightweight JavaScript library for creating reactive, server-rendered, and browser-based components.
222 lines (171 loc) • 7.97 kB
JavaScript
describe("Nested Components Tests", () => {
// Тест на рендеринг вложенных компонентов
it("should render nested components correctly", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
class ChildComponent extends Component {
render() {
return `<span>Child</span>`;
}
}
class ParentComponent extends Component {
render() {
return `<div><h1>Parent</h1>${new ChildComponent().call()}</div>`;
}
}
const instance = new ParentComponent();
instance.update();
const element = document.querySelector(instance.selector);
const childElement = element.querySelector("span");
assert.strictEqual(element.querySelector("h1").textContent, "Parent", "Parent component did not render correctly");
assert.strictEqual(childElement.textContent, "Child", "Child component did not render correctly");
element.remove();
});
// Тест на обновление вложенных компонентов
it("should update nested components when parent component is updated", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
class ChildComponent extends Component {
render({ count }) {
return `<span>Child Count: ${count}</span>`;
}
}
class ParentComponent extends Component {
render({ count }) {
return `<div><h1>Parent</h1>${new ChildComponent({ count }).call()}</div>`;
}
}
const instance = new ParentComponent({ count: 1 });
instance.update({ count: 2 });
const element = document.querySelector(instance.selector);
const childElement = element.querySelector("span");
assert.strictEqual(childElement.textContent, "Child Count: 2", "Child component did not update correctly");
element.remove();
});
// Тест на обработку событий в вложенных компонентах
it("should handle events in nested components correctly", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
let childClicked = false;
class ChildComponent extends Component {
render() {
return `<button click="${this.action('click', () => (childClicked = true))}">Click Me</button>`;
}
}
class ParentComponent extends Component {
render() {
return `<div><h1>Parent</h1>${new ChildComponent().call()}</div>`;
}
}
const instance = new ParentComponent();
instance.update();
const button = document.querySelector("button");
button.click();
assert(childClicked, "Click event in child component was not handled correctly");
instance.element.remove();
});
// Тест на обновление props для вложенных компонентов
it("should update props for nested components correctly", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
class ChildComponent extends Component {
render({ text }) {
return `<span>${text}</span>`;
}
}
class ParentComponent extends Component {
render() {
return `<div>${new ChildComponent({ text: "Initial" }).call()}</div>`;
}
}
const instance = new ParentComponent();
instance.update();
const childInstance = new ChildComponent({ text: "Updated" });
childInstance.update({ text: "Updated" });
const element = document.querySelector(childInstance.selector);
assert.strictEqual(element.textContent, "Updated", "Child component props were not updated correctly");
element.remove();
});
// Тест на вызов хуков для вложенных компонентов
it("should trigger mount and unmount hooks for nested components", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
let parentMount = false;
let childMount = false;
let childUnmount = false;
class ChildComponent extends Component {
render() {
this.on("mount", () => (childMount = true));
this.on("unmount", () => (childUnmount = true));
return `<span>Child</span>`;
}
}
class ParentComponent extends Component {
constructor(props) {super(props)}
render({child=true}) {
this.on("mount", () => (parentMount = true));
return `<div><h1>Parent</h1>${child ? new ChildComponent().call() : ''}</div>`;
}
}
const parentInstance = new ParentComponent();
const childInstance = new ChildComponent();
parentInstance.update();
assert(parentMount, "Parent mount hook was not triggered");
assert(childMount, "Child mount hook was not triggered");
parentInstance.update({child:false});
assert(childUnmount, "Child unmount hook was not triggered");
parentInstance.element.remove()
});
});
describe('More tests', () => {
it("should handle nested components with the same class name correctly", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
class ChildComponent extends Component {
render() {
return `<span>Child</span>`;
}
}
class ParentComponent extends Component {
render() {
return `<div>${new ChildComponent().call()}${new ChildComponent().call()}</div>`;
}
}
const instance = new ParentComponent();
instance.update();
const elements = document.querySelectorAll("span");
assert.strictEqual(elements.length, 2, "There should be two child components");
elements.forEach(element => element.remove());
});
it("should not duplicate event listeners after multiple updates", () => {
let clickCount = 0;
document.body.insertAdjacentHTML('beforeend',/*html*/`<button component="ButtonComponent"></button>`)
class ButtonComponent extends Component {
render() {
return `<button click="${this.action('click', () => clickCount++)}">Click Me</button>`;
}
}
const instance = new ButtonComponent();
instance.update();
instance.update();
const button = document.querySelector("button");
button.click();
button.click();
assert.strictEqual(clickCount, 2, "Event listeners were duplicated after multiple updates");
button.remove();
});
it("should update nested component directly without updating parent", () => {
document.body.insertAdjacentHTML('beforeend',/*html*/`<div component="ParentComponent"></div>`)
class ChildComponent extends Component {
render({ text }) {
return `<span>${text}</span>`;
}
}
class ParentComponent extends Component {
render() {
return `<div>${new ChildComponent({ text: "Initial" }).call()}</div>`;
}
}
const parentInstance = new ParentComponent();
const childInstance = new ChildComponent({ text: "Initial" });
parentInstance.update();
childInstance.update({ text: "Updated" });
const element = document.querySelector(childInstance.selector);
assert.strictEqual(element.textContent, "Updated", "Nested component did not update correctly");
element.remove();
});
})