Skip to content

Commit

Permalink
v0.1.0 parsePropTypes and PT provided as default
Browse files Browse the repository at this point in the history
  • Loading branch information
joonhocho committed Jun 14, 2016
1 parent f203723 commit f922ab0
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 41 deletions.
25 changes: 24 additions & 1 deletion README.md
Expand Up @@ -21,8 +21,31 @@ It also allows Type Composition via named definitions and spread operator `...`.
npm install --save proptypes-parser
```

### Now `proptypes-parser` provides a default parser as `parsePropTypes`.
```javascript
import {parsePropTypes} from 'proptypes-parser';

const propTypes = parsePropTypes(`{
number: Number
string: String!
}`);

```

Also, if you like [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals),

```javascript
import {PT} from 'proptypes-parser';

const propTypes = PT`{
number: Number
string: String!
}`;

```


### Usage
### Advanced Usage
in `proptypes.js`.
```javascript
import createPropTypesParser from 'proptypes-parser';
Expand Down
4 changes: 2 additions & 2 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "proptypes-parser",
"version": "0.0.13",
"version": "0.1.0",
"description": "PropTypes parser / generator for React and React Native components with GraphQL-like syntax.",
"main": "lib/index.js",
"scripts": {
Expand All @@ -14,7 +14,7 @@
"start": "npm test",
"test": "mocha",
"test-watch": "mocha --watch",
"update-D": "npm install --save-dev babel-cli@latest babel-preset-es2015@latest babel-preset-stage-0@latest babel-register@latest chai@latest chai-as-promised@latest coveralls@latest graphql@latest mocha@latest nyc@latest",
"update-D": "npm install --save-dev babel-cli@latest babel-preset-es2015@latest babel-preset-stage-0@latest babel-register@latest chai@latest chai-as-promised@latest coveralls@latest mocha@latest nyc@latest",
"watch": "npm run build-watch & npm run test-watch"
},
"repository": {
Expand Down
14 changes: 14 additions & 0 deletions src/index.js
@@ -1,3 +1,6 @@
import {PropTypes} from 'react';


let createParser;
if (process && process.env && process.env.NODE_ENV === 'production') {
// No-op if production
Expand All @@ -6,4 +9,15 @@ if (process && process.env && process.env.NODE_ENV === 'production') {
createParser = require('./parser.js').default;
}


const parsePropTypes = createParser(PropTypes);
const PT = parsePropTypes.PT;


export {
PropTypes,
parsePropTypes,
PT,
};

export default createParser;
2 changes: 2 additions & 0 deletions src/parser.js
Expand Up @@ -529,5 +529,7 @@ export default (PropTypes, extension) => {
}
};

parser.PT = (strings) => parser(strings.raw[0]);

return parser;
};
105 changes: 67 additions & 38 deletions test/index.js
@@ -1,25 +1,54 @@
import createParser from '../lib';
import {PropTypes} from 'react';
import {describe, it} from 'mocha';
import {expect} from 'chai';
import createParser, {
PropTypes,
parsePropTypes as defaultParser,
PT as defaultPT,
} from '../lib';

const assert = require('assert');

const log = (value) => console.log(JSON.stringify(value, null, ' '));

const testPass = (propType, value) => {
assert.equal(
null,
propType({testProp: value}, 'testProp')
);
expect(propType({testProp: value}, 'testProp')).to.be.null;
};

const testFail = (propType, value) => {
assert.equal(
true,
propType({testProp: value}, 'testProp') instanceof Error
);
expect(propType({testProp: value}, 'testProp')).to.be.an.instanceof(Error);
};


describe('PropTypes', () => {
it('should provide default parsePropTypes.', () => {
const propTypes = defaultParser(`{
number: Number
string: String!
boolean: Boolean
}`);

expect(propTypes.number).to.equal(PropTypes.number);

expect(propTypes.string).to.equal(PropTypes.string.isRequired);

expect(propTypes.boolean).to.equal(PropTypes.bool);
});


it('should provide default PT.', () => {
const propTypes = defaultPT`{
number: Number
string: String!
boolean: Boolean
}`;

expect(propTypes.number).to.equal(PropTypes.number);

expect(propTypes.string).to.equal(PropTypes.string.isRequired);

expect(propTypes.boolean).to.equal(PropTypes.bool);
});


it('should successfully parse and return valid propTypes.', () => {
class Message {}

Expand All @@ -45,20 +74,20 @@ describe('PropTypes', () => {
any: Any!
}`);

assert.equal(propTypes.number, PropTypes.number);
expect(propTypes.number).to.equal(PropTypes.number);

assert.equal(propTypes.string, PropTypes.string.isRequired);
expect(propTypes.string).to.equal(PropTypes.string.isRequired);

assert.equal(propTypes.boolean, PropTypes.bool);
expect(propTypes.boolean).to.equal(PropTypes.bool);

assert.equal(propTypes.function, PropTypes.func.isRequired);
expect(propTypes.function).to.equal(PropTypes.func.isRequired);

testPass(propTypes.date, new Date());
testFail(propTypes.date, null);
testFail(propTypes.date, Date);
testFail(propTypes.date, 1);

assert.equal(propTypes.object, PropTypes.object.isRequired);
expect(propTypes.object).to.equal(PropTypes.object.isRequired);

testPass(propTypes.shape, {
nested: 3,
Expand Down Expand Up @@ -100,15 +129,15 @@ describe('PropTypes', () => {
testPass(propTypes.arrayOfObjects, null);
testFail(propTypes.arrayOfObjects, [null]);

assert.equal(propTypes.node, PropTypes.node);
assert.equal(propTypes.element, PropTypes.element.isRequired);
expect(propTypes.node).to.equal(PropTypes.node);
expect(propTypes.element).to.equal(PropTypes.element.isRequired);

testPass(propTypes.message, new Message());
testFail(propTypes.message, null);
testFail(propTypes.message, Message);
testFail(propTypes.message, new Date());

assert.equal(propTypes.any, PropTypes.any.isRequired);
expect(propTypes.any).to.equal(PropTypes.any.isRequired);
});


Expand All @@ -135,7 +164,7 @@ describe('PropTypes', () => {
testFail(propTypes.date, new Date());

testPass(propTypes.element, new LocalElement());
assert.notEqual(propTypes.element, PropTypes.element);
expect(propTypes.element).to.not.equal(PropTypes.element);

testFail(propTypes.message, new Message());
testPass(propTypes.message, new LocalMessage());
Expand Down Expand Up @@ -193,25 +222,25 @@ describe('PropTypes', () => {
}
`);

assert.equal(propTypes, parser.getPropTypes('Car'));
expect(propTypes).to.equal(parser.getPropTypes('Car'));

assert.equal(propTypes.year, PropTypes.number.isRequired);
assert.equal(propTypes.model, PropTypes.string.isRequired);
expect(propTypes.year).to.equal(PropTypes.number.isRequired);
expect(propTypes.model).to.equal(PropTypes.string.isRequired);
});


it('should not allow name collisions.', () => {
const parser = createParser(PropTypes);

assert.throws(() => {
expect(() => {
// Cannot override default type, String.
const propTypes = parser(`
String {
year: Number!
model: String!
}
`);
}, /already defined/i);
}).to.throw(/already defined/i);

const propTypes = parser(`
Car {
Expand All @@ -220,7 +249,7 @@ describe('PropTypes', () => {
}
`);

assert.throws(() => {
expect(() => {
// Cannot override previously defined, Car.
const propTypes = parser(`
Car {
Expand All @@ -229,7 +258,7 @@ describe('PropTypes', () => {
wheelCount: Number!
}
`);
}, /already defined/i);
}).to.throw(/already defined/i);
});


Expand Down Expand Up @@ -262,15 +291,15 @@ describe('PropTypes', () => {
it('should allow composition with spread operator.', () => {
const parser = createParser(PropTypes);

assert.throws(() => {
expect(() => {
// Cannot spread unknown type.
const carWithMakePropTypes = parser(`
CarWithMake {
...Car
make: String!
}
`);
}, /unknown type/i);
}).to.throw(/unknown type/i);

const carPropTypes = parser(`
Car {
Expand All @@ -287,14 +316,14 @@ describe('PropTypes', () => {
`);

// carPropTypes stays untouched.
assert.equal(carPropTypes.make, undefined);
expect(carPropTypes.make).to.be.undefined;

// Inherited from Car
assert.equal(carWithMakePropTypes.year, PropTypes.number.isRequired);
assert.equal(carWithMakePropTypes.model, PropTypes.string.isRequired);
expect(carWithMakePropTypes.year).to.equal(PropTypes.number.isRequired);
expect(carWithMakePropTypes.model).to.equal(PropTypes.string.isRequired);

// Additional field
assert.equal(carWithMakePropTypes.make, PropTypes.string.isRequired);
expect(carWithMakePropTypes.make).to.equal(PropTypes.string.isRequired);
});


Expand All @@ -303,9 +332,9 @@ describe('PropTypes', () => {

class Message {}

assert.throws(() => {
expect(() => {
parser(`{ message: Message }`);
}, /Message/i);
}).to.throw(/Message/i);

parser.addType('Message', Message);

Expand All @@ -321,9 +350,9 @@ describe('PropTypes', () => {
it('should allow adding propTypes.', () => {
const parser = createParser(PropTypes);

assert.throws(() => {
expect(() => {
parser(`{ message: Message }`);
}, /Message/i);
}).to.throw(/Message/i);

const messagePropTypes = parser(`{
from: String!
Expand Down Expand Up @@ -351,7 +380,7 @@ describe('PropTypes', () => {
date: Date!
}`);

assert.equal(messagePropTypesWithDate.text, PropTypes.string.isRequired);
expect(messagePropTypesWithDate.text).to.equal(PropTypes.string.isRequired);
testPass(messagePropTypesWithDate.date, new Date());
testFail(messagePropTypesWithDate.date, null);

Expand Down

0 comments on commit f922ab0

Please sign in to comment.