2019-07-19 19:03:58 +02:00
|
|
|
import {
|
2020-01-18 00:06:42 +01:00
|
|
|
validateComponentDefinition,
|
2019-07-21 10:36:20 +02:00
|
|
|
validateProps,
|
|
|
|
recursivelyValidate
|
2019-07-29 08:48:40 +02:00
|
|
|
} from "../src/userInterface/pagesParsing/validateProps";
|
|
|
|
import { createProps } from "../src/userInterface/pagesParsing/createProps";
|
2019-09-20 09:01:35 +02:00
|
|
|
import {
|
|
|
|
setBinding
|
|
|
|
} from "../src/common/binding";
|
2019-07-19 19:03:58 +02:00
|
|
|
|
|
|
|
// not that allot of this functionality is covered
|
|
|
|
// in createDefaultProps - as validate props uses that.
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
describe("validateComponentDefinition", () => {
|
2019-07-19 19:03:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
it("should return error when no options for options field", () => {
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const compDef = {
|
|
|
|
name:"some_component",
|
|
|
|
props: {
|
|
|
|
size: {
|
|
|
|
type: "options",
|
|
|
|
options: []
|
|
|
|
}
|
2019-07-19 19:03:58 +02:00
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
};
|
2019-07-19 19:03:58 +02:00
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateComponentDefinition(compDef);
|
2019-07-19 19:03:58 +02:00
|
|
|
|
|
|
|
expect(errors.length).toEqual(1);
|
|
|
|
expect(errors[0].propName).toBe("size");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should not return error when options field has options", () => {
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const compDef = {
|
|
|
|
name: "some_component",
|
|
|
|
props: {
|
|
|
|
size: {
|
|
|
|
type: "options",
|
|
|
|
options: ["small", "medium", "large"]
|
|
|
|
}
|
2019-07-19 19:03:58 +02:00
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
};
|
2019-07-19 19:03:58 +02:00
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateComponentDefinition(compDef);
|
2019-07-19 19:03:58 +02:00
|
|
|
|
|
|
|
expect(errors).toEqual([]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const validComponentDef = {
|
|
|
|
name: "some_component",
|
|
|
|
props: {
|
|
|
|
size: {
|
|
|
|
type: "options",
|
|
|
|
options: ["small", "medium", "large"],
|
|
|
|
default:"medium"
|
|
|
|
},
|
|
|
|
rowCount : "number"
|
2019-07-19 19:03:58 +02:00
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
};
|
2019-07-19 19:03:58 +02:00
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const childComponentDef = {
|
|
|
|
name: "child_component",
|
|
|
|
props: {
|
|
|
|
width: "number",
|
|
|
|
units: {
|
|
|
|
type: "string",
|
|
|
|
default: "px"
|
|
|
|
}
|
|
|
|
}
|
2019-07-19 19:03:58 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const validProps = () => {
|
2020-01-18 00:06:42 +01:00
|
|
|
|
|
|
|
const { props } = createProps(validComponentDef);
|
|
|
|
props._children.push(
|
|
|
|
createProps(childComponentDef));
|
2019-07-19 19:03:58 +02:00
|
|
|
return props;
|
|
|
|
}
|
|
|
|
|
|
|
|
describe("validateProps", () => {
|
|
|
|
|
|
|
|
it("should have no errors with a big list of valid props", () => {
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateProps(validComponentDef, validProps(), [], true);
|
2019-07-19 19:03:58 +02:00
|
|
|
expect(errors).toEqual([]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should return error with invalid value", () => {
|
|
|
|
|
|
|
|
const props = validProps();
|
|
|
|
props.rowCount = "1";
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateProps(validComponentDef, props, [], true);
|
2019-07-19 19:03:58 +02:00
|
|
|
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";
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateProps(validComponentDef, props, [], true);
|
2019-07-19 19:03:58 +02:00
|
|
|
expect(errors.length).toEqual(1);
|
|
|
|
expect(errors[0].propName).toBe("size");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2019-09-20 09:01:35 +02:00
|
|
|
it("should not return error when has binding", () => {
|
|
|
|
const props = validProps();
|
2020-01-18 00:06:42 +01:00
|
|
|
props._children[0].width = setBinding({path:"some_path"});
|
2019-09-20 09:01:35 +02:00
|
|
|
props.size = setBinding({path:"other path", fallback:"small"});
|
2020-01-18 00:06:42 +01:00
|
|
|
const errors = validateProps(validComponentDef, props, [], true);
|
2019-09-20 09:01:35 +02:00
|
|
|
expect(errors.length).toEqual(0);
|
|
|
|
});
|
2019-07-21 10:36:20 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
describe("recursivelyValidateProps", () => {
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const rootComponent = {
|
|
|
|
name: "rootComponent",
|
|
|
|
children: true,
|
|
|
|
props: {
|
|
|
|
width: "number"
|
2019-07-21 10:36:20 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-01-18 00:06:42 +01:00
|
|
|
const todoListComponent = {
|
|
|
|
name: "todoListComponent",
|
|
|
|
props:{
|
|
|
|
showTitle: "bool"
|
|
|
|
}
|
2019-07-21 10:36:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const headerComponent = {
|
2020-01-18 00:06:42 +01:00
|
|
|
name: "headerComponent",
|
|
|
|
props: {
|
|
|
|
text: "string"
|
|
|
|
}
|
|
|
|
};
|
2019-07-21 10:36:20 +02:00
|
|
|
|
|
|
|
const iconComponent = {
|
2020-01-18 00:06:42 +01:00
|
|
|
name: "iconComponent",
|
|
|
|
props: {
|
|
|
|
iconName: "string"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const navItemComponent = {
|
|
|
|
name: "navItemComponent",
|
|
|
|
props: {
|
|
|
|
text: "string"
|
|
|
|
}
|
|
|
|
};
|
2019-07-21 10:36:20 +02:00
|
|
|
|
|
|
|
const getComponent = name => ({
|
|
|
|
rootComponent,
|
|
|
|
todoListComponent,
|
|
|
|
headerComponent,
|
2020-01-18 00:06:42 +01:00
|
|
|
iconComponent,
|
|
|
|
navItemComponent
|
2019-07-21 10:36:20 +02:00
|
|
|
})[name];
|
|
|
|
|
|
|
|
const rootProps = () => ({
|
|
|
|
_component: "rootComponent",
|
|
|
|
width: 100,
|
2020-01-18 00:06:42 +01:00
|
|
|
_children: [{
|
2019-07-21 10:36:20 +02:00
|
|
|
_component: "todoListComponent",
|
|
|
|
showTitle: true,
|
2020-01-18 00:06:42 +01:00
|
|
|
_children : [
|
|
|
|
{
|
|
|
|
_component: "navItemComponent",
|
|
|
|
text: "todos"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
_component: "headerComponent",
|
|
|
|
text: "Your todo list"
|
|
|
|
},
|
|
|
|
{
|
2019-07-21 10:36:20 +02:00
|
|
|
_component: "iconComponent",
|
2020-01-18 00:06:42 +01:00
|
|
|
iconName: "fa fa-list"
|
|
|
|
},
|
|
|
|
{
|
2019-07-21 10:36:20 +02:00
|
|
|
_component: "iconComponent",
|
|
|
|
iconName:"fa fa-cog"
|
|
|
|
}
|
2020-01-18 00:06:42 +01:00
|
|
|
]
|
|
|
|
}]
|
2019-07-21 10:36:20 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
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();
|
2020-01-18 00:06:42 +01:00
|
|
|
root._children[0].showTitle = "yeeeoooo";
|
2019-07-21 10:36:20 +02:00
|
|
|
const result = recursivelyValidate(root, getComponent);
|
|
|
|
expect(result.length).toBe(1);
|
2020-01-18 00:06:42 +01:00
|
|
|
expect(result[0].stack).toEqual([0]);
|
2019-07-21 10:36:20 +02:00
|
|
|
expect(result[0].propName).toBe("showTitle");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should return error on second nested child component", () => {
|
|
|
|
const root = rootProps();
|
2020-01-18 00:06:42 +01:00
|
|
|
root._children[0]._children[0].text = false;
|
2019-07-21 10:36:20 +02:00
|
|
|
const result = recursivelyValidate(root, getComponent);
|
|
|
|
expect(result.length).toBe(1);
|
2020-01-18 00:06:42 +01:00
|
|
|
expect(result[0].stack).toEqual([0,0]);
|
2019-07-21 10:36:20 +02:00
|
|
|
expect(result[0].propName).toBe("text");
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|