From d4f153aee9404ba5794e562647d5ecc6aff193e9 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Tue, 16 Dec 2025 09:52:03 -0600 Subject: [PATCH 01/13] build: add ESLint rule to enforce no empty lines between module-level require statements --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: passed - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- etc/eslint/rules/stdlib.js | 21 ++ .../@stdlib/_tools/eslint/rules/lib/index.js | 9 + .../no-empty-lines-between-requires/README.md | 161 ++++++++++ .../examples/index.js | 58 ++++ .../lib/index.js | 39 +++ .../lib/main.js | 288 ++++++++++++++++++ .../package.json | 67 ++++ .../test/fixtures/invalid.js | 261 ++++++++++++++++ .../test/fixtures/unvalidated.js | 91 ++++++ .../test/fixtures/valid.js | 147 +++++++++ .../test/test.js | 86 ++++++ 11 files changed, 1228 insertions(+) create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js create mode 100644 lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js diff --git a/etc/eslint/rules/stdlib.js b/etc/eslint/rules/stdlib.js index 06fab9b03564..cfc51e8e65b8 100644 --- a/etc/eslint/rules/stdlib.js +++ b/etc/eslint/rules/stdlib.js @@ -4186,6 +4186,27 @@ rules[ 'stdlib/no-dynamic-require' ] = 'error'; */ rules[ 'stdlib/no-empty-comments' ] = 'error'; +/** +* Enforce no empty lines between module-level require statements. +* +* @name no-empty-lines-between-requires +* @memberof rules +* @type {string} +* @default 'error' +* +* @example +* // Bad... +* var foo = require( 'foo' ); +* +* var bar = require( 'bar' ); +* +* @example +* // Good... +* var foo = require( 'foo' ); +* var bar = require( 'bar' ); +*/ +rules[ 'stdlib/no-empty-lines-between-requires' ] = 'error'; + /** * Disallow string concatenation in error messages. * diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js index 976b805fae13..fcf6e671c4c9 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/lib/index.js @@ -900,6 +900,15 @@ setReadOnly( rules, 'no-dynamic-require', require( '@stdlib/_tools/eslint/rules/ */ setReadOnly( rules, 'no-empty-comments', require( '@stdlib/_tools/eslint/rules/no-empty-comments' ) ); +/** +* @name no-empty-lines-between-requires +* @memberof rules +* @readonly +* @type {Function} +* @see {@link module:@stdlib/_tools/eslint/rules/no-empty-lines-between-requires} +*/ +setReadOnly( rules, 'no-empty-lines-between-requires', require( '@stdlib/_tools/eslint/rules/no-empty-lines-between-requires' ) ); + /** * @name no-error-string-concat * @memberof rules diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md new file mode 100644 index 000000000000..9ec2f56f3e2a --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md @@ -0,0 +1,161 @@ + + +# no-empty-lines-between-requires + +> [ESLint rule][eslint-rules] to enforce no empty lines between module-level require statements. + +
+ +
+ + + +
+ +## Usage + +```javascript +var rule = require( '@stdlib/_tools/eslint/rules/no-empty-lines-between-requires' ); +``` + +#### rule + +[ESLint rule][eslint-rules] to enforce no empty lines between module-level require statements. Section header comments (such as `// FIXTURES //`) are allowed to separate groups of require statements. + +This rule only applies to top-level (module-level) require statements. Require statements inside functions or blocks are not checked. + +**Bad**: + + + + + +```javascript +var tape = require( 'tape' ); + +var isnan = require( '@stdlib/math/base/assert/is-nan' ); + +var abs = require( '@stdlib/math/base/special/abs' ); +``` + +**Good**: + + + + + +```javascript +var tape = require( 'tape' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var abs = require( '@stdlib/math/base/special/abs' ); +``` + +**Good** (section headers separate groups): + + + + + +```javascript +var tape = require( 'tape' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); + + +// FIXTURES // + +var data = require( './fixtures/data.json' ); +var expected = require( './fixtures/expected.json' ); +``` + +
+ + + +
+ +## Examples + + + +```javascript +var Linter = require( 'eslint' ).Linter; +var rule = require( '@stdlib/_tools/eslint/rules/no-empty-lines-between-requires' ); + +var linter = new Linter(); +var result; +var code; + +var opts = { + 'rules': { + 'no-empty-lines-between-requires': 'error' + } +}; +linter.defineRule( 'no-empty-lines-between-requires', rule ); + +code = [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + '', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' +].join( '\n' ); + +result = linter.verify( code, opts ); +console.log( result ); +/* => + [ + { + 'ruleId': 'no-empty-lines-between-requires', + 'severity': 2, + 'message': 'Unexpected empty line between require statements.', + 'line': 6, + 'column': 0, + 'nodeType': null, + 'endLine': 7, + 'endColumn': 0 + } + ] +*/ +``` + +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js new file mode 100644 index 000000000000..2899110b4027 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js @@ -0,0 +1,58 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Linter = require( 'eslint' ).Linter; +var rule = require( './../lib' ); + +var linter = new Linter(); +var result; +var code; + +var opts = { + 'rules': { + 'no-empty-lines-between-requires': 'error' + } +}; +linter.defineRule( 'no-empty-lines-between-requires', rule ); + +code = [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + '', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );', + '', + '', + '// TESTS //', + '', + 'tape( \'test\', function() {} );' +].join( '\n' ); + +result = linter.verifyAndFix( code, opts ); +console.log( result ); +/* => + { + 'fixed': true, + 'messages': [], + 'output': '\'use strict\';\n\n// MODULES //\n\nvar tape = require( \'tape\' );\nvar isnan = require( \'@stdlib/math/base/assert/is-nan\' );\n\n\n// TESTS //\n\ntape( \'test\', function() {} );' + } +*/ diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js new file mode 100644 index 000000000000..47cb9c3b1b73 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js @@ -0,0 +1,39 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* ESLint rule to enforce no empty lines between module-level require statements. +* +* @module @stdlib/_tools/eslint/rules/no-empty-lines-between-requires +* +* @example +* var rule = require( '@stdlib/_tools/eslint/rules/no-empty-lines-between-requires' ); +* +* console.log( rule ); +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js new file mode 100644 index 000000000000..1a14329a0896 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js @@ -0,0 +1,288 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var endsWith = require( '@stdlib/string/ends-with' ); +var trim = require( '@stdlib/string/trim' ); + + +// VARIABLES // + +var REGEXP_HEADER = /^( )*[A-Z][A-Z0-9 ]+( )*(\/\/)?$/; +var rule; + + +// FUNCTIONS // + +/** +* Checks whether a comment is a section header. +* +* @private +* @param {Object} comment - comment object +* @returns {boolean} boolean indicating if a comment denotes a section header +*/ +function isSectionHeader( comment ) { + var val; + if ( comment.type !== 'Line' ) { + return false; + } + val = comment.value; + return REGEXP_HEADER.test( val ) || endsWith( val, '//' ); +} + +/** +* Checks whether a VariableDeclaration contains a require call. +* +* @private +* @param {ASTNode} node - AST node +* @returns {boolean} boolean indicating if node is a require declaration +*/ +function isRequireDeclaration( node ) { + var init; + var decl; + if ( + node.type !== 'VariableDeclaration' || + !node.declarations || + node.declarations.length === 0 + ) { + return false; + } + decl = node.declarations[ 0 ]; + init = decl.init; + if ( !init ) { + return false; + } + // Handle: var foo = require( 'bar' ); + if ( + init.type === 'CallExpression' && + init.callee && + init.callee.type === 'Identifier' && + init.callee.name === 'require' + ) { + return true; + } + // Handle: var foo = require( 'bar' ).baz; + if ( + init.type === 'MemberExpression' && + init.object && + init.object.type === 'CallExpression' && + init.object.callee && + init.object.callee.type === 'Identifier' && + init.object.callee.name === 'require' + ) { + return true; + } + return false; +} + +/** +* Rule for validating that there are no empty lines between module-level require statements. +* +* @param {Object} context - ESLint context +* @returns {Object} validators +*/ +function main( context ) { + var source = context.getSourceCode(); + var lines = source.lines; + + /** + * Checks whether there is a section header comment between two nodes. + * + * @private + * @param {ASTNode} prevNode - previous node + * @param {ASTNode} currNode - current node + * @returns {boolean} boolean indicating if a section header exists between nodes + */ + function hasSectionHeaderBetween( prevNode, currNode ) { + var comments; + var i; + + comments = source.getCommentsBefore( currNode ); + for ( i = 0; i < comments.length; i++ ) { + if ( + comments[ i ].loc.start.line > prevNode.loc.end.line && + isSectionHeader( comments[ i ] ) + ) { + return true; + } + } + return false; + } + + /** + * Checks whether there are empty lines between two nodes. + * + * @private + * @param {ASTNode} prevNode - previous node + * @param {ASTNode} currNode - current node + * @returns {boolean} boolean indicating if empty lines exist between the nodes + */ + function hasEmptyLinesBetween( prevNode, currNode ) { + var startLine; + var endLine; + var line; + var i; + + startLine = prevNode.loc.end.line; + endLine = currNode.loc.start.line; + + // Check each line between the two nodes + for ( i = startLine; i < endLine - 1; i++ ) { + line = lines[ i ]; // lines array is 0-indexed + if ( trim( line ) === '' ) { + return true; + } + } + return false; + } + + /** + * Reports the error message. + * + * @private + * @param {ASTNode} prevNode - previous require node + * @param {ASTNode} currNode - current require node + */ + function report( prevNode, currNode ) { + var loc = { + 'start': { + 'line': prevNode.loc.end.line + 1, + 'column': 0 + }, + 'end': { + 'line': currNode.loc.start.line, + 'column': 0 + } + }; + + context.report({ + 'node': null, + 'message': 'Unexpected empty line between require statements.', + 'loc': loc, + 'fix': fix + }); + + /** + * Fixes the lint error by removing empty lines between requires. + * + * @private + * @param {Object} fixer - ESLint fixer + * @returns {Object} fix + */ + function fix( fixer ) { + var replacement; + var startOfNext; + var startLine; + var endOfPrev; + var nonEmpty; + var endLine; + var range; + var line; + var i; + + // Get the range between the two requires + endOfPrev = prevNode.range[ 1 ]; + startOfNext = source.getIndexFromLoc({ + 'line': currNode.loc.start.line, + 'column': 0 + }); + + // Collect non-empty lines between the requires + startLine = prevNode.loc.end.line; + endLine = currNode.loc.start.line; + nonEmpty = []; + for ( i = startLine; i < endLine - 1; i++ ) { + line = lines[ i ]; // lines array is 0-indexed + if ( trim( line ) !== '' ) { + nonEmpty.push( line ); + } + } + + // Build replacement: newline + non-empty lines (each with newline) + final newline for current require + if ( nonEmpty.length === 0 ) { + replacement = '\n'; + } else { + replacement = '\n' + nonEmpty.join( '\n' ) + '\n'; + } + + range = [ endOfPrev, startOfNext ]; + return fixer.replaceTextRange( range, replacement ); + } + } + + /** + * Validates module-level require statements on program exit. + * + * @private + * @param {ASTNode} program - program node + */ + function validate( program ) { + var prevRequire; + var body; + var node; + var i; + + body = program.body; + prevRequire = null; + + for ( i = 0; i < body.length; i++ ) { + node = body[ i ]; + if ( isRequireDeclaration( node ) ) { + if ( prevRequire !== null ) { + // Check for empty lines between requires (even if other statements are in between) + if ( + hasEmptyLinesBetween( prevRequire, node ) && + !hasSectionHeaderBetween( prevRequire, node ) + ) { + report( prevRequire, node ); + } + } + prevRequire = node; + } + // Note: non-require statements do NOT reset prevRequire + // Empty lines between any two requires should be flagged + } + } + + return { + 'Program:exit': validate + }; +} + + +// MAIN // + +rule = { + 'meta': { + 'type': 'layout', + 'docs': { + 'description': 'enforce no empty lines between module-level require statements' + }, + 'fixable': 'whitespace', + 'schema': [] + }, + 'create': main +}; + + +// EXPORTS // + +module.exports = rule; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json new file mode 100644 index 000000000000..3efa203d3d9d --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/_tools/eslint/rules/no-empty-lines-between-requires", + "version": "0.0.0", + "description": "ESLint rule to enforce no empty lines between module-level require statements.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "bin": {}, + "main": "./lib", + "directories": { + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "tools", + "tool", + "eslint", + "lint", + "custom", + "rules", + "rule", + "plugin", + "require", + "import", + "empty", + "line", + "whitespace", + "newline", + "spacing" + ] +} diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js new file mode 100644 index 000000000000..a13f023aa0f9 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js @@ -0,0 +1,261 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var invalid = []; +var test; + +// Empty line between consecutive requires +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + '', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Multiple empty lines between requires +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + '', + '', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty line in middle of multiple requires +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );', + '', + 'var abs = require( \'./../lib\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );', + 'var abs = require( \'./../lib\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty lines in FIXTURES section (no section header between) +test = { + 'code': [ + '\'use strict\';', + '', + '// FIXTURES //', + '', + 'var data = require( \'./fixtures/data.json\' );', + '', + 'var expected = require( \'./fixtures/expected.json\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// FIXTURES //', + '', + 'var data = require( \'./fixtures/data.json\' );', + 'var expected = require( \'./fixtures/expected.json\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Multiple consecutive errors +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var a = require( \'a\' );', + '', + 'var b = require( \'b\' );', + '', + 'var c = require( \'c\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + }, + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var a = require( \'a\' );', + 'var b = require( \'b\' );', + 'var c = require( \'c\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty line before a regular comment (not a section header) +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var foo = require( \'foo\' );', + '', + '// A regular comment', + 'var bar = require( \'bar\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var foo = require( \'foo\' );', + '// A regular comment', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty line with require using property access +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var isString = require( \'@stdlib/assert/is-string\' ).isPrimitive;', + '', + 'var format = require( \'@stdlib/string/format\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var isString = require( \'@stdlib/assert/is-string\' ).isPrimitive;', + 'var format = require( \'@stdlib/string/format\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty line between requires separated by non-require statement +test = { + 'code': [ + '\'use strict\';', + '', + 'var foo = require( \'foo\' );', + 'var x = 1;', + '', + 'var bar = require( \'bar\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + 'var foo = require( \'foo\' );', + 'var x = 1;', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +invalid.push( test ); + + +// EXPORTS // + +module.exports = invalid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js new file mode 100644 index 000000000000..81c7c84f7d0d --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js @@ -0,0 +1,91 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var valid = []; +var test; + +// Non-require variable declarations (not validated) +test = { + 'code': [ + '\'use strict\';', + '', + '// VARIABLES //', + '', + 'var x = 1;', + '', + 'var y = 2;' + ].join( '\n' ) +}; +valid.push( test ); + +// Dynamic require (variable path - not a simple require pattern) +test = { + 'code': [ + '\'use strict\';', + '', + 'var path = \'./foo\';', + '', + 'var foo = require( path );' + ].join( '\n' ) +}; +valid.push( test ); + +// Require without assignment (expression statement, not variable declaration) +test = { + 'code': [ + '\'use strict\';', + '', + 'require( \'./setup\' );', + '', + 'require( \'./teardown\' );' + ].join( '\n' ) +}; +valid.push( test ); + +// Require in conditional (not module-level) +test = { + 'code': [ + '\'use strict\';', + '', + 'if ( condition ) {', + ' var foo = require( \'foo\' );', + '', + ' var bar = require( \'bar\' );', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +// Empty file +test = { + 'code': '' +}; +valid.push( test ); + +// File with only use strict +test = { + 'code': '\'use strict\';' +}; +valid.push( test ); + + +// EXPORTS // + +module.exports = valid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js new file mode 100644 index 000000000000..40376290080c --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -0,0 +1,147 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var valid = []; +var test; + +// Basic: consecutive requires without empty lines +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );', + 'var abs = require( \'./../lib\' );', + '', + '', + '// TESTS //', + '', + 'tape( \'test\', function() {} );' + ].join( '\n' ) +}; +valid.push( test ); + +// Test file with FIXTURES section - empty lines around section header are OK +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var tape = require( \'tape\' );', + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );', + '', + '', + '// FIXTURES //', + '', + 'var data = require( \'./fixtures/data.json\' );', + 'var expected = require( \'./fixtures/expected.json\' );', + '', + '', + '// TESTS //', + '', + 'tape( \'test\', function() {} );' + ].join( '\n' ) +}; +valid.push( test ); + +// Single require statement (nothing to check) +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var main = require( \'./main.js\' );', + '', + '', + '// EXPORTS //', + '', + 'module.exports = main;' + ].join( '\n' ) +}; +valid.push( test ); + +// Require with property access: var foo = require( 'bar' ).baz; +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var isString = require( \'@stdlib/assert/is-string\' ).isPrimitive;', + 'var format = require( \'@stdlib/string/format\' );', + '', + '', + '// MAIN //', + '', + 'function main() {}' + ].join( '\n' ) +}; +valid.push( test ); + +// No require statements at all +test = { + 'code': [ + '\'use strict\';', + '', + '// MAIN //', + '', + 'function foo() {', + ' return 1;', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +// Requires inside functions are not checked (only module-level) +test = { + 'code': [ + '\'use strict\';', + '', + 'function helper() {', + ' var a = require( \'a\' );', + '', + ' var b = require( \'b\' );', + '}' + ].join( '\n' ) +}; +valid.push( test ); + +// Comments (non-header) between requires are allowed if no empty lines +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var foo = require( \'foo\' );', + '// A regular comment', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +valid.push( test ); + + +// EXPORTS // + +module.exports = valid; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js new file mode 100644 index 000000000000..dcc06f7c75e0 --- /dev/null +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js @@ -0,0 +1,86 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var RuleTester = require( 'eslint' ).RuleTester; +var rule = require( './../lib' ); + + +// FIXTURES // + +var valid = require( './fixtures/valid.js' ); +var invalid = require( './fixtures/invalid.js' ); +var unvalidated = require( './fixtures/unvalidated.js' ); + + +// TESTS // + +tape( 'main export is an object', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof rule, 'object', 'main export is an object' ); + t.end(); +}); + +tape( 'the rule positively validates code where module-level require statements have no empty lines between them', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'no-empty-lines-between-requires', rule, { + 'valid': valid, + 'invalid': [] + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); + +tape( 'the rule negatively validates code where module-level require statements have empty lines between them', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'no-empty-lines-between-requires', rule, { + 'valid': [], + 'invalid': invalid + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); + +tape( 'the rule does not validate non-require declarations or non-module-level requires', function test( t ) { + var tester = new RuleTester(); + + try { + tester.run( 'no-empty-lines-between-requires', rule, { + 'valid': unvalidated, + 'invalid': [] + }); + t.pass( 'passed without errors' ); + } catch ( err ) { + t.fail( 'encountered an error: ' + err.message ); + } + t.end(); +}); From 1457ef5e8c523d875905de8642feda0e34af9a16 Mon Sep 17 00:00:00 2001 From: Philipp Burckhardt Date: Thu, 1 Jan 2026 23:22:57 -0600 Subject: [PATCH 02/13] fix: add column check to `isSectionHeader` and expand test coverage --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../lib/main.js | 5 +- .../test/fixtures/invalid.js | 91 +++++++++++++++++++ .../test/fixtures/valid.js | 32 +++++++ 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js index 1a14329a0896..582916b8411e 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js @@ -41,7 +41,10 @@ var rule; */ function isSectionHeader( comment ) { var val; - if ( comment.type !== 'Line' ) { + if ( + comment.type !== 'Line' || + comment.loc.start.column !== 0 + ) { return false; } val = comment.value; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js index a13f023aa0f9..f8f78937e0d2 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js @@ -255,6 +255,97 @@ test = { }; invalid.push( test ); +// Empty line between multi-line require statements +test = { + 'code': [ + '\'use strict\';', + '', + 'var foo = require(', + ' \'some/very/long/path/to/module\'', + ');', + '', + 'var bar = require( \'bar\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + 'var foo = require(', + ' \'some/very/long/path/to/module\'', + ');', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +invalid.push( test ); + +// Empty line after multi-line require followed by another multi-line require +test = { + 'code': [ + '\'use strict\';', + '', + 'var foo = require(', + ' \'path/one\'', + ');', + '', + 'var bar = require(', + ' \'path/two\'', + ');' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + 'var foo = require(', + ' \'path/one\'', + ');', + 'var bar = require(', + ' \'path/two\'', + ');' + ].join( '\n' ) +}; +invalid.push( test ); + +// Multiple non-require statements between requires with empty lines +test = { + 'code': [ + '\'use strict\';', + '', + 'var foo = require( \'foo\' );', + 'var x = 1;', + '', + 'var y = 2;', + 'var z = x + y;', + '', + 'var bar = require( \'bar\' );' + ].join( '\n' ), + 'errors': [ + { + 'message': 'Unexpected empty line between require statements.', + 'type': null + } + ], + 'output': [ + '\'use strict\';', + '', + 'var foo = require( \'foo\' );', + 'var x = 1;', + 'var y = 2;', + 'var z = x + y;', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +invalid.push( test ); + // EXPORTS // diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js index 40376290080c..317180dc94e8 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -141,6 +141,38 @@ test = { }; valid.push( test ); +// Multi-line require statements without empty lines between +test = { + 'code': [ + '\'use strict\';', + '', + '// MODULES //', + '', + 'var foo = require(', + ' \'some/very/long/path/to/module\'', + ');', + 'var bar = require( \'bar\' );', + 'var baz = require(', + ' \'another/long/path\'', + ');' + ].join( '\n' ) +}; +valid.push( test ); + +// Multiple non-require statements between requires without empty lines +test = { + 'code': [ + '\'use strict\';', + '', + 'var foo = require( \'foo\' );', + 'var x = 1;', + 'var y = 2;', + 'var z = x + y;', + 'var bar = require( \'bar\' );' + ].join( '\n' ) +}; +valid.push( test ); + // EXPORTS // From 6fa3fecf5957c96882d6a1ed7512415705796426 Mon Sep 17 00:00:00 2001 From: stdlib-bot <82920195+stdlib-bot@users.noreply.github.com> Date: Fri, 2 Jan 2026 05:29:27 +0000 Subject: [PATCH 03/13] chore: update copyright years --- .../eslint/rules/no-empty-lines-between-requires/README.md | 2 +- .../rules/no-empty-lines-between-requires/examples/index.js | 2 +- .../eslint/rules/no-empty-lines-between-requires/lib/index.js | 2 +- .../eslint/rules/no-empty-lines-between-requires/lib/main.js | 2 +- .../no-empty-lines-between-requires/test/fixtures/invalid.js | 2 +- .../test/fixtures/unvalidated.js | 2 +- .../no-empty-lines-between-requires/test/fixtures/valid.js | 2 +- .../eslint/rules/no-empty-lines-between-requires/test/test.js | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md index 9ec2f56f3e2a..7711f8a9f716 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md @@ -2,7 +2,7 @@ @license Apache-2.0 -Copyright (c) 2025 The Stdlib Authors. +Copyright (c) 2026 The Stdlib Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js index 2899110b4027..90e7fd48bbc2 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js index 47cb9c3b1b73..a182a71f00de 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js index 582916b8411e..4d41b936e99e 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js index f8f78937e0d2..94a4219f3f60 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js index 81c7c84f7d0d..f8bc25f5e0ac 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js index 317180dc94e8..b98470136502 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js index dcc06f7c75e0..a36e557a03bf 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/test.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 35d713832404f5937c3a22145c4c94a7ccf9270c Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:05:10 -0800 Subject: [PATCH 04/13] Apply suggestions from code review Signed-off-by: Athan --- .../eslint/rules/no-empty-lines-between-requires/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md index 7711f8a9f716..fab46cd1a572 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/README.md @@ -100,8 +100,6 @@ var Linter = require( 'eslint' ).Linter; var rule = require( '@stdlib/_tools/eslint/rules/no-empty-lines-between-requires' ); var linter = new Linter(); -var result; -var code; var opts = { 'rules': { @@ -110,7 +108,7 @@ var opts = { }; linter.defineRule( 'no-empty-lines-between-requires', rule ); -code = [ +var code = [ '\'use strict\';', '', '// MODULES //', @@ -120,7 +118,7 @@ code = [ 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' );' ].join( '\n' ); -result = linter.verify( code, opts ); +var result = linter.verify( code, opts ); console.log( result ); /* => [ From 1a3cc8ea645020a1bf5868c11226bf3ac5d2f367 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:06:03 -0800 Subject: [PATCH 05/13] docs: update example Signed-off-by: Athan --- .../rules/no-empty-lines-between-requires/examples/index.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js index 90e7fd48bbc2..8bed0b78776c 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/examples/index.js @@ -22,8 +22,6 @@ var Linter = require( 'eslint' ).Linter; var rule = require( './../lib' ); var linter = new Linter(); -var result; -var code; var opts = { 'rules': { @@ -32,7 +30,7 @@ var opts = { }; linter.defineRule( 'no-empty-lines-between-requires', rule ); -code = [ +var code = [ '\'use strict\';', '', '// MODULES //', @@ -47,7 +45,7 @@ code = [ 'tape( \'test\', function() {} );' ].join( '\n' ); -result = linter.verifyAndFix( code, opts ); +var result = linter.verifyAndFix( code, opts ); console.log( result ); /* => { From b6ac76510f6201816e5bc67f2ba96314ae1fea38 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:09:25 -0800 Subject: [PATCH 06/13] docs: remove comment Signed-off-by: Athan --- .../eslint/rules/no-empty-lines-between-requires/lib/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js index 4d41b936e99e..bfca60d11ac7 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js @@ -148,8 +148,8 @@ function main( context ) { endLine = currNode.loc.start.line; // Check each line between the two nodes - for ( i = startLine; i < endLine - 1; i++ ) { - line = lines[ i ]; // lines array is 0-indexed + for ( i = startLine; i < endLine-1; i++ ) { + line = lines[ i ]; if ( trim( line ) === '' ) { return true; } From 217da794ce30cd4a72271f39779d0c96da03fff2 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:11:42 -0800 Subject: [PATCH 07/13] chore: remove field Signed-off-by: Athan --- .../eslint/rules/no-empty-lines-between-requires/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json index 3efa203d3d9d..18f4ab48ec08 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/package.json @@ -13,7 +13,6 @@ "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" } ], - "bin": {}, "main": "./lib", "directories": { "example": "./examples", From 51fc782f00c546723c0ad72a7671ef36fb1d0543 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:15:56 -0800 Subject: [PATCH 08/13] chore: clean-up Signed-off-by: Athan --- .../no-empty-lines-between-requires/lib/main.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js index bfca60d11ac7..77418adfd7ff 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/lib/main.js @@ -147,7 +147,7 @@ function main( context ) { startLine = prevNode.loc.end.line; endLine = currNode.loc.start.line; - // Check each line between the two nodes + // Check each line between the two nodes... for ( i = startLine; i < endLine-1; i++ ) { line = lines[ i ]; if ( trim( line ) === '' ) { @@ -201,19 +201,19 @@ function main( context ) { var line; var i; - // Get the range between the two requires + // Get the range between the two requires... endOfPrev = prevNode.range[ 1 ]; startOfNext = source.getIndexFromLoc({ 'line': currNode.loc.start.line, 'column': 0 }); - // Collect non-empty lines between the requires + // Collect non-empty lines between the requires... startLine = prevNode.loc.end.line; endLine = currNode.loc.start.line; nonEmpty = []; for ( i = startLine; i < endLine - 1; i++ ) { - line = lines[ i ]; // lines array is 0-indexed + line = lines[ i ]; if ( trim( line ) !== '' ) { nonEmpty.push( line ); } @@ -225,14 +225,13 @@ function main( context ) { } else { replacement = '\n' + nonEmpty.join( '\n' ) + '\n'; } - range = [ endOfPrev, startOfNext ]; return fixer.replaceTextRange( range, replacement ); } } /** - * Validates module-level require statements on program exit. + * Validates module-level require statements. * * @private * @param {ASTNode} program - program node @@ -250,7 +249,7 @@ function main( context ) { node = body[ i ]; if ( isRequireDeclaration( node ) ) { if ( prevRequire !== null ) { - // Check for empty lines between requires (even if other statements are in between) + // Check for empty lines between requires... if ( hasEmptyLinesBetween( prevRequire, node ) && !hasSectionHeaderBetween( prevRequire, node ) @@ -260,8 +259,6 @@ function main( context ) { } prevRequire = node; } - // Note: non-require statements do NOT reset prevRequire - // Empty lines between any two requires should be flagged } } From bc27ed2b04df2531636a1d33cbefa0bfe2a55aa8 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:17:32 -0800 Subject: [PATCH 09/13] docs: update comments Signed-off-by: Athan --- .../test/fixtures/invalid.js | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js index 94a4219f3f60..74b1d52c3a4b 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/invalid.js @@ -19,10 +19,9 @@ 'use strict'; var invalid = []; -var test; -// Empty line between consecutive requires -test = { +// Empty line between consecutive requires: +var test = { 'code': [ '\'use strict\';', '', @@ -49,7 +48,7 @@ test = { }; invalid.push( test ); -// Multiple empty lines between requires +// Multiple empty lines between requires: test = { 'code': [ '\'use strict\';', @@ -78,7 +77,7 @@ test = { }; invalid.push( test ); -// Empty line in middle of multiple requires +// Empty line in middle of multiple requires: test = { 'code': [ '\'use strict\';', @@ -108,7 +107,7 @@ test = { }; invalid.push( test ); -// Empty lines in FIXTURES section (no section header between) +// Empty lines in FIXTURES section (no section header between): test = { 'code': [ '\'use strict\';', @@ -136,7 +135,7 @@ test = { }; invalid.push( test ); -// Multiple consecutive errors +// Multiple consecutive errors: test = { 'code': [ '\'use strict\';', @@ -171,7 +170,7 @@ test = { }; invalid.push( test ); -// Empty line before a regular comment (not a section header) +// Empty line before a regular comment (not a section header): test = { 'code': [ '\'use strict\';', @@ -201,7 +200,7 @@ test = { }; invalid.push( test ); -// Empty line with require using property access +// Empty line with require using property access: test = { 'code': [ '\'use strict\';', @@ -229,7 +228,7 @@ test = { }; invalid.push( test ); -// Empty line between requires separated by non-require statement +// Empty line between requires separated by non-require statement: test = { 'code': [ '\'use strict\';', @@ -255,7 +254,7 @@ test = { }; invalid.push( test ); -// Empty line between multi-line require statements +// Empty line between multi-line require statements: test = { 'code': [ '\'use strict\';', @@ -283,7 +282,7 @@ test = { }; invalid.push( test ); -// Empty line after multi-line require followed by another multi-line require +// Empty line after multi-line require followed by another multi-line require: test = { 'code': [ '\'use strict\';', @@ -315,7 +314,7 @@ test = { }; invalid.push( test ); -// Multiple non-require statements between requires with empty lines +// Multiple non-require statements between requires with empty lines: test = { 'code': [ '\'use strict\';', From 4be5a256bfee8124b73a882f09c454ea3b9ef118 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:19:49 -0800 Subject: [PATCH 10/13] docs: update comments Signed-off-by: Athan --- .../test/fixtures/unvalidated.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js index f8bc25f5e0ac..6e5594e5198e 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js @@ -21,7 +21,7 @@ var valid = []; var test; -// Non-require variable declarations (not validated) +// Non-require variable declarations (not validated): test = { 'code': [ '\'use strict\';', @@ -35,7 +35,7 @@ test = { }; valid.push( test ); -// Dynamic require (variable path - not a simple require pattern) +// Dynamic require (variable path: not a simple require pattern): test = { 'code': [ '\'use strict\';', @@ -47,7 +47,7 @@ test = { }; valid.push( test ); -// Require without assignment (expression statement, not variable declaration) +// Require without assignment (expression statement, not variable declaration): test = { 'code': [ '\'use strict\';', @@ -59,7 +59,7 @@ test = { }; valid.push( test ); -// Require in conditional (not module-level) +// Require in conditional (not module-level): test = { 'code': [ '\'use strict\';', @@ -73,13 +73,13 @@ test = { }; valid.push( test ); -// Empty file +// Empty file: test = { 'code': '' }; valid.push( test ); -// File with only use strict +// File with only use strict: test = { 'code': '\'use strict\';' }; From 1167310f7e38a943bd9b705c5a539b8346874729 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:21:28 -0800 Subject: [PATCH 11/13] docs: update comments Signed-off-by: Athan --- .../test/fixtures/valid.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js index b98470136502..347e3f333282 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -21,7 +21,7 @@ var valid = []; var test; -// Basic: consecutive requires without empty lines +// Consecutive requires without empty lines: test = { 'code': [ '\'use strict\';', @@ -40,7 +40,7 @@ test = { }; valid.push( test ); -// Test file with FIXTURES section - empty lines around section header are OK +// Test file with FIXTURES section (empty lines around section header are OK): test = { 'code': [ '\'use strict\';', @@ -64,7 +64,7 @@ test = { }; valid.push( test ); -// Single require statement (nothing to check) +// Single require statement (nothing to check): test = { 'code': [ '\'use strict\';', @@ -99,7 +99,7 @@ test = { }; valid.push( test ); -// No require statements at all +// No require statements: test = { 'code': [ '\'use strict\';', @@ -113,7 +113,7 @@ test = { }; valid.push( test ); -// Requires inside functions are not checked (only module-level) +// Requires inside functions are not checked (only module-level): test = { 'code': [ '\'use strict\';', @@ -127,7 +127,7 @@ test = { }; valid.push( test ); -// Comments (non-header) between requires are allowed if no empty lines +// Comments (non-header) between requires are allowed if no empty lines: test = { 'code': [ '\'use strict\';', @@ -141,7 +141,7 @@ test = { }; valid.push( test ); -// Multi-line require statements without empty lines between +// Multi-line require statements without empty lines between: test = { 'code': [ '\'use strict\';', @@ -159,7 +159,7 @@ test = { }; valid.push( test ); -// Multiple non-require statements between requires without empty lines +// Multiple non-require statements between requires without empty lines: test = { 'code': [ '\'use strict\';', From 62cb2c5bff2cbf8c7bd8631df4707b0b1d23e7d5 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:22:08 -0800 Subject: [PATCH 12/13] chore: move declaration Signed-off-by: Athan --- .../test/fixtures/unvalidated.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js index 6e5594e5198e..b00fdc1811d8 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/unvalidated.js @@ -19,10 +19,9 @@ 'use strict'; var valid = []; -var test; // Non-require variable declarations (not validated): -test = { +var test = { 'code': [ '\'use strict\';', '', From 8323128eb5c7d8b9a0b9db8859e42778c306f181 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 2 Jan 2026 00:22:37 -0800 Subject: [PATCH 13/13] chore: move declaration Signed-off-by: Athan --- .../no-empty-lines-between-requires/test/fixtures/valid.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js index 347e3f333282..658b136c16de 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -19,10 +19,9 @@ 'use strict'; var valid = []; -var test; // Consecutive requires without empty lines: -test = { +var test = { 'code': [ '\'use strict\';', '',