diff --git a/package.json b/package.json index 81c0c2adc3a3..66caa77d3da4 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "approve-size-tests": "node ./scripts/approve-size-golden.js", "integration-tests": "bazel test --test_tag_filters=-view-engine-only --build_tests_only -- //integration/... -//integration/size-test/...", "integration-tests:view-engine": "bazel test --test_tag_filters=view-engine-only --build_tests_only -- //integration/... -//integration/size-test/...", - "integration-tests:size-test": "bazel test //integration/size-test/..." + "integration-tests:size-test": "bazel test //integration/size-test/...", + "check-mdc-tests": "ts-node --project scripts/tsconfig.json scripts/check-mdc-tests.ts" }, "version": "11.0.0-next.0", "dependencies": { diff --git a/scripts/check-mdc-tests.ts b/scripts/check-mdc-tests.ts new file mode 100644 index 000000000000..420f72e49f12 --- /dev/null +++ b/scripts/check-mdc-tests.ts @@ -0,0 +1,87 @@ +import {readdirSync, readFileSync} from 'fs'; +import {join, basename} from 'path'; +import {sync as glob} from 'glob'; +import chalk from 'chalk'; +import * as ts from 'typescript'; + +const srcDirectory = join(__dirname, '../src'); +const materialDirectories = readdirSync(join(srcDirectory, 'material')); + +// Goes through all the unit tests and flags the ones that don't exist in the MDC components. +readdirSync(join(srcDirectory, 'material-experimental'), {withFileTypes: true}) + .reduce((matches, entity) => { + // Go through all the `material-experimental` directories and match them to ones in `material`. + if (entity.isDirectory()) { + const materialName = entity.name.replace(/^mdc-/, ''); + + if (materialDirectories.indexOf(materialName) > -1) { + matches.set(materialName, entity.name); + } + } + + return matches; + }, new Map()) + .forEach((mdcPackage, materialPackage) => { + const mdcTestFiles = getUnitTestFiles(`material-experimental/${mdcPackage}`); + + // MDC entry points that don't have test files may not have been implemented yet. + if (mdcTestFiles.length > 0) { + // Filter out files that don't exist in the MDC package, allowing + // us to ignore some files which may not need to be ported to MDC. + const materialTestFiles = getUnitTestFiles(`material/${materialPackage}`).filter(path => { + const fileName = basename(path); + return mdcTestFiles.some(file => basename(file) === fileName); + }); + const materialTests = getTestNames(materialTestFiles); + const mdcTests = getTestNames(mdcTestFiles); + const missingTests = materialTests.filter(test => !mdcTests.includes(test)); + + if (missingTests.length > 0) { + console.log(chalk.redBright(`\nMissing tests for ${mdcPackage}:`)); + console.log(missingTests.join('\n')); + } + } + }); + +/** + * Gets all the names of all unit test files inside a + * package name, excluding `testing` packages and e2e tests. + */ +function getUnitTestFiles(name: string): string[] { + return glob('{,!(testing)/**/}!(*.e2e).spec.ts', { + absolute: true, + cwd: join(srcDirectory, name) + }); +} + +/** Gets the name of all unit tests within a set of files. */ +function getTestNames(files: string[]): string[] { + const testNames: string[] = []; + + files.forEach(file => { + const content = readFileSync(file, 'utf-8'); + const sourceFile = ts.createSourceFile(file, content, ts.ScriptTarget.ES2015); + + sourceFile.forEachChild(function walk(node: ts.Node) { + if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && + node.expression.text === 'it') { + // Note that this is a little naive since it'll take the literal text of the test + // name expression which could include things like string concatenation. It's fine + // for the limited use cases of the script. + testNames.push(node.arguments[0].getText(sourceFile) + // Replace the quotes around the test name. + .replace(/^['`]|['`]$/g, '') + // Strip newlines followed by indentation. + .replace(/\n\s+/g, ' ') + // Strip escape characters. + .replace(/\\/g, '') + // Collapse concatenated strings. + .replace(/['`]\s+\+\s+['`]/g, '')); + } else { + node.forEachChild(walk); + } + }); + }); + + return testNames; +} diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index ac3e3866cf2e..15ae9e292329 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -3,6 +3,7 @@ "outDir": "../dist/dev-infra-scripts", "target": "es2015", "lib": ["es2016"], + "moduleResolution": "node", "types": ["node"], "strictNullChecks": true, "downlevelIteration": true