- {properties.map(({ content, index }) => (
+ {properties.map(({ content }, index) => (
{content}
diff --git a/test/SchemaField_test.js b/test/SchemaField_test.js
index a30e0cad45..a4e453880b 100644
--- a/test/SchemaField_test.js
+++ b/test/SchemaField_test.js
@@ -22,7 +22,9 @@ describe('SchemaField', () => {
describe('Unsupported field', () => {
it('should warn on invalid field type', () => {
- const { node } = createFormComponent({ schema: { type: 'invalid' } });
+ const { node } = createFormComponent({
+ schema: { type: 'invalid' },
+ });
expect(node.querySelector('.unsupported-field').textContent).to.contain(
'Unknown field type invalid'
@@ -231,7 +233,9 @@ describe('SchemaField', () => {
},
},
};
- const { node } = createFormComponent({ schema: schemaWithReference });
+ const { node } = createFormComponent({
+ schema: schemaWithReference,
+ });
const matches = node.querySelectorAll('#root_foo__description');
expect(matches).to.have.length.of(1);
@@ -288,7 +292,11 @@ describe('SchemaField', () => {
}
it("should render it's own errors", () => {
- const { node } = createFormComponent({ schema, uiSchema, validate });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ validate,
+ });
submit(node);
const matches = node.querySelectorAll(
@@ -299,12 +307,36 @@ describe('SchemaField', () => {
});
it('should pass errors to child component', () => {
- const { node } = createFormComponent({ schema, uiSchema, validate });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ validate,
+ });
submit(node);
const matches = node.querySelectorAll('form .form-group .form-group .text-danger');
expect(matches).to.have.length.of(1);
expect(matches[0].textContent).to.contain('test');
});
+
+ describe('Custom error rendering', () => {
+ const customStringWidget = props => {
+ return
{props.rawErrors}
;
+ };
+
+ it('should pass rawErrors down to custom widgets', () => {
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ validate,
+ widgets: { BaseInput: customStringWidget },
+ });
+ submit(node);
+
+ const matches = node.querySelectorAll('.custom-text-widget');
+ expect(matches).to.have.length.of(1);
+ expect(matches[0].textContent).to.eql('test');
+ });
+ });
});
});
diff --git a/test/StringField_test.js b/test/StringField_test.js
index c7cc02d573..a68cff7985 100644
--- a/test/StringField_test.js
+++ b/test/StringField_test.js
@@ -64,7 +64,9 @@ describe('StringField', () => {
});
it('should default state value to undefined', () => {
- const { comp } = createFormComponent({ schema: { type: 'string' } });
+ const { comp } = createFormComponent({
+ schema: { type: 'string' },
+ });
expect(comp.state.formData).eql(undefined);
});
@@ -189,6 +191,16 @@ describe('StringField', () => {
expect(node.querySelectorAll('.field select')).to.have.length.of(1);
});
+ it('should render a string field for an enum without a type', () => {
+ const { node } = createFormComponent({
+ schema: {
+ enum: ['foo', 'bar'],
+ },
+ });
+
+ expect(node.querySelectorAll('.field select')).to.have.length.of(1);
+ });
+
it('should render a string field with a label', () => {
const { node } = createFormComponent({
schema: {
@@ -225,7 +237,6 @@ describe('StringField', () => {
},
});
- console.log(node.querySelectorAll('.field option')[0].innerHTML);
expect(node.querySelectorAll('.field option')[0].textContent).eql('Test');
});
@@ -357,7 +368,10 @@ describe('StringField', () => {
it('should handle an empty string change event with custom ui:defaultValue', () => {
const { comp, node } = createFormComponent({
schema: { type: 'string' },
- uiSchema: { 'ui:widget': 'textarea', 'ui:emptyValue': 'default' },
+ uiSchema: {
+ 'ui:widget': 'textarea',
+ 'ui:emptyValue': 'default',
+ },
formData: 'x',
});
@@ -1505,7 +1519,9 @@ describe('StringField', () => {
});
Simulate.change(node.querySelector('[type=file]'), {
- target: { files: [{ name: 'file1.txt', size: 1, type: 'type' }] },
+ target: {
+ files: [{ name: 'file1.txt', size: 1, type: 'type' }],
+ },
});
return new Promise(setImmediate).then(() =>
diff --git a/test/uiSchema_test.js b/test/uiSchema_test.js
index 349d260d5e..74a3847dec 100644
--- a/test/uiSchema_test.js
+++ b/test/uiSchema_test.js
@@ -199,7 +199,11 @@ describe('uiSchema', () => {
});
it('should render merged ui:widget options for widget referenced as function', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
const widget = node.querySelector('#funcAll');
expect(widget.style.background).to.equal('purple');
@@ -209,7 +213,11 @@ describe('uiSchema', () => {
});
it('should render ui:widget default options for widget referenced as function', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
const widget = node.querySelector('#funcNone');
expect(widget.style.background).to.equal('yellow');
@@ -219,7 +227,11 @@ describe('uiSchema', () => {
});
it('should render merged ui:widget options for widget referenced as string', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
const widget = node.querySelector('#stringAll');
expect(widget.style.background).to.equal('blue');
@@ -229,7 +241,11 @@ describe('uiSchema', () => {
});
it('should render ui:widget default options for widget referenced as string', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
const widget = node.querySelector('#stringNone');
expect(widget.style.background).to.equal('yellow');
@@ -239,7 +255,11 @@ describe('uiSchema', () => {
});
it('should ui:option inputType for html5 input types', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
const widget = node.querySelector("input[type='tel']");
expect(widget).to.not.be.null;
});
@@ -279,7 +299,11 @@ describe('uiSchema', () => {
};
it('should render a nested custom widget', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
expect(node.querySelectorAll('.custom')).to.have.length.of(1);
});
@@ -332,7 +356,11 @@ describe('uiSchema', () => {
};
it('should render a custom widget with options', () => {
- const { node } = createFormComponent({ schema, uiSchema, widgets });
+ const { node } = createFormComponent({
+ schema,
+ uiSchema,
+ widgets,
+ });
expect(node.querySelectorAll('.custom')).to.have.length.of(1);
});
@@ -1745,7 +1773,11 @@ describe('uiSchema', () => {
};
const formData = ['a', 'b'];
- let rendered = createFormComponent({ schema, uiSchema, formData });
+ let rendered = createFormComponent({
+ schema,
+ uiSchema,
+ formData,
+ });
node = rendered.node;
});
@@ -2013,7 +2045,11 @@ describe('uiSchema', () => {
};
const formData = ['a', 'b'];
- let rendered = createFormComponent({ schema, uiSchema, formData });
+ let rendered = createFormComponent({
+ schema,
+ uiSchema,
+ formData,
+ });
node = rendered.node;
});
diff --git a/test/utils_test.js b/test/utils_test.js
index 7bf8e3d68e..0f2238888b 100644
--- a/test/utils_test.js
+++ b/test/utils_test.js
@@ -145,7 +145,14 @@ describe('utils', () => {
properties: {
level1: {
type: 'object',
- default: { level2: { leaf1: 1, leaf2: 1, leaf3: 1, leaf4: 1 } },
+ default: {
+ level2: {
+ leaf1: 1,
+ leaf2: 1,
+ leaf3: 1,
+ leaf4: 1,
+ },
+ },
properties: {
level2: {
type: 'object',
@@ -165,8 +172,14 @@ describe('utils', () => {
},
},
};
- expect(getDefaultFormState(schema, { level1: { level2: { leaf4: 4 } } })).eql({
- level1: { level2: { leaf1: 1, leaf2: 2, leaf3: 3, leaf4: 4 } },
+ expect(
+ getDefaultFormState(schema, {
+ level1: { level2: { leaf4: 4 } },
+ })
+ ).eql({
+ level1: {
+ level2: { leaf1: 1, leaf2: 2, leaf3: 3, leaf4: 4 },
+ },
});
});
@@ -181,7 +194,9 @@ describe('utils', () => {
},
},
};
- expect(getDefaultFormState(schema, {})).eql({ level1: [1, 2, 3] });
+ expect(getDefaultFormState(schema, {})).eql({
+ level1: [1, 2, 3],
+ });
});
it('should use parent defaults for ArrayFields if declared in parent', () => {
@@ -195,7 +210,9 @@ describe('utils', () => {
},
},
};
- expect(getDefaultFormState(schema, {})).eql({ level1: [1, 2, 3] });
+ expect(getDefaultFormState(schema, {})).eql({
+ level1: [1, 2, 3],
+ });
});
it('should map item defaults to fixed array default', () => {
@@ -316,7 +333,10 @@ describe('utils', () => {
describe('uniqueItems is true', () => {
describe('schema items enum is an array', () => {
it('should be true', () => {
- let schema = { items: { enum: ['foo', 'bar'] }, uniqueItems: true };
+ let schema = {
+ items: { enum: ['foo', 'bar'] },
+ uniqueItems: true,
+ };
expect(isMultiSelect(schema)).to.be.true;
});
});
@@ -357,13 +377,18 @@ describe('utils', () => {
items: { $ref: '#/definitions/FooItem' },
uniqueItems: true,
};
- const definitions = { FooItem: { type: 'string', enum: ['foo'] } };
+ const definitions = {
+ FooItem: { type: 'string', enum: ['foo'] },
+ };
expect(isMultiSelect(schema, definitions)).to.be.true;
});
});
it('should be false if uniqueItems is false', () => {
- const schema = { items: { enum: ['foo', 'bar'] }, uniqueItems: false };
+ const schema = {
+ items: { enum: ['foo', 'bar'] },
+ uniqueItems: false,
+ };
expect(isMultiSelect(schema)).to.be.false;
});
});
@@ -448,7 +473,9 @@ describe('utils', () => {
const obj1 = { a: { b: [1] } };
const obj2 = { a: { b: [2] } };
- expect(mergeObjects(obj1, obj2, true)).eql({ a: { b: [1, 2] } });
+ expect(mergeObjects(obj1, obj2, true)).eql({
+ a: { b: [1, 2] },
+ });
});
});
});
@@ -1014,6 +1041,27 @@ describe('utils', () => {
bar: { $id: 'root_bar' },
});
});
+
+ it('should handle idPrefix parameter', () => {
+ const schema = {
+ definitions: {
+ testdef: {
+ type: 'object',
+ properties: {
+ foo: { type: 'string' },
+ bar: { type: 'string' },
+ },
+ },
+ },
+ $ref: '#/definitions/testdef',
+ };
+
+ expect(toIdSchema(schema, undefined, schema.definitions, {}, 'rjsf')).eql({
+ $id: 'rjsf',
+ foo: { $id: 'rjsf_foo' },
+ bar: { $id: 'rjsf_bar' },
+ });
+ });
});
describe('parseDateString()', () => {
diff --git a/test/validate_test.js b/test/validate_test.js
index 8534d76cfd..67223cf9a6 100644
--- a/test/validate_test.js
+++ b/test/validate_test.js
@@ -131,6 +131,42 @@ describe('Validation', () => {
expect(errors[0].message).to.equal(newErrorMessage);
});
});
+
+ describe("Invalid schema", () => {
+ const schema = {
+ type: "object",
+ properties: {
+ foo: {
+ type: "string",
+ required: "invalid_type_non_array",
+ },
+ },
+ };
+
+ let errors, errorSchema;
+
+ beforeEach(() => {
+ const result = validateFormData({ foo: 42 }, schema);
+ errors = result.errors;
+ errorSchema = result.errorSchema;
+ });
+
+ it("should return an error list", () => {
+ expect(errors).to.have.length.of(1);
+ expect(errors[0].name).eql("type");
+ expect(errors[0].property).eql(".properties['foo'].required");
+ expect(errors[0].message).eql("should be array");
+ });
+
+ it("should return an errorSchema", () => {
+ expect(errorSchema.properties.foo.required.__errors).to.have.length.of(
+ 1
+ );
+ expect(errorSchema.properties.foo.required.__errors[0]).eql(
+ "should be array"
+ );
+ });
+ });
});
describe('Form integration', () => {
diff --git a/yarn.lock b/yarn.lock
index 3d9c29dbb3..c4e4f69d46 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5121,9 +5121,9 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
-prettier@^1.7.2:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.0.tgz#c024f70cab158c993f50fc0c25ffe738cb8b0f85"
+prettier@^1.12.0:
+ version "1.13.7"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281"
private@^0.1.6, private@^0.1.7:
version "0.1.8"
@@ -5294,9 +5294,9 @@ react-addons-test-utils@^15.3.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.6.2.tgz#c12b6efdc2247c10da7b8770d185080a7b047156"
-react-codemirror2@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-2.0.2.tgz#68b2ae8923174a2b3d8b6fe905d0fd3c91d97d97"
+react-codemirror2@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-4.3.0.tgz#e79aedca4da60d22402d2cd74f2885a3e5c009fd"
react-color@^2.13.8:
version "2.14.1"
@@ -5325,9 +5325,9 @@ react-dom-factories@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0"
-react-dom@16.2.0:
- version "16.2.0"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
+react-dom@^16.2.0:
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.1.tgz#7f8b0223b3a5fbe205116c56deb85de32685dad6"
dependencies:
fbjs "^0.8.16"
loose-envify "^1.1.0"
@@ -5421,6 +5421,15 @@ react-transition-group@^2.2.1:
loose-envify "^1.3.1"
prop-types "^15.6.1"
+react@^16.2.0:
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.4.1.tgz#de51ba5764b5dbcd1f9079037b862bd26b82fe32"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
reactcss@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"