Remove unused validateProps module and tests
This commit is contained in:
parent
aaae1fd1ef
commit
0490441d09
|
@ -1,7 +1,6 @@
|
|||
import { recursivelyValidate } from "./validateProps";
|
||||
import {
|
||||
isString,
|
||||
keys,
|
||||
import {
|
||||
isString,
|
||||
keys,
|
||||
flatten,
|
||||
isArray,
|
||||
map,
|
||||
|
@ -15,12 +14,12 @@ export const validatePage = (page, getComponent) => {
|
|||
const error = message => errors.push(message);
|
||||
|
||||
const noIndex = !page.index;
|
||||
if(noIndex) {
|
||||
if (noIndex) {
|
||||
error("Page does not define an index member");
|
||||
}
|
||||
|
||||
if(!page.appBody
|
||||
|| !isString(page.appBody)
|
||||
if (!page.appBody
|
||||
|| !isString(page.appBody)
|
||||
|| !page.appBody.endsWith(".json")) {
|
||||
error("App body must be set toa valid JSON file");
|
||||
}
|
||||
|
@ -28,7 +27,7 @@ export const validatePage = (page, getComponent) => {
|
|||
/* Commenting this for now
|
||||
* index is a load of static members just now, but maybe useful
|
||||
for pageLayout props (which is just a pipe dream at time of writing)
|
||||
const indexHtmlErrors = noIndex
|
||||
const indexHtmlErrors = noIndex
|
||||
? []
|
||||
: pipe(
|
||||
recursivelyValidate(page.index, getComponent), [
|
||||
|
@ -44,17 +43,17 @@ export const validatePages = (pages, getComponent) => {
|
|||
let errors = [];
|
||||
const error = message => errors.push(message);
|
||||
|
||||
if(!pages.main) {
|
||||
if (!pages.main) {
|
||||
error("must have a 'main' page");
|
||||
}
|
||||
|
||||
if(!pages.unauthenticated) {
|
||||
if (!pages.unauthenticated) {
|
||||
error("must have a 'unauthenticated' (login) page");
|
||||
}
|
||||
|
||||
if(!pages.componentLibraries
|
||||
|| !isArray(pages.componentLibraries)
|
||||
|| pages.componentLibraries.length === 0) {
|
||||
if (!pages.componentLibraries
|
||||
|| !isArray(pages.componentLibraries)
|
||||
|| pages.componentLibraries.length === 0) {
|
||||
|
||||
error("componentLibraries must be set to a non-empty array of strings");
|
||||
}
|
||||
|
@ -67,4 +66,4 @@ export const validatePages = (pages, getComponent) => {
|
|||
]);
|
||||
|
||||
return [...errors, ...pageErrors];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
import { types } from "./types";
|
||||
import {
|
||||
createProps, arrayElementComponentName
|
||||
} from "./createProps";
|
||||
import { isString } from "util";
|
||||
import {
|
||||
includes, filter, map, keys,
|
||||
flatten, flattenDeep, each,
|
||||
indexOf, isUndefined
|
||||
} from "lodash/fp";
|
||||
import { common } from "../../../../core/src";
|
||||
import {
|
||||
isBinding
|
||||
} from "../../common/binding";
|
||||
|
||||
const pipe = common.$;
|
||||
|
||||
const makeError = (errors, propName, stack) => (message) =>
|
||||
errors.push({
|
||||
stack,
|
||||
propName,
|
||||
error: message
|
||||
});
|
||||
|
||||
export const recursivelyValidate = (rootProps, getComponent, stack = []) => {
|
||||
|
||||
if (!rootProps._component) {
|
||||
const errs = [];
|
||||
makeError(errs, "_component", stack)("Component is not set");
|
||||
return errs;
|
||||
// this would break everything else anyway
|
||||
}
|
||||
|
||||
const componentDef = getComponent(
|
||||
rootProps._component);
|
||||
|
||||
|
||||
const errors = validateProps(
|
||||
componentDef,
|
||||
rootProps,
|
||||
stack,
|
||||
true);
|
||||
|
||||
const validateChildren = (_props, _stack) =>
|
||||
!_props._children
|
||||
? []
|
||||
: pipe(_props._children, [
|
||||
map(child => recursivelyValidate(
|
||||
child,
|
||||
getComponent,
|
||||
[..._stack, _props._children.indexOf(child)]))
|
||||
]);
|
||||
|
||||
const childErrors = validateChildren(
|
||||
rootProps, stack);
|
||||
|
||||
return flattenDeep([errors, ...childErrors]);
|
||||
}
|
||||
|
||||
const expandPropDef = propDef =>
|
||||
isString(propDef)
|
||||
? types[propDef].defaultDefinition()
|
||||
: propDef;
|
||||
|
||||
|
||||
|
||||
export const validateProps = (componentDefinition, props, stack = [], isFinal = true) => {
|
||||
|
||||
const errors = [];
|
||||
|
||||
if (isFinal && !props._component) {
|
||||
makeError(errors, "_component", stack)("Component is not set");
|
||||
return errors;
|
||||
// this would break everything else anyway
|
||||
}
|
||||
|
||||
const propsDefinition = componentDefinition.props;
|
||||
|
||||
for (let propDefName in props) {
|
||||
|
||||
const ignore = ['_component', "_children", '_layout', 'name', 'description', 'location'];
|
||||
|
||||
if (ignore.includes(propDefName)) continue;
|
||||
|
||||
const propDef = expandPropDef(propsDefinition[propDefName]);
|
||||
|
||||
const type = types[propDef.type];
|
||||
|
||||
const error = makeError(errors, propDefName, stack);
|
||||
|
||||
const propValue = props[propDefName];
|
||||
|
||||
// component declarations dont need to define al props.
|
||||
if (!isFinal && isUndefined(propValue)) continue;
|
||||
|
||||
if (isFinal && propDef.required && propValue) {
|
||||
error(`Property ${propDefName} is required`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isBinding(propValue)) {
|
||||
if (propDef.type === "event") {
|
||||
error(`Cannot apply binding to type ${propDef.type}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (!type.isOfType(propValue)) {
|
||||
error(`Property ${propDefName} is not of type ${propDef.type}. Actual value ${propValue}`)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (propDef.type === "options"
|
||||
&& propValue
|
||||
&& !isBinding(propValue)
|
||||
&& !includes(propValue)(propDef.options)) {
|
||||
error(`Property ${propDefName} is not one of allowed options. Acutal value is ${propValue}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
export const validateComponentDefinition = (componentDefinition) => {
|
||||
const { errors } = createProps(componentDefinition);
|
||||
|
||||
const propDefinitions = expandPropDef(componentDefinition.props);
|
||||
|
||||
pipe(propDefinitions, [
|
||||
keys,
|
||||
map(k => ({
|
||||
propDef: propDefinitions[k],
|
||||
propName: k
|
||||
})),
|
||||
filter(d => d.propDef.type === "options"
|
||||
&& (!d.propDef.options || d.propDef.options.length === 0)),
|
||||
each(d => makeError(errors, d.propName)(`${d.propName} does not have any options`))
|
||||
]);
|
||||
|
||||
return errors;
|
||||
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
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");
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue