├── .editorconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── lib ├── copyright-header.txt └── index.js ├── package.json ├── scripts ├── build-core.js └── node-tests.js └── tests ├── qunit.config.js └── tests.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = tab 8 | indent_size = 4 9 | 10 | [*.md] 11 | indent_style = space 12 | indent_size = 4 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .coveralls.yml 2 | .history 3 | node_modules/ 4 | dist/ 5 | coverage/ 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .npmignore 2 | .gitignore 3 | .coveralls.yml 4 | .history 5 | node_modules/ 6 | coverage/ 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - 8 5 | - 10 6 | 7 | git: 8 | depth: 5 9 | 10 | cache: 11 | directories: 12 | - node_modules 13 | 14 | env: 15 | - TEST_PACKAGE=true 16 | branches: 17 | only: 18 | - master 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Kyle Simpson 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # (DEPRECATED) ESLint Rule: arrow-require-this 2 | 3 | ---- 4 | ---- 5 | ---- 6 | 7 | **DEPRECATION NOTICE: This project has been deprecated and merged into [eslint-plugin-proper-arrows](https://github.com/getify/eslint-plugin-proper-arrows).** 8 | 9 | ---- 10 | ---- 11 | ---- 12 | 13 | [![Build Status](https://travis-ci.org/getify/eslint-plugin-arrow-require-this.svg?branch=master)](https://travis-ci.org/getify/eslint-plugin-arrow-require-this) 14 | [![npm Module](https://badge.fury.io/js/%40getify%2Feslint-plugin-arrow-require-this.svg)](https://www.npmjs.org/package/@getify/eslint-plugin-arrow-require-this) 15 | [![Dependencies](https://david-dm.org/getify/eslint-plugin-arrow-require-this.svg)](https://david-dm.org/getify/eslint-plugin-arrow-require-this) 16 | [![devDependencies](https://david-dm.org/getify/eslint-plugin-arrow-require-this/dev-status.svg)](https://david-dm.org/getify/eslint-plugin-arrow-require-this?type=dev) 17 | [![Coverage Status](https://coveralls.io/repos/github/getify/eslint-plugin-arrow-require-this/badge.svg?branch=master)](https://coveralls.io/github/getify/eslint-plugin-arrow-require-this?branch=master) 18 | 19 | ## Overview 20 | 21 | The **arrow-require-this** ESLint Rule requires `=>` arrow functions to reference the `this` keyword. It also supports a "never" configuration, which means that `=>` arrow functions should never use `this`. 22 | 23 | The main purpose of this rule is to prevent usage of `=>` arrow functions as just function shorthand (i.e., `arr.map(x => x * 2)`), which some argue is a misusage. The opinion follows that: the concise syntax (with all its myriad variations) can harm readability, so instead `=>` arrow functions should only be used when the "lexical this" behavior is needed. 24 | 25 | Since `=>` arrow functions don't have their own `this`, they treat any `this` reference as a normal variable (not a special keyword). That means `this` is just lexically looked up through any parent scopes until a valid definition of `this` is found -- from a normal non-arrow function, or finally in the global scope itself. 26 | 27 | Such `this` behavior is referred to as "lexical this", and it is one of the main design characteristics for `=>` arrow functions. 28 | 29 | For example: 30 | 31 | ```js 32 | var o = { 33 | id: 42, 34 | getData() { 35 | ajax("https://some.tld/api",() => console.log(this.id)); 36 | } 37 | }; 38 | 39 | o.getData(); // 42 40 | ``` 41 | 42 | In this snippet, the `=>` arrow function is inside a normal function and therefore looks up and adopts its `this` (aka, "lexical this") -- which is set to the `o` object by the `o.getData()` call. Therefore, the **arrow-require-this** rule would not report an error. 43 | 44 | By contrast, the **arrow-require-this** rule *would* report an error for: 45 | 46 | ```js 47 | var o = { 48 | id: 42, 49 | getData() { 50 | ajax("https://some.tld/api",() => console.log(o.id)); 51 | } 52 | }; 53 | 54 | o.getData(); // 42 55 | ``` 56 | 57 | Here, the `=>` arrow function is lexically closed over the `o` rather than using "lexical this", so it can be considered a misusage of the `=>` arrow function merely for shorthand; rather, the callback should have just been a regular named function expression (ie, `function onResp(){ console.log(o.id); }`). 58 | 59 | To pass the **arrow-require-this** rule without a reported error, all `=>` arrow functions must reference a `this` somewhere in their concise expression body or full `{ .. }` function body (or in its nested `=>` arrow functions when using "nested" configuration). 60 | 61 | ## Enabling The Plugin 62 | 63 | To use **arrow-require-this**, load it as a plugin into ESLint and [configure the rule](#rule-configuration) as desired. 64 | 65 | ### `.eslintrc.json` 66 | 67 | To load the plugin and enable its rule via a local or global `.eslintrc.json` configuration file: 68 | 69 | ```json 70 | "plugins": [ 71 | "@getify/arrow-require-this" 72 | ], 73 | "rules": { 74 | "@getify/arrow-require-this/all": "error" 75 | } 76 | ``` 77 | 78 | ### `package.json` 79 | 80 | To load the plugin and enable its rule via a project's `package.json`: 81 | 82 | ```json 83 | "eslintConfig": { 84 | "plugins": [ 85 | "@getify/arrow-require-this" 86 | ], 87 | "rules": { 88 | "@getify/arrow-require-this/all": "error" 89 | } 90 | } 91 | ``` 92 | 93 | ### ESLint CLI parameters 94 | 95 | To load the plugin and enable its rule via ESLint CLI parameters, use `--plugin` and `--rule`: 96 | 97 | ```cmd 98 | eslint .. --plugin='@getify/arrow-require-this' --rule='@getify/arrow-require-this/all: error' .. 99 | ``` 100 | 101 | ```cmd 102 | eslint .. --plugin='@getify/arrow-require-this' --rule='@getify/arrow-require-this/all: [error,always]' .. 103 | ``` 104 | 105 | ### ESLint Node API 106 | 107 | To use this plugin in Node.js with the ESLint API, require the npm module, and then (for example) pass the rule's definition to `Linter#defineRule(..)`, similar to: 108 | 109 | ```js 110 | var arrowRequireThis = require("@getify/eslint-plugin-arrow-require-this"); 111 | 112 | // .. 113 | 114 | var eslinter = new (require("eslint").Linter)(); 115 | 116 | eslinter.defineRule("@getify/arrow-require-this/all",arrowRequireThis.rules.all); 117 | ``` 118 | 119 | Then lint some code like this: 120 | 121 | ```js 122 | eslinter.verify(".. some code ..",{ 123 | rules: { 124 | "@getify/arrow-require-this/all": ["error","always"] 125 | } 126 | }); 127 | ``` 128 | 129 | ### Inline Comments 130 | 131 | Once the plugin is loaded, the rule can be configured using inline code comments if desired, such as: 132 | 133 | ```js 134 | /* eslint "@getify/arrow-require-this/all": "error" */ 135 | ``` 136 | 137 | ```js 138 | /* eslint "@getify/arrow-require-this/all": ["error","always"] */ 139 | ``` 140 | 141 | ## Rule Configuration 142 | 143 | The **arrow-require-this** rule can be configured in three modes: `"nested"` (default), `"always"`, and `"never"`. 144 | 145 | `"nested"` (default) permits a `this` to appear lower in a nested `=>` arrow function (i.e., `x = y => z => this.foo(z)`), as long as there is no non-arrow function boundary crossed. 146 | 147 | `"always"` is more strict, requiring every single `=>` arrow function to have its own `this` reference. 148 | 149 | `"never"` is the reverse, which is that all `=>` arrow functions are forbidden from using `this`. 150 | 151 | ### Configuration: `"nested"` 152 | 153 | To configure this rule mode (default): 154 | 155 | ```js 156 | "@getify/arrow-require-this/all": "error" 157 | ``` 158 | 159 | ```js 160 | "@getify/arrow-require-this/all": [ "error", "nested" ] 161 | ``` 162 | 163 | This rule mode allows a `this` to appear either in the `=>` arrow function, or nested in a chain of `=>` arrow functions, as long as there is no non-arrow function boundary crossed in between. 164 | 165 | These `=>` arrow functions will all pass the rule: 166 | 167 | ```js 168 | var a = b => this.foo(b); 169 | 170 | var c = d => e => this.foo(e); 171 | 172 | var f = (g = h => this.foo(h)) => g; 173 | ``` 174 | 175 | These `=>` arrow functions will each fail the rule: 176 | 177 | ```js 178 | var a = b => foo(b); 179 | 180 | var c = d => this.foo(e => e); 181 | 182 | var f = (g = h => h) => this.foo(g); 183 | 184 | var h = i => function(){ return j => this.foo(j); }; 185 | ``` 186 | 187 | ### Configuration: `"always"` 188 | 189 | To configure this rule mode: 190 | 191 | ```js 192 | "@getify/arrow-require-this/all": [ "error", "always" ] 193 | ``` 194 | 195 | This rule mode requires a `this` reference to appear in every single `=>` arrow function (e.g., nested `this` is not sufficient). 196 | 197 | These `=>` arrow functions will all pass the rule: 198 | 199 | ```js 200 | var a = b => this.foo(b); 201 | 202 | var c = d => this.foo(e => this.bar(e)); 203 | 204 | var f = (g = h => this.foo(h)) => this.bar(g); 205 | ``` 206 | 207 | These `=>` arrow functions will each fail the rule: 208 | 209 | ```js 210 | var a = b => foo(b); 211 | 212 | var c = d => e => this.foo(e); 213 | 214 | var f = g => this.foo(h => h); 215 | 216 | var i = (j = k => k) => this.foo(j); 217 | ``` 218 | 219 | **Note:** In each of the above examples, at least one of the `=>` arrow functions does not have its own `this`, hence the mode's rule failure (which doesn't consider nested `this`). 220 | 221 | ### Configuration: `"never"` 222 | 223 | To configure this rule mode: 224 | 225 | ```js 226 | "@getify/arrow-require-this/all": [ "error", "never" ] 227 | ``` 228 | 229 | This rule mode **forbids** a `this` reference from appearing in any `=>` arrow function. 230 | 231 | These `=>` arrow functions will all pass the rule: 232 | 233 | ```js 234 | var a = b => foo(b); 235 | 236 | var c = d => foo(e => bar(e)); 237 | 238 | var f = (g = h => foo(h)) => bar(g); 239 | ``` 240 | 241 | These `=>` arrow functions will each fail the rule: 242 | 243 | ```js 244 | var a = b => this.foo(b); 245 | 246 | var c = d => e => this.foo(e); 247 | 248 | var f = g => foo(h => this.bar(h)); 249 | ``` 250 | 251 | ## npm Package 252 | 253 | To use this plugin with a global install of ESLint (recommended): 254 | 255 | ```cmd 256 | npm install -g @getify/eslint-plugin-arrow-require-this 257 | ``` 258 | 259 | To use this plugin with a local install of ESLint: 260 | 261 | ```cmd 262 | npm install @getify/eslint-plugin-arrow-require-this 263 | ``` 264 | 265 | ## Builds 266 | 267 | [![Build Status](https://travis-ci.org/getify/eslint-plugin-arrow-require-this.svg?branch=master)](https://travis-ci.org/getify/eslint-plugin-arrow-require-this) 268 | [![npm Module](https://badge.fury.io/js/%40getify%2Feslint-plugin-arrow-require-this.svg)](https://www.npmjs.org/package/@getify/eslint-plugin-arrow-require-this) 269 | 270 | If you need to bundle/distribute this eslint plugin, use `dist/arrow-require-this.js`, which comes pre-built with the npm package distribution; you shouldn't need to rebuild it under normal circumstances. 271 | 272 | However, if you download this repository via Git: 273 | 274 | 1. The included build utility (`scripts/build-core.js`) builds (and minifies) `dist/arrow-require-this.js` from source. 275 | 276 | 2. To install the build and test dependencies, run `npm install` from the project root directory. 277 | 278 | 3. To manually run the build utility with npm: 279 | 280 | ```cmd 281 | npm run build 282 | ``` 283 | 284 | 4. To run the build utility directly without npm: 285 | 286 | ```cmd 287 | node scripts/build-core.js 288 | ``` 289 | 290 | ## Tests 291 | 292 | A comprehensive test suite is included in this repository, as well as the npm package distribution. The default test behavior runs the test suite against `lib/index.js`. 293 | 294 | 1. The included Node.js test utility (`scripts/node-tests.js`) runs the test suite. 295 | 296 | 2. Ensure the test dependencies are installed by running `npm install` from the project root directory. 297 | 298 | - **Note:** Starting with npm v5, the test utility is **not** run automatically during this `npm install`. With npm v4 and before, the test utility automatically runs at this point. 299 | 300 | 3. To run the test utility with npm: 301 | 302 | ```cmd 303 | npm test 304 | ``` 305 | 306 | Other npm test scripts: 307 | 308 | * `npm run test:dist` will run the test suite against `dist/arrow-require-this.js` instead of the default of `lib/index.js`. 309 | 310 | * `npm run test:package` will run the test suite as if the package had just been installed via npm. This ensures `package.json`:`main` properly references `dist/arrow-require-this.js` for inclusion. 311 | 312 | * `npm run test:all` will run all three modes of the test suite. 313 | 314 | 4. To run the test utility directly without npm: 315 | 316 | ```cmd 317 | node scripts/node-tests.js 318 | ``` 319 | 320 | ### Test Coverage 321 | 322 | [![Coverage Status](https://coveralls.io/repos/github/getify/eslint-plugin-arrow-require-this/badge.svg?branch=master)](https://coveralls.io/github/getify/eslint-plugin-arrow-require-this?branch=master) 323 | 324 | If you have [Istanbul](https://github.com/gotwarlost/istanbul) already installed on your system (requires v1.0+), you can use it to check the test coverage: 325 | 326 | ```cmd 327 | npm run coverage 328 | ``` 329 | 330 | Then open up `coverage/lcov-report/index.html` in a browser to view the report. 331 | 332 | To run Istanbul directly without npm: 333 | 334 | ```cmd 335 | istanbul cover scripts/node-tests.js 336 | ``` 337 | 338 | **Note:** The npm script `coverage:report` is only intended for use by project maintainers; it sends coverage reports to [Coveralls](https://coveralls.io/). 339 | 340 | ## License 341 | 342 | All code and documentation are (c) 2019 Kyle Simpson and released under the [MIT License](http://getify.mit-license.org/). A copy of the MIT License [is also included](LICENSE.txt). 343 | -------------------------------------------------------------------------------- /lib/copyright-header.txt: -------------------------------------------------------------------------------- 1 | /*! @getify/eslint-plugin-arrow-require-this 2 | v${version} (c) ${year} Kyle Simpson 3 | MIT License: http://getify.mit-license.org 4 | */ 5 | 6 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | rules: { 5 | all: { 6 | meta: { 7 | type: "problem", 8 | docs: { 9 | description: "Require arrow functions to reference the 'this' keyword", 10 | category: "Possible Errors", 11 | url: "https://github.com/getify/eslint-plugin-arrow-require-this", 12 | }, 13 | schema: [ 14 | { 15 | enum: ["always", "nested"], 16 | }, 17 | ], 18 | messages: { 19 | noThis: "Required 'this' not found in arrow function", 20 | noThisNested: "Required 'this' not found in arrow function (or nested arrow functions)", 21 | neverThis: "Forbidden 'this' found in arrow function", 22 | }, 23 | }, 24 | create(context) { 25 | var alwaysThis = (context.options[0] === "always"); 26 | var nestedThis = (context.options[0] === "nested" || !("0" in context.options)); 27 | var neverThis = (context.options[0] === "never"); 28 | var thisFoundIn = new Set(); 29 | 30 | return { 31 | "ThisExpression": function enter(node) { 32 | var parentArrow = getParentArrowFunction(context.getAncestors()); 33 | thisFoundIn.add(parentArrow); 34 | }, 35 | "ArrowFunctionExpression:exit": function exit(node) { 36 | var foundThis = thisFoundIn.has(node); 37 | 38 | if (foundThis && neverThis) { 39 | context.report({ 40 | node: node, 41 | messageId: "neverThis", 42 | }); 43 | } 44 | else if (!foundThis && !neverThis) { 45 | context.report({ 46 | node: node, 47 | messageId: alwaysThis ? "noThis" : "noThisNested", 48 | }); 49 | } 50 | // are we tracking nested `this`? 51 | else if (foundThis && nestedThis) { 52 | let parentArrow = getParentArrowFunction(context.getAncestors()); 53 | if (parentArrow) { 54 | thisFoundIn.add(parentArrow); 55 | } 56 | } 57 | }, 58 | }; 59 | }, 60 | }, 61 | }, 62 | }; 63 | 64 | function getParentArrowFunction(nodes) { 65 | for (let node of [...nodes].reverse()) { 66 | // bail if we find a function boundary that's not an arrow 67 | if ( 68 | node.type == "FunctionExpression" || 69 | node.type == "FunctionDeclaration" 70 | ) { 71 | return; 72 | } 73 | else if (node.type == "ArrowFunctionExpression") { 74 | return node; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@getify/eslint-plugin-arrow-require-this", 3 | "version": "2.0.0", 4 | "description": "(DEPRECATED) -- Please use '@getify/eslint-plugin-proper-arrows' instead", 5 | "main": "./lib/index.js", 6 | "scripts": { 7 | "test": "node scripts/node-tests.js", 8 | "test:dist": "TEST_DIST=true npm test", 9 | "test:package": "TEST_PACKAGE=true npm test", 10 | "test:all": "npm test && npm run test:dist && npm run test:package", 11 | "coverage": "istanbul cover scripts/node-tests.js", 12 | "coverage:report": "npm run coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", 13 | "build-core": "node scripts/build-core.js", 14 | "build": "npm run build-core", 15 | "prepare": "npm run build", 16 | "prepublish": "npm run build && npm run test:all", 17 | "publish": "npm run coverage:report" 18 | }, 19 | "dependencies": {}, 20 | "devDependencies": { 21 | "coveralls": "~3.0.2", 22 | "eslint": "~5.15.0", 23 | "qunit": "~2.9.1", 24 | "terser": "~3.16.1" 25 | }, 26 | "peerDependencies": { 27 | "eslint": ">= 5.0" 28 | }, 29 | "repository": "getify/eslint-plugin-arrow-require-this", 30 | "keywords": [ 31 | "eslint", 32 | "plugin", 33 | "eslintplugin", 34 | "rule", 35 | "arrow", 36 | "this" 37 | ], 38 | "bugs": { 39 | "url": "https://github.com/getify/eslint-plugin-arrow-require-this/issues", 40 | "email": "getify@gmail.com" 41 | }, 42 | "homepage": "https://github.com/getify/eslint-plugin-arrow-require-this", 43 | "author": "Kyle Simpson ", 44 | "license": "MIT" 45 | } 46 | -------------------------------------------------------------------------------- /scripts/build-core.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | "use strict"; 4 | 5 | var fs = require("fs"), 6 | path = require("path"), 7 | ugly = require("terser"), 8 | year = (new Date()).getFullYear(), 9 | 10 | ROOT_DIR = path.join(__dirname,".."), 11 | SRC_DIR = path.join(ROOT_DIR,"lib"), 12 | DIST_DIR = path.join(ROOT_DIR,"dist"), 13 | 14 | LIB_SRC = [ 15 | path.join(SRC_DIR,"index.js"), 16 | ], 17 | LIB_DIST = [ 18 | path.join(DIST_DIR,"arrow-require-this.js"), 19 | ] 20 | ; 21 | 22 | 23 | // *************************** 24 | 25 | console.log("*** Building ESLint Rule (arrow-require-this) ***"); 26 | 27 | // read version number from package.json 28 | var packageJSON = JSON.parse( 29 | fs.readFileSync( 30 | path.join(ROOT_DIR,"package.json"), 31 | { encoding: "utf8" } 32 | ) 33 | ); 34 | var version = packageJSON.version; 35 | 36 | // read copyright-header text, render with version and year 37 | var copyrightHeader = fs.readFileSync( 38 | path.join(SRC_DIR,"copyright-header.txt"), 39 | { encoding: "utf8" } 40 | ).replace(/`/g,""); 41 | copyrightHeader = Function("version","year",`return \`${copyrightHeader}\`;`)( version, year ); 42 | 43 | 44 | // *************************** 45 | 46 | // try to make the dist directory, if needed 47 | try { 48 | fs.mkdirSync(DIST_DIR,0o755); 49 | } 50 | catch (err) { } 51 | 52 | for (let [idx,SRC] of LIB_SRC.entries()) { 53 | let DIST = LIB_DIST[idx]; 54 | 55 | console.log(`Building: ${DIST}`); 56 | 57 | try { 58 | let result = ""; 59 | 60 | result += fs.readFileSync(SRC,{ encoding: "utf8" }); 61 | 62 | result = ugly.minify(result,{ 63 | mangle: { 64 | keep_fnames: true 65 | }, 66 | compress: { 67 | keep_fnames: true 68 | }, 69 | output: { 70 | comments: /^!/ 71 | } 72 | }); 73 | 74 | // was compression successful? 75 | if (!(result && result.code)) { 76 | if (result.error) throw result.error; 77 | else throw result; 78 | } 79 | 80 | // append copyright-header text 81 | result = `${copyrightHeader}${result.code}`; 82 | 83 | // write dist 84 | fs.writeFileSync( DIST, result, { encoding: "utf8" } ); 85 | } 86 | catch (err) { 87 | console.error(err); 88 | process.exit(1); 89 | } 90 | } 91 | 92 | console.log("Complete."); 93 | -------------------------------------------------------------------------------- /scripts/node-tests.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | "use strict"; 4 | 5 | var path = require("path"); 6 | 7 | var Linter = require("eslint").Linter; 8 | var eslinter = global.eslinter = new Linter(); 9 | var arrowRequireThis; 10 | 11 | /* istanbul ignore next */ 12 | if (process.env.TEST_DIST) { 13 | arrowRequireThis = require(path.join(__dirname,"..","dist","arrow-require-this.js")); 14 | } 15 | /* istanbul ignore next */ 16 | else if (process.env.TEST_PACKAGE) { 17 | arrowRequireThis = require(path.join(__dirname,"..")); 18 | } 19 | else { 20 | arrowRequireThis = require(path.join(__dirname,"..","lib","index.js")); 21 | } 22 | 23 | eslinter.defineRule("@getify/arrow-require-this/all",arrowRequireThis.rules.all); 24 | 25 | global.alwaysOptions = { 26 | parserOptions: { ecmaVersion: 2015, }, 27 | rules: { "@getify/arrow-require-this/all": ["error","always",], }, 28 | }; 29 | global.nestedOptions = { 30 | parserOptions: { ecmaVersion: 2015, }, 31 | rules: { "@getify/arrow-require-this/all": ["error","nested",], }, 32 | }; 33 | global.neverOptions = { 34 | parserOptions: { ecmaVersion: 2015, }, 35 | rules: { "@getify/arrow-require-this/all": ["error","never",], }, 36 | }; 37 | global.defaultOptions = { 38 | parserOptions: { ecmaVersion: 2015, }, 39 | rules: { "@getify/arrow-require-this/all": ["error",], }, 40 | }; 41 | 42 | global.QUnit = require("qunit"); 43 | 44 | require(path.join("..","tests","qunit.config.js")); 45 | require(path.join("..","tests","tests.js")); 46 | 47 | QUnit.start(); 48 | -------------------------------------------------------------------------------- /tests/qunit.config.js: -------------------------------------------------------------------------------- 1 | QUnit.config.requireExpects = true; 2 | 3 | QUnit.begin(begin); 4 | QUnit.log(testLog); 5 | QUnit.testDone(testDone); 6 | QUnit.done(done); 7 | 8 | var testLogEntries = {}; 9 | 10 | // ****************************** 11 | 12 | function begin(details){ 13 | printEnvNotification(); 14 | 15 | if (details.totalTests > 0) { 16 | console.log(`ESLint Rule (arrow-require-this) Test Suite (${details.totalTests})`); 17 | console.log(""); 18 | } 19 | else { 20 | console.log(`ESLint Rule (arrow-require-this) Test Suite: empty!`); 21 | process.exit(1); 22 | } 23 | } 24 | 25 | function testLog(details) { 26 | var testId = details.testId; 27 | 28 | testLogEntries[testId] = testLogEntries[testId] || {}; 29 | testLogEntries[testId][details.message] = {...details}; 30 | } 31 | 32 | function testDone(results){ 33 | var testId = results.testId; 34 | 35 | if (results.failed > 0) { 36 | console.log(`Failed: '${results.name}' (${results.failed}/${results.total})`); 37 | for (let i = 0; i < results.assertions.length; i++) { 38 | if (results.assertions[i].result === false) { 39 | let { message, expected, actual, source } = testLogEntries[testId][results.assertions[i].message]; 40 | console.log(` ${message}`); 41 | // is there a JS exception stack trace included? 42 | if (source && /^\w*Error: .+/.test(source)) { 43 | console.log(""); 44 | console.log(` ${source}`); 45 | console.log(""); 46 | } 47 | else { 48 | console.log(` expected: ${prettyPrint(expected)}`); 49 | console.log(` actual: ${prettyPrint(actual)}`); 50 | } 51 | } 52 | } 53 | } 54 | else if (results.passed > 0) { 55 | console.log(`Passed: '${results.name}' (${results.passed}/${results.total})`); 56 | } 57 | else { 58 | console.log(`No assertions run: '${results.name}'`); 59 | } 60 | } 61 | 62 | function done(results){ 63 | console.log(""); 64 | 65 | if (results.failed > 0) { 66 | console.log(`Failed (${results.failed}/${results.total})`); 67 | printEnvNotification(); 68 | process.exit(1); 69 | } 70 | else if (results.passed > 0) { 71 | console.log(`Passed (${results.passed}/${results.total})`); 72 | printEnvNotification(); 73 | process.exit(0); 74 | } 75 | else { 76 | console.log("No tests run!"); 77 | printEnvNotification(); 78 | process.exit(1); 79 | } 80 | } 81 | 82 | function prettyPrint(v) { 83 | if (Array.isArray(v)) { 84 | return `[${ v.map( prettyPrint ).toString() }]`; 85 | } 86 | else if (typeof v == "bigint") { 87 | return `${v}n`; 88 | } 89 | else if (v && typeof v == "object") { 90 | return JSON.stringify(v,function json(k,v){ 91 | if (v === undefined) { 92 | return null; 93 | } 94 | return v; 95 | }); 96 | } 97 | return String(v); 98 | } 99 | 100 | function printEnvNotification() { 101 | console.log(""); 102 | console.log("**********************************"); 103 | if (process.env.TEST_DIST) { 104 | console.log("********** TESTING DIST **********"); 105 | } 106 | else if (process.env.TEST_PACKAGE) { 107 | console.log("******** TESTING PACKAGE *********"); 108 | } 109 | else { 110 | console.log("********** TESTING SRC ***********"); 111 | } 112 | console.log("**********************************"); 113 | console.log(""); 114 | } 115 | -------------------------------------------------------------------------------- /tests/tests.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | QUnit.test( "one arrow, this (always)", function test(assert){ 4 | var code = ` 5 | var x = y => this.foo(y); 6 | `; 7 | 8 | var results = eslinter.verify(code,alwaysOptions); 9 | 10 | assert.expect(1); 11 | assert.strictEqual( results.length, 0, "no errors" ); 12 | } ); 13 | 14 | QUnit.test( "two nested arrows, both this (always)", function test(assert){ 15 | var code = ` 16 | var x = y => this.foo(z => this.bar(z)); 17 | `; 18 | 19 | var results = eslinter.verify(code,alwaysOptions); 20 | 21 | assert.expect(1); 22 | assert.strictEqual( results.length, 0, "no errors" ); 23 | } ); 24 | 25 | QUnit.test( "one arrow with param arrow, both this (always)", function test(assert){ 26 | var code = ` 27 | var x = (y = z => this.foo(z)) => this.bar(w); 28 | `; 29 | 30 | var results = eslinter.verify(code,alwaysOptions); 31 | 32 | assert.expect(1); 33 | assert.strictEqual( results.length, 0, "no errors" ); 34 | } ); 35 | 36 | QUnit.test( "two separate arrows, both this (always)", function test(assert){ 37 | var code = ` 38 | var x = y => this.foo(y); 39 | var z = w => this.bar(w); 40 | `; 41 | 42 | var results = eslinter.verify(code,alwaysOptions); 43 | 44 | assert.expect(1); 45 | assert.strictEqual( results.length, 0, "no errors" ); 46 | } ); 47 | 48 | QUnit.test( "simple arrow, no this (always)", function test(assert){ 49 | var code = ` 50 | var x = y => y; 51 | `; 52 | 53 | var results = eslinter.verify(code,alwaysOptions); 54 | var [{ ruleId, messageId, } = {}] = results || []; 55 | 56 | assert.expect(3); 57 | assert.strictEqual( results.length, 1, "only 1 error" ); 58 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 59 | assert.strictEqual( messageId, "noThis", "messageId" ); 60 | } ); 61 | 62 | QUnit.test( "two separate arrows, no this (always)", function test(assert){ 63 | var code = ` 64 | var x = y => foo(y); 65 | var z = w => bar(w); 66 | `; 67 | 68 | var results = eslinter.verify(code,alwaysOptions); 69 | var [ 70 | { ruleId: ruleId1, messageId: messageId1, } = {}, 71 | { ruleId: ruleId2, messageId: messageId2, } = {}, 72 | ] = results || []; 73 | 74 | assert.expect(5); 75 | assert.strictEqual( results.length, 2, "only 2 errors" ); 76 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 77 | assert.strictEqual( messageId1, "noThis", "messageId1" ); 78 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 79 | assert.strictEqual( messageId2, "noThis", "messageId2" ); 80 | } ); 81 | 82 | QUnit.test( "two nested arrows, one this nested (always)", function test(assert){ 83 | var code = ` 84 | var x = y => z => this.foo(z); 85 | `; 86 | 87 | var results = eslinter.verify(code,alwaysOptions); 88 | var [{ ruleId, messageId, } = {}] = results || []; 89 | 90 | assert.expect(3); 91 | assert.strictEqual( results.length, 1, "only 1 error" ); 92 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 93 | assert.strictEqual( messageId, "noThis", "messageId" ); 94 | } ); 95 | 96 | QUnit.test( "two nested arrows, one this not-nested (always)", function test(assert){ 97 | var code = ` 98 | var x = y => this.foo(z => z); 99 | `; 100 | 101 | var results = eslinter.verify(code,alwaysOptions); 102 | var [{ ruleId, messageId, } = {}] = results || []; 103 | 104 | assert.expect(3); 105 | assert.strictEqual( results.length, 1, "only 1 error" ); 106 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 107 | assert.strictEqual( messageId, "noThis", "messageId" ); 108 | } ); 109 | 110 | QUnit.test( "two nested arrows, no this (always)", function test(assert){ 111 | var code = ` 112 | var x = y => z => z; 113 | `; 114 | 115 | var results = eslinter.verify(code,alwaysOptions); 116 | var [ 117 | { ruleId: ruleId1, messageId: messageId1, } = {}, 118 | { ruleId: ruleId2, messageId: messageId2, } = {}, 119 | ] = results || []; 120 | 121 | assert.expect(5); 122 | assert.strictEqual( results.length, 2, "only 2 errors" ); 123 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 124 | assert.strictEqual( messageId1, "noThis", "messageId1" ); 125 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 126 | assert.strictEqual( messageId2, "noThis", "messageId2" ); 127 | } ); 128 | 129 | QUnit.test( "one arrow with param arrow, nested this (always)", function test(assert){ 130 | var code = ` 131 | var x = (y = z => foo(z)) => this.bar(w); 132 | `; 133 | 134 | var results = eslinter.verify(code,alwaysOptions); 135 | var [{ ruleId, messageId, } = {}] = results || []; 136 | 137 | assert.expect(3); 138 | assert.strictEqual( results.length, 1, "only 1 error" ); 139 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 140 | assert.strictEqual( messageId, "noThis", "messageId" ); 141 | } ); 142 | 143 | QUnit.test( "one arrow with param arrow, param this (always)", function test(assert){ 144 | var code = ` 145 | var x = (y = z => this.foo(z)) => bar(w); 146 | `; 147 | 148 | var results = eslinter.verify(code,alwaysOptions); 149 | var [{ ruleId, messageId, } = {}] = results || []; 150 | 151 | assert.expect(3); 152 | assert.strictEqual( results.length, 1, "only 1 error" ); 153 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 154 | assert.strictEqual( messageId, "noThis", "messageId" ); 155 | } ); 156 | 157 | QUnit.test( "one non-arrow and one arrow, nested this (always)", function test(assert){ 158 | var code = ` 159 | var x = function(){ return y => this.foo(y); }; 160 | `; 161 | 162 | var results = eslinter.verify(code,alwaysOptions); 163 | 164 | assert.expect(1); 165 | assert.strictEqual( results.length, 0, "no errors" ); 166 | } ); 167 | 168 | 169 | // ********************************************** 170 | 171 | 172 | QUnit.test( "one arrow, this (nested)", function test(assert){ 173 | var code = ` 174 | var x = y => this.foo(y); 175 | `; 176 | 177 | var results = eslinter.verify(code,nestedOptions); 178 | 179 | assert.expect(1); 180 | assert.strictEqual( results.length, 0, "no errors" ); 181 | } ); 182 | 183 | QUnit.test( "two nested arrows, both this (nested)", function test(assert){ 184 | var code = ` 185 | var x = y => this.foo(z => this.bar(z)); 186 | `; 187 | 188 | var results = eslinter.verify(code,nestedOptions); 189 | 190 | assert.expect(1); 191 | assert.strictEqual( results.length, 0, "no errors" ); 192 | } ); 193 | 194 | QUnit.test( "one arrow with param arrow, both this (nested)", function test(assert){ 195 | var code = ` 196 | var x = (y = z => this.foo(z)) => this.bar(w); 197 | `; 198 | 199 | var results = eslinter.verify(code,nestedOptions); 200 | 201 | assert.expect(1); 202 | assert.strictEqual( results.length, 0, "no errors" ); 203 | } ); 204 | 205 | QUnit.test( "two separate arrows, both this (nested)", function test(assert){ 206 | var code = ` 207 | var x = y => this.foo(y); 208 | var z = w => this.bar(w); 209 | `; 210 | 211 | var results = eslinter.verify(code,nestedOptions); 212 | 213 | assert.expect(1); 214 | assert.strictEqual( results.length, 0, "no errors" ); 215 | } ); 216 | 217 | QUnit.test( "simple arrow, no this (nested)", function test(assert){ 218 | var code = ` 219 | var x = y => y; 220 | `; 221 | 222 | var results = eslinter.verify(code,nestedOptions); 223 | var [{ ruleId, messageId, } = {}] = results || []; 224 | 225 | assert.expect(3); 226 | assert.strictEqual( results.length, 1, "only 1 error" ); 227 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 228 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 229 | } ); 230 | 231 | QUnit.test( "two separate arrows, no this (nested)", function test(assert){ 232 | var code = ` 233 | var x = y => foo(y); 234 | var z = w => bar(w); 235 | `; 236 | 237 | var results = eslinter.verify(code,nestedOptions); 238 | var [ 239 | { ruleId: ruleId1, messageId: messageId1, } = {}, 240 | { ruleId: ruleId2, messageId: messageId2, } = {}, 241 | ] = results || []; 242 | 243 | assert.expect(5); 244 | assert.strictEqual( results.length, 2, "only 2 errors" ); 245 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 246 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 247 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 248 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 249 | } ); 250 | 251 | QUnit.test( "two nested arrows, one this nested (nested)", function test(assert){ 252 | var code = ` 253 | var x = y => z => this.foo(z); 254 | `; 255 | 256 | var results = eslinter.verify(code,nestedOptions); 257 | 258 | assert.expect(1); 259 | assert.strictEqual( results.length, 0, "no errors" ); 260 | } ); 261 | 262 | QUnit.test( "two nested arrows, one this not-nested (nested)", function test(assert){ 263 | var code = ` 264 | var x = y => this.foo(z => z); 265 | `; 266 | 267 | var results = eslinter.verify(code,nestedOptions); 268 | var [{ ruleId, messageId, } = {}] = results || []; 269 | 270 | assert.expect(3); 271 | assert.strictEqual( results.length, 1, "only 1 error" ); 272 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 273 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 274 | } ); 275 | 276 | QUnit.test( "two nested arrows, no this (nested)", function test(assert){ 277 | var code = ` 278 | var x = y => z => z; 279 | `; 280 | 281 | var results = eslinter.verify(code,nestedOptions); 282 | var [ 283 | { ruleId: ruleId1, messageId: messageId1, } = {}, 284 | { ruleId: ruleId2, messageId: messageId2, } = {}, 285 | ] = results || []; 286 | 287 | assert.expect(5); 288 | assert.strictEqual( results.length, 2, "only 2 errors" ); 289 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 290 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 291 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 292 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 293 | } ); 294 | 295 | QUnit.test( "one arrow with param arrow, nested this (nested)", function test(assert){ 296 | var code = ` 297 | var x = (y = z => foo(z)) => this.bar(w); 298 | `; 299 | 300 | var results = eslinter.verify(code,nestedOptions); 301 | var [{ ruleId, messageId, } = {}] = results || []; 302 | 303 | assert.expect(3); 304 | assert.strictEqual( results.length, 1, "only 1 error" ); 305 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 306 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 307 | } ); 308 | 309 | QUnit.test( "one arrow with param arrow, param this (nested)", function test(assert){ 310 | var code = ` 311 | var x = (y = z => this.foo(z)) => bar(w); 312 | `; 313 | 314 | var results = eslinter.verify(code,nestedOptions); 315 | 316 | assert.expect(1); 317 | assert.strictEqual( results.length, 0, "no errors" ); 318 | } ); 319 | 320 | QUnit.test( "two arrows with non-arrow between, both this (nested)", function test(assert){ 321 | var code = ` 322 | var x = y => this.foo(function(){ return z => this.bar(z); }); 323 | `; 324 | 325 | var results = eslinter.verify(code,nestedOptions); 326 | 327 | assert.expect(1); 328 | assert.strictEqual( results.length, 0, "no errors" ); 329 | } ); 330 | 331 | QUnit.test( "two arrows with non-arrow between, nested this (nested)", function test(assert){ 332 | var code = ` 333 | var x = y => foo(function(){ return z => this.bar(z); }); 334 | `; 335 | 336 | var results = eslinter.verify(code,nestedOptions); 337 | var [{ ruleId, messageId, } = {}] = results || []; 338 | 339 | assert.expect(3); 340 | assert.strictEqual( results.length, 1, "only 1 error" ); 341 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 342 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 343 | } ); 344 | 345 | QUnit.test( "one arrow and non-arrow with arrow param, param this (nested)", function test(assert){ 346 | var code = ` 347 | var x = y => foo(function(z = w => this.bar(w)){ return bar(z); }); 348 | `; 349 | 350 | var results = eslinter.verify(code,nestedOptions); 351 | var [{ ruleId, messageId, } = {}] = results || []; 352 | 353 | assert.expect(3); 354 | assert.strictEqual( results.length, 1, "only 1 error" ); 355 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 356 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 357 | } ); 358 | 359 | QUnit.test( "two arrows with non-arrow between, not-nested this (nested)", function test(assert){ 360 | var code = ` 361 | var x = y => this.foo(function(){ return z => bar(z); }); 362 | `; 363 | 364 | var results = eslinter.verify(code,nestedOptions); 365 | var [{ ruleId, messageId, } = {}] = results || []; 366 | 367 | assert.expect(3); 368 | assert.strictEqual( results.length, 1, "only 1 error" ); 369 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 370 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 371 | } ); 372 | 373 | QUnit.test( "two arrows with non-arrow between, no this (nested)", function test(assert){ 374 | var code = ` 375 | var x = y => foo(function(){ return z => bar(z); }); 376 | `; 377 | 378 | var results = eslinter.verify(code,nestedOptions); 379 | var [ 380 | { ruleId: ruleId1, messageId: messageId1, } = {}, 381 | { ruleId: ruleId2, messageId: messageId2, } = {}, 382 | ] = results || []; 383 | 384 | assert.expect(5); 385 | assert.strictEqual( results.length, 2, "only 2 errors" ); 386 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 387 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 388 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 389 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 390 | } ); 391 | 392 | QUnit.test( "one arrow and one non-arrow, both this (nested)", function test(assert){ 393 | var code = ` 394 | var x = y => this.foo(function(){ return this.bar(z); }); 395 | `; 396 | 397 | var results = eslinter.verify(code,nestedOptions); 398 | 399 | assert.expect(1); 400 | assert.strictEqual( results.length, 0, "no errors" ); 401 | } ); 402 | 403 | QUnit.test( "one arrow and one non-arrow, nested this (nested)", function test(assert){ 404 | var code = ` 405 | var x = y => foo(function(){ return this.bar(z); }); 406 | `; 407 | 408 | var results = eslinter.verify(code,nestedOptions); 409 | var [{ ruleId, messageId, } = {}] = results || []; 410 | 411 | assert.expect(3); 412 | assert.strictEqual( results.length, 1, "only 1 error" ); 413 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 414 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 415 | } ); 416 | 417 | 418 | // ********************************************** 419 | 420 | 421 | QUnit.test( "one arrow, this (default: nested)", function test(assert){ 422 | var code = ` 423 | var x = y => this.foo(y); 424 | `; 425 | 426 | var results = eslinter.verify(code,defaultOptions); 427 | 428 | assert.expect(1); 429 | assert.strictEqual( results.length, 0, "no errors" ); 430 | } ); 431 | 432 | QUnit.test( "two nested arrows, both this (default: nested)", function test(assert){ 433 | var code = ` 434 | var x = y => this.foo(z => this.bar(z)); 435 | `; 436 | 437 | var results = eslinter.verify(code,defaultOptions); 438 | 439 | assert.expect(1); 440 | assert.strictEqual( results.length, 0, "no errors" ); 441 | } ); 442 | 443 | QUnit.test( "one arrow with param arrow, both this (default: nested)", function test(assert){ 444 | var code = ` 445 | var x = (y = z => this.foo(z)) => this.bar(w); 446 | `; 447 | 448 | var results = eslinter.verify(code,defaultOptions); 449 | 450 | assert.expect(1); 451 | assert.strictEqual( results.length, 0, "no errors" ); 452 | } ); 453 | 454 | QUnit.test( "two separate arrows, both this (default: nested)", function test(assert){ 455 | var code = ` 456 | var x = y => this.foo(y); 457 | var z = w => this.bar(w); 458 | `; 459 | 460 | var results = eslinter.verify(code,defaultOptions); 461 | 462 | assert.expect(1); 463 | assert.strictEqual( results.length, 0, "no errors" ); 464 | } ); 465 | 466 | QUnit.test( "simple arrow, no this (default: nested)", function test(assert){ 467 | var code = ` 468 | var x = y => y; 469 | `; 470 | 471 | var results = eslinter.verify(code,defaultOptions); 472 | var [{ ruleId, messageId, } = {}] = results || []; 473 | 474 | assert.expect(3); 475 | assert.strictEqual( results.length, 1, "only 1 error" ); 476 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 477 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 478 | } ); 479 | 480 | QUnit.test( "two separate arrows, no this (default: nested)", function test(assert){ 481 | var code = ` 482 | var x = y => foo(y); 483 | var z = w => bar(w); 484 | `; 485 | 486 | var results = eslinter.verify(code,defaultOptions); 487 | var [ 488 | { ruleId: ruleId1, messageId: messageId1, } = {}, 489 | { ruleId: ruleId2, messageId: messageId2, } = {}, 490 | ] = results || []; 491 | 492 | assert.expect(5); 493 | assert.strictEqual( results.length, 2, "only 2 errors" ); 494 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 495 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 496 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 497 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 498 | } ); 499 | 500 | QUnit.test( "two nested arrows, one this nested (default: nested)", function test(assert){ 501 | var code = ` 502 | var x = y => z => this.foo(z); 503 | `; 504 | 505 | var results = eslinter.verify(code,defaultOptions); 506 | 507 | assert.expect(1); 508 | assert.strictEqual( results.length, 0, "no errors" ); 509 | } ); 510 | 511 | QUnit.test( "two nested arrows, one this not-nested (default: nested)", function test(assert){ 512 | var code = ` 513 | var x = y => this.foo(z => z); 514 | `; 515 | 516 | var results = eslinter.verify(code,defaultOptions); 517 | var [{ ruleId, messageId, } = {}] = results || []; 518 | 519 | assert.expect(3); 520 | assert.strictEqual( results.length, 1, "only 1 error" ); 521 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 522 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 523 | } ); 524 | 525 | QUnit.test( "two nested arrows, no this (default: nested)", function test(assert){ 526 | var code = ` 527 | var x = y => z => z; 528 | `; 529 | 530 | var results = eslinter.verify(code,defaultOptions); 531 | var [ 532 | { ruleId: ruleId1, messageId: messageId1, } = {}, 533 | { ruleId: ruleId2, messageId: messageId2, } = {}, 534 | ] = results || []; 535 | 536 | assert.expect(5); 537 | assert.strictEqual( results.length, 2, "only 2 errors" ); 538 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 539 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 540 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 541 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 542 | } ); 543 | 544 | QUnit.test( "one arrow with param arrow, nested this (default: nested)", function test(assert){ 545 | var code = ` 546 | var x = (y = z => foo(z)) => this.bar(w); 547 | `; 548 | 549 | var results = eslinter.verify(code,defaultOptions); 550 | var [{ ruleId, messageId, } = {}] = results || []; 551 | 552 | assert.expect(3); 553 | assert.strictEqual( results.length, 1, "only 1 error" ); 554 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 555 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 556 | } ); 557 | 558 | QUnit.test( "one arrow with param arrow, param this (default: nested)", function test(assert){ 559 | var code = ` 560 | var x = (y = z => this.foo(z)) => bar(w); 561 | `; 562 | 563 | var results = eslinter.verify(code,defaultOptions); 564 | 565 | assert.expect(1); 566 | assert.strictEqual( results.length, 0, "no errors" ); 567 | } ); 568 | 569 | QUnit.test( "two arrows with non-arrow between, both this (default: nested)", function test(assert){ 570 | var code = ` 571 | var x = y => this.foo(function(){ return z => this.bar(z); }); 572 | `; 573 | 574 | var results = eslinter.verify(code,defaultOptions); 575 | 576 | assert.expect(1); 577 | assert.strictEqual( results.length, 0, "no errors" ); 578 | } ); 579 | 580 | QUnit.test( "two arrows with non-arrow between, nested this (default: nested)", function test(assert){ 581 | var code = ` 582 | var x = y => foo(function(){ return z => this.bar(z); }); 583 | `; 584 | 585 | var results = eslinter.verify(code,defaultOptions); 586 | var [{ ruleId, messageId, } = {}] = results || []; 587 | 588 | assert.expect(3); 589 | assert.strictEqual( results.length, 1, "only 1 error" ); 590 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 591 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 592 | } ); 593 | 594 | QUnit.test( "one arrow and non-arrow with arrow param, param this (default: nested)", function test(assert){ 595 | var code = ` 596 | var x = y => foo(function(z = w => this.bar(w)){ return bar(z); }); 597 | `; 598 | 599 | var results = eslinter.verify(code,defaultOptions); 600 | var [{ ruleId, messageId, } = {}] = results || []; 601 | 602 | assert.expect(3); 603 | assert.strictEqual( results.length, 1, "only 1 error" ); 604 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 605 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 606 | } ); 607 | 608 | QUnit.test( "two arrows with non-arrow between, not-nested this (default: nested)", function test(assert){ 609 | var code = ` 610 | var x = y => this.foo(function(){ return z => bar(z); }); 611 | `; 612 | 613 | var results = eslinter.verify(code,defaultOptions); 614 | var [{ ruleId, messageId, } = {}] = results || []; 615 | 616 | assert.expect(3); 617 | assert.strictEqual( results.length, 1, "only 1 error" ); 618 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 619 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 620 | } ); 621 | 622 | QUnit.test( "two arrows with non-arrow between, no this (default: nested)", function test(assert){ 623 | var code = ` 624 | var x = y => foo(function(){ return z => bar(z); }); 625 | `; 626 | 627 | var results = eslinter.verify(code,defaultOptions); 628 | var [ 629 | { ruleId: ruleId1, messageId: messageId1, } = {}, 630 | { ruleId: ruleId2, messageId: messageId2, } = {}, 631 | ] = results || []; 632 | 633 | assert.expect(5); 634 | assert.strictEqual( results.length, 2, "only 2 errors" ); 635 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 636 | assert.strictEqual( messageId1, "noThisNested", "messageId1" ); 637 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 638 | assert.strictEqual( messageId2, "noThisNested", "messageId2" ); 639 | } ); 640 | 641 | QUnit.test( "one arrow and one non-arrow, both this (default: nested)", function test(assert){ 642 | var code = ` 643 | var x = y => this.foo(function(){ return this.bar(z); }); 644 | `; 645 | 646 | var results = eslinter.verify(code,defaultOptions); 647 | 648 | assert.expect(1); 649 | assert.strictEqual( results.length, 0, "no errors" ); 650 | } ); 651 | 652 | QUnit.test( "one arrow and one non-arrow, nested this (default: nested)", function test(assert){ 653 | var code = ` 654 | var x = y => foo(function(){ return this.bar(z); }); 655 | `; 656 | 657 | var results = eslinter.verify(code,defaultOptions); 658 | var [{ ruleId, messageId, } = {}] = results || []; 659 | 660 | assert.expect(3); 661 | assert.strictEqual( results.length, 1, "only 1 error" ); 662 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 663 | assert.strictEqual( messageId, "noThisNested", "messageId" ); 664 | } ); 665 | 666 | 667 | // ********************************************** 668 | 669 | 670 | QUnit.test( "one arrow, this (never)", function test(assert){ 671 | var code = ` 672 | var x = y => this.foo(y); 673 | `; 674 | 675 | var results = eslinter.verify(code,neverOptions); 676 | var [{ ruleId, messageId, } = {}] = results || []; 677 | 678 | assert.expect(3); 679 | assert.strictEqual( results.length, 1, "only 1 error" ); 680 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 681 | assert.strictEqual( messageId, "neverThis", "messageId" ); 682 | } ); 683 | 684 | QUnit.test( "two nested arrows, both this (never)", function test(assert){ 685 | var code = ` 686 | var x = y => this.foo(z => this.bar(z)); 687 | `; 688 | 689 | var results = eslinter.verify(code,neverOptions); 690 | var [ 691 | { ruleId: ruleId1, messageId: messageId1, } = {}, 692 | { ruleId: ruleId2, messageId: messageId2, } = {}, 693 | ] = results || []; 694 | 695 | assert.expect(5); 696 | assert.strictEqual( results.length, 2, "only 2 errors" ); 697 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 698 | assert.strictEqual( messageId1, "neverThis", "messageId1" ); 699 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 700 | assert.strictEqual( messageId2, "neverThis", "messageId2" ); 701 | } ); 702 | 703 | QUnit.test( "one arrow with param arrow, both this (never)", function test(assert){ 704 | var code = ` 705 | var x = (y = z => this.foo(z)) => this.bar(w); 706 | `; 707 | 708 | var results = eslinter.verify(code,neverOptions); 709 | var [ 710 | { ruleId: ruleId1, messageId: messageId1, } = {}, 711 | { ruleId: ruleId2, messageId: messageId2, } = {}, 712 | ] = results || []; 713 | 714 | assert.expect(5); 715 | assert.strictEqual( results.length, 2, "only 2 errors" ); 716 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 717 | assert.strictEqual( messageId1, "neverThis", "messageId1" ); 718 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 719 | assert.strictEqual( messageId2, "neverThis", "messageId2" ); 720 | } ); 721 | 722 | QUnit.test( "two separate arrows, both this (never)", function test(assert){ 723 | var code = ` 724 | var x = y => this.foo(y); 725 | var z = w => this.bar(w); 726 | `; 727 | 728 | var results = eslinter.verify(code,neverOptions); 729 | var [ 730 | { ruleId: ruleId1, messageId: messageId1, } = {}, 731 | { ruleId: ruleId2, messageId: messageId2, } = {}, 732 | ] = results || []; 733 | 734 | assert.expect(5); 735 | assert.strictEqual( results.length, 2, "only 2 errors" ); 736 | assert.strictEqual( ruleId1, "@getify/arrow-require-this/all", "ruleId1" ); 737 | assert.strictEqual( messageId1, "neverThis", "messageId1" ); 738 | assert.strictEqual( ruleId2, "@getify/arrow-require-this/all", "ruleId2" ); 739 | assert.strictEqual( messageId2, "neverThis", "messageId2" ); 740 | } ); 741 | 742 | QUnit.test( "simple arrow, no this (never)", function test(assert){ 743 | var code = ` 744 | var x = y => y; 745 | `; 746 | 747 | var results = eslinter.verify(code,neverOptions); 748 | 749 | assert.expect(1); 750 | assert.strictEqual( results.length, 0, "no errors" ); 751 | } ); 752 | 753 | QUnit.test( "two separate arrows, no this (never)", function test(assert){ 754 | var code = ` 755 | var x = y => foo(y); 756 | var z = w => bar(w); 757 | `; 758 | 759 | var results = eslinter.verify(code,neverOptions); 760 | 761 | assert.expect(1); 762 | assert.strictEqual( results.length, 0, "no errors" ); 763 | } ); 764 | 765 | QUnit.test( "two separate arrows, one this (never)", function test(assert){ 766 | var code = ` 767 | var x = y => this.foo(y); 768 | var z = w => bar(w); 769 | `; 770 | 771 | var results = eslinter.verify(code,neverOptions); 772 | var [{ ruleId, messageId, } = {}] = results || []; 773 | 774 | assert.expect(3); 775 | assert.strictEqual( results.length, 1, "only 1 error" ); 776 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 777 | assert.strictEqual( messageId, "neverThis", "messageId" ); 778 | } ); 779 | 780 | QUnit.test( "two nested arrows, one this nested (never)", function test(assert){ 781 | var code = ` 782 | var x = y => foo(z => this.bar(z)); 783 | `; 784 | 785 | var results = eslinter.verify(code,neverOptions); 786 | var [{ ruleId, messageId, } = {}] = results || []; 787 | 788 | assert.expect(3); 789 | assert.strictEqual( results.length, 1, "only 1 error" ); 790 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 791 | assert.strictEqual( messageId, "neverThis", "messageId" ); 792 | } ); 793 | 794 | QUnit.test( "two nested arrows, one this not-nested (never)", function test(assert){ 795 | var code = ` 796 | var x = y => this.foo(z => z); 797 | `; 798 | 799 | var results = eslinter.verify(code,neverOptions); 800 | var [{ ruleId, messageId, } = {}] = results || []; 801 | 802 | assert.expect(3); 803 | assert.strictEqual( results.length, 1, "only 1 error" ); 804 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 805 | assert.strictEqual( messageId, "neverThis", "messageId" ); 806 | } ); 807 | 808 | QUnit.test( "two nested arrows, no this (never)", function test(assert){ 809 | var code = ` 810 | var x = y => z => z; 811 | `; 812 | 813 | var results = eslinter.verify(code,neverOptions); 814 | 815 | assert.expect(1); 816 | assert.strictEqual( results.length, 0, "no errors" ); 817 | } ); 818 | 819 | QUnit.test( "one arrow with param arrow, param this (never)", function test(assert){ 820 | var code = ` 821 | var x = (y = z => this.foo(z)) => bar(w); 822 | `; 823 | 824 | var results = eslinter.verify(code,neverOptions); 825 | var [{ ruleId, messageId, } = {}] = results || []; 826 | 827 | assert.expect(3); 828 | assert.strictEqual( results.length, 1, "only 1 error" ); 829 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 830 | assert.strictEqual( messageId, "neverThis", "messageId" ); 831 | } ); 832 | 833 | QUnit.test( "one arrow and one non-arrow, both this (never)", function test(assert){ 834 | var code = ` 835 | var x = y => this.foo(function(){ return this.bar(z); }); 836 | `; 837 | 838 | var results = eslinter.verify(code,neverOptions); 839 | var [{ ruleId, messageId, } = {}] = results || []; 840 | 841 | assert.expect(3); 842 | assert.strictEqual( results.length, 1, "only 1 error" ); 843 | assert.strictEqual( ruleId, "@getify/arrow-require-this/all", "ruleId" ); 844 | assert.strictEqual( messageId, "neverThis", "messageId" ); 845 | } ); 846 | 847 | QUnit.test( "one arrow and one non-arrow, nested this (never)", function test(assert){ 848 | var code = ` 849 | var x = y => foo(function(){ return this.bar(z); }); 850 | `; 851 | 852 | var results = eslinter.verify(code,neverOptions); 853 | 854 | assert.expect(1); 855 | assert.strictEqual( results.length, 0, "no errors" ); 856 | } ); 857 | --------------------------------------------------------------------------------