budibase/packages/builder/tests/validateProps.spec.js

232 lines
5.9 KiB
JavaScript

import {
validateComponentDefinition,
validateProps,
recursivelyValidate
} from "../src/userInterface/pagesParsing/validateProps";
import { createProps } from "../src/userInterface/pagesParsing/createProps";
import {
setBinding
} from "../src/common/binding";
// not that allot of this functionality is covered
// in createDefaultProps - as validate props uses that.
describe("validateComponentDefinition", () => {
it("should return error when no options for options field", () => {
const compDef = {
name:"some_component",
props: {
size: {
type: "options",
options: []
}
}
};
const errors = validateComponentDefinition(compDef);
expect(errors.length).toEqual(1);
expect(errors[0].propName).toBe("size");
});
it("should not return error when options field has options", () => {
const compDef = {
name: "some_component",
props: {
size: {
type: "options",
options: ["small", "medium", "large"]
}
}
};
const errors = validateComponentDefinition(compDef);
expect(errors).toEqual([]);
});
});
const validComponentDef = {
name: "some_component",
props: {
size: {
type: "options",
options: ["small", "medium", "large"],
default:"medium"
},
rowCount : "number"
}
};
const childComponentDef = {
name: "child_component",
props: {
width: "number",
units: {
type: "string",
default: "px"
}
}
};
const validProps = () => {
const { props } = createProps(validComponentDef);
props._children.push(
createProps(childComponentDef));
return props;
}
describe("validateProps", () => {
it("should have no errors with a big list of valid props", () => {
const errors = validateProps(validComponentDef, validProps(), [], true);
expect(errors).toEqual([]);
});
it("should return error with invalid value", () => {
const props = validProps();
props.rowCount = "1";
const errors = validateProps(validComponentDef, props, [], true);
expect(errors.length).toEqual(1);
expect(errors[0].propName).toBe("rowCount");
});
it("should return error with invalid option", () => {
const props = validProps();
props.size = "really_small";
const errors = validateProps(validComponentDef, props, [], true);
expect(errors.length).toEqual(1);
expect(errors[0].propName).toBe("size");
});
it("should not return error when has binding", () => {
const props = validProps();
props._children[0].width = setBinding({path:"some_path"});
props.size = setBinding({path:"other path", fallback:"small"});
const errors = validateProps(validComponentDef, props, [], true);
expect(errors.length).toEqual(0);
});
});
describe("recursivelyValidateProps", () => {
const rootComponent = {
name: "rootComponent",
children: true,
props: {
width: "number"
}
};
const todoListComponent = {
name: "todoListComponent",
props:{
showTitle: "bool"
}
};
const headerComponent = {
name: "headerComponent",
props: {
text: "string"
}
};
const iconComponent = {
name: "iconComponent",
props: {
iconName: "string"
}
};
const navItemComponent = {
name: "navItemComponent",
props: {
text: "string"
}
};
const getComponent = name => ({
rootComponent,
todoListComponent,
headerComponent,
iconComponent,
navItemComponent
})[name];
const rootProps = () => ({
_component: "rootComponent",
width: 100,
_children: [{
_component: "todoListComponent",
showTitle: true,
_children : [
{
_component: "navItemComponent",
text: "todos"
},
{
_component: "headerComponent",
text: "Your todo list"
},
{
_component: "iconComponent",
iconName: "fa fa-list"
},
{
_component: "iconComponent",
iconName:"fa fa-cog"
}
]
}]
});
it("should return no errors for valid structure", () => {
const result = recursivelyValidate(
rootProps(),
getComponent);
expect(result).toEqual([]);
});
it("should return error on root component", () => {
const root = rootProps();
root.width = "yeeeoooo";
const result = recursivelyValidate(root, getComponent);
expect(result.length).toBe(1);
expect(result[0].propName).toBe("width");
});
it("should return error on first nested child component", () => {
const root = rootProps();
root._children[0].showTitle = "yeeeoooo";
const result = recursivelyValidate(root, getComponent);
expect(result.length).toBe(1);
expect(result[0].stack).toEqual([0]);
expect(result[0].propName).toBe("showTitle");
});
it("should return error on second nested child component", () => {
const root = rootProps();
root._children[0]._children[0].text = false;
const result = recursivelyValidate(root, getComponent);
expect(result.length).toBe(1);
expect(result[0].stack).toEqual([0,0]);
expect(result[0].propName).toBe("text");
});
});