UNPKG

@player-ui/player

Version:

1,018 lines (922 loc) 24.5 kB
import { describe, it, expect, test } from "vitest"; import { LocalModel, withParser } from "../../data"; import { ExpressionEvaluator } from "../../expressions"; import { BindingParser } from "../../binding"; import { SchemaController } from "../../schema"; import { MultiNodePlugin, StringResolverPlugin, SwitchPlugin, ViewInstance, toNodeResolveOptions, } from ".."; const parseBinding = new BindingParser().parse; describe("view", () => { describe("switch", () => { it("works on a static switch", () => { const model = withParser( new LocalModel({ foo: { bar: true, baz: false, }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { staticSwitch: [ { case: "{{foo.baz}}", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.bar}}", asset: { id: "input-2", type: "input", }, }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "input-2", type: "input", }, }, }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toBe(resolved); }); test("works with no valid static switch cases in an array", () => { const model = withParser(new LocalModel({}), parseBinding); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "test", type: "view", title: [ { staticSwitch: [ { case: false, asset: { id: "false-case", type: "text", value: "some text", }, }, { case: false, asset: { id: "false-case-2", type: "text", value: "some text", }, }, ], }, ], }, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new MultiNodePlugin().apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "test", type: "view", }); }); test("works with no valid dynamic switch cases in an array", () => { const model = withParser(new LocalModel({}), parseBinding); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "test", type: "view", title: [ { dynamicSwitch: [ { case: false, asset: { id: "false-case", type: "text", value: "some text", }, }, { case: false, asset: { id: "false-case-2", type: "text", value: "some text", }, }, ], }, ], }, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new MultiNodePlugin().apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "test", title: [], type: "view", }); }); it("does not return a field object if the case does not resolve an asset", () => { const model = withParser( new LocalModel({ foo: { bar: true, baz: false, }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { staticSwitch: [ { case: "{{foo.baz}}", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.bar}}", }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toBe(resolved); }); it("works with default case", () => { const model = withParser( new LocalModel({ foo: { baz: "bad", }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { staticSwitch: [ { case: '{{foo.baz}} === "good"', asset: { id: "input-1", type: "input", }, }, { case: true, asset: { id: "input-2", type: "input", }, }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "input-2", type: "input", }, }, }); }); it("works on a dynamic switch", () => { const model = withParser( new LocalModel({ foo: { bar: true, baz: false, }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { dynamicSwitch: [ { case: "{{foo.baz}}", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.bar}}", asset: { id: "input-2", type: "input", }, }, ], }, } as any, { schema, model, parseBinding, evaluator, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "input-2", type: "input", }, }, }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toStrictEqual({ id: "foo", fields: { asset: { id: "input-1", type: "input", }, }, }); }); it("dynamic - works inside of an array", () => { const model = withParser( new LocalModel({ foo: { baz: "bad", }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { asset: { type: "collection", id: "collection", values: [ { dynamicSwitch: [ { case: '{{foo.baz}} === "good"', asset: { id: "input-1", type: "input", }, }, { case: '{{foo.baz}} === "bad"', asset: { id: "input-2", type: "input", }, }, ], }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new MultiNodePlugin().apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "collection", type: "collection", values: [ { asset: { id: "input-2", type: "input", }, }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toStrictEqual({ id: "foo", fields: { asset: { id: "collection", type: "collection", values: [ { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, }); }); it("static - works inside of an array", () => { const model = withParser(new LocalModel({}), parseBinding); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "test", type: "view", title: { staticSwitch: [ { case: false, asset: { id: "false-case", type: "text", value: "some text", }, }, { case: false, asset: { id: "false-case-2", type: "text", value: "some text", }, }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "test", type: "view", }); }); it("does not return a field object if the case does not resolve an asset", () => { const model = withParser( new LocalModel({ foo: { bar: true, baz: false, }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { staticSwitch: [ { case: "{{foo.baz}}", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.bar}}", }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toBe(resolved); }); it("works with default case", () => { const model = withParser( new LocalModel({ foo: { baz: "bad", }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { staticSwitch: [ { case: "{{foo.baz}} === 'good'", asset: { id: "input-1", type: "input", }, }, { case: true, asset: { id: "input-2", type: "input", }, }, ], }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "input-2", type: "input", }, }, }); }); it("works on a dynamic switch", () => { const model = withParser( new LocalModel({ foo: { bar: true, baz: false, }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { dynamicSwitch: [ { case: "{{foo.baz}}", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.bar}}", asset: { id: "input-2", type: "input", }, }, ], }, } as any, { schema, model, parseBinding, evaluator, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "input-2", type: "input", }, }, }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toStrictEqual({ id: "foo", fields: { asset: { id: "input-1", type: "input", }, }, }); }); it("dynamic - works inside of an array", () => { const model = withParser( new LocalModel({ foo: { baz: "bad", }, }), parseBinding, ); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { asset: { type: "collection", id: "collection", values: [ { dynamicSwitch: [ { case: "{{foo.baz}} === 'good'", asset: { id: "input-1", type: "input", }, }, { case: "{{foo.baz}} === 'bad'", asset: { id: "input-2", type: "input", }, }, ], }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new MultiNodePlugin().apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "collection", type: "collection", values: [ { asset: { id: "input-2", type: "input", }, }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, }); const bazBinding = parseBinding("foo.baz"); model.set([[bazBinding, true]]); const updated = view.update(new Set([bazBinding])); expect(updated).toStrictEqual({ id: "foo", fields: { asset: { id: "collection", type: "collection", values: [ { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, }); }); it("static - works inside of an array", () => { const model = withParser(new LocalModel({}), parseBinding); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", fields: { asset: { type: "collection", id: "collection", values: [ { staticSwitch: [ { case: true, asset: { id: "input-2", type: "input", }, }, ], }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, } as any, { model, parseBinding, evaluator, schema, }, ); const pluginOptions = toNodeResolveOptions(view.resolverOptions); new SwitchPlugin(pluginOptions).apply(view); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "collection", type: "collection", values: [ { asset: { id: "input-2", type: "input", }, }, { asset: { id: "other-asset", type: "text", value: "other value", }, }, ], }, }, }); }); }); describe("string-updates", () => { it("works on expressions", () => { const model = withParser( new LocalModel({ foo: { hello: "Hello", world: "World", }, }), parseBinding, ); const schema = new SchemaController(); const evaluator = new ExpressionEvaluator({ model }); const view = new ViewInstance( { id: "foo", fields: { asset: { id: "test", type: "text", value: "Before @[ {{foo.hello}} + ' ' + {{foo.world}} ]@ After", }, }, } as any, { model, parseBinding, evaluator, schema, }, ); new StringResolverPlugin().apply(view); const resolved = view.update(); expect(resolved).toStrictEqual({ id: "foo", fields: { asset: { id: "test", type: "text", value: "Before Hello World After", }, }, }); const worldBinding = parseBinding("foo.world"); model.set([[worldBinding, "Adam"]]); const updated = view.update(new Set([worldBinding])); expect(updated).toStrictEqual({ id: "foo", fields: { asset: { id: "test", type: "text", value: "Before Hello Adam After", }, }, }); model.set([[parseBinding("foo.unrelated"), "other stuff"]]); expect(view.update(new Set([parseBinding("foo.unrelated")]))).toBe( updated, ); }); }); test("handles a top level validation thats not an array", () => { const model = withParser(new LocalModel({}), parseBinding); const evaluator = new ExpressionEvaluator({ model }); const schema = new SchemaController(); const view = new ViewInstance( { id: "foo", validation: { broken: true, }, } as any, { model, parseBinding, evaluator, schema, }, ); expect(view).toBeDefined(); }); });