import { mount, patch } from "../../src/runtime/blockdom"; import { makeTestFixture, renderToBdom, renderToString, snapshotEverything } from "../helpers"; snapshotEverything(); // ----------------------------------------------------------------------------- // attributes // ----------------------------------------------------------------------------- describe("attributes", () => { test("static attributes", () => { const template = `
`; expect(renderToString(template)).toBe(`
`); }); test("two classes", () => { const template = `
`; expect(renderToString(template)).toBe(`
`); }); test("static attributes with dashes", () => { const template = `
`; expect(renderToString(template)).toBe(`
`); }); test("static attributes on void elements", () => { const template = `Test`; expect(renderToString(template)).toBe(`Test`); }); test("dynamic attributes", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("two dynamic attributes", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("dynamic class attribute", () => { const template = `
`; const result = renderToString(template, { c: "abc" }); expect(result).toBe(`
`); }); test("dynamic empty class attribute", () => { const template = `
`; const result = renderToString(template, { c: "" }); expect(result).toBe(`
`); }); test("dynamic undefined generic attribute", () => { const template = `
`; const result = renderToString(template, { c: undefined }); expect(result).toBe(`
`); }); test("dynamic undefined class attribute", () => { const template = `
`; const result = renderToString(template, { c: undefined }); expect(result).toBe(`
`); }); test("dynamic attribute with a dash", () => { const template = `
`; const result = renderToString(template, { id: 32 }); expect(result).toBe(`
`); }); test("dynamic formatted attributes with a dash", () => { const template = `
`; const result = renderToString(template, { id: 32 }); expect(result).toBe(`
`); }); test("fixed variable", () => { const template = `
`; const result = renderToString(template, { value: "ok" }); expect(result).toBe(`
`); }); test("dynamic attribute evaluating to 0", () => { const template = `
`; const result = renderToString(template, { value: 0 }); expect(result).toBe(`
`); }); test("dynamic class attribute evaluating to 0", () => { const template = `
`; const result = renderToString(template, { value: 0 }); expect(result).toBe(`
`); }); test("dynamic attribute falsy variable ", () => { const template = `
`; const result = renderToString(template, { value: false }); expect(result).toBe(`
`); }); test("tuple literal", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("tuple variable", () => { const template = `
`; const result = renderToString(template, { value: ["foo", "bar"] }); expect(result).toBe(`
`); }); test("object", () => { const template = `
`; const result = renderToString(template, { value: { a: 1, b: 2, c: 3 }, }); expect(result).toBe(`
`); }); test("format literal", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("format value", () => { const template = `
`; const result = renderToString(template, { value: "a" }); expect(result).toBe(`
`); }); test("t-attf-class", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("t-attf-class with multiple classes", () => { const template = `
`; const result = renderToString(template, { word: "world" }); expect(result).toBe(`
`); }); test("t-attf-class with multiple classes separated by multiple spaces", () => { const template = `
`; const result = renderToString(template, { word: "world" }); expect(result).toBe(`
`); }); test("t-attf-class should combine with class", () => { const template = `
`; const result = renderToString(template); expect(result).toBe(`
`); }); test("from variables set previously", () => { const template = `
`; const result = renderToString(template); expect(result).toBe('
'); }); test("from variables set previously (no external node)", () => { const template = ` `; const result = renderToString(template); expect(result).toBe(''); }); test("from object variables set previously", () => { // Note: standard qweb does not allow this... const template = `
`; const result = renderToString(template); expect(result).toBe('
'); }); test("format expression", () => { const template = `
`; const result = renderToString(template, { value: 5 }); expect(result).toBe(`
`); }); test("format multiple", () => { const template = `
`; const result = renderToString(template, { value1: 0, value2: 1, value3: 2, }); expect(result).toBe(`
`); }); test("various escapes", () => { const template = `
`; const result = renderToString(template, { bar: 0, baz: 1, qux: { qux: "<>" }, }); const expected = '
'; expect(result).toBe(expected); }); test("various escapes 2", () => { const template = `
<
`; const result = renderToString(template, {}); const expected = "
<
"; expect(result).toBe(expected); }); test("t-att-class and class should combine together", () => { const template = `
`; const result = renderToString(template, { value: "world" }); expect(result).toBe(`
`); }); test("class and t-att-class should combine together", () => { const template = `
`; const result = renderToString(template, { value: "world" }); expect(result).toBe(`
`); }); test("class and t-attf-class with ternary operation", () => { const template = `
`; const result = renderToString(template, { value: true }); expect(result).toBe(`
`); }); test("t-att-class with object", () => { const template = `
`; const result = renderToString(template, { b: true, d: false, f: true }); expect(result).toBe(`
`); }); test("t-att-class with multiple classes", () => { expect(renderToString(`
`, { value: true })).toBe( '
' ); expect(renderToString(`
`, { value: true })).toBe( '
' ); }); test("t-att-class with multiple classes, some of which are duplicate", () => { expect( renderToString(`
`, { value: true }) ).toBe('
'); expect( renderToString(`
`, { value: false }) ).toBe('
'); }); test("changing an attribute with t-att-", () => { // render input with initial value const template = `
`; const bnode1 = renderToBdom(template, { v: "zucchini" }); const fixture = makeTestFixture(); mount(bnode1, fixture); expect(fixture.innerHTML).toBe('
'); const bnode2 = renderToBdom(template, { v: "potato" }); patch(bnode1, bnode2); expect(fixture.innerHTML).toBe('
'); const bnode3 = renderToBdom(template, { v: "" }); patch(bnode1, bnode3); // not sure about this. maybe we want to remove the attribute? expect(fixture.innerHTML).toBe('
'); }); test("changing a class with t-att-class", () => { // render input with initial value const template = `
`; const bnode1 = renderToBdom(template, { v: "zucchini" }); const fixture = makeTestFixture(); mount(bnode1, fixture); expect(fixture.innerHTML).toBe('
'); const bnode2 = renderToBdom(template, { v: "potato" }); patch(bnode1, bnode2); expect(fixture.innerHTML).toBe('
'); const bnode3 = renderToBdom(template, { v: "" }); patch(bnode1, bnode3); // not sure about this. maybe we want to remove the attribute? expect(fixture.innerHTML).toBe('
'); }); test("changing a class with t-att-class (preexisting class", () => { // render input with initial value const template = `
`; const bnode1 = renderToBdom(template, { v: "zucchini" }); const fixture = makeTestFixture(); mount(bnode1, fixture); expect(fixture.innerHTML).toBe('
'); const bnode2 = renderToBdom(template, { v: "potato" }); patch(bnode1, bnode2); expect(fixture.innerHTML).toBe('
'); const bnode3 = renderToBdom(template, { v: "" }); patch(bnode1, bnode3); // not sure about this. maybe we want to remove the attribute? expect(fixture.innerHTML).toBe('
'); }); test("updating classes (with obj notation)", () => { // render input with initial value const template = `
`; const bnode1 = renderToBdom(template, { condition: true }); const fixture = makeTestFixture(); mount(bnode1, fixture); expect(fixture.innerHTML).toBe('
'); const bnode2 = renderToBdom(template, { condition: false }); patch(bnode1, bnode2); expect(fixture.innerHTML).toBe('
'); const bnode3 = renderToBdom(template, { condition: true }); patch(bnode1, bnode3); // not sure about this. maybe we want to remove the attribute? expect(fixture.innerHTML).toBe('
'); }); }); describe("special cases for some specific html attributes/properties", () => { test("input type= checkbox, with t-att-checked", () => { const template = ``; const result = renderToString(template, { flag: true }); expect(result).toBe(``); }); test("various boolean html attributes", () => { // will cause the template to be snapshotted renderToString(`
`); }); test("input with t-att-value", () => { // render input with initial value const template = ``; const bnode1 = renderToBdom(template, { v: "zucchini" }); const fixture = makeTestFixture(); mount(bnode1, fixture); const input = fixture.querySelector("input")!; expect(input.value).toBe("zucchini"); // change value manually in input, to simulate user input input.value = "tomato"; expect(input.value).toBe("tomato"); // rerender with a different value, and patch actual dom, to check that // input value was properly reset by owl const bnode2 = renderToBdom(template, { v: "potato" }); patch(bnode1, bnode2); expect(input.value).toBe("potato"); }); test("input of type checkbox with t-att-indeterminate", () => { const template = ``; const bnode1 = renderToBdom(template, { v: true }); const fixture = makeTestFixture(); mount(bnode1, fixture); const input = fixture.querySelector("input")!; expect(input.indeterminate).toBe(true); }); test("textarea with t-att-value", () => { // render textarea with initial value const template = `