From f0789f4ab6d145978ea01423412455905650ea18 Mon Sep 17 00:00:00 2001 From: Charlike Mike Reagent Date: Fri, 18 Oct 2019 23:04:03 +0300 Subject: [PATCH] feat: add `parse-function` to monorepo (#62) * fix(rename): rename "result.valid" to "result.isValid" * docs(isValid): update docs because isValid change * fix(rename): the "result.orig" to "result.value" * docs(result): update docs for "result.orig" to "result.value" change * docs(api): update docs * feat(benchmarks): add benchmarks * test(espree): add tests using espree parser * chore(yarn): force update * docs(tips): add Pro Tips section * docs(related): update related libs * fix(package): add engines field * chore(release): 3.0.0 * refactor(index): plugins api, more tests, support es6 method notation * fix(package): bump to babylon@next * fix(codeclimate): xx * fix(style): codeclimate issues * test(*): clarify a bit the tests for "anonymous" functions * fix(package): force update yarn * docs(*): update readme, description and site url * fix(package): update deps and npm scripts, fix travis/appveyor * chore(package): standard ignore benchmark dir * fix(package): fix linting * feat(methods): reorganize repo, introduce ".use" and ".parse" methods * fix(codeclimate): analize lib folder * docs(api): start docs * docs(api): update api docs * docs(readme): update usage example * docs(readme): add Features and few more sections * fix(.use): allow plugins that just extends the core api and not return a * docs(notes): add human description on the Plugins Architecture * docs(readme): better navigation * chore(release): 4.0.0 * fix(package): include files in npm package * fix(arrows): bug when found arrow on function body * docs(readme): update * chore(release): 4.0.1 * fix(objectMethod): bug when default arguments is used in object method * docs(links): update links pointing to test.js file * chore(release): 4.0.2 * fix(tests): make it work on node 4 * chore(release): 4.0.3 * chore(renovate): Configure Renovate (#34) * Add renovate.json * chore(renovate): update config * refactor(deps): Pin Dependencies (#36) * fix(renovate/deps): Update dependency define-property to version ^1.0.0 * chore(renovate/devDeps): Update dependency acorn to version 5.1.1 * chore(renovate/devDeps): Update dependency benchmarked to version 1.1.1 * chore(deps): pin prod deps * fix(renovate/deps): Update dependency babylon to version 7.0.0-beta.18 * chore(renovate/devDeps): Update dependency clone-deep to version 1.0.0 * chore(renovate/devDeps): Update dependency cz-conventional-changelog to version 2.0.0 * chore(renovate/devDeps): Update dependency for-in to version 1.0.2 * chore(renovate/devDeps): Update dependency nyc to version 11.1.0 * chore(renovate/devDeps): Update dependency standard to version 10.0.2 * fix(renovate/deps): update dependency babylon to version 7.0.0-beta.19 * chore(renovate/devDeps): update dependency espree to v3.5.0 * chore(deps): update lock file * chore(renovate/devDeps): update dependency standard to v10.0.3 * major(release): BREAKING CHANGE: Require Node.js >= 6 & npm >= 5 * fix(readme): generate readme * fix(logo): fix logo to be centered * fix(readme): add features section again * fix(sr): fix semantic-release added things * chore(devDeps): update dependency eslint-config-standard-tunnckocore to * fix(codeclimate): add config file, to exclude benchmarks * fix(pkg): fix codeclimate and npm script for release * chore(bump): force bump hela to latest, update renovate config * chore(nyc): bump everything to 100% * chore(benchmarks): remove them since we dont need * fix(build): move to es6 modules by default * fix(deps): bump hela to latest * fix(deps): force bump to hela@0.4.0; include fresh script * fix(deps): bump hela * chore(devDeps): update dependency hela to v0.4.2 * fix(deps): update deps, renovate config, contrib file * chore(devDeps): update dependency hela to v0.5.4 * chore(devDeps): update dependency hela to v0.5.5 * chore(devDeps): update dependency eslint-config-standard-tunnckocore to * fix(misc): update codeclimate * chore(devDeps): update dependency eslint-config-standard-tunnckocore to v1.0.5 * chore(devDeps): update dependency semantic-release to ^7.0.0 (#45) * chore(devDeps): update dependency hela to v0.5.6 * chore(devDeps): update dependency hela to v0.5.7 * chore(devDeps): update dependency eslint to v4.5.0 * chore(devDeps): update dependency hela to v0.5.8 * fix(deps): update dependency babylon to v7.0.0-beta.20 * chore(devDeps): update dependency hela to v0.5.9 * chore(devDeps): update dependency eslint-config-standard-tunnckocore to v1.0.6 * chore(devDeps): update dependency eslint-config-standard-tunnckocore to v1.0.7 * chore(devDeps): update dependency hela to v0.6.0 * chore(devDeps): update dependency hela to v0.7.0 * fix(deps): update dependency babylon to v7.0.0-beta.21 * chore(devDeps): update dependency hela to v0.7.2 * fix(deps): update dependency babylon to v7.0.0-beta.22 * chore(devDeps): update dependency hela to v0.7.3 * chore(devDeps): update dependency eslint to v4.6.0 * chore(devDeps): update dependency eslint to v4.6.1 * chore(devDeps): update dependency acorn to v5.1.2 * chore(devDeps): update dependency hela to v0.7.4 * chore(devDeps): update dependency hela to v0.7.5 * chore(renovate): update config to try DCO * chore(cfg): update renovate config * chore(devDeps): update dependency hela to v0.7.6 (#49) * chore(devDeps): update dependency hela to 0.7.6 * chore(deps): update Signed-off-by tag * chore(devDeps): update dependency hela to 0.7.7 * fix(deps): update dependency babylon to 7.0.0-beta.23 * chore(devDeps): update dependency eslint to 4.7.0 * chore(devDeps): update dependency espree to 3.5.1 * chore(devDeps): update dependency eslint to 4.7.1 * fix(deps): update dependency babylon to 7.0.0-beta.24 * chore(devDeps): update dependency eslint-config-standard-tunnckocore to v1.0.8 (#60) * chore(devDeps): update dependency eslint-config-standard-tunnckocore to 1.0.9 * fix(deps): update dependency babylon to 7.0.0-beta.25 * fix(arrows): handle async arrow functions * add case for async arrow functions when wrapping * add missing `done()` to test case * fix(deps): update dependency babylon to 7.0.0-beta.26 * chore(devDeps): update dependency eslint-config-standard-tunnckocore to 1.0.10 * fix(deps): update dependency babylon to 7.0.0-beta.27 * chore(devDeps): update dependency eslint to 4.8.0 * fix(boilerplate): update stuff and modernize tests * fix(docs): update dogs * fix(deps): force update hela preset, activate semantic-release * fix(renovate): test use of shareable configs * fix(renovate): pin all deps, pr not pending * refactor(deps): renovate pin dependencies packages (#70) * chore(deps): update dependency hela to v1.1.3 * fix(misc): force update * fix(docs): publish docs folder * Set theme jekyll-theme-minimal * Set theme jekyll-theme-cayman * fix(deps): update dependency babylon to v7.0.0-beta.28 * fix(deps): update dependency babylon to v7.0.0-beta.29 * fix: remove yarn release * fix(deps): update dependency babylon to v7.0.0-beta.30 * chore(deps): update dependency acorn to v5.2.0 * chore(deps): update dependency acorn to v5.2.1 * fix(deps): update dependency babylon to v7.0.0-beta.31 * chore(deps): update dependency espree to v3.5.2 * fix(deps): update dependency babylon to v7.0.0-beta.32 * chore(deps): update dependency clone-deep to v2.0.1 * fix(deps): update dependency babylon to v7.0.0-beta.33 * fix(deps): update dependency define-property to v2.0.0 * fix(deps): update dependency babylon to v7.0.0-beta.34 * fix(deps): update dependency babylon to v7.0.0-beta.35 * fix(deps): update dependency babylon to v7.0.0-beta.36 * chore(deps): update dependency acorn to v5.3.0 * fix(deps): update dependency babylon to v7.0.0-beta.37 * fix(deps): update dependency babylon to v7.0.0-beta.38 * chore(deps): update dependency clone-deep to v2.0.2 * fix(deps): update dependency define-property to v2.0.1 * fix(deps): update dependency define-property to v2.0.2 * fix(deps): update dependency babylon to v7.0.0-beta.39 * chore(deps): update dependency acorn to v5.4.0 * chore(deps): update dependency acorn to v5.4.1 * chore(deps): update dependency espree to v3.5.3 * feat(params): add support for list of expressions as default value (#111) (a = (doSomething(), doSomethingElse(), true)) => {} is a prefectly valid syntax that is used extensively by code instrumenters. When a list of expressions is used as a default value, only the last expression is the actual default value. This commit add support for this syntax. TAG: latest fixes #110 * chore(readme): update nsp id * chore(readme): fix links for NodeSecurity * chore(readme): update releasing badge * fix(dist): include bundles in dist, so in npm package * fix(deps): update dependency babylon to v7.0.0-beta.40 * chore: 5.1.2 manual publish * fix(deps): use new-release package for automatic publishing * fix(ci): use npx in travis and test only on node 6 * fix(releasing): update readme and travis * fix(misc): obviously manual publishing... * chore(readme): fix badges and readme * fix(stuff): finally release and publish with dist/index.js * chore(deps): update dependency acorn to v5.5.0 * feat(result): values of default params to be always strings (#121) Changes in [Result object](https://github.com/tunnckoCore/parse-function#result)! **Possible breaking change, if you depend on values of `result.defaults`!** Now `result.defaults` is key/value pairs as before, but the value is always of type `string` or `undefined`! Casting of values is delegated to the end user which before was not consistent and was actual value of the default parameter. Example **(before)**: ```js const result = app.parse('(a = 123) => {}') console.log(result.defaults) // => { a: 123 } ``` Example **(after)**: ```js const result = app.parse('(a = 123) => {}') // notice that `123` now is string! console.log(result.defaults) // => { a: '123' } ``` * chore: publish v5.2.0 to npm * chore(deps): update dependency espree to v3.5.4 * fix: release 5.2.1 with dist folder * fix(release): add new-release to publish on CI * fix(release): add new-release to publish on CI - 2 * fix(ci): switch to CircleCI * fix: circle config update * fix: circle config update Signed-off-by: Charlike Mike Reagent * fix(ci): update readme badges and CircleCI config * fix(pkg): placeholder Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.5.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.5.3 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.41 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.42 Signed-off-by: Charlike Mike Reagent * chore(deps): update circleci/node to tag 8 Signed-off-by: Charlike Mike Reagent * chore(deps): update circleci/node:8 digest Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.43 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.44 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency clone-deep to v4.0.0 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.45 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.46 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency babylon to v7.0.0-beta.47 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.6.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.6.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.6.2 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.2 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.3 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.7.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v4 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.4 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.5 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.6 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.7.2 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.7 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency acorn to v5.7.3 Signed-off-by: Charlike Mike Reagent * chore: update build badge * chore: update codecov badge * chore(deps): update dependency husky to v1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.0.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.1.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.1.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.1.2 Signed-off-by: Charlike Mike Reagent * fix: say "Bye bye!" to NodeSecurityProject ;( It was a great service. Sadly @npm bought them and integrated it into their CLI, which totally sucks, because if you don't use npm you lose that cool functionality. * chore(deps): update dependency new-release to v4.0.8 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v4.1.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.1.3 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v4.0.9 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v5 Signed-off-by: Charlike Mike Reagent * chore(deps): update new-release to latest * chore(deps): update dependency husky to v1.1.4 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency new-release to v5.0.4 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.2.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency clone-deep to v4.0.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v5 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.2.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.3.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v1.3.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v5.0.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2 Signed-off-by: Charlike Mike Reagent * fix(deps): update dependency arrify to v2 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2.4.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2.4.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v6 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2.5.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2.6.0 Signed-off-by: Charlike Mike Reagent * chore: add GitHub Sponsoring button (funding file) * chore(github/funding): fix typo * chore(funding): re-fix the typo Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v2.7.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.2 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.3 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.4 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v6.1.0 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency espree to v6.1.1 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.5 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.7 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.8 Signed-off-by: Charlike Mike Reagent * chore(deps): update dependency husky to v3.0.9 Signed-off-by: Charlike Mike Reagent * feat: add parse-function to monorepo Signed-off-by: Charlike Mike Reagent * chore: fmt Signed-off-by: Charlike Mike Reagent * chore: wrong place Signed-off-by: Charlike Mike Reagent --- .prettierignore | 1 + jest/docs.js | 1 - jest/test.js | 10 +- package.json | 15 +- packages/parse-function/.verb.head.md | 11 + packages/parse-function/.verb.md | 358 ++ packages/parse-function/README.md | 593 ++ packages/parse-function/package.json | 87 + packages/parse-function/src/index.js | 235 + .../parse-function/src/lib/plugins/body.js | 24 + .../parse-function/src/lib/plugins/initial.js | 43 + .../parse-function/src/lib/plugins/params.js | 40 + .../parse-function/src/lib/plugins/props.js | 32 + packages/parse-function/src/lib/utils.js | 92 + .../test/__snapshots__/index.js.snap | 4907 +++++++++++++++++ packages/parse-function/test/index.js | 470 ++ readme-template.md | 10 +- yarn.lock | 33 + 18 files changed, 6948 insertions(+), 14 deletions(-) create mode 100644 packages/parse-function/.verb.head.md create mode 100644 packages/parse-function/.verb.md create mode 100644 packages/parse-function/README.md create mode 100644 packages/parse-function/package.json create mode 100644 packages/parse-function/src/index.js create mode 100644 packages/parse-function/src/lib/plugins/body.js create mode 100644 packages/parse-function/src/lib/plugins/initial.js create mode 100644 packages/parse-function/src/lib/plugins/params.js create mode 100644 packages/parse-function/src/lib/plugins/props.js create mode 100644 packages/parse-function/src/lib/utils.js create mode 100644 packages/parse-function/test/__snapshots__/index.js.snap create mode 100644 packages/parse-function/test/index.js diff --git a/.prettierignore b/.prettierignore index da5d9536..c96980f4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -13,3 +13,4 @@ __fixtures__ .cache .*cache *.cache +*.js.snap diff --git a/jest/docs.js b/jest/docs.js index 150af7ad..0edd268e 100644 --- a/jest/docs.js +++ b/jest/docs.js @@ -9,7 +9,6 @@ const docsIgnore = ['renovate-config', 'typescript-config']; const testMatches = Object.values(alias) .map((source) => `${source}/index.{${exts.join(',')}}`) .filter((x) => !docsIgnore.includes(x)); -console.log(testMatches); module.exports = { rootDir: ROOT, diff --git a/jest/test.js b/jest/test.js index be89bfc1..9f9cdd89 100644 --- a/jest/test.js +++ b/jest/test.js @@ -4,14 +4,18 @@ const utils = require('../@tunnckocore/utils/src'); const ROOT = path.dirname(__dirname); const { workspaces } = utils.createAliases(ROOT, 'src'); +const exts = ['js', 'jsx', 'ts', 'tsx']; + module.exports = { rootDir: ROOT, displayName: 'test', - testMatch: workspaces.map((ws) => `/${ws}/*/test/**/*`), + testMatch: workspaces.map( + (ws) => `/${ws}/*/test/**/*.{${exts.join(',')}}`, + ), testPathIgnorePatterns: [ /node_modules/.toString(), - /(?:__)?(?:fixtures?|supports?|shared)(?:__)?/.toString(), + /(?:__)?(?:fixtures?|supports?|shared|snapshots)(?:__)?/.toString(), ], // moduleNameMapper: alias, - moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'], + moduleFileExtensions: exts, }; diff --git a/package.json b/package.json index 0990c8d8..fe1b596c 100644 --- a/package.json +++ b/package.json @@ -24,13 +24,6 @@ "setup:ci": "yarn --frozen-lockfile && yarn bootstrap", "test": "jest -c jest/test.js" }, - "meta": { - "build": [ - "koa-better-body", - "@tunnckocore/execa" - ], - "bundle": [] - }, "dependencies": { "@babel/cli": "^7.6.0", "@babel/core": "^7.6.0", @@ -67,6 +60,14 @@ "commit-msg": "echo 'commitlint -E HUSKY_GIT_PARAMS'" } }, + "meta": { + "build": [ + "koa-better-body", + "parse-function", + "@tunnckocore/execa" + ], + "bundle": [] + }, "renovate": { "extends": "@tunnckocore" } diff --git a/packages/parse-function/.verb.head.md b/packages/parse-function/.verb.head.md new file mode 100644 index 00000000..6dfccce9 --- /dev/null +++ b/packages/parse-function/.verb.head.md @@ -0,0 +1,11 @@ +## Features + +- **Always up-to-date:** auto-publish new version when new version of dependency is out, [Renovate](https://renovateapp.com) +- **Standard:** using StandardJS, Prettier, SemVer, Semantic Release and conventional commits +- **Smart Plugins:** for extending the core API or the end [Result](#result), see [.use](#use) method and [Plugins Architecture](#plugins-architecture) +- **Extensible:** using plugins for working directly on AST nodes, see the [Plugins Architecture](#plugins-architecture) +- **ES2020+ Ready:** by using `.parseExpression` method of the Babel `v7.x` parser +- **Customization:** allows switching the parser, through `options.parse` +- **Support for:** arrow functions, default parameters, generators and async/await functions +- **Stable:** battle-tested in production and against all parsers - [espree][], [acorn][], [@babel/parser](https://npmjs.com/packages/@babel/parser) +- **Tested:** with [450+ tests](./test/index.js) for _200%_ coverage diff --git a/packages/parse-function/.verb.md b/packages/parse-function/.verb.md new file mode 100644 index 00000000..0e461268 --- /dev/null +++ b/packages/parse-function/.verb.md @@ -0,0 +1,358 @@ +## Which version to use? + +There's no breaking changes between the `v2.x` version. The only breaking is `v2.1` which also is not +working properly, so no use it. + +**Use v2.0.x** + +When you don't need support for `arrow functions` and `es6 default params`. This version +uses a RegExp expression to work. + +**Use v2.2.x** + +Only when you need a _basic_ support for `es6 features` like arrow functions. This version +uses a RegExp expression to work. + +**Use v2.3.x** + +When you want _full\*_ support for `arrow functions` and `es6 default params`. Where this "full", +means "almost full", because it has bugs. This version also uses (`acorn.parse`) real parser +to do the parsing. + +**Use v3.x** + +When you want to use different parser instead of the default `babylon.parse`, by passing custom +parse function to the `options.parse` option. **From this version we require `node >= 4`**. + +**Use v4.x** + +When you want full customization and most stable support for old and modern features. This version +uses `babylon.parseExpression` for parsing and provides a [Plugins API](#plugins-architecture). +See the [Features](#features) section for more info. + +**Use v5.x** + +It is basically the same as `v4`, but requires Node 6 & npm 5. Another is boilerplate stuff. + +**[back to top](#readme)** + +## Notes + +### Throws in one specific case + +> _see: [issue #3](https://github.com/tunnckoCore/parse-function/issues/3) and [test/index.js#L229-L235](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L229-L235)_ + +It may throw in one specific case, otherwise it won't throw, so you should +relay on the `result.isValid` for sure. + +### Function named _"anonymous"_ + +> _see: [test/index.js#L319-L324](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L319-L324) and [Result](#result) section_ + +If you pass a function which is named _"anonymous"_ the `result.name` will be `'anonymous'`, +but the `result.isAnonymous` will be `false` and `result.isNamed` will be `true`, because +in fact it's a named function. + +### Real anonymous function + +> _see: [test/index.js#L326-L331](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L326-L331) and [Result](#result) section_ + +Only if you pass really an anonymous function you will get `result.name` equal to `null`, +`result.isAnonymous` equal to `true` and `result.isNamed` equal to `false`. + +**[back to top](#readme)** + +### Plugins Architecture + +> _see: the [.use](#use) method, [test/index.js#L305-L317](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L305-L317) and [test/index.js#L396-L414](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L396-L414)_ + +A more human description of the plugin mechanism. Plugins are **synchronous** - no support +and no need for **async** plugins here, but notice that you can do that manually, because +that exact architecture. + +The first function that is passed to the [.use](#use) method is used for extending the core API, +for example adding a new method to the `app` instance. That function is immediately invoked. + +```js +const parseFunction = require('parse-function'); +const app = parseFunction(); + +app.use((self) => { + // self is same as `app` + console.log(self.use); + console.log(self.parse); + console.log(self.define); + + self.define(self, 'foo', (bar) => bar + 1); +}); + +console.log(app.foo(2)); // => 3 +``` + +On the other side, if you want to access the AST of the parser, you should return a function +from that plugin, which function is passed with `(node, result)` signature. + +This function is lazy plugin, it is called only when the [.parse](#parse) method is called. + +```js +const parseFunction = require('parse-function'); +const app = parseFunction(); + +app.use((self) => { + console.log('immediately called'); + + return (node, result) => { + console.log('called only when .parse is invoked'); + console.log(node); + console.log(result); + }; +}); +``` + +Where **1)** the `node` argument is an object - actual and real AST Node coming from the parser +and **2)** the `result` is an object too - the end [Result](#result), on which +you can add more properties if you want. + +**[back to top](#readme)** + + +## API + +_Generated using [jest-runner-docs](https://npmjs.com/package/jest-runner-docs)._ + +### [parseFunction](./src/index.js#L59) + +> Initializes with optional `opts` object which is passed directly +to the desired parser and returns an object +with `.use` and `.parse` methods. The default parse which +is used is [babylon][]'s `.parseExpression` method from `v7`. + +**Signature** + +```ts +function(opts) +``` + +**Params** + +- `opts` - optional, merged with options passed to `.parse` method +- `returns` - app object with `.use` and `.parse` methods + + + +**Example** + +```js +const parseFunction = require('parse-function') + +const app = parseFunction({ + ecmaVersion: 2017 +}) + +const fixtureFn = (a, b, c) => { + a = b + c + return a + 2 +} + +const result = app.parse(fixtureFn) +console.log(result) + +// see more +console.log(result.name) // => null +console.log(result.isNamed) // => false +console.log(result.isArrow) // => true +console.log(result.isAnonymous) // => true + +// array of names of the arguments +console.log(result.args) // => ['a', 'b', 'c'] + +// comma-separated names of the arguments +console.log(result.params) // => 'a, b, c' +``` + +### [.parse](./src/index.js#L124) + +> Parse a given `code` and returns a `result` object +with useful properties - such as `name`, `body` and `args`. +By default it uses Babylon parser, but you can switch it by +passing `options.parse` - for example `options.parse: acorn.parse`. +In the below example will show how to use `acorn` parser, instead +of the default one. + +**Signature** + +```ts +function +``` + +**Params** + +- `code` - any kind of function or string to be parsed +- `options` - directly passed to the parser babylon, acorn, espree +- `options.parse` - by default `babylon.parseExpression`, + all `options` are passed as second argument +- `returns` - result see [result section](#result) for more info + + + +**Example** + +```js +const acorn = require('acorn') +const parseFn = require('parse-function') +const app = parseFn() + +const fn = function foo (bar, baz) { return bar * baz } +const result = app.parse(fn, { + parse: acorn.parse, + ecmaVersion: 2017 +}) + +console.log(result.name) // => 'foo' +console.log(result.args) // => ['bar', 'baz'] +console.log(result.body) // => ' return bar * baz ' +console.log(result.isNamed) // => true +console.log(result.isArrow) // => false +console.log(result.isAnonymous) // => false +console.log(result.isGenerator) // => false +``` + +### [.use](./src/index.js#L177) + +> Add a plugin `fn` function for extending the API or working on the +AST nodes. The `fn` is immediately invoked and passed +with `app` argument which is instance of `parseFunction()` call. +That `fn` may return another function that +accepts `(node, result)` signature, where `node` is an AST node +and `result` is an object which will be returned [result](#result) +from the `.parse` method. This retuned function is called on each +node only when `.parse` method is called. + +**Signature** + +```ts +function +``` + +**Params** + +- `fn` - plugin to be called +- `returns` - app instance for chaining + +_See [Plugins Architecture](#plugins-architecture) section._ + +**Example** + +```js +// plugin extending the `app` +app.use((app) => { + app.define(app, 'hello', (place) => `Hello ${place}!`) +}) + +const hi = app.hello('World') +console.log(hi) // => 'Hello World!' + +// or plugin that works on AST nodes +app.use((app) => (node, result) => { + if (node.type === 'ArrowFunctionExpression') { + result.thatIsArrow = true + } + return result +}) + +const result = app.parse((a, b) => (a + b + 123)) +console.log(result.name) // => null +console.log(result.isArrow) // => true +console.log(result.thatIsArrow) // => true + +const result = app.parse(function foo () { return 123 }) +console.log(result.name) // => 'foo' +console.log(result.isArrow) // => false +console.log(result.thatIsArrow) // => undefined +``` + +### [.define](./src/index.js#L235) + +> Define a non-enumerable property on an object. Just +a convenience mirror of the [define-property][] library, +so check out its docs. Useful to be used in plugins. + +**Signature** + +```ts +function +``` + +**Params** + +- `obj` - the object on which to define the property +- `prop` - the name of the property to be defined or modified +- `val` - the descriptor for the property being defined or modified +- `returns` - obj the passed object, but modified + + + +**Example** + +```js +const parseFunction = require('parse-function') +const app = parseFunction() + +// use it like `define-property` lib +const obj = {} +app.define(obj, 'hi', 'world') +console.log(obj) // => { hi: 'world' } + +// or define a custom plugin that adds `.foo` property +// to the end result, returned from `app.parse` +app.use((app) => { + return (node, result) => { + // this function is called + // only when `.parse` is called + + app.define(result, 'foo', 123) + + return result + } +}) + +// fixture function to be parsed +const asyncFn = async (qux) => { + const bar = await Promise.resolve(qux) + return bar +} + +const result = app.parse(asyncFn) + +console.log(result.name) // => null +console.log(result.foo) // => 123 +console.log(result.args) // => ['qux'] + +console.log(result.isAsync) // => true +console.log(result.isArrow) // => true +console.log(result.isNamed) // => false +console.log(result.isAnonymous) // => true +``` + + + +**[back to top](#readme)** + +## Result + +> In the result object you have `name`, `args`, `params`, `body` and few hidden properties +> that can be useful to determine what the function is - arrow, regular, async/await or generator. + +- `name` **{String|null}**: name of the passed function or `null` if anonymous +- `args` **{Array}**: arguments of the function +- `params` **{String}**: comma-separated list representing the `args` +- `defaults` **{Object}**: key/value pairs, useful when use ES2015 default arguments +- `body` **{String}**: actual body of the function, respects trailing newlines and whitespaces +- `isValid` **{Boolean}**: is the given value valid or not, that's because it never throws! +- `isAsync` **{Boolean}**: `true` if function is ES2015 async/await function +- `isArrow` **{Boolean}**: `true` if the function is arrow function +- `isNamed` **{Boolean}**: `true` if function has name, or `false` if is anonymous +- `isGenerator` **{Boolean}**: `true` if the function is ES2015 generator function +- `isAnonymous` **{Boolean}**: `true` if the function don't have name + +**[back to top](#readme)** diff --git a/packages/parse-function/README.md b/packages/parse-function/README.md new file mode 100644 index 00000000..6f396da2 --- /dev/null +++ b/packages/parse-function/README.md @@ -0,0 +1,593 @@ +# parse-function [![npm version][npmv-img]][npmv-url] [![License][license-img]][license-url] + +> Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins + +Please consider following this project's author, [Charlike Mike Reagent](https://github.com/tunnckoCore), and :star: the project to show your :heart: and support. + +
+ +[![Code style][codestyle-img]][codestyle-url] +[![CircleCI linux build][linuxbuild-img]][linuxbuild-url] +[![CodeCov coverage status][codecoverage-img]][codecoverage-url] +[![DavidDM dependency status][dependencies-img]][dependencies-url] +[![Renovate App Status][renovateapp-img]][renovateapp-url] +[![Time Since Last Commit][last-commit-img]][last-commit-url] +[![Make A Pull Request][prs-welcome-img]][prs-welcome-url] + + + +If you have any _how-to_ kind of questions, please read the [Contributing Guide][contributing-url] and [Code of Conduct][code_of_conduct-url] documents. +For bugs reports and feature requests, [please create an issue][open-issue-url] or ping +[@tunnckoCore](https://twitter.com/tunnckoCore) at Twitter. + +[![Conventional Commits][ccommits-img]][ccommits-url] +[![Minimum Required Nodejs][nodejs-img]][npmv-url] +[![NPM Downloads Monthly][downloads-monthly-img]][npmv-url] +[![NPM Downloads Total][downloads-total-img]][npmv-url] +[![Share Love Tweet][twitter-share-img]][twitter-share-url] +[![Twitter][twitter-img]][twitter-url] + +Project is [semantically](https://semver.org) versioned & automatically released from [GitHub Actions](https://github.com/features/actions) with [Lerna](https://github.com/lerna/lerna). + +[![Become a Patron][patreon-img]][patreon-url] +[![Buy me a Kofi][kofi-img]][kofi-url] +[![PayPal Donation][paypal-img]][paypal-url] +[![Bitcoin Coinbase][bitcoin-img]][bitcoin-url] +[![Keybase PGP][keybase-img]][keybase-url] + +| Topic | Contact | +| :--------------------------------------------------------------- | ------------------------------------------------: | +| Any legal or licensing questions, like private or commerical use | ![tunnckocore_legal][tunnckocore_legal] | +| For any critical problems and security reports | ![tunnckocore_security][tunnckocore_security] | +| Consulting, professional support, personal or team training | ![tunnckocore_consulting][tunnckocore_consulting] | +| For any questions about Open Source, partnerships and sponsoring | ![tunnckocore_opensource][tunnckocore_opensource] | + + + +## Features + +- **Always up-to-date:** auto-publish new version when new version of dependency is out, [Renovate](https://renovateapp.com) +- **Standard:** using StandardJS, Prettier, SemVer, Semantic Release and conventional commits +- **Smart Plugins:** for extending the core API or the end [Result](#result), see [.use](#use) method and [Plugins Architecture](#plugins-architecture) +- **Extensible:** using plugins for working directly on AST nodes, see the [Plugins Architecture](#plugins-architecture) +- **ES2020+ Ready:** by using `.parseExpression` method of the Babel `v7.x` parser +- **Customization:** allows switching the parser, through `options.parse` +- **Support for:** arrow functions, default parameters, generators and async/await functions +- **Stable:** battle-tested in production and against all parsers - [espree][], [acorn][], [@babel/parser](https://npmjs.com/packages/@babel/parser) +- **Tested:** with [450+ tests](./test/index.js) for _200%_ coverage + +## Table of Contents + +- [Install](#install) +- [Which version to use?](#which-version-to-use) +- [Notes](#notes) + - [Throws in one specific case](#throws-in-one-specific-case) + - [Function named _"anonymous"_](#function-named-_anonymous_) + - [Real anonymous function](#real-anonymous-function) + - [Plugins Architecture](#plugins-architecture) +- [API](#api) + - [parseFunction](#parsefunction) + - [.parse](#parse) + - [.use](#use) + - [.define](#define) +- [Result](#result) +- [Contributing](#contributing) + - [Guides and Community](#guides-and-community) + - [Support the project](#support-the-project) + - [OPEN Open Source](#open-open-source) + - [Wonderful Contributors](#wonderful-contributors) +- [License](#license) + +_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ + +## Install + +This project requires [**Node.js**](https://nodejs.org) **>=8.11** _(see [Support & Release Policy](https://github.com/tunnckoCoreLabs/support-release-policy))_. Install it using +[**yarn**](https://yarnpkg.com) or [**npm**](https://npmjs.com).
+_We highly recommend to use Yarn when you think to contribute to this project._ + +```bash +$ yarn add parse-function +``` + +## Which version to use? + +There's no breaking changes between the `v2.x` version. The only breaking is `v2.1` which also is not +working properly, so no use it. + +**Use v2.0.x** + +When you don't need support for `arrow functions` and `es6 default params`. This version +uses a RegExp expression to work. + +**Use v2.2.x** + +Only when you need a _basic_ support for `es6 features` like arrow functions. This version +uses a RegExp expression to work. + +**Use v2.3.x** + +When you want _full\*_ support for `arrow functions` and `es6 default params`. Where this "full", +means "almost full", because it has bugs. This version also uses (`acorn.parse`) real parser +to do the parsing. + +**Use v3.x** + +When you want to use different parser instead of the default `babylon.parse`, by passing custom +parse function to the `options.parse` option. **From this version we require `node >= 4`**. + +**Use v4.x** + +When you want full customization and most stable support for old and modern features. This version +uses `babylon.parseExpression` for parsing and provides a [Plugins API](#plugins-architecture). +See the [Features](#features) section for more info. + +**Use v5.x** + +It is basically the same as `v4`, but requires Node 6 & npm 5. Another is boilerplate stuff. + +**[back to top](#readme)** + +## Notes + +### Throws in one specific case + +> _see: [issue #3](https://github.com/tunnckoCore/parse-function/issues/3) and [test/index.js#L229-L235](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L229-L235)_ + +It may throw in one specific case, otherwise it won't throw, so you should +relay on the `result.isValid` for sure. + +### Function named _"anonymous"_ + +> _see: [test/index.js#L319-L324](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L319-L324) and [Result](#result) section_ + +If you pass a function which is named _"anonymous"_ the `result.name` will be `'anonymous'`, +but the `result.isAnonymous` will be `false` and `result.isNamed` will be `true`, because +in fact it's a named function. + +### Real anonymous function + +> _see: [test/index.js#L326-L331](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L326-L331) and [Result](#result) section_ + +Only if you pass really an anonymous function you will get `result.name` equal to `null`, +`result.isAnonymous` equal to `true` and `result.isNamed` equal to `false`. + +**[back to top](#readme)** + +### Plugins Architecture + +> _see: the [.use](#use) method, [test/index.js#L305-L317](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L305-L317) and [test/index.js#L396-L414](https://github.com/tunnckoCore/parse-function/blob/master/test/index.js#L396-L414)_ + +A more human description of the plugin mechanism. Plugins are **synchronous** - no support +and no need for **async** plugins here, but notice that you can do that manually, because +that exact architecture. + +The first function that is passed to the [.use](#use) method is used for extending the core API, +for example adding a new method to the `app` instance. That function is immediately invoked. + +```js +const parseFunction = require('parse-function'); +const app = parseFunction(); + +app.use((self) => { + // self is same as `app` + console.log(self.use); + console.log(self.parse); + console.log(self.define); + + self.define(self, 'foo', (bar) => bar + 1); +}); + +console.log(app.foo(2)); // => 3 +``` + +On the other side, if you want to access the AST of the parser, you should return a function +from that plugin, which function is passed with `(node, result)` signature. + +This function is lazy plugin, it is called only when the [.parse](#parse) method is called. + +```js +const parseFunction = require('parse-function'); +const app = parseFunction(); + +app.use((self) => { + console.log('immediately called'); + + return (node, result) => { + console.log('called only when .parse is invoked'); + console.log(node); + console.log(result); + }; +}); +``` + +Where **1)** the `node` argument is an object - actual and real AST Node coming from the parser +and **2)** the `result` is an object too - the end [Result](#result), on which +you can add more properties if you want. + +**[back to top](#readme)** + + + +## API + +_Generated using [jest-runner-docs](https://npmjs.com/package/jest-runner-docs)._ + +### [parseFunction](./src/index.js#L59) + +> Initializes with optional `opts` object which is passed directly +> to the desired parser and returns an object +> with `.use` and `.parse` methods. The default parse which +> is used is [babylon][]'s `.parseExpression` method from `v7`. + +**Signature** + +```ts +function(opts) +``` + +**Params** + +- `opts` - optional, merged with options passed to `.parse` method +- `returns` - app object with `.use` and `.parse` methods + +**Example** + +```js +const parseFunction = require('parse-function'); + +const app = parseFunction({ + ecmaVersion: 2017, +}); + +const fixtureFn = (a, b, c) => { + a = b + c; + return a + 2; +}; + +const result = app.parse(fixtureFn); +console.log(result); + +// see more +console.log(result.name); // => null +console.log(result.isNamed); // => false +console.log(result.isArrow); // => true +console.log(result.isAnonymous); // => true + +// array of names of the arguments +console.log(result.args); // => ['a', 'b', 'c'] + +// comma-separated names of the arguments +console.log(result.params); // => 'a, b, c' +``` + +### [.parse](./src/index.js#L124) + +> Parse a given `code` and returns a `result` object +> with useful properties - such as `name`, `body` and `args`. +> By default it uses Babylon parser, but you can switch it by +> passing `options.parse` - for example `options.parse: acorn.parse`. +> In the below example will show how to use `acorn` parser, instead +> of the default one. + +**Signature** + +```ts +function +``` + +**Params** + +- `code` - any kind of function or string to be parsed +- `options` - directly passed to the parser babylon, acorn, espree +- `options.parse` - by default `babylon.parseExpression`, + all `options` are passed as second argument +- `returns` - result see [result section](#result) for more info + +**Example** + +```js +const acorn = require('acorn'); +const parseFn = require('parse-function'); +const app = parseFn(); + +const fn = function foo(bar, baz) { + return bar * baz; +}; +const result = app.parse(fn, { + parse: acorn.parse, + ecmaVersion: 2017, +}); + +console.log(result.name); // => 'foo' +console.log(result.args); // => ['bar', 'baz'] +console.log(result.body); // => ' return bar * baz ' +console.log(result.isNamed); // => true +console.log(result.isArrow); // => false +console.log(result.isAnonymous); // => false +console.log(result.isGenerator); // => false +``` + +### [.use](./src/index.js#L177) + +> Add a plugin `fn` function for extending the API or working on the +> AST nodes. The `fn` is immediately invoked and passed +> with `app` argument which is instance of `parseFunction()` call. +> That `fn` may return another function that +> accepts `(node, result)` signature, where `node` is an AST node +> and `result` is an object which will be returned [result](#result) +> from the `.parse` method. This retuned function is called on each +> node only when `.parse` method is called. + +**Signature** + +```ts +function +``` + +**Params** + +- `fn` - plugin to be called +- `returns` - app instance for chaining + +_See [Plugins Architecture](#plugins-architecture) section._ + +**Example** + +```js +// plugin extending the `app` +app.use((app) => { + app.define(app, 'hello', (place) => `Hello ${place}!`); +}); + +const hi = app.hello('World'); +console.log(hi); // => 'Hello World!' + +// or plugin that works on AST nodes +app.use((app) => (node, result) => { + if (node.type === 'ArrowFunctionExpression') { + result.thatIsArrow = true; + } + return result; +}); + +const result = app.parse((a, b) => a + b + 123); +console.log(result.name); // => null +console.log(result.isArrow); // => true +console.log(result.thatIsArrow); // => true + +const result = app.parse(function foo() { + return 123; +}); +console.log(result.name); // => 'foo' +console.log(result.isArrow); // => false +console.log(result.thatIsArrow); // => undefined +``` + +### [.define](./src/index.js#L235) + +> Define a non-enumerable property on an object. Just +> a convenience mirror of the [define-property][] library, +> so check out its docs. Useful to be used in plugins. + +**Signature** + +```ts +function +``` + +**Params** + +- `obj` - the object on which to define the property +- `prop` - the name of the property to be defined or modified +- `val` - the descriptor for the property being defined or modified +- `returns` - obj the passed object, but modified + +**Example** + +```js +const parseFunction = require('parse-function'); +const app = parseFunction(); + +// use it like `define-property` lib +const obj = {}; +app.define(obj, 'hi', 'world'); +console.log(obj); // => { hi: 'world' } + +// or define a custom plugin that adds `.foo` property +// to the end result, returned from `app.parse` +app.use((app) => { + return (node, result) => { + // this function is called + // only when `.parse` is called + + app.define(result, 'foo', 123); + + return result; + }; +}); + +// fixture function to be parsed +const asyncFn = async (qux) => { + const bar = await Promise.resolve(qux); + return bar; +}; + +const result = app.parse(asyncFn); + +console.log(result.name); // => null +console.log(result.foo); // => 123 +console.log(result.args); // => ['qux'] + +console.log(result.isAsync); // => true +console.log(result.isArrow); // => true +console.log(result.isNamed); // => false +console.log(result.isAnonymous); // => true +``` + + + +**[back to top](#readme)** + +## Result + +> In the result object you have `name`, `args`, `params`, `body` and few hidden properties +> that can be useful to determine what the function is - arrow, regular, async/await or generator. + +- `name` **{String|null}**: name of the passed function or `null` if anonymous +- `args` **{Array}**: arguments of the function +- `params` **{String}**: comma-separated list representing the `args` +- `defaults` **{Object}**: key/value pairs, useful when use ES2015 default arguments +- `body` **{String}**: actual body of the function, respects trailing newlines and whitespaces +- `isValid` **{Boolean}**: is the given value valid or not, that's because it never throws! +- `isAsync` **{Boolean}**: `true` if function is ES2015 async/await function +- `isArrow` **{Boolean}**: `true` if the function is arrow function +- `isNamed` **{Boolean}**: `true` if function has name, or `false` if is anonymous +- `isGenerator` **{Boolean}**: `true` if the function is ES2015 generator function +- `isAnonymous` **{Boolean}**: `true` if the function don't have name + +**[back to top](#readme)** + +**[back to top](#readme)** + +## Contributing + +### Guides and Community + +Please read the [Contributing Guide][contributing-url] and [Code of Conduct][code_of_conduct-url] documents for advices. + +For bug reports and feature requests, please join our [community][community-url] forum and open a thread there with prefixing the title of the thread with the name of the project if there's no separate channel for it. + +Consider reading the [Support and Release Policy](https://github.com/tunnckoCoreLabs/support-release-policy) guide if you are interested in what are the supported Node.js versions and how we proceed. In short, we support latest two even-numbered Node.js release lines. + +### Support the project + +[Become a Partner or Sponsor?][patreon-url] :dollar: Check the **Partner**, **Sponsor** or **Omega-level** tiers! :tada: You can get your company logo, link & name on this file. It's also rendered on package page in [npmjs.com][npmv-url] and [yarnpkg.com](https://yarnpkg.com/en/package/parse-function) sites too! :rocket: + +Not financial support? Okey! [Pull requests](https://github.com/tunnckoCoreLabs/contributing#opening-a-pull-request), stars and all kind of [contributions](https://opensource.guide/how-to-contribute/#what-it-means-to-contribute) are always +welcome. :sparkles: + + + +### Wonderful Contributors + +Thanks to the hard work of these wonderful people this project is alive! It follows the +[all-contributors](https://github.com/kentcdodds/all-contributors) specification. +Don't hesitate to add yourself to that list if you have made any contribution! ;) [See how, +here](https://github.com/jfmengels/all-contributors-cli#usage). + + + +| [
Charlike Mike Reagent](https://tunnckocore.com)
[💻](https://github.com/tunnckoCore/opensource/commits?author=tunnckoCore "Code") [📖](https://github.com/tunnckoCore/opensource/commits?author=tunnckoCore "Documentation") [💬](#question-tunnckoCore "Answering Questions") [👀](#review-tunnckoCore "Reviewed Pull Requests") [🔍](#fundingFinding-tunnckoCore "Funding Finding") | +| :---: | + + + +Consider showing your [support](#support-the-project) to them. :sparkling_heart: + +**[back to top](#readme)** + +## License + +Copyright (c) 2016-present, [Charlike Mike Reagent](https://tunnckocore.com) `` & [contributors](#wonderful-contributors).
+Released under the [MPL-2.0 License][license-url]. + +[contributing-url]: https://github.com/tunnckoCore/opensource/blob/master/CONTRIBUTING.md +[code_of_conduct-url]: https://github.com/tunnckoCore/opensource/blob/master/CODE_OF_CONDUCT.md + + + +[npmv-url]: https://www.npmjs.com/package/parse-function +[npmv-img]: https://badgen.net/npm/v/parse-function?icon=npm +[nodejs-img]: https://badgen.net/npm/node/parse-function + + + +[license-url]: https://github.com/tunnckoCore/opensource/blob/master/packages/parse-function/LICENSE +[license-img]: https://badgen.net/npm/license/parse-function + + + +[codestyle-url]: https://github.com/airbnb/javascript +[codestyle-img]: https://badgen.net/badge/code%20style/airbnb/ff5a5f?icon=airbnb +[linuxbuild-url]: https://github.com/tunnckocore/opensource/actions +[linuxbuild-img]: https://badgen.net/github/status/tunnckoCore/opensource/master?label=build&icon=github +[codecoverage-url]: https://codecov.io/gh/tunnckoCore/opensource +[codecoverage-img]: https://badgen.net/codecov/c/github/tunnckoCore/opensource?icon=codecov +[dependencies-url]: https://david-dm.org/tunnckoCore/opensource +[dependencies-img]: https://badgen.net/david/dep/tunnckoCore/opensource?label=deps +[ccommits-url]: https://conventionalcommits.org/ +[ccommits-img]: https://badgen.net/badge/conventional%20commits/v1.0.0/green +[standard-release-url]: https://github.com/standard-release/standard-release +[standard-release-img]: https://badgen.net/badge/semantically/released/05c5ff +[community-img]: https://badgen.net/badge/join/community/7b16ff +[community-url]: https://github.com/tunnckocorehq/community +[last-commit-img]: https://badgen.net/github/last-commit/tunnckoCore/opensource/master +[last-commit-url]: https://github.com/tunnckoCore/opensource/commits/master +[downloads-weekly-img]: https://badgen.net/npm/dw/parse-function?icon=npm +[downloads-monthly-img]: https://badgen.net/npm/dm/parse-function?icon=npm +[downloads-total-img]: https://badgen.net/npm/dt/parse-function?icon=npm +[renovateapp-url]: https://renovatebot.com +[renovateapp-img]: https://badgen.net/badge/renovate/enabled/green +[prs-welcome-img]: https://badgen.net/badge/PRs/welcome/green +[prs-welcome-url]: http://makeapullrequest.com + + + +[paypal-url]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HYJJEZNSGAPGC&source=url +[paypal-img]: https://badgen.net/badge/PayPal/donate/003087?icon=https://simpleicons.now.sh/paypal/fff + + + +[kofi-url]: https://ko-fi.com/tunnckoCore +[kofi-img]: https://badgen.net/badge/Buy%20me/a%20coffee/29abe0c2?icon=https://rawcdn.githack.com/tunnckoCore/badgen-icons/f8264c6414e0bec449dd86f2241d50a9b89a1203/icons/kofi.svg + + + +[bitcoin-url]: https://www.blockchain.com/btc/payment_request?address=3QNHKun1K1SUui1b4Z3KEGPPsWC1TgtnqA&message=Open+Source+Software&amount_local=10¤cy=USD +[bitcoin-img]: https://badgen.net/badge/Bitcoin%20tip/3QNHKun...b4Z3KEGPPsWC1TgtnqA/yellow?icon=https://simpleicons.now.sh/bitcoin/fff +[keybase-url]: https://keybase.io/tunnckoCore +[keybase-img]: https://badgen.net/keybase/pgp/tunnckoCore +[twitter-url]: https://twitter.com/tunnckoCore +[twitter-img]: https://badgen.net/twitter/follow/tunnckoCore?icon=twitter&color=1da1f2 +[patreon-url]: https://www.patreon.com/bePatron?u=5579781 +[patreon-img]: https://badgen.net/badge/Become/a%20patron/F96854?icon=patreon + + + +[patreon-sponsor-img]: https://badgen.net/badge/become/a%20sponsor/F96854?icon=patreon +[twitter-share-url]: https://twitter.com/intent/tweet?text=https://github.com/tunnckoCore/opensource&via=tunnckoCore +[twitter-share-img]: https://badgen.net/badge/twitter/share/1da1f2?icon=twitter +[open-issue-url]: https://github.com/tunnckoCore/opensource/issues/new +[tunnckocore_legal]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/legal/tunnckocore?label&color=A56016&icon=https://svgshare.com/i/Dt6.svg +[tunnckocore_consulting]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/consulting/tunnckocore?label&color=07ba96&icon=https://svgshare.com/i/Dt6.svg +[tunnckocore_security]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/security/tunnckocore?label&color=ed1848&icon=https://svgshare.com/i/Dt6.svg +[tunnckocore_opensource]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/opensource/tunnckocore?label&color=ff7a2f&icon=https://svgshare.com/i/Dt6.svg +[tunnckocore_newsletter]: https://badgen.net/https/liam-badge-daknys6gadky.runkit.sh/com/newsletter/tunnckocore?label&color=5199FF&icon=https://svgshare.com/i/Dt6.svg +[acorn]: https://github.com/acornjs/acorn +[babylon]: https://babeljs.io/ +[define-property]: https://github.com/jonschlinkert/define-property +[espree]: https://github.com/eslint/espree diff --git a/packages/parse-function/package.json b/packages/parse-function/package.json new file mode 100644 index 00000000..28886a05 --- /dev/null +++ b/packages/parse-function/package.json @@ -0,0 +1,87 @@ +{ + "name": "parse-function", + "version": "5.2.11", + "description": "Parse a function into an object using espree, acorn or babylon parsers. Extensible through Smart Plugins", + "repository": "https://github.com/tunnckoCore/opensource/tree/master/packages/parse-fn", + "homepage": "https://tunnckocore.com/opensource", + "author": "Charlike Mike Reagent (https://tunnckocore.com)", + "license": "MPL-2.0", + "engines": { + "node": ">=8.11" + }, + "main": "dist/main/index.js", + "module": "dist/module/index.js", + "types": "dist/types/index.d.ts", + "files": [ + "dist" + ], + "keywords": [ + "args", + "arguments", + "async", + "async-await", + "asyncawait", + "await", + "babel", + "developer-experience", + "development", + "dx", + "fn", + "func", + "function", + "generators", + "hela", + "parameters", + "params", + "parse", + "parse-function", + "parser", + "tostring", + "tunnckocore-oss", + "tunnckocorehq", + "typescript", + "utilities" + ], + "scripts": {}, + "dependencies": { + "arrify": "^2.0.1", + "@babel/parser": "^7.6.4", + "define-property": "^2.0.2" + }, + "devDependencies": { + "acorn": "^7.1.0", + "acorn-loose": "^7.0.0", + "espree": "^6.1.1", + "for-in": "^1.0.2" + }, + "publishConfig": { + "access": "public", + "tag": "latest" + }, + "licenseStart": 2016, + "verb": { + "readme": "../../readme-template.md", + "run": true, + "toc": { + "render": true, + "method": "preWrite", + "maxdepth": 4 + }, + "layout": "empty", + "tasks": [ + "readme" + ], + "lint": { + "reflinks": true + }, + "reflinks": [ + "acorn", + "babylon", + "define-property", + "espree" + ], + "related": { + "list": [] + } + } +} diff --git a/packages/parse-function/src/index.js b/packages/parse-function/src/index.js new file mode 100644 index 00000000..2ba5e8d4 --- /dev/null +++ b/packages/parse-function/src/index.js @@ -0,0 +1,235 @@ +/*! + * parse-function + * + * Copyright (c) 2017 Charlike Mike Reagent (https://i.am.charlike.online) + * Released under the MIT license. + */ + +/** + * Utilities + */ + +import utils from './lib/utils'; + +/** + * Core plugins + */ + +import initial from './lib/plugins/initial'; + +/** + * > Initializes with optional `opts` object which is passed directly + * to the desired parser and returns an object + * with `.use` and `.parse` methods. The default parse which + * is used is [babylon][]'s `.parseExpression` method from `v7`. + * + * ```js + * const parseFunction = require('parse-function') + * + * const app = parseFunction({ + * ecmaVersion: 2017 + * }) + * + * const fixtureFn = (a, b, c) => { + * a = b + c + * return a + 2 + * } + * + * const result = app.parse(fixtureFn) + * console.log(result) + * + * // see more + * console.log(result.name) // => null + * console.log(result.isNamed) // => false + * console.log(result.isArrow) // => true + * console.log(result.isAnonymous) // => true + * + * // array of names of the arguments + * console.log(result.args) // => ['a', 'b', 'c'] + * + * // comma-separated names of the arguments + * console.log(result.params) // => 'a, b, c' + * ``` + * + * @param {Object} `opts` optional, merged with options passed to `.parse` method + * @return {Object} `app` object with `.use` and `.parse` methods + * @name parseFunction + * @api public + */ +export default function parseFunction(opts) { + const plugins = []; + const app = { + /** + * > Parse a given `code` and returns a `result` object + * with useful properties - such as `name`, `body` and `args`. + * By default it uses Babylon parser, but you can switch it by + * passing `options.parse` - for example `options.parse: acorn.parse`. + * In the below example will show how to use `acorn` parser, instead + * of the default one. + * + * ```js + * const acorn = require('acorn') + * const parseFn = require('parse-function') + * const app = parseFn() + * + * const fn = function foo (bar, baz) { return bar * baz } + * const result = app.parse(fn, { + * parse: acorn.parse, + * ecmaVersion: 2017 + * }) + * + * console.log(result.name) // => 'foo' + * console.log(result.args) // => ['bar', 'baz'] + * console.log(result.body) // => ' return bar * baz ' + * console.log(result.isNamed) // => true + * console.log(result.isArrow) // => false + * console.log(result.isAnonymous) // => false + * console.log(result.isGenerator) // => false + * ``` + * + * @param {Function|String} `code` any kind of function or string to be parsed + * @param {Object} `options` directly passed to the parser - babylon, acorn, espree + * @param {Function} `options.parse` by default `babylon.parseExpression`, + * all `options` are passed as second argument + * to that provided function + * @return {Object} `result` see [result section](#result) for more info + * @name .parse + * @api public + */ + parse(code, options) { + const result = utils.setDefaults(code); + + if (!result.isValid) { + return result; + } + + const mergedOptions = { ...opts, ...options }; + + const isFunction = result.value.startsWith('function'); + const isAsyncFn = result.value.startsWith('async function'); + const isAsync = result.value.startsWith('async'); + const isArrow = result.value.includes('=>'); + const isAsyncArrow = isAsync && isArrow; + + const isMethod = /^\*?.+\([\s\S\w\W]*\)\s*\{/i.test(result.value); + + if (!(isFunction || isAsyncFn || isAsyncArrow) && isMethod) { + result.value = `{ ${result.value} }`; + } + + const node = utils.getNode(result, mergedOptions); + return plugins.reduce((res, fn) => fn(node, res) || res, result); + }, + + /** + * > Add a plugin `fn` function for extending the API or working on the + * AST nodes. The `fn` is immediately invoked and passed + * with `app` argument which is instance of `parseFunction()` call. + * That `fn` may return another function that + * accepts `(node, result)` signature, where `node` is an AST node + * and `result` is an object which will be returned [result](#result) + * from the `.parse` method. This retuned function is called on each + * node only when `.parse` method is called. + * + * _See [Plugins Architecture](#plugins-architecture) section._ + * + * ```js + * // plugin extending the `app` + * app.use((app) => { + * app.define(app, 'hello', (place) => `Hello ${place}!`) + * }) + * + * const hi = app.hello('World') + * console.log(hi) // => 'Hello World!' + * + * // or plugin that works on AST nodes + * app.use((app) => (node, result) => { + * if (node.type === 'ArrowFunctionExpression') { + * result.thatIsArrow = true + * } + * return result + * }) + * + * const result = app.parse((a, b) => (a + b + 123)) + * console.log(result.name) // => null + * console.log(result.isArrow) // => true + * console.log(result.thatIsArrow) // => true + * + * const result = app.parse(function foo () { return 123 }) + * console.log(result.name) // => 'foo' + * console.log(result.isArrow) // => false + * console.log(result.thatIsArrow) // => undefined + * ``` + * + * @param {Function} `fn` plugin to be called + * @return {Object} `app` instance for chaining + * @name .use + * @api public + */ + use(fn) { + const ret = fn(app); + if (typeof ret === 'function') { + plugins.push(ret); + } + return app; + }, + + /** + * > Define a non-enumerable property on an object. Just + * a convenience mirror of the [define-property][] library, + * so check out its docs. Useful to be used in plugins. + * + * ```js + * const parseFunction = require('parse-function') + * const app = parseFunction() + * + * // use it like `define-property` lib + * const obj = {} + * app.define(obj, 'hi', 'world') + * console.log(obj) // => { hi: 'world' } + * + * // or define a custom plugin that adds `.foo` property + * // to the end result, returned from `app.parse` + * app.use((app) => { + * return (node, result) => { + * // this function is called + * // only when `.parse` is called + * + * app.define(result, 'foo', 123) + * + * return result + * } + * }) + * + * // fixture function to be parsed + * const asyncFn = async (qux) => { + * const bar = await Promise.resolve(qux) + * return bar + * } + * + * const result = app.parse(asyncFn) + * + * console.log(result.name) // => null + * console.log(result.foo) // => 123 + * console.log(result.args) // => ['qux'] + * + * console.log(result.isAsync) // => true + * console.log(result.isArrow) // => true + * console.log(result.isNamed) // => false + * console.log(result.isAnonymous) // => true + * ``` + * + * @param {Object} `obj` the object on which to define the property + * @param {String} `prop` the name of the property to be defined or modified + * @param {Any} `val` the descriptor for the property being defined or modified + * @return {Object} `obj` the passed object, but modified + * @name .define + * @api public + */ + define: utils.define, + }; + + app.use(initial); + + return app; +} diff --git a/packages/parse-function/src/lib/plugins/body.js b/packages/parse-function/src/lib/plugins/body.js new file mode 100644 index 00000000..547b2378 --- /dev/null +++ b/packages/parse-function/src/lib/plugins/body.js @@ -0,0 +1,24 @@ +/* eslint-disable no-param-reassign, unicorn/consistent-function-scoping */ + +/** + * > Micro plugin to get the raw body, without the + * surrounding curly braces. It also preserves + * the whitespaces and newlines - they are original. + * + * @param {Object} node + * @param {Object} result + * @return {Object} result + * @private + */ +export default () => (node, result) => { + result.body = result.value.slice(node.body.start, node.body.end); + + const openCurly = result.body.charCodeAt(0) === 123; + const closeCurly = result.body.charCodeAt(result.body.length - 1) === 125; + + if (openCurly && closeCurly) { + result.body = result.body.slice(1, -1); + } + + return result; +}; diff --git a/packages/parse-function/src/lib/plugins/initial.js b/packages/parse-function/src/lib/plugins/initial.js new file mode 100644 index 00000000..4537fd17 --- /dev/null +++ b/packages/parse-function/src/lib/plugins/initial.js @@ -0,0 +1,43 @@ +/* eslint-disable no-param-reassign */ + +import body from './body'; +import props from './props'; +import params from './params'; + +/** + * > Default plugin that handles regular functions, + * arrow functions, generator functions + * and ES6 object method notation. + * + * @param {Object} node + * @param {Object} result + * @return {Object} resul + * @private + */ +export default (app) => (node, result) => { + const isFn = node.type.endsWith('FunctionExpression'); + const isMethod = node.type === 'ObjectExpression'; + + /* istanbul ignore next */ + if (!isFn && !isMethod) { + return; + } + + node = isMethod ? node.properties[0] : node; + node.id = isMethod ? node.key : node.id; + + // babylon node.properties[0] is `ObjectMethod` that has `params` and `body`; + // acorn node.properties[0] is `Property` that has `value`; + if (node.type === 'Property') { + const id = node.key; + node = node.value; + node.id = id; + } + + result = props(app)(node, result); + result = params(app)(node, result); + result = body(app)(node, result); + + // eslint-disable-next-line consistent-return + return result; +}; diff --git a/packages/parse-function/src/lib/plugins/params.js b/packages/parse-function/src/lib/plugins/params.js new file mode 100644 index 00000000..92d9c174 --- /dev/null +++ b/packages/parse-function/src/lib/plugins/params.js @@ -0,0 +1,40 @@ +/* eslint-disable no-param-reassign, unicorn/consistent-function-scoping */ +/** + * > Micro plugin to visit each of the params + * in the given function and collect them into + * an `result.args` array and `result.params` string. + * + * @param {Object} node + * @param {Object} result + * @return {Object} result + * @private + */ +export default () => (node, result) => { + node.params.forEach((param) => { + const defaultArgsName = + param.type === 'AssignmentPattern' && param.left && param.left.name; + + const restArgName = + param.type === 'RestElement' && param.argument && param.argument.name; + + const name = param.name || defaultArgsName || restArgName; + + result.args.push(name); + + if (param.right && param.right.type === 'SequenceExpression') { + const lastExpression = param.right.expressions.pop(); + + result.defaults[name] = result.value.slice( + lastExpression.start, + lastExpression.end, + ); + } else { + result.defaults[name] = param.right + ? result.value.slice(param.right.start, param.right.end) + : undefined; + } + }); + result.params = result.args.join(', '); + + return result; +}; diff --git a/packages/parse-function/src/lib/plugins/props.js b/packages/parse-function/src/lib/plugins/props.js new file mode 100644 index 00000000..7a19e6df --- /dev/null +++ b/packages/parse-function/src/lib/plugins/props.js @@ -0,0 +1,32 @@ +/** + * > Set couple of hidden properties and + * the name of the given function to + * the returned result object. Notice that + * if function is called "anonymous" then + * the `result.isAnonymous` would be `false`, because + * in reality it is named function. It would be `true` + * only when function is really anonymous and don't have + * any name. + * + * @param {Object} node + * @param {Object} result + * @return {Object} result + * @private + */ +export default (app) => (node, result) => { + app.define(result, 'isArrow', node.type.startsWith('Arrow')); + app.define(result, 'isAsync', node.async || false); + app.define(result, 'isGenerator', node.generator || false); + app.define(result, 'isExpression', node.expression || false); + app.define(result, 'isAnonymous', node.id === null); + app.define(result, 'isNamed', !result.isAnonymous); + + // if real anonymous -> set to null, + // notice that you can name you function `anonymous`, haha + // and it won't be "real" anonymous, so `isAnonymous` will be `false` + + // eslint-disable-next-line no-param-reassign + result.name = result.isAnonymous ? null : node.id.name; + + return result; +}; diff --git a/packages/parse-function/src/lib/utils.js b/packages/parse-function/src/lib/utils.js new file mode 100644 index 00000000..a774de38 --- /dev/null +++ b/packages/parse-function/src/lib/utils.js @@ -0,0 +1,92 @@ +/*! + * parse-function + * + * Copyright (c) 2017 Charlike Mike Reagent (https://i.am.charlike.online) + * Released under the MIT license. + */ + +import arrayify from 'arrify'; +import { parseExpression } from '@babel/parser'; +import define from 'define-property'; + +const utils = {}; +utils.define = define; +utils.arrayify = arrayify; + +/** + * > Create default result object, + * and normalize incoming arguments. + * + * @param {Function|String} code + * @return {Object} result + * @private + */ +utils.setDefaults = function setDefaults(code) { + const result = { + name: null, + body: '', + args: [], + params: '', + }; + + if (typeof code === 'function') { + // eslint-disable-next-line no-param-reassign + code = code.toString('utf8'); + } + + // makes result.isValid === false + if (typeof code !== 'string') { + // eslint-disable-next-line no-param-reassign + code = ''; + } + + return utils.setHiddenDefaults(result, code || ''); +}; + +/** + * > Create hidden properties into + * the result object. + * + * @param {Object} result + * @param {Function|String} code + * @return {Object} result + * @private + */ +utils.setHiddenDefaults = function setHiddenDefaults(result, code) { + utils.define(result, 'defaults', {}); + utils.define(result, 'value', code); + utils.define(result, 'isValid', code.length > 0); + utils.define(result, 'isArrow', false); + utils.define(result, 'isAsync', false); + utils.define(result, 'isNamed', false); + utils.define(result, 'isAnonymous', false); + utils.define(result, 'isGenerator', false); + utils.define(result, 'isExpression', false); + + return result; +}; + +/** + * > Get needed AST tree, depending on what + * parse method is used. + * + * @param {Object} result + * @param {Object} opts + * @return {Object} node + * @private + */ +utils.getNode = function getNode(result, opts) { + if (typeof opts.parse === 'function') { + // eslint-disable-next-line no-param-reassign + result.value = `(${result.value})`; + + const ast = opts.parse(result.value, opts); + const body = (ast.program && ast.program.body) || ast.body; + + return body[0].expression; + } + + return parseExpression(result.value, opts); +}; + +export default utils; diff --git a/packages/parse-function/test/__snapshots__/index.js.snap b/packages/parse-function/test/__snapshots__/index.js.snap new file mode 100644 index 00000000..3503ea9c --- /dev/null +++ b/packages/parse-function/test/__snapshots__/index.js.snap @@ -0,0 +1,4907 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`#1 - babel (default) - function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#2 - babel (default) - function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#3 - babel (default) - function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#4 - babel (default) - function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#5 - babel (default) - function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#6 - babel (default) - function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#7 - babel (default) - function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#8 - babel (default) - function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#9 - babel (default) - function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#10 - babel (default) - function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#11 - babel (default) - function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#12 - babel (default) - function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#13 - babel (default) - function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#14 - babel (default) - function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#15 - babel (default) - function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#16 - babel (default) - function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#17 - babel (default) - function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#18 - babel (default) - function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#19 - babel (default) - function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#20 - babel (default) - function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#21 - babel (default) - function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#22 - babel (default) - function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#23 - babel (default) - function * namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#24 - babel (default) - function * namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#25 - babel (default) - function * namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#26 - babel (default) - function * namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#27 - babel (default) - function * namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#28 - babel (default) - function * namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#29 - babel (default) - function * namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#30 - babel (default) - function * namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#31 - babel (default) - a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#32 - babel (default) - b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#33 - babel (default) - c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#34 - babel (default) - ...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#35 - babel (default) - ) => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#36 - babel (default) - a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#37 - babel (default) - a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#38 - babel (default) - a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#39 - babel (default) - a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#40 - babel (default) - a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#41 - babel (default) - a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#42 - babel (default) - d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#43 - babel (default) - e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#44 - babel (default) - a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#45 - babel (default) - x, y, ...restArgs) => console.log({ value: x * y } 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#46 - babel (default) - async function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#47 - babel (default) - async function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#48 - babel (default) - async function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#49 - babel (default) - async function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#50 - babel (default) - async function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#51 - babel (default) - async function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#52 - babel (default) - async function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#53 - babel (default) - async function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#54 - babel (default) - async function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#55 - babel (default) - async function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#56 - babel (default) - async function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#57 - babel (default) - async function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#58 - babel (default) - async function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#59 - babel (default) - async function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#60 - babel (default) - async function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#61 - babel (default) - async function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#62 - babel (default) - async function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#63 - babel (default) - async function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#64 - babel (default) - async function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#65 - babel (default) - async function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#66 - babel (default) - async (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#67 - babel (default) - async (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#68 - babel (default) - async (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#69 - babel (default) - async (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#70 - babel (default) - async () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#71 - babel (default) - async (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#72 - babel (default) - async (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#73 - babel (default) - async (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#74 - babel (default) - async (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#75 - babel (default) - async (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#76 - babel (default) - async (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#77 - babel (default) - async d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#78 - babel (default) - async e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#79 - babel (default) - async (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#80 - babel (default) - async (x, y, ...restArgs) => console.log({ value: x * y } 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#81 - babel (default) - should return object with default values when invalid 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#82 - babel (default) - should have '.isValid' and few '.is*'' hidden properties 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#87 - babel (default) - should work for object methods 1`] = ` +Object { + "args": Array [ + "a", + "b", + "c", + ], + "body": " + return 123; + ", + "name": "foo", + "params": "a, b, c", +} +`; + +exports[`#87 - babel (default) - should work for object methods 2`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return () => a; + ", + "name": "bar", + "params": "a", +} +`; + +exports[`#87 - babel (default) - should work for object methods 3`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return yield a * 321; + ", + "name": "gen", + "params": "a", +} +`; + +exports[`#87 - babel (default) - should work for object methods 4`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": " return a * 3 ", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#91 - options.parse + ecmaVersion: 2019 - function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#92 - options.parse + ecmaVersion: 2019 - function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#93 - options.parse + ecmaVersion: 2019 - function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#94 - options.parse + ecmaVersion: 2019 - function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#95 - options.parse + ecmaVersion: 2019 - function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#96 - options.parse + ecmaVersion: 2019 - function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#97 - options.parse + ecmaVersion: 2019 - function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#98 - options.parse + ecmaVersion: 2019 - function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#99 - options.parse + ecmaVersion: 2019 - function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#100 - options.parse + ecmaVersion: 2019 - function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#101 - options.parse + ecmaVersion: 2019 - function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#102 - options.parse + ecmaVersion: 2019 - function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#103 - options.parse + ecmaVersion: 2019 - function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#104 - options.parse + ecmaVersion: 2019 - function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#105 - options.parse + ecmaVersion: 2019 - function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#106 - options.parse + ecmaVersion: 2019 - function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#107 - options.parse + ecmaVersion: 2019 - function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#108 - options.parse + ecmaVersion: 2019 - function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#109 - options.parse + ecmaVersion: 2019 - function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#110 - options.parse + ecmaVersion: 2019 - function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#111 - options.parse + ecmaVersion: 2019 - function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#112 - options.parse + ecmaVersion: 2019 - function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#113 - options.parse + ecmaVersion: 2019 - function * namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#114 - options.parse + ecmaVersion: 2019 - function * namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#115 - options.parse + ecmaVersion: 2019 - function * namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#116 - options.parse + ecmaVersion: 2019 - function * namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#117 - options.parse + ecmaVersion: 2019 - function * namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#118 - options.parse + ecmaVersion: 2019 - function * namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#119 - options.parse + ecmaVersion: 2019 - function * namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#120 - options.parse + ecmaVersion: 2019 - function * namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#121 - options.parse + ecmaVersion: 2019 - (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#122 - options.parse + ecmaVersion: 2019 - (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#123 - options.parse + ecmaVersion: 2019 - (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#124 - options.parse + ecmaVersion: 2019 - (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#125 - options.parse + ecmaVersion: 2019 - () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#126 - options.parse + ecmaVersion: 2019 - (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#127 - options.parse + ecmaVersion: 2019 - (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#128 - options.parse + ecmaVersion: 2019 - (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#129 - options.parse + ecmaVersion: 2019 - (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#130 - options.parse + ecmaVersion: 2019 - (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#131 - options.parse + ecmaVersion: 2019 - (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#132 - options.parse + ecmaVersion: 2019 - d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#133 - options.parse + ecmaVersion: 2019 - e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#134 - options.parse + ecmaVersion: 2019 - (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#135 - options.parse + ecmaVersion: 2019 - (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#136 - options.parse + ecmaVersion: 2019 - async function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#137 - options.parse + ecmaVersion: 2019 - async function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#138 - options.parse + ecmaVersion: 2019 - async function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#139 - options.parse + ecmaVersion: 2019 - async function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#140 - options.parse + ecmaVersion: 2019 - async function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#141 - options.parse + ecmaVersion: 2019 - async function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#142 - options.parse + ecmaVersion: 2019 - async function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#143 - options.parse + ecmaVersion: 2019 - async function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#144 - options.parse + ecmaVersion: 2019 - async function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#145 - options.parse + ecmaVersion: 2019 - async function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#146 - options.parse + ecmaVersion: 2019 - async function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#147 - options.parse + ecmaVersion: 2019 - async function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#148 - options.parse + ecmaVersion: 2019 - async function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#149 - options.parse + ecmaVersion: 2019 - async function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#150 - options.parse + ecmaVersion: 2019 - async function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#151 - options.parse + ecmaVersion: 2019 - async function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#152 - options.parse + ecmaVersion: 2019 - async function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#153 - options.parse + ecmaVersion: 2019 - async function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#154 - options.parse + ecmaVersion: 2019 - async function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#155 - options.parse + ecmaVersion: 2019 - async function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#156 - options.parse + ecmaVersion: 2019 - async (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#157 - options.parse + ecmaVersion: 2019 - async (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#158 - options.parse + ecmaVersion: 2019 - async (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#159 - options.parse + ecmaVersion: 2019 - async (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#160 - options.parse + ecmaVersion: 2019 - async () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#161 - options.parse + ecmaVersion: 2019 - async (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#162 - options.parse + ecmaVersion: 2019 - async (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#163 - options.parse + ecmaVersion: 2019 - async (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#164 - options.parse + ecmaVersion: 2019 - async (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#165 - options.parse + ecmaVersion: 2019 - async (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#166 - options.parse + ecmaVersion: 2019 - async (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#167 - options.parse + ecmaVersion: 2019 - async d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#168 - options.parse + ecmaVersion: 2019 - async e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#169 - options.parse + ecmaVersion: 2019 - async (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#170 - options.parse + ecmaVersion: 2019 - async (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#171 - options.parse + ecmaVersion: 2019 - should return object with default values when invalid 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#172 - options.parse + ecmaVersion: 2019 - should have '.isValid' and few '.is*'' hidden properties 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#177 - options.parse + ecmaVersion: 2019 - should work for object methods 1`] = ` +Object { + "args": Array [ + "a", + "b", + "c", + ], + "body": " + return 123; + ", + "name": "foo", + "params": "a, b, c", +} +`; + +exports[`#177 - options.parse + ecmaVersion: 2019 - should work for object methods 2`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return () => a; + ", + "name": "bar", + "params": "a", +} +`; + +exports[`#177 - options.parse + ecmaVersion: 2019 - should work for object methods 3`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return yield a * 321; + ", + "name": "gen", + "params": "a", +} +`; + +exports[`#177 - options.parse + ecmaVersion: 2019 - should work for object methods 4`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": " return a * 3 ", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#181 - acorn.parse - function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#182 - acorn.parse - function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#183 - acorn.parse - function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#184 - acorn.parse - function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#185 - acorn.parse - function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#186 - acorn.parse - function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#187 - acorn.parse - function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#188 - acorn.parse - function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#189 - acorn.parse - function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#190 - acorn.parse - function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#191 - acorn.parse - function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#192 - acorn.parse - function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#193 - acorn.parse - function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#194 - acorn.parse - function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#195 - acorn.parse - function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#196 - acorn.parse - function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#197 - acorn.parse - function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#198 - acorn.parse - function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#199 - acorn.parse - function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#200 - acorn.parse - function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#201 - acorn.parse - function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#202 - acorn.parse - function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#203 - acorn.parse - function * namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#204 - acorn.parse - function * namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#205 - acorn.parse - function * namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#206 - acorn.parse - function * namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#207 - acorn.parse - function * namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#208 - acorn.parse - function * namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#209 - acorn.parse - function * namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#210 - acorn.parse - function * namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#211 - acorn.parse - (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#212 - acorn.parse - (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#213 - acorn.parse - (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#214 - acorn.parse - (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#215 - acorn.parse - () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#216 - acorn.parse - (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#217 - acorn.parse - (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#218 - acorn.parse - (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#219 - acorn.parse - (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#220 - acorn.parse - (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#221 - acorn.parse - (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#222 - acorn.parse - d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#223 - acorn.parse - e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#224 - acorn.parse - (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#225 - acorn.parse - (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#226 - acorn.parse - async function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#227 - acorn.parse - async function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#228 - acorn.parse - async function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#229 - acorn.parse - async function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#230 - acorn.parse - async function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#231 - acorn.parse - async function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#232 - acorn.parse - async function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#233 - acorn.parse - async function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#234 - acorn.parse - async function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#235 - acorn.parse - async function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#236 - acorn.parse - async function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#237 - acorn.parse - async function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#238 - acorn.parse - async function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#239 - acorn.parse - async function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#240 - acorn.parse - async function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#241 - acorn.parse - async function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#242 - acorn.parse - async function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#243 - acorn.parse - async function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#244 - acorn.parse - async function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#245 - acorn.parse - async function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#246 - acorn.parse - async (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#247 - acorn.parse - async (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#248 - acorn.parse - async (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#249 - acorn.parse - async (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#250 - acorn.parse - async () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#251 - acorn.parse - async (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#252 - acorn.parse - async (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#253 - acorn.parse - async (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#254 - acorn.parse - async (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#255 - acorn.parse - async (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#256 - acorn.parse - async (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#257 - acorn.parse - async d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#258 - acorn.parse - async e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#259 - acorn.parse - async (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#260 - acorn.parse - async (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#261 - acorn.parse - should return object with default values when invalid 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#262 - acorn.parse - should have '.isValid' and few '.is*'' hidden properties 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#267 - acorn.parse - should work for object methods 1`] = ` +Object { + "args": Array [ + "a", + "b", + "c", + ], + "body": " + return 123; + ", + "name": "foo", + "params": "a, b, c", +} +`; + +exports[`#267 - acorn.parse - should work for object methods 2`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return () => a; + ", + "name": "bar", + "params": "a", +} +`; + +exports[`#267 - acorn.parse - should work for object methods 3`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return yield a * 321; + ", + "name": "gen", + "params": "a", +} +`; + +exports[`#267 - acorn.parse - should work for object methods 4`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": " return a * 3 ", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#271 - acorn loose - function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#272 - acorn loose - function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#273 - acorn loose - function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#274 - acorn loose - function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#275 - acorn loose - function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#276 - acorn loose - function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#277 - acorn loose - function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#278 - acorn loose - function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#279 - acorn loose - function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#280 - acorn loose - function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#281 - acorn loose - function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#282 - acorn loose - function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#283 - acorn loose - function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#284 - acorn loose - function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#285 - acorn loose - function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#286 - acorn loose - function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#287 - acorn loose - function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#288 - acorn loose - function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#289 - acorn loose - function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#290 - acorn loose - function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#291 - acorn loose - function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#292 - acorn loose - function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#293 - acorn loose - function * namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#294 - acorn loose - function * namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#295 - acorn loose - function * namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#296 - acorn loose - function * namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#297 - acorn loose - function * namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#298 - acorn loose - function * namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#299 - acorn loose - function * namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#300 - acorn loose - function * namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#301 - acorn loose - (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#302 - acorn loose - (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#303 - acorn loose - (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#304 - acorn loose - (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#305 - acorn loose - () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#306 - acorn loose - (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#307 - acorn loose - (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#308 - acorn loose - (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#309 - acorn loose - (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#310 - acorn loose - (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#311 - acorn loose - (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#312 - acorn loose - d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#313 - acorn loose - e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#314 - acorn loose - (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#315 - acorn loose - (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#316 - acorn loose - async function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#317 - acorn loose - async function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#318 - acorn loose - async function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#319 - acorn loose - async function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#320 - acorn loose - async function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#321 - acorn loose - async function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#322 - acorn loose - async function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#323 - acorn loose - async function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#324 - acorn loose - async function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#325 - acorn loose - async function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#326 - acorn loose - async function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#327 - acorn loose - async function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#328 - acorn loose - async function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#329 - acorn loose - async function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#330 - acorn loose - async function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#331 - acorn loose - async function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#332 - acorn loose - async function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#333 - acorn loose - async function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#334 - acorn loose - async function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#335 - acorn loose - async function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#336 - acorn loose - async (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#337 - acorn loose - async (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#338 - acorn loose - async (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#339 - acorn loose - async (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#340 - acorn loose - async () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#341 - acorn loose - async (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#342 - acorn loose - async (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#343 - acorn loose - async (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#344 - acorn loose - async (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#345 - acorn loose - async (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#346 - acorn loose - async (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#347 - acorn loose - async d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#348 - acorn loose - async e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#349 - acorn loose - async (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#350 - acorn loose - async (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#351 - acorn loose - should return object with default values when invalid 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#352 - acorn loose - should have '.isValid' and few '.is*'' hidden properties 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#357 - acorn loose - should work for object methods 1`] = ` +Object { + "args": Array [ + "a", + "b", + "c", + ], + "body": " + return 123; + ", + "name": "foo", + "params": "a, b, c", +} +`; + +exports[`#357 - acorn loose - should work for object methods 2`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return () => a; + ", + "name": "bar", + "params": "a", +} +`; + +exports[`#357 - acorn loose - should work for object methods 3`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return yield a * 321; + ", + "name": "gen", + "params": "a", +} +`; + +exports[`#357 - acorn loose - should work for object methods 4`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": " return a * 3 ", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#361 - espree.parse - function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#362 - espree.parse - function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#363 - espree.parse - function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#364 - espree.parse - function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#365 - espree.parse - function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#366 - espree.parse - function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#367 - espree.parse - function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#368 - espree.parse - function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#369 - espree.parse - function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#370 - espree.parse - function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#371 - espree.parse - function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#372 - espree.parse - function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#373 - espree.parse - function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#374 - espree.parse - function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#375 - espree.parse - function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#376 - espree.parse - function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#377 - espree.parse - function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#378 - espree.parse - function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#379 - espree.parse - function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#380 - espree.parse - function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#381 - espree.parse - function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#382 - espree.parse - function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#383 - espree.parse - function * namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#384 - espree.parse - function * namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#385 - espree.parse - function * namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#386 - espree.parse - function * namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#387 - espree.parse - function * namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#388 - espree.parse - function * namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#389 - espree.parse - function * namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#390 - espree.parse - function * namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#391 - espree.parse - (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#392 - espree.parse - (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#393 - espree.parse - (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#394 - espree.parse - (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#395 - espree.parse - () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#396 - espree.parse - (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#397 - espree.parse - (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#398 - espree.parse - (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#399 - espree.parse - (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#400 - espree.parse - (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#401 - espree.parse - (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#402 - espree.parse - d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#403 - espree.parse - e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#404 - espree.parse - (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#405 - espree.parse - (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#406 - espree.parse - async function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#407 - espree.parse - async function (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#408 - espree.parse - async function (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#409 - espree.parse - async function (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#410 - espree.parse - async function () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#411 - espree.parse - async function (a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#412 - espree.parse - async function (a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#413 - espree.parse - async function (a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#414 - espree.parse - async function (a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#415 - espree.parse - async function (a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#416 - espree.parse - async function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`#417 - espree.parse - async function namedFn (b, callback, ...restArgs) {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": "namedFn", + "params": "b, callback, restArgs", +} +`; + +exports[`#418 - espree.parse - async function namedFn (c) {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": "namedFn", + "params": "c", +} +`; + +exports[`#419 - espree.parse - async function namedFn (...restArgs) {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": "namedFn", + "params": "restArgs", +} +`; + +exports[`#420 - espree.parse - async function namedFn () {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": "namedFn", + "params": "", +} +`; + +exports[`#421 - espree.parse - async function namedFn(a = (true, false)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#422 - espree.parse - async function namedFn(a = (true, null)) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#423 - espree.parse - async function namedFn(a = (true, "bar")) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#424 - espree.parse - async function namedFn(a, b = (i++, true)) {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": "namedFn", + "params": "a, b", +} +`; + +exports[`#425 - espree.parse - async function namedFn(a = 1) {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": "namedFn", + "params": "a", +} +`; + +exports[`#426 - espree.parse - async (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3} 1`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": "return a * 3", + "name": null, + "params": "a, cb, restArgs", +} +`; + +exports[`#427 - espree.parse - async (b, callback, ...restArgs) => {callback(null, b + 3)} 1`] = ` +Object { + "args": Array [ + "b", + "callback", + "restArgs", + ], + "body": "callback(null, b + 3)", + "name": null, + "params": "b, callback, restArgs", +} +`; + +exports[`#428 - espree.parse - async (c) => {return c * 3} 1`] = ` +Object { + "args": Array [ + "c", + ], + "body": "return c * 3", + "name": null, + "params": "c", +} +`; + +exports[`#429 - espree.parse - async (...restArgs) => {return 321} 1`] = ` +Object { + "args": Array [ + "restArgs", + ], + "body": "return 321", + "name": null, + "params": "restArgs", +} +`; + +exports[`#430 - espree.parse - async () => {} 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#431 - espree.parse - async (a = (true, false)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#432 - espree.parse - async (a = (true, null)) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#433 - espree.parse - async (a = (true, "bar")) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#434 - espree.parse - async (a, b = (i++, true)) => {} 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "", + "name": null, + "params": "a, b", +} +`; + +exports[`#435 - espree.parse - async (a = 1) => {} 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "", + "name": null, + "params": "a", +} +`; + +exports[`#436 - espree.parse - async (a) => a * 3 * a 1`] = ` +Object { + "args": Array [ + "a", + ], + "body": "a * 3 * a", + "name": null, + "params": "a", +} +`; + +exports[`#437 - espree.parse - async d => d * 355 * d 1`] = ` +Object { + "args": Array [ + "d", + ], + "body": "d * 355 * d", + "name": null, + "params": "d", +} +`; + +exports[`#438 - espree.parse - async e => {return e + 5235 / e} 1`] = ` +Object { + "args": Array [ + "e", + ], + "body": "return e + 5235 / e", + "name": null, + "params": "e", +} +`; + +exports[`#439 - espree.parse - async (a, b) => a + 3 + b 1`] = ` +Object { + "args": Array [ + "a", + "b", + ], + "body": "a + 3 + b", + "name": null, + "params": "a, b", +} +`; + +exports[`#440 - espree.parse - async (x, y, ...restArgs) => console.log({ value: x * y }) 1`] = ` +Object { + "args": Array [ + "x", + "y", + "restArgs", + ], + "body": "console.log({ value: x * y })", + "name": null, + "params": "x, y, restArgs", +} +`; + +exports[`#441 - espree.parse - should return object with default values when invalid 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#442 - espree.parse - should have '.isValid' and few '.is*'' hidden properties 1`] = ` +Object { + "args": Array [], + "body": "", + "name": null, + "params": "", +} +`; + +exports[`#447 - espree.parse - should work for object methods 1`] = ` +Object { + "args": Array [ + "a", + "b", + "c", + ], + "body": " + return 123; + ", + "name": "foo", + "params": "a, b, c", +} +`; + +exports[`#447 - espree.parse - should work for object methods 2`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return () => a; + ", + "name": "bar", + "params": "a", +} +`; + +exports[`#447 - espree.parse - should work for object methods 3`] = ` +Object { + "args": Array [ + "a", + ], + "body": " + return yield a * 321; + ", + "name": "gen", + "params": "a", +} +`; + +exports[`#447 - espree.parse - should work for object methods 4`] = ` +Object { + "args": Array [ + "a", + "cb", + "restArgs", + ], + "body": " return a * 3 ", + "name": "namedFn", + "params": "a, cb, restArgs", +} +`; + +exports[`should work with an async arrow function with an \`if\` statement 1`] = ` +Object { + "args": Array [ + "v", + ], + "body": " if (v) {} ", + "name": null, + "params": "v", +} +`; diff --git a/packages/parse-function/test/index.js b/packages/parse-function/test/index.js new file mode 100644 index 00000000..8f5522a0 --- /dev/null +++ b/packages/parse-function/test/index.js @@ -0,0 +1,470 @@ +/* eslint-disable unicorn/consistent-function-scoping */ +/* eslint-disable no-plusplus */ + +// import test from 'mukla'; + +import espree from 'espree'; +import { parse as babylonParse } from '@babel/parser'; + +import { parse as acornParse } from 'acorn'; +import { parse as acornLooseParse } from 'acorn-loose'; +import forIn from 'for-in'; +import parseFunction from '../src'; + +const espreeParse = espree.parse; + +const fixtures = { + regulars: [ + 'function (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3}', + 'function (b, callback, ...restArgs) {callback(null, b + 3)}', + 'function (c) {return c * 3}', + 'function (...restArgs) {return 321}', + 'function () {}', + 'function (a = (true, false)) {}', + 'function (a = (true, null)) {}', + 'function (a = (true, "bar")) {}', + 'function (a, b = (i++, true)) {}', + 'function (a = 1) {}', + ], + named: [ + 'function namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3}', + 'function namedFn (b, callback, ...restArgs) {callback(null, b + 3)}', + 'function namedFn (c) {return c * 3}', + 'function namedFn (...restArgs) {return 321}', + 'function namedFn () {}', + 'function namedFn(a = (true, false)) {}', + 'function namedFn(a = (true, null)) {}', + 'function namedFn(a = (true, "bar")) {}', + 'function namedFn(a, b = (i++, true)) {}', + 'function namedFn(a = 1) {}', + ], + generators: [ + 'function * namedFn (a = {foo: "ba)r", baz: 123}, cb, ...restArgs) {return a * 3}', + 'function * namedFn (b, callback, ...restArgs) {callback(null, b + 3)}', + 'function * namedFn (c) {return c * 3}', + 'function * namedFn (...restArgs) {return 321}', + 'function * namedFn () {}', + 'function * namedFn(a = (true, false)) {}', + 'function * namedFn(a = (true, null)) {}', + 'function * namedFn(a = (true, "bar")) {}', + 'function * namedFn(a, b = (i++, true)) {}', + 'function * namedFn(a = 1) {}', + ], + arrows: [ + '(a = {foo: "ba)r", baz: 123}, cb, ...restArgs) => {return a * 3}', + '(b, callback, ...restArgs) => {callback(null, b + 3)}', + '(c) => {return c * 3}', + '(...restArgs) => {return 321}', + '() => {}', + '(a = (true, false)) => {}', + '(a = (true, null)) => {}', + '(a = (true, "bar")) => {}', + '(a, b = (i++, true)) => {}', + '(a = 1) => {}', + '(a) => a * 3 * a', + 'd => d * 355 * d', + 'e => {return e + 5235 / e}', + '(a, b) => a + 3 + b', + '(x, y, ...restArgs) => console.log({ value: x * y })', + ], +}; + +/** + * Merge all into one + * and prepend `async` keyword + * before each function + */ + +fixtures.asyncs = fixtures.regulars + .concat(fixtures.named) + .concat(fixtures.arrows) + .map((item) => `async ${item}`); + +// const regulars = [ +// { +// name: null, +// params: 'a, cb, restArgs', +// args: ['a', 'cb', 'restArgs'], +// body: 'return a * 3', +// defaults: { +// a: '{foo: "ba)r", baz: 123}', +// cb: undefined, +// restArgs: undefined, +// }, +// }, +// { +// name: null, +// params: 'b, callback, restArgs', +// args: ['b', 'callback', 'restArgs'], +// body: 'callback(null, b + 3)', +// defaults: { b: undefined, callback: undefined, restArgs: undefined }, +// }, +// { +// name: null, +// params: 'c', +// args: ['c'], +// body: 'return c * 3', +// defaults: { c: undefined }, +// }, +// { +// name: null, +// params: 'restArgs', +// args: ['restArgs'], +// body: 'return 321', +// defaults: { restArgs: undefined }, +// }, +// { +// name: null, +// params: '', +// args: [], +// body: '', +// defaults: {}, +// }, +// { +// name: null, +// params: 'a', +// args: ['a'], +// body: '', +// defaults: { a: 'false' }, +// }, +// { +// name: null, +// params: 'a', +// args: ['a'], +// body: '', +// defaults: { a: 'null' }, +// }, +// { +// name: null, +// params: 'a', +// args: ['a'], +// body: '', +// defaults: { a: '"bar"' }, +// }, +// { +// name: null, +// params: 'a, b', +// args: ['a', 'b'], +// body: '', +// defaults: { a: undefined, b: 'true' }, +// }, +// { +// name: null, +// params: 'a', +// args: ['a'], +// body: '', +// defaults: { a: '1' }, +// }, +// ]; + +/** + * All of the regular functions + * variants plus few more + */ + +// const arrows = clone(regulars).concat([ +// { +// name: null, +// params: 'a', +// args: ['a'], +// body: 'a * 3 * a', +// defaults: { a: undefined }, +// }, +// { +// name: null, +// params: 'd', +// args: ['d'], +// body: 'd * 355 * d', +// defaults: { d: undefined }, +// }, +// { +// name: null, +// params: 'e', +// args: ['e'], +// body: 'return e + 5235 / e', +// defaults: { e: undefined }, +// }, +// { +// name: null, +// params: 'a, b', +// args: ['a', 'b'], +// body: 'a + 3 + b', +// defaults: { a: undefined, b: undefined }, +// }, +// { +// name: null, +// params: 'x, y, restArgs', +// args: ['x', 'y', 'restArgs'], +// body: 'console.log({ value: x * y })', +// defaults: { x: undefined, y: undefined, restArgs: undefined }, +// }, +// ]); + +/** + * All of the regulars, but + * with different name + */ + +// const named = clone(regulars).map((item) => ({ ...item, name: 'namedFn' })); + +// const expectedResults = { +// regulars, +// named, +// generators: named, +// arrows, +// asyncs: regulars.concat(named).concat(arrows), +// }; + +let testsCount = 1; + +/** + * Factory for DRY, we run all tests + * over two available parsers - one + * is the default `babylon`, second is + * the `acorn.parse` method. + */ + +function factory(parserName, parseFn) { + forIn(fixtures, (values) => { + values.forEach((code) => { + const actual = parseFn(code); + // const expected = expectedResults[key][i]; + const value = actual.value.replace(/^\(\{? ?/, '').replace(/\)$/, ''); + + test(`#${testsCount++} - ${parserName} - ${value}`, () => { + expect(actual).toMatchSnapshot(); + }); + }); + }); + + test(`#${testsCount++} - ${parserName} - should return object with default values when invalid`, () => { + const actual = parseFn(123456); + + expect(actual).toMatchSnapshot(); + // test.strictEqual(actual.isValid, false); + // test.strictEqual(actual.value, ''); + // test.strictEqual(actual.name, null); + // test.strictEqual(actual.body, ''); + // test.strictEqual(actual.params, ''); + // test.deepEqual(actual.args, []); + }); + + test(`#${testsCount++} - ${parserName} - should have '.isValid' and few '.is*'' hidden properties`, () => { + const actual = parseFn([1, 2, 3]); + + expect(actual).toMatchSnapshot(); + // test.strictEqual(actual.isValid, false); + // test.strictEqual(actual.isArrow, false); + // test.strictEqual(actual.isAsync, false); + // test.strictEqual(actual.isNamed, false); + // test.strictEqual(actual.isAnonymous, false); + // test.strictEqual(actual.isGenerator, false); + // test.strictEqual(actual.isExpression, false); + }); + + // bug in v4 and v5 + // https://github.com/tunnckoCore/parse-function/issues/3 + // test(`#${testsCount++} - ${parserName} - should not fails to get .body when something after close curly`, () => { + // const actual = parseFn('function (a) {return a * 2}; var b = 1') + // expect(actual.body, 'return a * 2') + // done() + // }) + + test(`#${testsCount++} - ${parserName} - should work when comment in arguments (see #11)`, () => { + const actual = parseFn('function (/* done */) { return 123 }'); + expect(actual.params).toStrictEqual(''); + expect(actual.body).toStrictEqual(' return 123 '); + + const res = parseFn('function (foo/* done */, bar) { return 123 }'); + expect(res.params).toStrictEqual('foo, bar'); + expect(res.body).toStrictEqual(' return 123 '); + }); + + test(`#${testsCount++} - ${parserName} - should support to parse generator functions`, () => { + const actual = parseFn('function * named (abc) { return abc + 123 }'); + expect(actual.name).toStrictEqual('named'); + expect(actual.params).toStrictEqual('abc'); + expect(actual.body).toStrictEqual(' return abc + 123 '); + }); + + test(`#${testsCount++} - ${parserName} - should support to parse async functions (ES2016)`, () => { + const actual = parseFn('async function foo (bar) { return bar }'); + expect(actual.name).toStrictEqual('foo'); + expect(actual.params).toStrictEqual('bar'); + expect(actual.body).toStrictEqual(' return bar '); + }); + + test(`#${testsCount++} - ${parserName} - should parse a real function which is passed`, () => { + const actual = parseFn(function fooBar(a, bc) { + return a + bc; + }); + expect(actual.name).toStrictEqual('fooBar'); + expect(actual.params).toStrictEqual('a, bc'); + expect(actual.body).toStrictEqual('\n return a + bc;\n '); + }); + + test(`#${testsCount++} - ${parserName} - should work for object methods`, () => { + const obj = { + // eslint-disable-next-line no-unused-vars + foo(a, b, c) { + return 123; + }, + bar(a) { + return () => a; + }, + *gen(a) { + return yield a * 321; + }, + }; + + const foo = parseFn(obj.foo); + expect(foo).toMatchSnapshot(); + // expect(foo.name, 'foo'); + // expect(foo.params, 'a, b, c'); + // expect(foo.body, '\n return 123;\n '); + + const bar = parseFn(obj.bar); + expect(bar).toMatchSnapshot(); + // expect(bar.name, 'bar'); + // expect(bar.body, '\n return () => a;\n '); + + const gen = parseFn(obj.gen); + expect(gen).toMatchSnapshot(); + // expect(gen.name).toStrictEqual('gen'); + + const namedFn = `namedFn (a = {foo: 'ba)r', baz: 123}, cb, ...restArgs) { return a * 3 }`; + const namedFnc = parseFn(namedFn); + expect(namedFnc).toMatchSnapshot(); + // expect(namedFnc.name).toStrictEqual('namedFn'); + // expect(namedFnc.args.length).toStrictEqual(3); + // expect(namedFnc.body).toStrictEqual(' return a * 3 '); + }); + + test(`#${testsCount++} - ${parserName} - plugins api`, () => { + const fnStr = `() => 123 + a + 44`; + // eslint-disable-next-line no-unused-vars + const plugin = (app) => (node, result) => { + // eslint-disable-next-line no-param-reassign + result.called = true; + // you may want to return the `result`, + // but it is the same as not return it + // return result + }; + const result = parseFn(fnStr, {}, plugin); + + expect(result.called).toStrictEqual(true); + }); + + test(`#${testsCount++} - ${parserName} - fn named "anonymous" has .name: 'anonymous'`, () => { + const result = parseFn('function anonymous () {}'); + expect(result.name).toStrictEqual('anonymous'); + expect(result.isAnonymous).toStrictEqual(false); + }); + + test(`#${testsCount++} - ${parserName} - real anonymous fn has .name: null`, () => { + const actual = parseFn('function () {}'); + expect(actual.name).toBeNull(); + expect(actual.isAnonymous).toStrictEqual(true); + }); +} + +/** + * Actually run all the tests + */ + +factory('babel (default)', (code, opts, plugin) => { + const app = parseFunction(); + if (plugin) app.use(plugin); + return app.parse(code, opts); +}); + +factory('options.parse + ecmaVersion: 2019', (code, opts, plugin) => { + const app = parseFunction({ + parse: babylonParse, + ecmaVersion: 2019, + }); + if (plugin) app.use(plugin); + return app.parse(code, opts); +}); + +factory('acorn.parse', (code, opts, plugin) => { + const app = parseFunction({ + parse: acornParse, + ecmaVersion: 2017, + }); + if (plugin) app.use(plugin); + return app.parse(code, opts); +}); + +factory('acorn loose', (code, opts, plugin) => { + const app = parseFunction(); + if (plugin) app.use(plugin); + return app.parse(code, { + parse: acornLooseParse, + ecmaVersion: 2017, + ...opts, + }); +}); + +factory('espree.parse', (code, opts, plugin) => { + const app = parseFunction({ + parse: espreeParse, + ecmaVersion: 8, + }); + if (plugin) app.use(plugin); + return app.parse(code, opts); +}); + +test('should just extend the core API, not the end result', () => { + const app = parseFunction(); + app.use((inst) => { + app.define(inst, 'hello', (place) => `Hello ${place}!!`); + }); + const ret = app.hello('pinky World'); + expect(ret).toStrictEqual('Hello pinky World!!'); +}); + +test('should call fn returned from plugin only when `parse` is called', () => { + const app = parseFunction({ + ecmaVersion: 2017, + }); + + let called = 0; + + app.use(() => { + called = 1; + return () => { + called = 2; + }; + }); + + expect(called).toStrictEqual(1); + + const res = app.parse('(a, b) => {}'); + expect(called).toStrictEqual(2); + expect(res.params).toStrictEqual('a, b'); +}); + +// https://github.com/tunnckoCore/parse-function/issues/61 +test('should work with an async arrow function with an `if` statement', () => { + const app = parseFunction(); + const parsed = app.parse('async (v) => { if (v) {} }'); + expect(parsed).toMatchSnapshot(); +}); + +test(`fn named "anonymous" has .name: 'anonymous'`, () => { + const app = parseFunction({ ecmaVersion: 2017 }); + const result = app.parse(function anonymous() {}); + + expect(result.name).toStrictEqual('anonymous'); + expect(result.isAnonymous).toStrictEqual(false); +}); + +test(`real anonymous fn has .name: null`, () => { + const app = parseFunction({ ecmaVersion: 2017 }); + + /* eslint-disable-next-line prefer-arrow-callback, func-names */ + const actual = app.parse(function() {}); + expect(actual.name).toBeNull(); + expect(actual.isAnonymous).toStrictEqual(true); +}); diff --git a/readme-template.md b/readme-template.md index a3212bc0..1c4bf1cd 100644 --- a/readme-template.md +++ b/readme-template.md @@ -4,7 +4,7 @@ Please consider following this project's author, [Charlike Mike Reagent](https://github.com/tunnckoCore), and :star: the project to show your :heart: and support. -
+
[![Code style][codestyle-img]][codestyle-url] [![CircleCI linux build][linuxbuild-img]][linuxbuild-url] @@ -52,6 +52,8 @@ Project is [semantically](https://semver.org) versioned & automatically released --> +{%= ifExists([process.cwd() + '/.verb.head.md'], include(process.cwd() + '/.verb.head.md')) %} + ## Table of Contents @@ -68,7 +70,7 @@ $ yarn add {%= name %} {%= ifExists([process.cwd() + '/.verb.md'], include(process.cwd() + '/.verb.md')) %} -**[back to top](#thetop)** +**[back to top](#readme)** {% if (verb.related && verb.related.list && verb.related.list.length) { %} @@ -78,7 +80,7 @@ Some of these projects are used here or were inspiration for this one, others ar {%= related(verb.related.list, { words: 10 }) %} -**[back to top](#thetop)** +**[back to top](#readme)** {% } %} ## Contributing @@ -128,6 +130,8 @@ here](https://github.com/jfmengels/all-contributors-cli#usage). Consider showing your [support](#support-the-project) to them. :sparkling_heart: +**[back to top](#readme)** + ## License Copyright (c) {%= licenseStart %}-present, [Charlike Mike Reagent](https://tunnckocore.com) `` & [contributors](#wonderful-contributors).
diff --git a/yarn.lock b/yarn.lock index e8a8388a..bba5b918 100644 --- a/yarn.lock +++ b/yarn.lock @@ -274,6 +274,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1" integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg== +"@babel/parser@^7.6.4": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81" + integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A== + "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" @@ -2344,6 +2349,13 @@ acorn-jsx@^5.0.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== +acorn-loose@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn-loose/-/acorn-loose-7.0.0.tgz#a4a6e8d2ae51dd5a8bdbc274b7ce3dd84964d13a" + integrity sha512-TIqpAWkqpdBXfj1XDVBQ/jNbAb6ByGfoqkcz2Pwd8mEHUndxOCw9FR6TqkMCMAr5XV8zYx0+m9GcGjxZzQuA2w== + dependencies: + acorn "^7.0.0" + acorn-walk@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" @@ -2919,6 +2931,11 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -4226,6 +4243,15 @@ clone-deep@^0.2.4: lazy-cache "^1.0.3" shallow-clone "^0.1.2" +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" @@ -12387,6 +12413,13 @@ shallow-clone@^0.1.2: lazy-cache "^0.2.3" mixin-object "^2.0.1" +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"