import { describe, expect, it } from 'vitest' import { print } from './utils'; import { nodeType } from '../core'; describe('LML - List-based Markup Language', () => { describe('Text Nodes', () => { it('should support simple text nodes', async () => { expect(print("Hello World")).toMatchObject([ "Hello World" ]); }); it('should support list of text nodes', async () => { expect(print(["Hello", " World"])).toMatchObject([ "Hello", " World" ]); 1 }); }); describe('Node types', () => { it('should be text', async () => { expect(nodeType("Hello")).toBe("text"); }); it('should be element', async () => { expect(nodeType(["#span", "Hello"])).toBe("element"); }); it('should be component', async () => { expect(nodeType(["*cpt", "Hello"])).toBe("component"); }); it('should be fragment', async () => { expect(nodeType([])).toBe("fragment"); expect(nodeType(["a"])).toBe("fragment"); expect(nodeType(["", ["#span", "b"]])).toBe("fragment"); expect(nodeType([["#span", "b"]])).toBe("fragment"); expect(nodeType(["a", "b"])).toBe("fragment"); }); it('should be invalid', async () => { expect(nodeType(["!x", "Hello"])).toBe("invalid"); expect(nodeType(["@x", "Hello"])).toBe("invalid"); expect(nodeType(123 as any)).toBe("invalid"); expect(nodeType({} as any)).toBe("invalid"); }); }); describe('Elements', () => { it('should support empty elements', async () => { expect(print(["#div"])).toMatchObject([ "
" ]); }); it('should support empty elements', async () => { expect(print(["#foo-bar"])).toMatchObject([ "" ]); }); it('should support empty elements with attributes', async () => { expect(print(["#div", { "title": "abc" }])).toMatchObject([ '
', ]); expect(print(["#div", { "foo": "bar", "size": 123, "ok": true }])).toMatchObject([ '
', ]); expect(print(["#div", { "foo": "bar", "baz": { foo: "bar", blah: 123 } }])).toMatchObject([ '
', ]); }); it('should support text content', async () => { expect(print(["#div", "Some Content"])).toMatchObject([ '
', ' Some Content', '
' ]); expect(print(["#div", "Some", "Content"])).toMatchObject([ '
', ' Some', ' Content', '
' ]); expect(print(["#div", { "title": "abc" }, "Some Content", ["#span", "Hello"]])).toMatchObject([ '
', ' Some Content', ' ', ' Hello', ' ', '
' ]); }); it('should support fragments', async () => { expect(print(["#div", { "title": "abc" }, [ "Some Content", ["#span", "Hello"] ]])).toMatchObject([ '
', ' Some Content', ' ', ' Hello', ' ', '
' ]); expect(print(["#div", { "title": "abc" }, [ "Some Content", ["#span", ["Hello"]] ]])).toMatchObject([ '
', ' Some Content', ' ', ' Hello', ' ', '
' ]); }); it('should support no values attributes', async () => { expect(print(["#input", { "type": "checkbox", "!checked": 1, "title": "Check me!" }, [ "Option A", ]])).toMatchObject([ '', ' Option A', '' ]); }); it('should support class names shortcut', async () => { expect(print(["#div.foo", { "maxlength": 123 }])).toMatchObject([ '
', ]); expect(print(["#div.p-3", { "maxlength": 123 }])).toMatchObject([ '
', ]); expect(print(["#div.foo.bar", { "maxlength": 123 }])).toMatchObject([ '
', ]); expect(print(["#div.mt-3.pb-2", { "maxlength": 123 }])).toMatchObject([ '
', ]); expect(print(["Hello", ["#span.highlight", "World"], "!"])).toMatchObject([ 'Hello', '', ' World', '', '!' ]); }); it('should support type attribute shortcut', async () => { expect(print(["#input+checkbox.abc", { "id": "subscribeNews", "name": "subscribe", "value": "newsletter", "!checked": 1 }])).toMatchObject([ '' ]); }); it('should support namespaces', async () => { expect(print(["#x:div.foo", { "maxlength": 123 }])).toMatchObject([ '', ]); }); it('shoul support component nodes', async () => { expect(print(["*x:mycpt.foo", { "maxlength": 123 }])).toMatchObject([ '', ]); }); }); // TODO: encoding for text nodes starting with reserved prefixes ! or # or @ or * // error case: ["#x:div.foo", { "maxlength": 123 }] });