diff --git a/.eslintrc.js b/.eslintrc.js index fd3553f..990eaf8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,6 +35,7 @@ module.exports = { }, ], 'import/prefer-default-export': 'off', + '@typescript-eslint/explicit-function-return-type': 'warn', 'class-methods-use-this': 'off', 'prettier/prettier': [ 'error', @@ -43,12 +44,36 @@ module.exports = { }, ], 'no-unused-vars': 'warn', + '@typescript-eslint/no-explicit-any': 'error', 'no-plusplus': [ 'warn', { allowForLoopAfterthoughts: true, }, ], + 'max-len': [ + 'warn', + { + code: 500, + tabWidth: 2, + comments: 250, + ignoreComments: false, + ignoreTrailingComments: true, + ignoreUrls: true, + ignoreStrings: true, + ignoreTemplateLiterals: true, + ignoreRegExpLiterals: true, + }, + ], }, + overrides: [ + { + // enable the rule specifically for TypeScript files + files: ['*.ts', '*.tsx'], + rules: { + '@typescript-eslint/explicit-function-return-type': ['error'], + }, + }, + ], ignorePatterns: ['dist/**', 'coverage/**'], }; diff --git a/.prettierrc.js b/.prettierrc.js index 89b964c..4095113 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,4 +2,5 @@ module.exports = { semi: true, trailingComma: 'all', singleQuote: true, + printWidth: 120, }; diff --git a/README.md b/README.md index 24fc51e..8f9e0a4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # NgTestGenerator Angular unit test generator for component render tests. +This is literally the opposite of TDD. ## Setup 1. Clone this repository with `git clone https://github.com/nishant/NgTestGenerator.git` diff --git a/package-lock.json b/package-lock.json index d4347f4..a07d3cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,12 @@ "": { "version": "1.0.0", "license": "ISC", + "dependencies": { + "@types/glob": "^7.1.4", + "glob": "^7.1.7", + "node-html-parser": "^4.1.4", + "tslog": "^3.2.1" + }, "devDependencies": { "@types/node": "^16.7.5", "@typescript-eslint/eslint-plugin": "^4.29.3", @@ -755,6 +761,15 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -767,11 +782,15 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, "node_modules/@types/node": { "version": "16.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.5.tgz", - "integrity": "sha512-E7SpxDXoHEpmZ9C1gSqwadhE6zPRtf3g0gJy9Y51DsImnR5TcDs3QEiV/3Q7zOM8LWaZp5Gph71NK6ElVMG1IQ==", - "dev": true + "integrity": "sha512-E7SpxDXoHEpmZ9C1gSqwadhE6zPRtf3g0gJy9Y51DsImnR5TcDs3QEiV/3Q7zOM8LWaZp5Gph71NK6ElVMG1IQ==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1338,8 +1357,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -1350,6 +1368,11 @@ "node": ">=8" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, "node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -1376,7 +1399,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1417,6 +1439,11 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "node_modules/builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -1648,8 +1675,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "node_modules/configstore": { "version": "5.0.1", @@ -1724,6 +1750,32 @@ "node": ">=8" } }, + "node_modules/css-select": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", @@ -1818,6 +1870,57 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", + "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -1869,6 +1972,14 @@ "node": ">=8.6" } }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2836,8 +2947,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/fsevents": { "version": "2.3.2", @@ -2904,7 +3014,6 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3097,6 +3206,14 @@ "node": ">=8" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -3162,7 +3279,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3171,8 +3287,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.7", @@ -3774,7 +3889,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3818,6 +3932,15 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/node-html-parser": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-4.1.4.tgz", + "integrity": "sha512-Uk9zI1IhGrPTfUyhRvImKGZspsqJ0ss6aRysGfkDuPDPfLisMlInYT/3FCydsC2UamzPPhpOax9xbTVUsO6n8Q==", + "dependencies": { + "css-select": "^4.1.3", + "he": "1.2.0" + } + }, "node_modules/node-releases": { "version": "1.1.75", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", @@ -3898,6 +4021,17 @@ "node": ">=8" } }, + "node_modules/nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3998,7 +4132,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "dependencies": { "wrappy": "1" } @@ -4124,7 +4257,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4688,6 +4820,23 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -5103,6 +5252,17 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, + "node_modules/tslog": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.1.tgz", + "integrity": "sha512-m8wAtox9wt+h6UDcN1WAQnYwRDOGhMIOp+GAuuufo8T8qKuu726i2W3r47BrA69goVOwgUkp5YwDTvAxTktvPg==", + "dependencies": { + "source-map-support": "^0.5.19" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -5331,8 +5491,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -5933,6 +6092,15 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -5945,11 +6113,15 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, "@types/node": { "version": "16.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.5.tgz", - "integrity": "sha512-E7SpxDXoHEpmZ9C1gSqwadhE6zPRtf3g0gJy9Y51DsImnR5TcDs3QEiV/3Q7zOM8LWaZp5Gph71NK6ElVMG1IQ==", - "dev": true + "integrity": "sha512-E7SpxDXoHEpmZ9C1gSqwadhE6zPRtf3g0gJy9Y51DsImnR5TcDs3QEiV/3Q7zOM8LWaZp5Gph71NK6ElVMG1IQ==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -6335,8 +6507,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "binary-extensions": { "version": "2.2.0", @@ -6344,6 +6515,11 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, "boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", @@ -6364,7 +6540,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6392,6 +6567,11 @@ "node-releases": "^1.1.75" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -6569,8 +6749,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "configstore": { "version": "5.0.1", @@ -6631,6 +6810,23 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "css-select": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + } + }, + "css-what": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==" + }, "damerau-levenshtein": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", @@ -6707,6 +6903,39 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + }, + "domhandler": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz", + "integrity": "sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -6752,6 +6981,11 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -7469,8 +7703,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.3.2", @@ -7521,7 +7754,6 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7655,6 +7887,11 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -7705,7 +7942,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7714,8 +7950,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.7", @@ -8169,7 +8404,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -8207,6 +8441,15 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node-html-parser": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-4.1.4.tgz", + "integrity": "sha512-Uk9zI1IhGrPTfUyhRvImKGZspsqJ0ss6aRysGfkDuPDPfLisMlInYT/3FCydsC2UamzPPhpOax9xbTVUsO6n8Q==", + "requires": { + "css-select": "^4.1.3", + "he": "1.2.0" + } + }, "node-releases": { "version": "1.1.75", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", @@ -8264,6 +8507,14 @@ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "requires": { + "boolbase": "^1.0.0" + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8334,7 +8585,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -8431,8 +8681,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -8833,6 +9082,22 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -9153,6 +9418,14 @@ } } }, + "tslog": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.1.tgz", + "integrity": "sha512-m8wAtox9wt+h6UDcN1WAQnYwRDOGhMIOp+GAuuufo8T8qKuu726i2W3r47BrA69goVOwgUkp5YwDTvAxTktvPg==", + "requires": { + "source-map-support": "^0.5.19" + } + }, "tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -9334,8 +9607,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index 641e319..989345b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "angular test generator for component render tests", "main": "src/parser.js", "scripts": { - "start": "./node_modules/.bin/tsc && node ./dist/parser.js", + "start": "./node_modules/.bin/tsc && node ./dist/src/parser.js", "watch": "./node_modules/.bin/nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/parser.ts", "lint": "./node_modules/.bin/eslint .", "lint:fix": "./node_modules/.bin/eslint . --fix", @@ -41,5 +41,11 @@ "ts-node": "^10.2.1", "tslint": "^6.1.3", "typescript": "^4.4.2" + }, + "dependencies": { + "@types/glob": "^7.1.4", + "glob": "^7.1.7", + "node-html-parser": "^4.1.4", + "tslog": "^3.2.1" } } diff --git a/sample-web-app/src/app/app.component.expected.spec.ts b/sample-web-app/src/app/app.component.expected.spec.ts index c960ff5..7119304 100644 --- a/sample-web-app/src/app/app.component.expected.spec.ts +++ b/sample-web-app/src/app/app.component.expected.spec.ts @@ -1,7 +1,11 @@ -import {ComponentFixture, TestBed} from '@angular/core/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { + fixtureQueryAll, + fixtureQueryNative, + stubComponent, +} from '../testing-helpers'; import { AppComponent } from './app.component'; -import {fixtureQueryAll, fixtureQueryNative} from "../testing-helpers"; describe('AppComponentExpected', () => { let fixture: ComponentFixture; @@ -9,12 +13,8 @@ describe('AppComponentExpected', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], + imports: [RouterTestingModule], + declarations: [AppComponent, stubComponent('app-button')], }).compileComponents(); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; @@ -38,9 +38,8 @@ describe('AppComponentExpected', () => { }); it(`should render ${numLinks} links`, () => { - const links = fixtureQueryAll(fixture, '.quick-link'); + const links = fixtureQueryAll(fixture, '.links-section .quick-link'); expect(links.length).toEqual(numLinks); }); }); }); - diff --git a/sample-web-app/src/app/app.component.html b/sample-web-app/src/app/app.component.html index e029698..6b9cadb 100644 --- a/sample-web-app/src/app/app.component.html +++ b/sample-web-app/src/app/app.component.html @@ -11,3 +11,5 @@

Quick Links:

+ + diff --git a/sample-web-app/src/app/app.component.spec.ts b/sample-web-app/src/app/app.component.spec.ts index 2867669..bec7ab8 100644 --- a/sample-web-app/src/app/app.component.spec.ts +++ b/sample-web-app/src/app/app.component.spec.ts @@ -5,12 +5,8 @@ import { AppComponent } from './app.component'; describe('AppComponentActual', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule - ], - declarations: [ - AppComponent - ], + imports: [RouterTestingModule], + declarations: [AppComponent], }).compileComponents(); const fixture = TestBed.createComponent(AppComponent); const app = fixture.componentInstance; diff --git a/sample-web-app/src/app/app.module.ts b/sample-web-app/src/app/app.module.ts index b1c6c96..7a8f6d4 100644 --- a/sample-web-app/src/app/app.module.ts +++ b/sample-web-app/src/app/app.module.ts @@ -1,18 +1,13 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; - +import { ButtonComponent } from '../components/button/button.component'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ - declarations: [ - AppComponent - ], - imports: [ - BrowserModule, - AppRoutingModule - ], + declarations: [AppComponent, ButtonComponent], + imports: [BrowserModule, AppRoutingModule], providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/sample-web-app/src/components/button/button.component.html b/sample-web-app/src/components/button/button.component.html new file mode 100644 index 0000000..0d8633e --- /dev/null +++ b/sample-web-app/src/components/button/button.component.html @@ -0,0 +1 @@ + diff --git a/sample-web-app/src/components/button/button.component.scss b/sample-web-app/src/components/button/button.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/sample-web-app/src/components/button/button.component.spec.ts b/sample-web-app/src/components/button/button.component.spec.ts new file mode 100644 index 0000000..1392257 --- /dev/null +++ b/sample-web-app/src/components/button/button.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ButtonComponent } from './button.component'; + +describe('ButtonComponent', () => { + let component: ButtonComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ButtonComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ButtonComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/sample-web-app/src/components/button/button.component.ts b/sample-web-app/src/components/button/button.component.ts new file mode 100644 index 0000000..5c53953 --- /dev/null +++ b/sample-web-app/src/components/button/button.component.ts @@ -0,0 +1,13 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-button', + templateUrl: './button.component.html', + styleUrls: ['./button.component.scss'], +}) +export class ButtonComponent implements OnInit { + // eslint-disable-next-line no-useless-constructor + constructor() {} + + ngOnInit(): void {} +} diff --git a/sample-web-app/src/testing-helpers.ts b/sample-web-app/src/testing-helpers.ts index d7135ae..5c6a340 100644 --- a/sample-web-app/src/testing-helpers.ts +++ b/sample-web-app/src/testing-helpers.ts @@ -1,25 +1,31 @@ -import {Component, DebugElement} from '@angular/core'; -import {ComponentFixture} from "@angular/core/testing"; -import {By} from "@angular/platform-browser"; +import { Component, DebugElement } from '@angular/core'; +import { ComponentFixture } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; // stub an external component by selector export const stubComponent = ( selector: string, inputs: string[] = [], - template = '' -): typeof Component => { - return Component({selector, inputs, template})(class {}) as any; -}; + template = '', +): typeof Component => + Component({ selector, inputs, template })(class {}) as never; // returns an array of debug elements from a component fixture based on a selector -export const fixtureQueryAll = (fixture: ComponentFixture, selector: string): DebugElement[] => { - return fixture.debugElement.queryAll(By.css(selector)); -}; +export const fixtureQueryAll = ( + fixture: ComponentFixture, + selector: string, +): DebugElement[] => fixture.debugElement.queryAll(By.css(selector)); // returns the native html element from a component fixture based on a selector -export const fixtureQueryNative = (fixture: ComponentFixture, selector: string): DebugElement => { - const debugElement: DebugElement = fixture.debugElement.query(By.css(selector)); - expect(debugElement).not.toBeNull(`!! null value returned for selector "${selector}" !!`); +export const fixtureQueryNative = ( + fixture: ComponentFixture, + selector: string, +): DebugElement => { + const debugElement: DebugElement = fixture.debugElement.query( + By.css(selector), + ); + expect(debugElement).not.toBeNull( + `!! null value returned for selector "${selector}" !!`, + ); return debugElement.nativeElement; }; - diff --git a/src/parser.ts b/src/parser.ts index 9729ed7..e6e0c8f 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1 +1,23 @@ -console.log('running :)'); +import { HTMLElement, parse } from 'node-html-parser'; +import { logger } from '../utils/logger'; +import { getHtmlFiles, getWebAppDir, readFile } from './preload-helpers'; + +logger.info('Running Parser...\n'); + +const webappRootDir: string = getWebAppDir(); +const htmlFiles: Array = getHtmlFiles(webappRootDir); +const fileContents: Map = new Map(); + +htmlFiles.forEach((file) => { + fileContents.set(file, readFile(file)); +}); + +logger.info(`Webapp Root Directory: ${webappRootDir}\n`); +logger.info(`HTML Files Found:\n* ${htmlFiles.join('\n')}`); +logger.info([...fileContents.entries()]); + +htmlFiles.forEach((file) => { + const root: HTMLElement = parse(fileContents.get(file)!); + logger.info(`Parsed structure for '${file}'`); + logger.info(`\n${(root.firstChild as HTMLElement).structure}`); +}); diff --git a/src/preload-helpers.ts b/src/preload-helpers.ts new file mode 100644 index 0000000..a8cfc68 --- /dev/null +++ b/src/preload-helpers.ts @@ -0,0 +1,26 @@ +import * as fs from 'fs'; + +export const getWebAppDir = (): string => + process.argv.slice(2)[0] || 'sample-web-app'; + +export const getHtmlFiles = ( + webappRootDir: string = '', + htmlFiles: Array = [], +): Array => { + fs.readdirSync(webappRootDir).forEach((filename) => { + const path = `${webappRootDir}/${filename}`; + if (fs.statSync(path).isDirectory()) getHtmlFiles(path, htmlFiles); + if (path.endsWith('.component.html')) htmlFiles.push(path); + }); + + return htmlFiles; +}; + +export const readFile = (path: string): string => { + try { + return fs.readFileSync(`${path}`, 'utf8'); + } catch (err) { + console.error(err); + } + return ''; +}; diff --git a/utils/logger.ts b/utils/logger.ts new file mode 100644 index 0000000..974bac5 --- /dev/null +++ b/utils/logger.ts @@ -0,0 +1,10 @@ +import { ILogObject, Logger } from 'tslog'; + +/* log levels available: silly | trace | debug | info | warn | error | fatal */ +const formatAsJson: boolean = false; + +export const logger: Logger = formatAsJson + ? new Logger({ type: 'json' }) + : new Logger(); + +export const log = (...args: unknown[]): ILogObject => logger.info(...args);