Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Layout] Extract requireProp to utils #6473

Merged
merged 2 commits into from
Mar 31, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 2 additions & 13 deletions src/Layout/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import React, { PropTypes } from 'react';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';
import requirePropFactory from '../utils/requirePropFactory';

const GUTTERS = [0, 8, 16, 24, 40];
const GRID_SIZES = [true, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
Expand Down Expand Up @@ -309,19 +310,7 @@ Layout.contextTypes = {
let LayoutWrapper = Layout; // eslint-disable-line import/no-mutable-exports

if (process.env.NODE_ENV !== 'production') {
const requireProp = (requiredProp) =>
(props, propName, componentName, location, propFullName) => {
const propFullNameSafe = propFullName || propName;

if (typeof props[propName] !== 'undefined' && !props[requiredProp]) {
return new Error(
`The property \`${propFullNameSafe}\` of ` +
`\`Layout\` must be used on \`${requiredProp}\`.`,
);
}

return null;
};
const requireProp = requirePropFactory('Layout');

LayoutWrapper = (props) => <Layout {...props} />;

Expand Down
109 changes: 109 additions & 0 deletions src/utils/requireProp.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// @flow weak

import { assert } from 'chai';
import requirePropFactory from './requirePropFactory';

describe('requirePropFactory()', () => {
const componentNameInError = 'componentNameInError';
let requireProp;

before(() => {
requireProp = requirePropFactory(componentNameInError);
});

it('should be a function', () => {
assert.strictEqual(typeof requirePropFactory, 'function');
});

it('should return a function', () => {
assert.strictEqual(typeof requireProp, 'function');
});

describe('requireProp()', () => {
const requiredPropName = 'requiredPropName';

let requirePropValidator;

before(() => {
requirePropValidator = requireProp(requiredPropName);
});

it('should return a function', () => {
assert.strictEqual(typeof requirePropValidator, 'function');
});

describe('requirePropValidator', () => {
let props;
let propName;

it('should return null for propName not in props', () => {
propName = 'propName';
props = {};
const result = requirePropValidator(props, propName, undefined, undefined, undefined);
assert.strictEqual(result, null);
});

it('should return null for propName and requiredProp in props', () => {
propName = 'propName';
props = {};
props[propName] = true;
props[requiredPropName] = true;
const result = requirePropValidator(props, propName, undefined, undefined, undefined);
assert.strictEqual(result, null);
});

describe('propName is in props and requiredProp not in props', () => {
let result;

before(() => {
props = {};
propName = 'propName';
props[propName] = true;
delete props[requiredPropName];
result = requirePropValidator(props, propName, undefined, undefined, undefined);
});

it('returned error should have name property', () => {
assert.property(result, 'name', 'result should have name property');
});

it('should return Error', () => {
assert.property(result, 'name', 'result should have name property');
assert.strictEqual(result.name, 'Error');
});

it('returned error should have message property', () => {
assert.property(result, 'message', 'result should have message property');
});

it('returned error message should have propName', () => {
assert.strictEqual(result.message.indexOf(propName) > -1, true);
});

it('returned error message should have requiredPropName', () => {
assert.strictEqual(result.message.indexOf(requiredPropName) > -1, true);
});

it('returned error message should have componentNameInError', () => {
assert.strictEqual(result.message.indexOf(componentNameInError) > -1, true);
});

describe('propFullName given to validator', () => {
let propFullName;
before(() => {
propFullName = 'propFullName';
result = requirePropValidator(props, propName, undefined, undefined, propFullName);
});

it('returned error message should have propFullName', () => {
assert.strictEqual(result.message.indexOf(propFullName) > -1, true);
});

it('returned error message should not have propName', () => {
assert.strictEqual(result.message.indexOf(propName), -1);
});
});
});
});
});
});
21 changes: 21 additions & 0 deletions src/utils/requirePropFactory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow weak

const requirePropFactory = (componentNameInError) => {
const requireProp = (requiredProp) =>
(props, propName, componentName, location, propFullName) => {
const propFullNameSafe = propFullName || propName;

if (typeof props[propName] !== 'undefined' && !props[requiredProp]) {
return new Error(
`The property \`${propFullNameSafe}\` of ` +
`\`${componentNameInError}\` must be used on \`${requiredProp}\`.`,
);
}

return null;
};
return requireProp;
};


export default requirePropFactory;