Skip to content

Commit

Permalink
Merge pull request #2 from peterkhayes/1.3
Browse files Browse the repository at this point in the history
changed extend scripts and import method
  • Loading branch information
peterkhayes committed Apr 10, 2017
2 parents 197e59e + 82397bd commit 93fdd62
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 108 deletions.
33 changes: 16 additions & 17 deletions README.md
Expand Up @@ -4,51 +4,50 @@
Useful proptypes for React components. Developed for and tested on ClassDojo's web app.

## Usage
Individual validators can be imported under `/validators`.
This module exports a set of proptype validators.
```js
import keyedObject from "extended-proptypes/validators/keyedObject";
import ExtendedPropTypes from "extended-proptypes";

class MyComponent extends Component {

static propTypes = {
mySpecialObject: keyedObject(/keyregex/).isRequired,
myDate: ExtendedPropTypes.date.isRequired,
mySatanicString: ExtendedPropTypes.stringMatching(/^6+$/).isRequired,
};
}
```

If you want to extend React's `PropTypes` with all included validators, you can
import `extended-proptypes/lib/extend`.
If you only need a few of the provided functions, individual validators can be imported under `/lib/validators`.
```js
import {PropTypes} from "react";
import `extended-proptypes/lib/extend`;
import keyedObject from "extended-proptypes/lib/validators/keyedObject";

class MyComponent extends Component {

static propTypes = {
myEmailAddress: PropTypes.emailAddress.isRequired,
myArrayOrObject: PropTypes.collectionOf(PropTypes.bool),
mySpecialObject: keyedObject(/keyregex/).isRequired,
};
}
```

It may be convenient to not have to reference both the original proptypes object and also this one. To resolve this, you can use one of two methods:
* `extended-proptypes/lib/extend-from-react` imports `{PropTypes}` from `react` and adds all of its methods to this module's export.
* `extended-proptypes/lib/extend-from-standalone` imports `PropTypes` from `prop-types` and adds all of its methods to this module's export.

Or, you can also import the whole module and call it on `React.PropTypes`.
```js
import {PropTypes} from "react";
import ExtendedPropTypes from "extended-proptypes";

// New options will now be available on React's `PropTypes` export.
ExtendedPropTypes(PropTypes);
import `extended-proptypes/lib/extend-from-react`;
import PropTypes from "extended-proptypes";

class MyComponent extends Component {

static propTypes = {
myDate: PropTypes.date.isRequired,
mySatanicString: PropTypes.stringMatching(/^6+$/).isRequired,
myEmailAddress: PropTypes.emailAddress.isRequired,
myArrayOrObject: PropTypes.collectionOf(PropTypes.bool),
};
}
```

When `NODE_ENV === "production"`, since React will not validate PropTypes, this method exports stubbed versions of each validator.

## New Prop Types

All validators expose basic and `isRequired` versions.
Expand Down
5 changes: 3 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "extended-proptypes",
"version": "1.2.2",
"version": "1.3.0",
"description": "Useful proptypes for react components",
"main": "lib/index.js",
"scripts": {
Expand All @@ -25,8 +25,9 @@
"lodash": "^3.8.0",
"mocha": "^2.3.4",
"mocha-lcov-reporter": "^1.2.0",
"prop-types": "^15.5.6",
"proptypes": "^0.14.3",
"react": "^15.4.1",
"react": "15.3.*",
"require-uncached": "^1.0.3"
},
"keywords": [
Expand Down
10 changes: 10 additions & 0 deletions src/extend-from-react.js
@@ -0,0 +1,10 @@
/*
Import this file to automatically extend ExtendedPropTypes with React's
built-in proptypes.
*/

import {PropTypes} from "react";
import ExtendedPropTypes from ".";
Object.keys(PropTypes).forEach((name) => {
ExtendedPropTypes[name] = PropTypes[name];
});
10 changes: 10 additions & 0 deletions src/extend-from-standalone.js
@@ -0,0 +1,10 @@
/*
Import this file to automatically extend ExtendedPropTypes with the
standalone `prop-types` library's validators.
*/

import PropTypes from "prop-types";
import ExtendedPropTypes from ".";
Object.keys(PropTypes).forEach((name) => {
ExtendedPropTypes[name] = PropTypes[name];
});
7 changes: 0 additions & 7 deletions src/extend.js

This file was deleted.

64 changes: 1 addition & 63 deletions src/index.js
@@ -1,63 +1 @@
import collection from "./validators/collection";
import collectionOf from "./validators/collectionOf";
import color from "./validators/color";
import constant from "./validators/constant";
import cssLength from "./validators/cssLength";
import cssSize from "./validators/cssSize";
import date from "./validators/date";
import dateBetween from "./validators/dateBetween";
import elementWithType from "./validators/elementWithType";
import emailAddress from "./validators/emailAddress";
import hex from "./validators/hex";
import iterable from "./validators/iterable";
import keyedObject from "./validators/keyedObject";
import keyedObjectOf from "./validators/keyedObjectOf";
import locale from "./validators/locale";
import mongoId from "./validators/mongoId";
import mongoIdKeyedObject from "./validators/mongoIdKeyedObject";
import mongoIdKeyedObjectOf from "./validators/mongoIdKeyedObjectOf";
import percent from "./validators/percent";
import primative from "./validators/primative";
import stringMatching from "./validators/stringMatching";
import stringWithLength from "./validators/stringWithLength";
import time from "./validators/time";
import timeBetween from "./validators/timeBetween";
import uuid from "./validators/uuid";

const validators = {
collection,
collectionOf,
color,
constant,
cssLength,
cssSize,
date,
dateBetween,
elementWithType,
emailAddress,
hex,
iterable,
keyedObject,
keyedObjectOf,
locale,
mongoId,
mongoIdKeyedObject,
mongoIdKeyedObjectOf,
percent,
primative,
stringMatching,
stringWithLength,
time,
timeBetween,
uuid,
};

function extendWithPropTypes (target) {
Object.keys(validators).forEach((name) => {
target[name] = validators[name];
});
}

extendWithPropTypes(extendWithPropTypes);

module.exports = extendWithPropTypes;
module.exports = process.env.NODE_ENV === "production" ? require("./mocks") : require("./proptypes");
30 changes: 30 additions & 0 deletions src/mocks.js
@@ -0,0 +1,30 @@
function noop () {};
function noopThunk () { return noop; }

module.exports = {
collection: noopThunk,
collectionOf: noopThunk,
color: noopThunk,
constant: noopThunk,
cssLength: noopThunk,
cssSize: noopThunk,
date: noopThunk,
dateBetween: noopThunk,
elementWithType: noopThunk,
emailAddress: noopThunk,
hex: noopThunk,
iterable: noopThunk,
keyedObject: noopThunk,
keyedObjectOf: noopThunk,
locale: noopThunk,
mongoId: noopThunk,
mongoIdKeyedObject: noopThunk,
mongoIdKeyedObjectOf: noopThunk,
percent: noopThunk,
primative: noopThunk,
stringMatching: noopThunk,
stringWithLength: noopThunk,
time: noopThunk,
timeBetween: noopThunk,
uuid: noopThunk,
};
53 changes: 53 additions & 0 deletions src/proptypes.js
@@ -0,0 +1,53 @@
import collection from "./validators/collection";
import collectionOf from "./validators/collectionOf";
import color from "./validators/color";
import constant from "./validators/constant";
import cssLength from "./validators/cssLength";
import cssSize from "./validators/cssSize";
import date from "./validators/date";
import dateBetween from "./validators/dateBetween";
import elementWithType from "./validators/elementWithType";
import emailAddress from "./validators/emailAddress";
import hex from "./validators/hex";
import iterable from "./validators/iterable";
import keyedObject from "./validators/keyedObject";
import keyedObjectOf from "./validators/keyedObjectOf";
import locale from "./validators/locale";
import mongoId from "./validators/mongoId";
import mongoIdKeyedObject from "./validators/mongoIdKeyedObject";
import mongoIdKeyedObjectOf from "./validators/mongoIdKeyedObjectOf";
import percent from "./validators/percent";
import primative from "./validators/primative";
import stringMatching from "./validators/stringMatching";
import stringWithLength from "./validators/stringWithLength";
import time from "./validators/time";
import timeBetween from "./validators/timeBetween";
import uuid from "./validators/uuid";

module.exports = {
collection,
collectionOf,
color,
constant,
cssLength,
cssSize,
date,
dateBetween,
elementWithType,
emailAddress,
hex,
iterable,
keyedObject,
keyedObjectOf,
locale,
mongoId,
mongoIdKeyedObject,
mongoIdKeyedObjectOf,
percent,
primative,
stringMatching,
stringWithLength,
time,
timeBetween,
uuid,
};
66 changes: 47 additions & 19 deletions test/index.js
Expand Up @@ -3,38 +3,66 @@ const assert = require("assert");
const path = require("path");

const requireUncached = require("require-uncached");
const ExtendedPropTypes = require("../src");

const validators = fs.readdirSync(path.join(__dirname, "../src/validators")).map((f) => f.replace(".js", ""));

describe("index file", () => {

it("can be extended on to base proptypes object", () => {
const PropTypes = requireUncached("proptypes");
Object.assign(PropTypes, ExtendedPropTypes);
describe("in production", () => {

beforeEach(() => process.env.NODE_ENV = "production")
afterEach(() => process.env.NODE_ENV = "testing");

validators.forEach((validator) => {
assert(PropTypes[validator], `should have added ${validator} to proptypes object`);
it("exports noops", () => {
const ExtendedPropTypes = requireUncached("../src");
validators.forEach((name) => {
const actual = requireUncached(`../src/validators/${name}`);
assert(ExtendedPropTypes[name], `did not export ${name}`);
assert(ExtendedPropTypes[name].toString() !== actual.toString(), `exported real validator for ${name}`);
ExtendedPropTypes[name]();
});
});
});

it("can be called on base proptypes object", () => {
const PropTypes = requireUncached("proptypes");
ExtendedPropTypes(PropTypes);
describe("in development", () => {

validators.forEach((validator) => {
assert(PropTypes[validator], `should have added ${validator} to proptypes object`);
beforeEach(() => process.env.NODE_ENV = "dev");
afterEach(() => process.env.NODE_ENV = "testing");

it("exports each proptype", () => {
const ExtendedPropTypes = requireUncached("../src");
validators.forEach((name) => {
const actual = requireUncached(`../src/validators/${name}`);
assert(ExtendedPropTypes[name], `did not export ${name}`);
assert(ExtendedPropTypes[name].toString() === actual.toString(), `exported stub for ${name}`);
});
});
});

// NOTE: THIS TEST MUST BE LAST
it("can work by requiring `extend` file", () => {
const PropTypes = require("proptypes");
require("../src/extend");
// NOTE: THIS SECTION MUST BE LAST
describe("extend scripts", () => {

it("extend-from-react", () => {
const ReactPropTypes = require("react").PropTypes;
const StandalonePropTypes = require("prop-types");
const ExtendedPropTypes = require("../src");

validators.forEach((validator) => {
assert(PropTypes[validator], `should have added ${validator} to proptypes object`);
require("../src/extend-from-react");
Object.keys(ReactPropTypes).forEach((name) => {
assert(ExtendedPropTypes[name] === ReactPropTypes[name], `did not export ${name} from react`);
assert(ExtendedPropTypes[name] !== StandalonePropTypes[name], `exported ${name} from prop-types`);
});
});
});

it("extend-from-standalone", () => {
const ReactPropTypes = require("react").PropTypes;
const StandalonePropTypes = require("prop-types");
const ExtendedPropTypes = require("../src");

require("../src/extend-from-standalone");
Object.keys(ReactPropTypes).forEach((name) => {
assert(ExtendedPropTypes[name] !== ReactPropTypes[name], `exported ${name} from react`);
assert(ExtendedPropTypes[name] === StandalonePropTypes[name], `did not export ${name} from prop-types`);
});
});
});
});

0 comments on commit 93fdd62

Please sign in to comment.