diff --git a/.eslintrc.json b/.eslintrc.json index 7421a4eadb0..b552961207f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,13 @@ "node": true }, "plugins": ["jsdoc"], - "extends": ["eslint:recommended", "plugin:jsdoc/recommended", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:jsdoc/recommended", + "plugin:jest/recommended", + "plugin:node/recommended", + "prettier" + ], "globals": { "Set": true, "Symbol": true }, "rules": { "array-callback-return": [ @@ -35,6 +41,7 @@ "no-use-before-define": [2, "nofunc"], "no-void": 2, "yoda": 2, + "strict": 2, "jsdoc/require-jsdoc": 0, "jsdoc/check-param-names": 2, @@ -47,7 +54,10 @@ "jsdoc/require-param-name": 2, "jsdoc/require-param-type": 2, "jsdoc/require-param": 2, - "jsdoc/valid-types": 2 + "jsdoc/valid-types": 2, + + "node/no-unsupported-features/es-builtins": 0, // TODO + "node/shebang": 0 }, "settings": { "jsdoc": { diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js index 3b4f31c7687..2d614b03bfb 100755 --- a/benchmark/benchmark.js +++ b/benchmark/benchmark.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +'use strict'; var Suites = require('./suite'); var suites = new Suites(); @@ -6,8 +7,7 @@ var suites = new Suites(); var regexIdx = process.argv.indexOf('--regex') + 1; if (regexIdx > 0) { if (regexIdx === process.argv.length) { - console.error('Error: the "--regex" option requires a value'); - process.exit(1); + throw new Error('Error: the "--regex" option requires a value'); } suites.filter(process.argv[regexIdx]); } diff --git a/benchmark/suite.js b/benchmark/suite.js index 2f3db732e16..6a1aa4004db 100644 --- a/benchmark/suite.js +++ b/benchmark/suite.js @@ -1,3 +1,4 @@ +'use strict'; var fs = require('fs'); var path = require('path'); diff --git a/index.js b/index.js index 422691cc33d..f5a6c562800 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +'use strict'; /** * @module cheerio * @borrows static.load as load diff --git a/lib/api/attributes.js b/lib/api/attributes.js index 367e11d06cb..62bfcacaff2 100644 --- a/lib/api/attributes.js +++ b/lib/api/attributes.js @@ -1,3 +1,4 @@ +'use strict'; /** * Methods for getting and modifying attributes. * diff --git a/lib/api/css.js b/lib/api/css.js index 3786b028ee9..873ef6a1b14 100644 --- a/lib/api/css.js +++ b/lib/api/css.js @@ -1,3 +1,4 @@ +'use strict'; /** @module cheerio/css */ var domEach = require('../utils').domEach; diff --git a/lib/api/forms.js b/lib/api/forms.js index 8d627ed0ca6..46dc0747ea0 100644 --- a/lib/api/forms.js +++ b/lib/api/forms.js @@ -1,3 +1,4 @@ +'use strict'; /** @module cheerio/forms */ // https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js diff --git a/lib/api/manipulation.js b/lib/api/manipulation.js index 516a33848bc..01b75a46834 100644 --- a/lib/api/manipulation.js +++ b/lib/api/manipulation.js @@ -1,3 +1,4 @@ +'use strict'; /** * Methods for modifying the DOM structure. * diff --git a/lib/api/traversing.js b/lib/api/traversing.js index bd417beac8e..ef12a8e8856 100644 --- a/lib/api/traversing.js +++ b/lib/api/traversing.js @@ -1,3 +1,4 @@ +'use strict'; /** * Methods for traversing the DOM structure. * diff --git a/lib/cheerio.js b/lib/cheerio.js index fc72c4de741..b03942367af 100644 --- a/lib/cheerio.js +++ b/lib/cheerio.js @@ -1,3 +1,4 @@ +'use strict'; /* Module dependencies */ diff --git a/lib/options.js b/lib/options.js index 1f3b9a0af2a..8f6a7f0eaa1 100644 --- a/lib/options.js +++ b/lib/options.js @@ -1,3 +1,4 @@ +'use strict'; /** Cheerio default options. */ exports.default = { xml: false, diff --git a/lib/parse.js b/lib/parse.js index 09abc5d89da..3c884cf5474 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1,3 +1,4 @@ +'use strict'; /* Module Dependencies */ diff --git a/lib/parsers/htmlparser2.js b/lib/parsers/htmlparser2.js index 0564b492c8e..ec9c20d79c8 100644 --- a/lib/parsers/htmlparser2.js +++ b/lib/parsers/htmlparser2.js @@ -1,2 +1,3 @@ +'use strict'; exports.parse = require('htmlparser2').parseDocument; exports.render = require('dom-serializer').default; diff --git a/lib/parsers/parse5.js b/lib/parsers/parse5.js index 6b4c9bcb64a..870103c3f5c 100644 --- a/lib/parsers/parse5.js +++ b/lib/parsers/parse5.js @@ -1,3 +1,4 @@ +'use strict'; var parse5 = require('parse5'); var htmlparser2Adapter = require('parse5-htmlparser2-tree-adapter'); diff --git a/lib/static.js b/lib/static.js index cc76a5c543b..c496efeb6d1 100644 --- a/lib/static.js +++ b/lib/static.js @@ -1,3 +1,4 @@ +'use strict'; /** * @module cheerio/static * @ignore @@ -117,7 +118,7 @@ exports.html = function (dom, options) { options = Object.assign( {}, defaultOptions, - this._options, + this ? this._options : {}, flattenOptions(options || {}) ); diff --git a/lib/utils.js b/lib/utils.js index 95a01c476fe..aab06ce576c 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,4 @@ +'use strict'; var htmlparser2 = require('htmlparser2'); var domhandler = require('domhandler'); diff --git a/package-lock.json b/package-lock.json index f11d3a73a9e..d2b00d048e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -757,6 +757,12 @@ "@types/istanbul-lib-report": "*" } }, + "@types/json-schema": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "dev": true + }, "@types/minimist": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", @@ -808,6 +814,62 @@ "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", "dev": true }, + "@typescript-eslint/experimental-utils": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.11.1.tgz", + "integrity": "sha512-mAlWowT4A6h0TC9F+J5pdbEhjNiEMO+kqPKQ4sc3fVieKL71dEqfkKgtcFVSX3cjSBwYwhImaQ/mXQF0oaI38g==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.11.1", + "@typescript-eslint/types": "4.11.1", + "@typescript-eslint/typescript-estree": "4.11.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.11.1.tgz", + "integrity": "sha512-Al2P394dx+kXCl61fhrrZ1FTI7qsRDIUiVSuN6rTwss6lUn8uVO2+nnF4AvO0ug8vMsy3ShkbxLu/uWZdTtJMQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.11.1", + "@typescript-eslint/visitor-keys": "4.11.1" + } + }, + "@typescript-eslint/types": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.11.1.tgz", + "integrity": "sha512-5kvd38wZpqGY4yP/6W3qhYX6Hz0NwUbijVsX2rxczpY6OXaMxh0+5E5uLJKVFwaBM7PJe1wnMym85NfKYIh6CA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.11.1.tgz", + "integrity": "sha512-tC7MKZIMRTYxQhrVAFoJq/DlRwv1bnqA4/S2r3+HuHibqvbrPcyf858lNzU7bFmy4mLeIHFYr34ar/1KumwyRw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.11.1", + "@typescript-eslint/visitor-keys": "4.11.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.11.1.tgz", + "integrity": "sha512-IrlBhD9bm4bdYcS8xpWarazkKXlE7iYb1HzRuyBP114mIaj5DJPo11Us1HgH60dTt41TCZXMaTCAW+OILIYPOg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.11.1", + "eslint-visitor-keys": "^2.0.0" + } + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -2235,6 +2297,25 @@ "supports-hyperlinks": "^2.0.0" } }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-jest": { + "version": "24.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz", + "integrity": "sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, "eslint-plugin-jsdoc": { "version": "30.7.13", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.13.tgz", @@ -2250,6 +2331,34 @@ "spdx-expression-parse": "^3.0.1" } }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "eslint-rule-docs": { "version": "1.1.217", "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.217.tgz", @@ -5065,9 +5174,9 @@ "dev": true }, "prettier-plugin-jsdoc": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/prettier-plugin-jsdoc/-/prettier-plugin-jsdoc-0.2.12.tgz", - "integrity": "sha512-AijMY+SwUlsjusg1Cmubv82Zit5/Y5IlrWCXKPYrR1Axh8MNeER06prd8Rfl7WjjLI04Lih/CCsje67NzPB7kA==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/prettier-plugin-jsdoc/-/prettier-plugin-jsdoc-0.2.13.tgz", + "integrity": "sha512-8b4yTPPe07TmbiLQlufQaAZk3XzRuZRYIemuxUH4yuXC4I2bqrLKPR3nq58stkcuIhRqQwKBio4npI908N4Fvw==", "dev": true, "requires": { "comment-parser": "^0.7.6", @@ -6397,6 +6506,15 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "tsutils": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.18.0.tgz", + "integrity": "sha512-D9Tu8nE3E7D1Bsf/V29oMHceMf+gnVO+pDguk/A5YRo1cLpkiQ48ZnbbS57pvvHeY+OIeNQx1vf4ASPlEtRpcA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 619845d2bea..f4b6352f792 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,9 @@ "benchmark": "^2.1.4", "eslint": "^7.17.0", "eslint-config-prettier": "^7.1.0", + "eslint-plugin-jest": "^24.1.3", "eslint-plugin-jsdoc": "^30.7.13", + "eslint-plugin-node": "^11.1.0", "husky": "^4.3.6", "jest": "^26.6.3", "jquery": "^3.5.1", @@ -51,7 +53,7 @@ "jsdom": "^16.4.0", "lint-staged": "^10.5.3", "prettier": "^2.2.1", - "prettier-plugin-jsdoc": "^0.2.12", + "prettier-plugin-jsdoc": "^0.2.13", "tsd": "^0.14.0" }, "scripts": { @@ -68,6 +70,7 @@ "format:prettier:raw": "prettier \"**/*.{js,ts,md,json,yml}\" --ignore-path .gitignore", "build:docs": "jsdoc --configure jsdoc-config.json", "benchmark": "node benchmark/benchmark.js --regex \"^(?!.*highmem)\"", + "bench": "npm run benchmark", "pre-commit": "lint-staged" }, "prettier": { diff --git a/test/__fixtures__/fixtures.js b/test/__fixtures__/fixtures.js index cdfa0cccb71..79f85ca3f09 100644 --- a/test/__fixtures__/fixtures.js +++ b/test/__fixtures__/fixtures.js @@ -1,3 +1,4 @@ +'use strict'; exports.fruits = [ '
').wrapAll('
').parent(); expect(parent).toHaveLength(1); expect(parent.is('div')).toBe(true); diff --git a/test/api/traversing.js b/test/api/traversing.js index 6b475df1ee2..eea17f020a2 100644 --- a/test/api/traversing.js +++ b/test/api/traversing.js @@ -1,3 +1,4 @@ +'use strict'; var cheerio = require('../..'); var food = require('../__fixtures__/fixtures').food; var fruits = require('../__fixtures__/fixtures').fruits; @@ -13,16 +14,9 @@ describe('$(...)', function () { describe('.load', function () { it('should throw a TypeError if given invalid input', function () { - try { - (function () { - cheerio.load(); - })(); - - throw new Error('Function did not throw'); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err.message).toBe('cheerio.load() expects a string'); - } + expect(function () { + cheerio.load(); + }).toThrow('cheerio.load() expects a string'); }); }); @@ -81,16 +75,9 @@ describe('$(...)', function () { }); it('should throw an Error if given an invalid selector', function () { - try { - (function () { - $('#fruits').find(':bah'); - })(); - - throw new Error('Function did not throw'); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err.message).toContain('unmatched pseudo-class'); - } + expect(function () { + $('#fruits').find(':bah'); + }).toThrow('unmatched pseudo-class'); }); describe('(cheerio object) :', function () { @@ -464,16 +451,9 @@ describe('$(...)', function () { }); it('(selector) : should throw an Error if given an invalid selector', function () { - try { - (function () { - $('.orange').siblings(':bah'); - })(); - - throw new Error('Function did not throw'); - } catch (err) { - expect(err).toBeInstanceOf(Error); - expect(err.message).toContain('unmatched pseudo-class'); - } + expect(function () { + $('.orange').siblings(':bah'); + }).toThrow('unmatched pseudo-class'); }); it('(selector) : does not consider the contents of siblings when filtering (GH-374)', function () { diff --git a/test/api/utils.js b/test/api/utils.js index 1cd19d3066e..7cec4f7a961 100644 --- a/test/api/utils.js +++ b/test/api/utils.js @@ -1,3 +1,4 @@ +'use strict'; var fixtures = require('../__fixtures__/fixtures'); var cheerio = require('../..'); @@ -110,15 +111,16 @@ describe('cheerio', function () { expect($.html()).toBe('foo bar'); }); - // TODO: - // it('(html) : should handle xml tag option', function() { - // var $ = $.load('', { xml : true }); - // console.log($('script')[0].type); - // expect($('script')[0].type).to.be('tag'); - // }); + it('(html) : should handle xml tag option', function () { + var $ = cheerio.load('', { + xml: true, + }); + expect($('script')[0].children[0].type).toBe('tag'); + }); it('(buffer) : should accept a buffer', function () { var html = 'foo'; + // eslint-disable-next-line node/no-unsupported-features/node-builtins var $html = cheerio.load(Buffer.from(html)); expect($html.html()).toBe(html); }); diff --git a/test/cheerio.js b/test/cheerio.js index fe73fe466f4..674ea57f8ad 100644 --- a/test/cheerio.js +++ b/test/cheerio.js @@ -1,3 +1,4 @@ +'use strict'; var htmlparser2 = require('htmlparser2'); var cheerio = require('..'); var fixtures = require('./__fixtures__/fixtures'); diff --git a/test/parse.js b/test/parse.js index b0634cda273..d022eb82597 100644 --- a/test/parse.js +++ b/test/parse.js @@ -1,3 +1,4 @@ +'use strict'; var parse = require('../lib/parse'); var defaultOpts = require('../lib/options').default; @@ -210,7 +211,7 @@ describe('parse', function () { expect(root.childNodes[0].type).toBe('directive'); }); - it('should simply return root ', function () { + it('should simply return root', function () { var oldroot = parse(basic, defaultOpts, true); var root = parse(oldroot, defaultOpts, true); expect(root).toBe(oldroot); diff --git a/test/xml.js b/test/xml.js index 5e780ef9236..6fe0ce82f0f 100644 --- a/test/xml.js +++ b/test/xml.js @@ -1,3 +1,4 @@ +'use strict'; var cheerio = require('..'); function xml(str, options) { @@ -38,7 +39,7 @@ describe('render', function () { }); describe('(dom)', function () { - it('should keep camelCase for new nodes', function () { + it('should not keep camelCase for new nodes', function () { var str = '