Skip to content

Commit

Permalink
feat(src): support TypeApplication like Array.<string>
Browse files Browse the repository at this point in the history
  • Loading branch information
azu committed Aug 28, 2016
1 parent 6ed22ec commit ee9a94a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
8 changes: 6 additions & 2 deletions src/tag/Expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ export function Expression(tagName, typeValue) {
const expectedType = typeofName(typeValue.name);
if (expectedType == null) {
const expectedName = typeValue.name;
// if right-hand is undefined, return true
// if right-hand(expectedName) is undefined, return true
// if right-hand is not function, return true
// if right-hand is function && left instanceof right
// if right-hand is function && left-hand(tagName) instanceof right-hand(expectedName)
// expectation, if left-hand is Array, use Array.isArray
if (expectedName === "Array") {
return `Array.isArray(${tagName})`;
}
return `(
typeof ${expectedName} === "undefined" || typeof ${expectedName} !== "function" || ${tagName} instanceof ${expectedName}
)`;
Expand Down
21 changes: 19 additions & 2 deletions src/tag/TypeApplication.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
// LICENSE : MIT
"use strict";
// @param {Array<string>}
import {Expression} from "./Expression";
// @param {Array.<string>}
/**
* @return {string|undefined}
*/
export function TypeApplication(tag, CodeGenerator) {
const expectedType = tag.type.expression.name;
if (expectedType === "Array") {
return CodeGenerator.assert(`Array.isArray(${tag.name})`);
const applications = tag.type.applications;
if (applications) {
const createGenericsAssert = () => {
// or
const expressions = applications.map(application => {
return Expression("item", application);
});
// Array.<String,Number>
// => (String || Number)
const expression = expressions.join(" || ");
return `function(item){ return (${expression}); }`;
};
const expression = `${tag.name}.every(${createGenericsAssert()})`;
return CodeGenerator.assert(`Array.isArray(${tag.name}) && ${expression}`);
} else {
return CodeGenerator.assert(`Array.isArray(${tag.name})`);
}
}
}
50 changes: 42 additions & 8 deletions test/create-asserts-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,48 @@ describe("create-assert", function() {
astEqual(numberAssertion, `typeof A === 'undefined' || typeof A !== 'function' || x instanceof A`);
});
});
context("when pass ArrayType", function() {
it("should return assert typeof nullable", function() {
context("when pass Array only", function() {
it("should return Array.isArray(x)", function() {
const jsdoc = `/**
* @param {number[]} x - this is ArrayType param.
* @param {Array} x - this is ArrayType param.
*/`;
const numberAssertion = createAssertion(jsdoc);
astEqual(numberAssertion, `Array.isArray(x)`);
});
});

context("when pass *[]", function() {
it("should return Array.isArray(x)", function() {
const jsdoc = `/**
* @param {*[]} x
*/`;
const numberAssertion = createAssertion(jsdoc);
astEqual(numberAssertion, `Array.isArray(x) && x.every(function (item) {
return typeof undefined === 'undefined' || typeof undefined !== 'function' || item instanceof undefined;
});`);
});
});
context("when pass number[]", function() {
it("should return Array.isArray(array) && check every type", function() {
const jsdoc = `/**
* @param {number[]} x - this is ArrayType param.
*/`;
const numberAssertion = createAssertion(jsdoc);
astEqual(numberAssertion, `Array.isArray(x) && x.every(function (item) {
return typeof item === 'number';
});`);
});
});
context("when pass CustomType[]", function() {
it("should return Array.isArray(array) && check every type", function() {
const jsdoc = `/**
* @param {CustomType[]} x - this is ArrayType param.
*/`;
const numberAssertion = createAssertion(jsdoc);
astEqual(numberAssertion, `Array.isArray(x) && x.every(function (item) {
return typeof CustomType === 'undefined' || typeof CustomType !== 'function' || item instanceof CustomType;
});`);
});
});
context("when pass nullable", function() {
it("should return assert typeof nullable", function() {
const jsdoc = `/**
Expand Down Expand Up @@ -262,13 +294,15 @@ describe("create-assert", function() {
astEqual(numberAssertion, `typeof x.foo === 'number' && (typeof RegExp === 'undefined' || typeof RegExp !== 'function' || x.bar instanceof RegExp)`);
});
});
context("When generic", function() {
it("should return ", function() {
context("When pass Array.<string>", function() {
it("should return Array.isArray(x) && check every type", function() {
const jsdoc = `/**
* @param {Array<string>} x - this is Array param.
* @param {Array.<string>} x - this is Array param.
*/`;
const numberAssertion = createAssertion(jsdoc);
astEqual(numberAssertion, `Array.isArray(x);`);
astEqual(numberAssertion, `Array.isArray(x) && x.every(function (item) {
return typeof item === 'string';
});`);
});
});
});

0 comments on commit ee9a94a

Please sign in to comment.