├── .gitignore ├── README.md ├── build.js ├── dist-template.js ├── dist └── babel-features.js ├── lib ├── index.js └── tests.js ├── package.json ├── src ├── features.yaml └── features │ ├── async-functions.js │ ├── async-generators.js │ ├── es2015-arrow-functions.js │ ├── es2015-block-scoped-functions.js │ ├── es2015-block-scoping.js │ ├── es2015-classes.js │ ├── es2015-computed-properties.js │ ├── es2015-constants.js │ ├── es2015-destructuring.js │ ├── es2015-duplicate-keys.js │ ├── es2015-for-of.js │ ├── es2015-function-name.js │ ├── es2015-generator-return.js │ ├── es2015-generators.js │ ├── es2015-literals.js │ ├── es2015-object-super.js │ ├── es2015-parameters.js │ ├── es2015-shorthand-properties.js │ ├── es2015-spread.js │ ├── es2015-sticky-regex.js │ ├── es2015-template-literals.js │ ├── es2015-typeof-symbol.js │ ├── es2015-unicode-regex.js │ ├── es3-function-scope.js │ ├── es3-member-expression-literals.js │ ├── es3-property-literals.js │ ├── es5-property-mutators.js │ ├── exponentiation-operator.js │ ├── function-sent.js │ ├── object-rest-spread.js │ └── trailing-function-commas.js ├── test.html └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /sandbox 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-features 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/hax/babel-features.svg)](https://greenkeeper.io/) 4 | Test babel features, can be used to generate babel options for specific compilation targets 5 | 6 | 7 | NOTE: The latest version (2.x) is for babel 6.x, for babel 5.x please use [version 1.x](https://github.com/hax/babel-features/tree/1.x) 8 | 9 | ## Install 10 | 11 | ```sh 12 | npm install babel-features@latest 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Node.js 18 | ```js 19 | var features = require('babel-features').test() 20 | console.log(features) 21 | // output on Node.js 5.0.0: 22 | // { 'es3-member-expression-literals': true, 23 | // 'es3-property-literals': true, 24 | // 'es5-property-mutators': true, 25 | // 'es2015-arrow-functions': true, 26 | // 'es2015-block-scoping': true, 27 | // 'es2015-classes': true, 28 | // 'es2015-computed-properties': true, 29 | // 'es2015-constants': true, 30 | // 'es2015-destructuring': false, 31 | // 'es2015-for-of': true, 32 | // 'es2015-function-name': false, 33 | // 'es2015-literals': true, 34 | // 'es2015-object-super': true, 35 | // 'es2015-parameters': false, 36 | // 'es2015-shorthand-properties': true, 37 | // 'es2015-spread': false, 38 | // 'es2015-sticky-regex': false, 39 | // 'es2015-template-literals': true, 40 | // 'es2015-typeof-symbol': true, 41 | // 'es2015-unicode-regex': false, 42 | // 'es2015-modules': false, 43 | // 'es2015-generators': false, 44 | // 'es3-function-scope': true } 45 | ``` 46 | 47 | ### Use babel preset 48 | See https://github.com/ariporad/babel-preset-features 49 | 50 | ### Use babel register 51 | ```js 52 | var babelOptions = require('babel-features').options() 53 | require('babel-core/register')(babelOptions) 54 | ``` 55 | 56 | 57 | ## TODO 58 | - Generate `.babelrc` 59 | - Generate `multiform.json` for https://github.com/callumlocke/multiform 60 | - Auto generate babel presets for some targets 61 | -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | const {readFileSync, writeFileSync} = require('fs') 2 | 3 | const tests = require('./lib/tests') 4 | 5 | const tpl = readFileSync(__dirname + '/dist-template.js', 'utf-8') 6 | const code = readFileSync(__dirname + '/lib/index.js', 'utf-8') 7 | 8 | let body = 'var tests = ' + JSON.stringify(tests, undefined, '\t') 9 | body += /\/\*\s*BEGIN\s*\*\/([\S\s]*)\/\*\s*END\s*\*\//.exec(code)[1] 10 | const result = tpl.replace(/\/\*\s*BODY\s*\*\//, body.trim()) 11 | 12 | writeFileSync('./dist/babel-features.js', result) 13 | -------------------------------------------------------------------------------- /dist-template.js: -------------------------------------------------------------------------------- 1 | void function(global) { 2 | 'use strict' 3 | 4 | switch (moduleFormat()) { 5 | case 'systemjs': 6 | System.register([], function (_export) { 7 | return { 8 | execute: function () { 9 | _export("test", test) 10 | _export("options", options) 11 | } 12 | } 13 | }) 14 | break 15 | case 'amd': 16 | define({test: test, options: options}) 17 | break 18 | case 'commonjs': 19 | exports.test = test 20 | exports.options = options 21 | break 22 | default: 23 | global.BabelFeatures = {test: test, options: options} 24 | } 25 | 26 | /* BODY */ 27 | 28 | }(this) 29 | -------------------------------------------------------------------------------- /dist/babel-features.js: -------------------------------------------------------------------------------- 1 | void function(global) { 2 | 'use strict' 3 | 4 | switch (moduleFormat()) { 5 | case 'systemjs': 6 | System.register([], function (_export) { 7 | return { 8 | execute: function () { 9 | _export("test", test) 10 | _export("options", options) 11 | } 12 | } 13 | }) 14 | break 15 | case 'amd': 16 | define({test: test, options: options}) 17 | break 18 | case 'commonjs': 19 | exports.test = test 20 | exports.options = options 21 | break 22 | default: 23 | global.BabelFeatures = {test: test, options: options} 24 | } 25 | 26 | var tests = [ 27 | { 28 | "feature": "es3-member-expression-literals", 29 | "code": "var foo = {}\nfoo.if = true\n\nassert(\n\tfoo.if\n)\n" 30 | }, 31 | { 32 | "feature": "es3-property-literals", 33 | "code": "var foo = {if: true}\n\nassert(\n\tfoo[\"if\"]\n)\n" 34 | }, 35 | { 36 | "feature": "es5-property-mutators", 37 | "code": "var foo = {\n\tget bar() { return true }\n}\n\nassert(\n\tfoo.bar\n)\n" 38 | }, 39 | { 40 | "feature": "es2015-arrow-functions", 41 | "code": "var foo = () => true\n\nassert(\n\tfoo()\n)\n" 42 | }, 43 | { 44 | "feature": "es2015-block-scoped-functions", 45 | "code": "var outer = foo()\nfunction foo() { return 1 }\n\n{\n\tvar inner = foo()\n\tfunction foo() { return 0 }\n}\n\nassert(\n\tinner === 0 && outer === 1\n)\n" 46 | }, 47 | { 48 | "feature": "es2015-block-scoping", 49 | "code": "let foo = 0, bar = 1\nfoo += bar\n{\n\tconst bar = 2\n\tfoo += bar\n}\n\nassert(\n\tfoo === 3\n)\n\nswitch (0) {\n\tdefault:\n\t\tconst bar = 3\n\t\tfoo += bar\n}\n\nassert(\n\tfoo === 6\n)\n" 50 | }, 51 | { 52 | "feature": "es2015-classes", 53 | "code": "class A {\n\tfoo() { return false }\n}\nclass B extends A {\n\tbar() { return !super.foo() }\n}\n\nassert(\n\tnew B().bar()\n)\n" 54 | }, 55 | { 56 | "feature": "es2015-computed-properties", 57 | "code": "var foo = {[\"b\" + \"ar\"]: true}\n\nassert(\n\tfoo.bar\n)\n" 58 | }, 59 | { 60 | "feature": "es2015-constants", 61 | "code": "const foo = true\n\ntry {\n\tfoo = false\n} catch (e) {\n\tassert(\n\t\tfoo\n\t)\n}\n\nassert(\n\tfoo\n)\n" 62 | }, 63 | { 64 | "feature": "es2015-destructuring", 65 | "code": "function foo({a, b: b1, c: [x, , y]}) {\n\treturn a === 1 && b1 === 2 && x === 3 && y === 5\n}\n\nassert(\n\tfoo({a: 1, b: 2, c: [3, 4, 5]})\n)\n" 66 | }, 67 | { 68 | "feature": "es2015-duplicate-keys", 69 | "code": "var x = {a: 5, a: 6}\nassert(x.a === 6)\n\nvar y = {\n\tget a() { return 1 },\n\ta: 2,\n}\nassert(y.a === 2)\n" 70 | }, 71 | { 72 | "feature": "es2015-for-of", 73 | "code": "var o = {}\no[Symbol.iterator] = function () {\n\tvar i = 0\n\treturn {\n\t\tnext: function () {\n\t\t\tif (i < 3) return {value: ++i}\n\t\t\treturn {done: true}\n\t\t}\n\t}\n}\nvar sum = 0\nfor (var x of o) {\n\tsum += x\n}\n\nassert(\n\tsum === 6\n)\n" 74 | }, 75 | { 76 | "feature": "es2015-function-name", 77 | "code": "var foo = function () {}\n\nassert(\n\tfoo.name === 'foo'\n)\n\nvar obj = { bar: function () {} }\n\nassert(\n\tobj.bar.name === 'bar'\n)\n" 78 | }, 79 | { 80 | "feature": "es2015-literals", 81 | "code": "assert(\n\t0b111 === 0o7\n)\n\nassert(\n\t'\\u{20bb7}' === '𠮷'\n)\n" 82 | }, 83 | { 84 | "feature": "es2015-object-super", 85 | "code": "var a = { foo() { return 'f' } }\nvar b = { foo() { return super.foo() + 'oo' } }\nObject.setPrototypeOf(b, a)\n\nassert(\n\tb.foo() === 'foo'\n)\n" 86 | }, 87 | { 88 | "feature": "es2015-parameters", 89 | "code": "function foo(x = true) {\n\treturn x\n}\n\nassert(\n\tfoo()\n)\n" 90 | }, 91 | { 92 | "feature": "es2015-shorthand-properties", 93 | "code": "var foo = true\nvar bar = {foo}\n\nassert(\n\tbar.foo\n)\n" 94 | }, 95 | { 96 | "feature": "es2015-spread", 97 | "code": "function foo(a, b, c) {\n\treturn a + b === c\n}\nvar list = [2, 3]\n\nassert(\n\tfoo(1, ...list)\n)\n" 98 | }, 99 | { 100 | "feature": "es2015-sticky-regex", 101 | "code": "// NOTE: Up to now, there is no runtime polyfill/shim available for sticky,\n// So this test never pass even with babel plugin applied.\n\nassert(\n\t/o+/y.sticky\n)\n" 102 | }, 103 | { 104 | "feature": "es2015-template-literals", 105 | "code": "var foo = \"foo\"\nvar bar = `${foo}bar`\n\nassert(\n\tbar === \"foobar\"\n)\n" 106 | }, 107 | { 108 | "feature": "es2015-typeof-symbol", 109 | "code": "assert(\n\ttypeof Symbol() === 'symbol'\n)\n" 110 | }, 111 | { 112 | "feature": "es2015-unicode-regex", 113 | "code": "var re = /^.$/u\n\nassert(\n\tre.test(\"𠮷\")\n)\n" 114 | }, 115 | { 116 | "feature": "exponentiation-operator", 117 | "code": "assert(\n\t2 ** 10 === 1024\n)\n" 118 | }, 119 | { 120 | "feature": "trailing-function-commas", 121 | "code": "function foo(a, b,) { return a + b }\n\nassert(\n\tfoo(1, 2,) === 3\n)\n" 122 | }, 123 | { 124 | "feature": "es3-function-scope", 125 | "code": "var foo = function $babel_features_es3_function_scope$() {}\n\nassert(\n\ttypeof $babel_features_es3_function_scope$ === \"undefined\"\n)\n" 126 | }, 127 | { 128 | "feature": "es2015-generators", 129 | "code": "function* g() {\n\tyield 1\n\tyield 2\n\tyield 3\n}\nvar foo = g()\n\nassert(\n\tfoo.next().value === 1\n)\nassert(\n\tfoo.next().value === 2\n)\nassert(\n\tfoo.next().value === 3\n)\nassert(\n\tfoo.next().done\n)\n\nvar result = function* () { return 1 }().next()\n\nassert(\n\tresult.done && result.value === 1\n)\n" 130 | }, 131 | { 132 | "feature": "es2015-generator-return", 133 | "code": "var closed\nfunction* g() {\n\ttry {\n\t\tclosed = false\n\t\twhile (true) yield\n\t} finally {\n\t\tclosed = true\n\t}\n}\nvar foo = g()\nfoo.next()\nvar result = foo.return('ok')\n\nassert(\n\tresult.done && result.value === 'ok' && closed\n)\n\nresult = foo.next()\n\nassert(\n\tresult.done && result.value === undefined\n)\n\nresult = function* () {}().return('ok2')\n\nassert(\n\tresult.done && result.value === 'ok2'\n)\n" 134 | }, 135 | { 136 | "feature": "async-functions", 137 | "code": "async function foo(x) {\n\treturn await x\n}\n\nvar called = false\nvar p = foo({\n\tthen: function () {\n\t\tcalled = true\n\t\tthrow 'test async functions'\n\t}\n})\n\nassert(typeof p.then === 'function')\nassert(called)\n" 138 | }, 139 | { 140 | "feature": "async-generators", 141 | "code": "async function* foo(x) {\n\treturn await x\n}\n" 142 | }, 143 | { 144 | "feature": "function-sent", 145 | "code": "function* g() {\n\tassert(function.sent === 1)\n\tyield\n\tassert(function.sent === 2)\n\tvar x = yield\n\tassert(function.sent === x)\n}\n\nvar test = g()\ntest.next(1)\ntest.next(2)\ntest.next(Math.random())\n" 146 | }, 147 | { 148 | "feature": "object-rest-spread", 149 | "code": "var {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4}\nassert(Object.keys(z).length === 2 && z.a === 3 && z.b === 4)\n\nvar o = {x, y, ...z}\nassert(Object.keys(o).length === 4 && o.a === 3 && o.b === 4)\n" 150 | } 151 | ] 152 | 153 | function test() { 154 | var result = {} 155 | for (var i = 0; i < tests.length; ++i) { 156 | var name = tests[i].feature 157 | var code = tests[i].code 158 | result[name] = testFeature(code) || testFeature(code, true) 159 | } 160 | return result 161 | } 162 | 163 | function testFeature(code, strict) { 164 | if (strict) code = '"use strict";' + code 165 | try { 166 | var r 167 | new Function('assert', code)(function assert(test) { 168 | if (r === false) return 169 | r = !!test 170 | }) 171 | if (r === undefined) throw new Error('no assert for ' + f) 172 | if (r) return strict ? 'strict' : true 173 | } catch (e) {} 174 | return false 175 | } 176 | 177 | 178 | var enumerable = {}.propertyIsEnumerable 179 | var PREFIX = 'transform-' 180 | 181 | function options(opts) { 182 | if (opts === undefined) opts = {} 183 | var strict = opts.strict === undefined ? true : !!opts.strict 184 | var modules = opts.modules === undefined ? true : !!opts.modules 185 | 186 | var plugins = [] 187 | var testResult = test() 188 | var regeneratorOptions = {generators: false, async: false, asyncGenerators: false} 189 | for (var f in testResult) { 190 | if (!enumerable.call(testResult, f)) continue 191 | if (testResult[f] === true) continue 192 | if (testResult[f] === 'strict' && strict) continue 193 | switch (f) { 194 | case 'es2015-constants': 195 | plugins.push('check-' + f) 196 | break 197 | case 'trailing-function-commas': 198 | case 'function-sent': 199 | plugins.push('syntax-' + f) 200 | break 201 | case 'object-rest-spread': 202 | plugins.push(PREFIX + f) 203 | // currently transform-object-rest-spread only enable syntax, 204 | // need destructuring transform, 205 | // also need parameters transform for destructuring function parameters 206 | if (testResult['es2015-destructuring']) { 207 | plugins.push( PREFIX + 'es2015-destructuring', 208 | PREFIX + 'es2015-parameters') 209 | } 210 | break 211 | case 'es3-function-scope': 212 | plugins.push('jscript') 213 | break 214 | case 'es2015-generators': 215 | regeneratorOptions.generators = true 216 | break 217 | case 'es2015-generator-return': 218 | if (testResult['es2015-generators']) plugins.push(PREFIX + f) 219 | break 220 | case 'async-functions': 221 | plugins.push('syntax-' + f) 222 | regeneratorOptions.async = true 223 | break 224 | case 'async-generators': 225 | plugins.push('syntax-' + f) 226 | regeneratorOptions.asyncGenerators = true 227 | break 228 | default: 229 | plugins.push(PREFIX + f) 230 | } 231 | } 232 | plugins.push([PREFIX + 'regenerator', regeneratorOptions]) 233 | 234 | if (modules) { 235 | var m = PREFIX + 'es2015-modules-' + moduleFormat() 236 | if (strict) plugins.push(m) 237 | else plugins.push([m, {strict: false}]) 238 | } else if (strict) { 239 | plugins.push(PREFIX + 'strict-mode') 240 | } 241 | 242 | return {plugins: plugins} 243 | } 244 | 245 | function moduleFormat() { 246 | if (typeof System === 'function' && typeof System.register === 'function') return 'systemjs' 247 | if (typeof define === 'function' && define.amd) return 'amd' 248 | if (typeof require === 'function' && typeof exports === 'object') return 'commonjs' 249 | return 'umd' 250 | } 251 | 252 | }(this) 253 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | 4 | var tests = require('./tests') 5 | 6 | /* BEGIN */ 7 | 8 | function test() { 9 | var result = {} 10 | for (var i = 0; i < tests.length; ++i) { 11 | var name = tests[i].feature 12 | var code = tests[i].code 13 | result[name] = testFeature(code) || testFeature(code, true) 14 | } 15 | return result 16 | } 17 | 18 | function testFeature(code, strict) { 19 | if (strict) code = '"use strict";' + code 20 | try { 21 | var r 22 | new Function('assert', code)(function assert(test) { 23 | if (r === false) return 24 | r = !!test 25 | }) 26 | if (r === undefined) throw new Error('no assert for ' + f) 27 | if (r) return strict ? 'strict' : true 28 | } catch (e) {} 29 | return false 30 | } 31 | 32 | 33 | var enumerable = {}.propertyIsEnumerable 34 | var PREFIX = 'transform-' 35 | 36 | function options(opts) { 37 | if (opts === undefined) opts = {} 38 | var strict = opts.strict === undefined ? true : !!opts.strict 39 | var modules = opts.modules === undefined ? true : !!opts.modules 40 | 41 | var plugins = [] 42 | var testResult = test() 43 | var regeneratorOptions = {generators: false, async: false, asyncGenerators: false} 44 | for (var f in testResult) { 45 | if (!enumerable.call(testResult, f)) continue 46 | if (testResult[f] === true) continue 47 | if (testResult[f] === 'strict' && strict) continue 48 | switch (f) { 49 | case 'es2015-constants': 50 | plugins.push('check-' + f) 51 | break 52 | case 'trailing-function-commas': 53 | case 'function-sent': 54 | plugins.push('syntax-' + f) 55 | break 56 | case 'object-rest-spread': 57 | plugins.push(PREFIX + f) 58 | // currently transform-object-rest-spread only enable syntax, 59 | // need destructuring transform, 60 | // also need parameters transform for destructuring function parameters 61 | if (testResult['es2015-destructuring']) { 62 | plugins.push( PREFIX + 'es2015-destructuring', 63 | PREFIX + 'es2015-parameters') 64 | } 65 | break 66 | case 'es3-function-scope': 67 | plugins.push('jscript') 68 | break 69 | case 'es2015-generators': 70 | regeneratorOptions.generators = true 71 | break 72 | case 'es2015-generator-return': 73 | if (testResult['es2015-generators']) plugins.push(PREFIX + f) 74 | break 75 | case 'async-functions': 76 | plugins.push('syntax-' + f) 77 | regeneratorOptions.async = true 78 | break 79 | case 'async-generators': 80 | plugins.push('syntax-' + f) 81 | regeneratorOptions.asyncGenerators = true 82 | break 83 | default: 84 | plugins.push(PREFIX + f) 85 | } 86 | } 87 | plugins.push([PREFIX + 'regenerator', regeneratorOptions]) 88 | 89 | if (modules) { 90 | var m = PREFIX + 'es2015-modules-' + moduleFormat() 91 | if (strict) plugins.push(m) 92 | else plugins.push([m, {strict: false}]) 93 | } else if (strict) { 94 | plugins.push(PREFIX + 'strict-mode') 95 | } 96 | 97 | return {plugins: plugins} 98 | } 99 | 100 | function moduleFormat() { 101 | if (typeof System === 'function' && typeof System.register === 'function') return 'systemjs' 102 | if (typeof define === 'function' && define.amd) return 'amd' 103 | if (typeof require === 'function' && typeof exports === 'object') return 'commonjs' 104 | return 'umd' 105 | } 106 | 107 | /* END */ 108 | 109 | exports.test = test 110 | exports.options = options 111 | -------------------------------------------------------------------------------- /lib/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var fs = require('fs') 4 | var yaml = require('js-yaml') 5 | 6 | module.exports = 7 | yaml.safeLoad(fs.readFileSync(__dirname + '/../src/features.yaml', 'utf-8')) 8 | .map(function (f) { 9 | return { 10 | feature: f, 11 | code: fs.readFileSync(__dirname + '/../src/features/' + f + '.js', 'utf-8') 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-features", 3 | "version": "2.0.1", 4 | "description": "Test babel features, can be used to generate babel options for specific compilation targets", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "prepublish": "node build", 8 | "test": "node test", 9 | "test-es2015": "BABEL_DISABLE_CACHE=1 babel-node --presets es2015 test", 10 | "test-features": "BABEL_DISABLE_CACHE=1 babel-node --presets features test", 11 | "test-generator": "BABEL_DISABLE_CACHE=1 babel-node test -w transform-async-to-generator,transform-es2015-generator-return", 12 | "test-function-name": "BABEL_DISABLE_CACHE=1 babel-node --plugins transform-es2015-function-name test" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/hax/babel-features.git" 17 | }, 18 | "keywords": [ 19 | "babel" 20 | ], 21 | "author": "HE Shi-Jun ", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/hax/babel-features/issues" 25 | }, 26 | "homepage": "https://github.com/hax/babel-features#readme", 27 | "devDependencies": { 28 | "babel-cli": "^6.16.0", 29 | "babel-plugin-syntax-function-sent": "^6.8.0", 30 | "babel-plugin-transform-es2015-generator-return": "^1.2.0", 31 | "babel-polyfill": "^6.16.0", 32 | "babel-preset-es2015": "^6.18.0", 33 | "babel-preset-features": "^2.0.2", 34 | "babel-preset-stage-0": "^6.16.0" 35 | }, 36 | "dependencies": { 37 | "js-yaml": "^3.7.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/features.yaml: -------------------------------------------------------------------------------- 1 | # ES3 2 | - es3-member-expression-literals 3 | - es3-property-literals 4 | 5 | # ES5 6 | - es5-property-mutators 7 | 8 | # ES2015 9 | - es2015-arrow-functions 10 | - es2015-block-scoped-functions 11 | - es2015-block-scoping 12 | - es2015-classes 13 | - es2015-computed-properties 14 | - es2015-constants 15 | - es2015-destructuring 16 | - es2015-duplicate-keys 17 | - es2015-for-of 18 | - es2015-function-name 19 | - es2015-literals 20 | - es2015-object-super 21 | - es2015-parameters 22 | - es2015-shorthand-properties 23 | - es2015-spread 24 | - es2015-sticky-regex 25 | - es2015-template-literals 26 | - es2015-typeof-symbol 27 | - es2015-unicode-regex 28 | 29 | # Stage 3 30 | - exponentiation-operator # ES2016 31 | - trailing-function-commas # Stage 3 32 | 33 | # Special features 34 | - es3-function-scope 35 | - es2015-generators 36 | - es2015-generator-return 37 | - async-functions # Stage 3 38 | - async-generators # Stage 2 39 | - function-sent # Stage 2 40 | - object-rest-spread # Stage 2 41 | -------------------------------------------------------------------------------- /src/features/async-functions.js: -------------------------------------------------------------------------------- 1 | async function foo(x) { 2 | return await x 3 | } 4 | 5 | var called = false 6 | var p = foo({ 7 | then: function () { 8 | called = true 9 | throw 'test async functions' 10 | } 11 | }) 12 | 13 | assert(typeof p.then === 'function') 14 | assert(called) 15 | -------------------------------------------------------------------------------- /src/features/async-generators.js: -------------------------------------------------------------------------------- 1 | async function* foo(x) { 2 | return await x 3 | } 4 | -------------------------------------------------------------------------------- /src/features/es2015-arrow-functions.js: -------------------------------------------------------------------------------- 1 | var foo = () => true 2 | 3 | assert( 4 | foo() 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-block-scoped-functions.js: -------------------------------------------------------------------------------- 1 | var outer = foo() 2 | function foo() { return 1 } 3 | 4 | { 5 | var inner = foo() 6 | function foo() { return 0 } 7 | } 8 | 9 | assert( 10 | inner === 0 && outer === 1 11 | ) 12 | -------------------------------------------------------------------------------- /src/features/es2015-block-scoping.js: -------------------------------------------------------------------------------- 1 | let foo = 0, bar = 1 2 | foo += bar 3 | { 4 | const bar = 2 5 | foo += bar 6 | } 7 | 8 | assert( 9 | foo === 3 10 | ) 11 | 12 | switch (0) { 13 | default: 14 | const bar = 3 15 | foo += bar 16 | } 17 | 18 | assert( 19 | foo === 6 20 | ) 21 | -------------------------------------------------------------------------------- /src/features/es2015-classes.js: -------------------------------------------------------------------------------- 1 | class A { 2 | foo() { return false } 3 | } 4 | class B extends A { 5 | bar() { return !super.foo() } 6 | } 7 | 8 | assert( 9 | new B().bar() 10 | ) 11 | -------------------------------------------------------------------------------- /src/features/es2015-computed-properties.js: -------------------------------------------------------------------------------- 1 | var foo = {["b" + "ar"]: true} 2 | 3 | assert( 4 | foo.bar 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-constants.js: -------------------------------------------------------------------------------- 1 | const foo = true 2 | 3 | try { 4 | foo = false 5 | } catch (e) { 6 | assert( 7 | foo 8 | ) 9 | } 10 | 11 | assert( 12 | foo 13 | ) 14 | -------------------------------------------------------------------------------- /src/features/es2015-destructuring.js: -------------------------------------------------------------------------------- 1 | function foo({a, b: b1, c: [x, , y]}) { 2 | return a === 1 && b1 === 2 && x === 3 && y === 5 3 | } 4 | 5 | assert( 6 | foo({a: 1, b: 2, c: [3, 4, 5]}) 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-duplicate-keys.js: -------------------------------------------------------------------------------- 1 | var x = {a: 5, a: 6} 2 | assert(x.a === 6) 3 | 4 | var y = { 5 | get a() { return 1 }, 6 | a: 2, 7 | } 8 | assert(y.a === 2) 9 | -------------------------------------------------------------------------------- /src/features/es2015-for-of.js: -------------------------------------------------------------------------------- 1 | var o = {} 2 | o[Symbol.iterator] = function () { 3 | var i = 0 4 | return { 5 | next: function () { 6 | if (i < 3) return {value: ++i} 7 | return {done: true} 8 | } 9 | } 10 | } 11 | var sum = 0 12 | for (var x of o) { 13 | sum += x 14 | } 15 | 16 | assert( 17 | sum === 6 18 | ) 19 | -------------------------------------------------------------------------------- /src/features/es2015-function-name.js: -------------------------------------------------------------------------------- 1 | var foo = function () {} 2 | 3 | assert( 4 | foo.name === 'foo' 5 | ) 6 | 7 | var obj = { bar: function () {} } 8 | 9 | assert( 10 | obj.bar.name === 'bar' 11 | ) 12 | -------------------------------------------------------------------------------- /src/features/es2015-generator-return.js: -------------------------------------------------------------------------------- 1 | var closed 2 | function* g() { 3 | try { 4 | closed = false 5 | while (true) yield 6 | } finally { 7 | closed = true 8 | } 9 | } 10 | var foo = g() 11 | foo.next() 12 | var result = foo.return('ok') 13 | 14 | assert( 15 | result.done && result.value === 'ok' && closed 16 | ) 17 | 18 | result = foo.next() 19 | 20 | assert( 21 | result.done && result.value === undefined 22 | ) 23 | 24 | result = function* () {}().return('ok2') 25 | 26 | assert( 27 | result.done && result.value === 'ok2' 28 | ) 29 | -------------------------------------------------------------------------------- /src/features/es2015-generators.js: -------------------------------------------------------------------------------- 1 | function* g() { 2 | yield 1 3 | yield 2 4 | yield 3 5 | } 6 | var foo = g() 7 | 8 | assert( 9 | foo.next().value === 1 10 | ) 11 | assert( 12 | foo.next().value === 2 13 | ) 14 | assert( 15 | foo.next().value === 3 16 | ) 17 | assert( 18 | foo.next().done 19 | ) 20 | 21 | var result = function* () { return 1 }().next() 22 | 23 | assert( 24 | result.done && result.value === 1 25 | ) 26 | -------------------------------------------------------------------------------- /src/features/es2015-literals.js: -------------------------------------------------------------------------------- 1 | assert( 2 | 0b111 === 0o7 3 | ) 4 | 5 | assert( 6 | '\u{20bb7}' === '𠮷' 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-object-super.js: -------------------------------------------------------------------------------- 1 | var a = { foo() { return 'f' } } 2 | var b = { foo() { return super.foo() + 'oo' } } 3 | Object.setPrototypeOf(b, a) 4 | 5 | assert( 6 | b.foo() === 'foo' 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-parameters.js: -------------------------------------------------------------------------------- 1 | function foo(x = true) { 2 | return x 3 | } 4 | 5 | assert( 6 | foo() 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-shorthand-properties.js: -------------------------------------------------------------------------------- 1 | var foo = true 2 | var bar = {foo} 3 | 4 | assert( 5 | bar.foo 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es2015-spread.js: -------------------------------------------------------------------------------- 1 | function foo(a, b, c) { 2 | return a + b === c 3 | } 4 | var list = [2, 3] 5 | 6 | assert( 7 | foo(1, ...list) 8 | ) 9 | -------------------------------------------------------------------------------- /src/features/es2015-sticky-regex.js: -------------------------------------------------------------------------------- 1 | // NOTE: Up to now, there is no runtime polyfill/shim available for sticky, 2 | // So this test never pass even with babel plugin applied. 3 | 4 | assert( 5 | /o+/y.sticky 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es2015-template-literals.js: -------------------------------------------------------------------------------- 1 | var foo = "foo" 2 | var bar = `${foo}bar` 3 | 4 | assert( 5 | bar === "foobar" 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es2015-typeof-symbol.js: -------------------------------------------------------------------------------- 1 | assert( 2 | typeof Symbol() === 'symbol' 3 | ) 4 | -------------------------------------------------------------------------------- /src/features/es2015-unicode-regex.js: -------------------------------------------------------------------------------- 1 | var re = /^.$/u 2 | 3 | assert( 4 | re.test("𠮷") 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es3-function-scope.js: -------------------------------------------------------------------------------- 1 | var foo = function $babel_features_es3_function_scope$() {} 2 | 3 | assert( 4 | typeof $babel_features_es3_function_scope$ === "undefined" 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es3-member-expression-literals.js: -------------------------------------------------------------------------------- 1 | var foo = {} 2 | foo.if = true 3 | 4 | assert( 5 | foo.if 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es3-property-literals.js: -------------------------------------------------------------------------------- 1 | var foo = {if: true} 2 | 3 | assert( 4 | foo["if"] 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es5-property-mutators.js: -------------------------------------------------------------------------------- 1 | var foo = { 2 | get bar() { return true } 3 | } 4 | 5 | assert( 6 | foo.bar 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/exponentiation-operator.js: -------------------------------------------------------------------------------- 1 | assert( 2 | 2 ** 10 === 1024 3 | ) 4 | -------------------------------------------------------------------------------- /src/features/function-sent.js: -------------------------------------------------------------------------------- 1 | function* g() { 2 | assert(function.sent === 1) 3 | yield 4 | assert(function.sent === 2) 5 | var x = yield 6 | assert(function.sent === x) 7 | } 8 | 9 | var test = g() 10 | test.next(1) 11 | test.next(2) 12 | test.next(Math.random()) 13 | -------------------------------------------------------------------------------- /src/features/object-rest-spread.js: -------------------------------------------------------------------------------- 1 | var {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4} 2 | assert(Object.keys(z).length === 2 && z.a === 3 && z.b === 4) 3 | 4 | var o = {x, y, ...z} 5 | assert(Object.keys(o).length === 4 && o.a === 3 && o.b === 4) 6 | -------------------------------------------------------------------------------- /src/features/trailing-function-commas.js: -------------------------------------------------------------------------------- 1 | function foo(a, b,) { return a + b } 2 | 3 | assert( 4 | foo(1, 2,) === 3 5 | ) 6 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

 8 | 
26 | 


--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
 1 | 'use strict'
 2 | 
 3 | var f = require('./lib')
 4 | console.log('Node.js:', process.versions.node)
 5 | console.log('V8:', process.versions.v8)
 6 | console.log()
 7 | 
 8 | console.log('babel features test result:')
 9 | console.log(f.test())
10 | console.log()
11 | 
12 | console.log('recommended plugins:')
13 | console.log(f.options().plugins)
14 | console.log()
15 | 


--------------------------------------------------------------------------------