GithubHelp home page GithubHelp logo

jsdoc-to-assert's Introduction

jsdoc-to-assert Build Status

Convert JSDoc to assert that runtime assert.

Easy to use it with Babel.

Example

jsdoc-to-assert create detection expression string:

Array.isArray(x) && x.every(function (item) {
    return typeof item === 'number';
});

from following JSDoc comment:

/**
 * @param {number[]} x 
 */

Installation

npm install jsdoc-to-assert

Usage

import {AssertGenerator, CommentConverter, CodeGenerator} from "jsdoc-to-assert";

AssertGenerator class

Create assertion AST from comment nodes.

/**
 * @typedef {Object} AssertGeneratorOptions
 * @property {Function} generator
 */
const defaultOptions = {
    Generator: CodeGenerator
};
/**
 *
 * @param {Array<Object>} comments AST's comment nodes. it should be BlockComment
 * @param {AssertGeneratorOptions} options
 * @returns {Array<String>} array of assertion
 */
static createAsserts(comments, options = {});
/**
 * @param tagNode tagNode is defined by doctorin
 * @param {CodeGenerator} Generator
 * @return {string|undefined} return assertion code string
 * Reference https://esdoc.org/tags.html#type-syntax
 * https://github.com/eslint/doctrine/blob/master/test/parse.js
 */
static createAssertFromTag(tagNode, Generator = CodeGenerator);

CommentConverter class

/**
 * Parse comment nodes which is provided by JavaScript parser like esprima, babylon 
 * and return assertions code strings.
 * This is mutable function.
 * @param {Array<Object>} comment
 * @param {AssertGeneratorOptions} [options]
 * @returns {string[]}
 */
static toAsserts(comment, options);    

CodeGenerator class

Assertion code generator class

/**
 * @param commentTagNode commentTagNode is doctrine tag node
 */
constructor(commentTagNode);
/**
 * wrap assert function
 * @param {string} expression
 * @returns {string}
 */
assert(expression) {
    return `console.assert(${expression},'${expression}');`;
}

Tests

npm test

Realated

Comment to assert

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

License

MIT

jsdoc-to-assert's People

Contributors

azu avatar mohayonao avatar victor-homyakov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jsdoc-to-assert's Issues

Problems with nested params

It seems to have problems with params like this:

/**
* @param {object} thing
* @param {object[]} thing.stuff
* @param {string} thing.stuff[].name
* @param {number} thing.stuff[].index
*/

It seems to interpret everything from thing.stuff as thing.stuff and doesn't dive lower than that.

Generate assertion for Object Type Application?

https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#type-application describes possible Type Application for Object: Object<string, someType>. It's easy to implement assert generation for this case as

/**
 * @param {Object<string, number>} x
 */

=>

Object.values(x).every(function (item) {
    return typeof item  === 'number';
});

AFAIK there is no need to generate assertion for first type (for object keys), as it will always be string.

If it looks good, then I'll make a PR.

Support class-specific callbacks

From: http://usejsdoc.org/tags-callback.html#examples

/**
 * @class
 */
function Requester() {}

/**
 * Send a request.
 * @param {Requester~requestCallback} cb - The callback that handles the response.
 */
Requester.prototype.send = function(cb) {
    // code
};

/**
 * This callback is displayed as part of the Requester class.
 * @callback Requester~requestCallback
 * @param {number} responseCode
 * @param {string} responseMessage
 */

The above code results in the error: Unexpected token, expected , . Removing the Requester~ prefix seems to make things happy, but then the callback is documented globally.

Optional arguments support

/**
 * @param {number} a - this is a param.
 * @param {string} b - this is a param.
 * @param {string[]} c - this is a param.
 * @param {boolean} [d] - this is a optional.
 */
function myFunc(a, b, c, d) {
    //...
}

=>

/**
 * @param {number} param - this is a param.
 * @param {string} b - this is a param.
 * @param {string[]} c - this is a param.
 */
function myFunc(param, b, c) {
  console.assert(typeof a === 'number');
  console.assert(typeof b === 'string');
  console.assert(Array.isArray(c));
}

`d` is just ignore. 

We want to support optional arguments.

JSDoc Parse Error: Cannot read property 'type' of null

This JsDoc annotation produces error

        /**
         * @param {{SubscriptionId,Data}} data
         */
        handleData: function(data) {
Cannot read property 'type' of null
    at Expression (C:\Code\node_modules\jsdoc-to-assert\lib\tag\Expression.js:13:18)
    at C:\Code\node_modules\jsdoc-to-assert\lib\tag\RecordType.js:23:43
    at Array.map (native)
    at RecordType (C:\Code\node_modules\jsdoc-to-assert\lib\tag\RecordType.js:20:49)
    at Function.createAssertFromTag (C:\Code\node_modules\jsdoc-to-assert\lib\AssertGenerator.js:187:51)
    at createTag (C:\Code\node_modules\jsdoc-to-assert\lib\AssertGenerator.js:72:40)
    at Array.map (native)
    at Function.createAsserts (C:\Code\node_modules\jsdoc-to-assert\lib\AssertGenerator.js:74:34)
    at Function.toAsserts (C:\Code\node_modules\jsdoc-to-assert\lib\CommentConverter.js:43:50)
    at injectParameterAssert (C:\Code\node_modules\babel-plugin-jsdoc-to-assert\lib\index.js:46:51)

Improve Generics

@param {Array<string>} a

should be

assert(Array.isArray(a) && a.every(a => typeof a === "string")

Current:

assert(Array.isArray(a));

TODO

  • Does Array<string> has optional or nullable?

Issue with transpiling + destructuring

I have a class w/ destructured params in its constructor like this:

class Foo {
  /**
   * @param {?string} x - param.
   */
  constructor({x}) {
    this.x = x

My .babelrc looks like this:

{
  "presets": [["es2015", { "modules": false }], "stage-2"],
  "plugins": [
    "jsdoc-to-assert",
  ],
}

And the code is incorrectly generated like this:

var Foo = function () {
  /**
   * @param {?string} x - param.
   */
  function Foo(_ref) {
    if (!(x == null || typeof x === "string")) {
      console.assert(x == null || typeof x === "string", 'Expected type: @param {?string} x\nActual value:', x, '\nFailure assertion: (x == null || typeof x === "string")');
    }

    var x = _ref.x

NOTE The assert reads x before it's defined.

I'd expect it to be:

var Foo = function () {
  /**
   * @param {?string} x - param.
   */
  function Foo(_ref) {
    var x = _ref.x

    if (!(x == null || typeof x === "string")) {
      console.assert(x == null || typeof x === "string", 'Expected type: @param {?string} x\nActual value:', x, '\nFailure assertion: (x == null || typeof x === "string")');
    }

NOTE that the destructuring happens before the assertion. The current order would also work if the assertion were based on _ref.x instead of x.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.