├── .npmignore ├── README.md ├── index.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── package.json ├── LICENSE ├── rules └── dollar-sign.js └── tests └── dollar-sign.js /.npmignore: -------------------------------------------------------------------------------- 1 | # Everything 2 | * 3 | 4 | !index.js 5 | !rules/* 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-plugin-dollar-sign 2 | 3 | Enforce $varName for jQuery assignment. 4 | 5 | Based on the `requireDollarBeforejQueryAssignment` rule from JSCS. 6 | 7 | ## Usage 8 | 9 | `npm i --save-dev eslint-plugin-dollar-sign` 10 | 11 | ```json 12 | { 13 | "plugins": [ 14 | "dollar-sign" 15 | ], 16 | "rules": { 17 | "dollar-sign/dollar-sign": [2, "ignoreProperties"] 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Enforce $varName for jQuery assignment. 3 | * @author Erik Desjardins 4 | * @copyright 2013-2016 JSCS contributors. All rights reserved. 5 | * @copyright 2016 Erik Desjardins. All rights reserved. 6 | * See LICENSE file in root directory for full license. 7 | */ 8 | 'use strict'; 9 | 10 | module.exports = { 11 | rules: { 12 | 'dollar-sign': require('./rules/dollar-sign') 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v*.*.* 9 | pull_request: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v1 16 | - uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | registry-url: 'https://registry.npmjs.org' 20 | - run: npm install 21 | - run: npm test 22 | - run: npm publish 23 | if: startsWith(github.ref, 'refs/tags/') 24 | env: 25 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-dollar-sign", 3 | "version": "1.0.2", 4 | "description": "Enforce $varName for jQuery assignment.", 5 | "keywords": [ 6 | "eslint", 7 | "eslintplugin", 8 | "eslint-plugin" 9 | ], 10 | "author": "Erik Desjardins", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/erikdesjardins/eslint-plugin-dollar-sign.git" 14 | }, 15 | "main": "index.js", 16 | "scripts": { 17 | "test": "mocha ./tests/*.js" 18 | }, 19 | "peerDependencies": { 20 | "eslint": ">=1.0.0" 21 | }, 22 | "devDependencies": { 23 | "@typescript-eslint/parser": "^2.6.0", 24 | "eslint": "^6.6.0", 25 | "mocha": "^6.2.2", 26 | "typescript": "^3.6.4" 27 | }, 28 | "license": "MIT" 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2016 JSCS contributors 4 | Copyright (c) 2016 Erik Desjardins 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /rules/dollar-sign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Enforce $varName for jQuery assignment. 3 | * @author Erik Desjardins 4 | * @copyright 2013-2016 JSCS contributors. All rights reserved. 5 | * @copyright 2016 Erik Desjardins. All rights reserved. 6 | * See LICENSE file in root directory for full license. 7 | */ 8 | 'use strict'; 9 | 10 | module.exports = function(context) { 11 | var ignoreProperties = context.options[0] === 'ignoreProperties'; 12 | 13 | function shouldVarNameStartWithDollar(name, assignee) { 14 | return ( 15 | name && !(/^_?\$/).test(name) && 16 | assignee && assignee.type === 'CallExpression' && 17 | assignee.callee.type === 'Identifier' && assignee.callee.name === '$' 18 | ); 19 | } 20 | 21 | function reportIdentifier(identifier, fix) { 22 | var reportObj = { 23 | node: identifier, 24 | message: 'jQuery identifiers must start with a $' 25 | }; 26 | 27 | if (fix) { 28 | reportObj.fix = function(fixer) { 29 | return fixer.insertTextBefore(identifier, '$'); 30 | }; 31 | } 32 | 33 | context.report(reportObj); 34 | } 35 | 36 | function collectReferenceIdentifiers(variable) { 37 | var allRefs = variable.references.concat(variable.scope.references); 38 | var refs = variable.identifiers.slice(); 39 | var i, id; 40 | 41 | // avoid adding duplicate references 42 | for (i = 0; i < allRefs.length; ++i) { 43 | id = allRefs[i].identifier; 44 | 45 | if (refs.indexOf(id) !== -1) continue; 46 | 47 | if (id.name === variable.name) { 48 | refs.push(id); 49 | } 50 | } 51 | 52 | return refs; 53 | } 54 | 55 | function reportAllReferences(variable) { 56 | var refs = collectReferenceIdentifiers(variable); 57 | var autofix = true; 58 | var i, id; 59 | 60 | for (i = 0; i < refs.length; ++i) { 61 | id = refs[i]; 62 | if (id.parent && id.parent.type === 'Property' && id.parent.shorthand) { 63 | // if any reference is used for a shorthand property, don't autofix 64 | autofix = false; 65 | break; 66 | } 67 | } 68 | 69 | for (i = 0; i < refs.length; ++i) { 70 | id = refs[i]; 71 | reportIdentifier(id, autofix); 72 | } 73 | } 74 | 75 | function shouldVarAssignmentStartWithDollar(def, variable) { 76 | var refs = collectReferenceIdentifiers(variable); 77 | var i, parent; 78 | 79 | for (i = 0; i < refs.length; ++i) { 80 | parent = refs[i].parent; 81 | 82 | if (!parent || parent.type !== 'AssignmentExpression' || parent.operator !== '=') continue; 83 | 84 | if (shouldVarNameStartWithDollar(def.name.name, parent.right)) return true; 85 | } 86 | 87 | return false; 88 | } 89 | 90 | function checkVarDeclarations(scope) { 91 | var i, variable, def; 92 | 93 | for (i = 0; i < scope.variables.length; ++i) { 94 | variable = scope.variables[i]; 95 | 96 | if (!variable.defs.length) continue; 97 | def = variable.defs[0]; 98 | 99 | if (!def.node.id || def.node.id.type === 'ObjectPattern' || def.node.id.type === 'ArrayPattern') continue; 100 | 101 | if ( 102 | def.node.init ? 103 | shouldVarNameStartWithDollar(def.name.name, def.node.init) : 104 | shouldVarAssignmentStartWithDollar(def, variable) 105 | ) { 106 | reportAllReferences(variable); 107 | } 108 | } 109 | 110 | for (i = 0; i < scope.childScopes.length; ++i) { 111 | checkVarDeclarations(scope.childScopes[i]); 112 | } 113 | } 114 | 115 | function checkAssignmentExpressionForObject(node) { 116 | if (ignoreProperties) { 117 | return; 118 | } 119 | 120 | var left = node.left; 121 | if (left.computed) { 122 | return; 123 | } 124 | 125 | if (left.type === 'ObjectPattern' || left.type === 'ArrayPattern') { 126 | return; 127 | } 128 | 129 | if (!left.property) { 130 | return; 131 | } 132 | 133 | if (shouldVarNameStartWithDollar(left.property.name, node.right)) { 134 | reportIdentifier(left.property, false); 135 | } 136 | } 137 | 138 | function checkObjectExpression(node) { 139 | if (ignoreProperties) { 140 | return; 141 | } 142 | 143 | var props = node.properties; 144 | 145 | if (!props) { 146 | return; 147 | } 148 | 149 | props.forEach(function(prop) { 150 | var left = prop.key; 151 | 152 | if (!left) { 153 | return; 154 | } 155 | 156 | if (shouldVarNameStartWithDollar(left.name, prop.value)) { 157 | reportIdentifier(left, false); 158 | } 159 | }); 160 | } 161 | 162 | return { 163 | ObjectExpression: checkObjectExpression, 164 | AssignmentExpression: checkAssignmentExpressionForObject, 165 | 'Program:exit': function() { 166 | checkVarDeclarations(context.getScope()); 167 | } 168 | }; 169 | }; 170 | 171 | module.exports.schema = [ 172 | { 173 | enum: ['ignoreProperties'] 174 | } 175 | ]; 176 | -------------------------------------------------------------------------------- /tests/dollar-sign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Enforce $varName for jQuery assignment. 3 | * @author Erik Desjardins 4 | * @copyright 2013-2016 JSCS contributors. All rights reserved. 5 | * @copyright 2016 Erik Desjardins. All rights reserved. 6 | * See LICENSE file in root directory for full license. 7 | */ 8 | 'use strict'; 9 | 10 | var rule = require('../rules/dollar-sign'); 11 | var RuleTester = require("eslint").RuleTester; 12 | 13 | var errorMessage = 'jQuery identifiers must start with a $'; 14 | 15 | var ruleTester = new RuleTester({ env: { es6: true } }); 16 | ruleTester.run('dollar-sign', rule, { 17 | valid: [ 18 | // basic jquery operator with dollar 19 | 'var $x = $();', 20 | // basic jquery operator with leading underscore and dollar 21 | 'var _$x = $();', 22 | // basic assignment 23 | 'var x = 2;', 24 | // var declaration without assignment 25 | 'var x;', 26 | // function assignment 27 | 'var x = function() {};', 28 | // function call 29 | 'var x = fn("foo")', 30 | // logical assignment 31 | 'var a = 1 || 2;', 32 | // assignment against dollar prefixed function 33 | 'var a = $func("foo")', 34 | // dollar addition 35 | 'var a = $ + 2', 36 | // binary assignment 37 | 'var a = 1 + 2;', 38 | // for loops 39 | 'for (var prop in rawVars) {}', 40 | // keyed object assignments with string key 41 | 'obj["foo"] = "bar"', 42 | // jquery root functions 43 | 'var x = $.extends();', 44 | // jquery operator with html with dollar 45 | 'var $x = $("

foo

");', 46 | // jquery operator with selector with dollar 47 | 'var $x = $(".foo");', 48 | // jquery operator using val 49 | 'var x = $(".foo").val();', 50 | // chained jquery operator with variable 51 | 'var x = $(evt.target).val();', 52 | // jquery operator using val over multiple lines 53 | 'var x = $(".foo")\n.val();', 54 | // jquery operator using chained methods 55 | 'var x = $(".foo").val().toString();', 56 | // jquery operator with dollar and line not beginning with var 57 | '$x = $(".foo");', 58 | // jquery operator with dollar and line not ending in semicolon 59 | 'var $x = $(".foo")', 60 | // jquery operator with dollar and single quotes around selector 61 | 'var $x = $(\'.foo\');', 62 | // object destructuring 63 | 'var {beep, boop} = meep;\nvar $s = $("#id")', 64 | 'var {beep, boop} = $("#id")', 65 | // object destructuring without var 66 | '({beep, boop} = $("#id"))', 67 | // array destructuring 68 | 'var [beep, boop] = meep;\nvar $s = $("#id")', 69 | 'var [beep, boop] = $("#id")', 70 | // array destructuring without var 71 | '([beep, boop] = $("#id"))', 72 | // defined with a non-jQuery type 73 | 'var x = 5; x = $(".foo");', 74 | // late assignment with jQuery 75 | 'var $x; $x = $(".foo");', 76 | // parameters 77 | '(function(x) {});', 78 | 79 | //// in object definition 80 | 81 | // basic object creation with string key assignment 82 | '!{"a": true}', 83 | // object with string key assignment 84 | 'var a = {"a": true};', 85 | // basic jquery operator with dollar 86 | 'var x = { $foo: $() }', 87 | // jquery operator with html 88 | 'var x = { $foo: $("

foo

") }', 89 | // jquery operator with html with dollar 90 | 'var $x = { $foo: $("

foo

") }', 91 | // jquery operator with selector with dollar 92 | 'var $x = { $foo: $(".foo") }', 93 | // jquery operator using val 94 | 'var x = { foo: $(".foo").val() }', 95 | // jquery operator using val over multiple lines 96 | 'var x = { foo: $(".foo")\n.val() }', 97 | // jquery operator using chained methods 98 | 'var x = { foo: $(".foo").val().toString() }', 99 | 100 | //// in object properties 101 | 102 | // basic jquery operator with dollar 103 | 'this.$x = $();', 104 | // jquery operator with html with dollar 105 | 'this.$x = $("

foo

");', 106 | // jquery operator with selector with dollar 107 | 'this.$x = $(".foo");', 108 | // jquery operator using val 109 | 'this.x = $(".foo").val();', 110 | // jquery operator using val over multiple lines 111 | 'this.x = $(".foo")\n.val();', 112 | // jquery operator using chained methods 113 | 'this.x = $(".foo").val().toString();', 114 | // jquery operator with dollar and line not ending in semicolon 115 | 'this.$x = $(".foo")', 116 | // jquery operator with dollar and single quotes around selector 117 | 'this.$x = $(\'.foo\');', 118 | // direct assignment 119 | 'this.$video = $video;', 120 | // basic assignment 121 | 'w.x = 2;', 122 | // function assignment 123 | 'w.x = function() {};', 124 | // logical assignment 125 | 'w.a = 1 || 2;', 126 | // object logical assignment 127 | 'w.a = w.a || {};', 128 | // binary assignment 129 | 'w.a = 1 + 2;', 130 | // multi level object assignment 131 | 'a.b.$c = $()', 132 | // object spread 133 | { code: 'var foo = { ...{ a: 1 } };', parserOptions: { ecmaVersion: 2018 } }, 134 | // object rest 135 | { code: 'var { ...foo } = { a: 1 };', parserOptions: { ecmaVersion: 2018 } }, 136 | 137 | //// option value `"ignoreProperties"` 138 | 139 | // basic jquery operator with dollar 140 | { code: 'var $x = $();', options: ['ignoreProperties'] }, 141 | // basic jquery operator in object definition 142 | { code: 'var x = { foo: $() }', options: ['ignoreProperties'] }, 143 | // basic jquery operator in object properties 144 | { code: 'this.x = $();', options: ['ignoreProperties'] } 145 | ], 146 | invalid: [ 147 | // basic jquery operator 148 | { 149 | code: 'var x = $();', 150 | output: 'var $x = $();', 151 | errors: [{ 152 | message: errorMessage, 153 | type: 'Identifier', 154 | line: 1, 155 | column: 5 156 | }] 157 | }, 158 | // assignment on nextline without semicolon 159 | { 160 | code: 'var a = $(".foo")\nvar b = $()', 161 | output: 'var $a = $(".foo")\nvar $b = $()', 162 | errors: [{ 163 | message: errorMessage, 164 | type: 'Identifier', 165 | line: 1, 166 | column: 5 167 | }, { 168 | message: errorMessage, 169 | type: 'Identifier', 170 | line: 2, 171 | column: 5 172 | }] 173 | }, 174 | // jquery operator with html 175 | { 176 | code: 'var x = $("

foo

");', 177 | output: 'var $x = $("

foo

");', 178 | errors: [{ 179 | message: errorMessage, 180 | type: 'Identifier', 181 | line: 1, 182 | column: 5 183 | }] 184 | }, 185 | // jquery operator with selector 186 | { 187 | code: 'var x = $(".foo");', 188 | output: 'var $x = $(".foo");', 189 | errors: [{ 190 | message: errorMessage, 191 | type: 'Identifier', 192 | line: 1, 193 | column: 5 194 | }] 195 | }, 196 | // assignment on right hand side of object destructuring 197 | { 198 | code: 'var {foo} = {foo: $(".foo")}', 199 | output: 'var {foo} = {foo: $(".foo")}', 200 | errors: [{ 201 | message: errorMessage, 202 | type: 'Identifier', 203 | line: 1, 204 | column: 14 205 | }] 206 | }, 207 | // multiple var declarations 208 | { 209 | code: 'var bar, foo = $(".foo");', 210 | output: 'var bar, $foo = $(".foo");', 211 | errors: [{ 212 | message: errorMessage, 213 | type: 'Identifier', 214 | line: 1, 215 | column: 10 216 | }] 217 | }, 218 | 219 | //// in object definition 220 | 221 | // basic jquery operator 222 | { 223 | code: 'var x = { foo: $() }', 224 | output: 'var x = { foo: $() }', 225 | errors: [{ 226 | message: errorMessage, 227 | type: 'Identifier', 228 | line: 1, 229 | column: 11 230 | }] 231 | }, 232 | // jquery operator with selector 233 | { 234 | code: 'var x = { foo: $(".foo") }', 235 | output: 'var x = { foo: $(".foo") }', 236 | errors: [{ 237 | message: errorMessage, 238 | type: 'Identifier', 239 | line: 1, 240 | column: 11 241 | }] 242 | }, 243 | // jquery operator with dollar and single quotes around selector 244 | { 245 | code: 'var $x = { foo: $(\'.foo\') }', 246 | output: 'var $x = { foo: $(\'.foo\') }', 247 | errors: [{ 248 | message: errorMessage, 249 | type: 'Identifier', 250 | line: 1, 251 | column: 12 252 | }] 253 | }, 254 | // keys besides the first 255 | { 256 | code: 'var x = { bar: 1, foo: $(".foo") }', 257 | output: 'var x = { bar: 1, foo: $(".foo") }', 258 | errors: [{ 259 | message: errorMessage, 260 | type: 'Identifier', 261 | line: 1, 262 | column: 19 263 | }] 264 | }, 265 | 266 | //// in object properties 267 | 268 | // basic jquery operator 269 | { 270 | code: 'this.x = $();', 271 | output: 'this.x = $();', 272 | errors: [{ 273 | message: errorMessage, 274 | type: 'Identifier', 275 | line: 1, 276 | column: 6 277 | }] 278 | }, 279 | // jquery operator with html 280 | { 281 | code: 'this.x = $("

foo

");', 282 | output: 'this.x = $("

foo

");', 283 | errors: [{ 284 | message: errorMessage, 285 | type: 'Identifier', 286 | line: 1, 287 | column: 6 288 | }] 289 | }, 290 | // jquery operator with selector 291 | { 292 | code: 'this.x = $(".foo");', 293 | output: 'this.x = $(".foo");', 294 | errors: [{ 295 | message: errorMessage, 296 | type: 'Identifier', 297 | line: 1, 298 | column: 6 299 | }] 300 | }, 301 | // multi level object assignment without dollar 302 | { 303 | code: 'a.b.c = $()', 304 | output: 'a.b.c = $()', 305 | errors: [{ 306 | message: errorMessage, 307 | type: 'Identifier', 308 | line: 1, 309 | column: 5 310 | }] 311 | }, 312 | 313 | //// option value `"ignoreProperties"` 314 | 315 | // basic jquery operator 316 | { 317 | code: 'var x = $();', 318 | output: 'var $x = $();', 319 | options: ['ignoreProperties'], 320 | errors: [{ 321 | message: errorMessage, 322 | type: 'Identifier', 323 | line: 1, 324 | column: 5 325 | }] 326 | }, 327 | 328 | //// Autofixing 329 | 330 | // autofix var usages 331 | { 332 | code: 'var x = $(".foo"); x.bar(); baz(x);', 333 | output: 'var $x = $(".foo"); $x.bar(); baz($x);', 334 | errors: [{ 335 | message: errorMessage, 336 | type: 'Identifier', 337 | line: 1, 338 | column: 5 339 | }, { 340 | message: errorMessage, 341 | type: 'Identifier', 342 | line: 1, 343 | column: 20 344 | }, { 345 | message: errorMessage, 346 | type: 'Identifier', 347 | line: 1, 348 | column: 33 349 | }] 350 | }, 351 | // autofix assignments to object properties 352 | { 353 | code: 'var x = $(".foo"); ({ abc: x }); this.def = x;', 354 | output: 'var $x = $(".foo"); ({ abc: $x }); this.def = $x;', 355 | errors: [{ 356 | message: errorMessage, 357 | type: 'Identifier', 358 | line: 1, 359 | column: 5 360 | }, { 361 | message: errorMessage, 362 | type: 'Identifier', 363 | line: 1, 364 | column: 28 365 | }, { 366 | message: errorMessage, 367 | type: 'Identifier', 368 | line: 1, 369 | column: 45 370 | }] 371 | }, 372 | // don't autofix object property keys 373 | { 374 | code: 'var x = $(".foo"); ({ x });', 375 | output: 'var x = $(".foo"); ({ x });', 376 | errors: [{ 377 | message: errorMessage, 378 | type: 'Identifier', 379 | line: 1, 380 | column: 5 381 | }, { 382 | message: errorMessage, 383 | type: 'Identifier', 384 | line: 1, 385 | column: 23 386 | }] 387 | }, 388 | // autofix shadowed vars in child scopes 389 | { 390 | code: 'var x; (function() { var x = $(); (function() { x; (function() { var x; }); }); });', 391 | output: 'var x; (function() { var $x = $(); (function() { $x; (function() { var x; }); }); });', 392 | errors: [{ 393 | message: errorMessage, 394 | type: 'Identifier', 395 | line: 1, 396 | column: 26 397 | }, { 398 | message: errorMessage, 399 | type: 'Identifier', 400 | line: 1, 401 | column: 49 402 | }] 403 | }, 404 | // autofix late-assigned vars 405 | { 406 | code: 'var x; x = $();', 407 | output: 'var $x; $x = $();', 408 | errors: [{ 409 | message: errorMessage, 410 | type: 'Identifier', 411 | line: 1, 412 | column: 5 413 | }, { 414 | message: errorMessage, 415 | type: 'Identifier', 416 | line: 1, 417 | column: 8 418 | }] 419 | } 420 | ] 421 | }); 422 | 423 | var ruleTesterTs = new RuleTester({ parser: require.resolve('@typescript-eslint/parser') }); 424 | ruleTesterTs.run('dollar-sign', rule, { 425 | valid: [ 426 | 'require([], function() {\n' + 427 | ' const ViewModel = (function() {\n' + 428 | ' const enum cfg {ENTRIES_PER_PAGE = 50};\n' + 429 | ' })();\n' + 430 | '});\n' 431 | ], 432 | invalid: [ 433 | { 434 | code: 'var x = $();', 435 | output: 'var $x = $();', 436 | errors: [{ 437 | message: errorMessage, 438 | type: 'Identifier', 439 | line: 1, 440 | column: 5 441 | }] 442 | } 443 | ] 444 | }); 445 | --------------------------------------------------------------------------------