test(bazel): fix all ng_package tests not working on windows (#27829)

PR Close #27829
This commit is contained in:
Paul Gschwendtner
2019-01-07 14:46:47 -08:00
committed by Kara Erickson
parent 8473d68ea8
commit 8122970f63
6 changed files with 324 additions and 329 deletions
+1 -1
View File
@@ -61,6 +61,7 @@
"chokidar": "1.7.0",
"convert-source-map": "^1.5.1",
"dependency-graph": "^0.7.2",
"diff": "^3.5.0",
"domino": "2.1.0",
"fs-extra": "4.0.2",
"jasmine": "^3.1.0",
@@ -105,7 +106,6 @@
"conventional-changelog": "^2.0.3",
"core-js": "^2.4.1",
"cors": "2.8.4",
"diff": "^3.5.0",
"entities": "1.1.1",
"firefox-profile": "1.0.3",
"glob": "7.1.2",
+3 -2
View File
@@ -73,9 +73,10 @@ nodejs_binary(
name = "example_package.accept",
testonly = True,
data = [
"example_package.golden",
":example_spec_lib",
"//packages/bazel/test/ng_package/example:npm_package",
"@ngdeps//diff",
":example_spec_lib",
"example_package.golden",
],
entry_point = "angular/packages/bazel/test/ng_package/example_package.spec.js",
templated_args = ["--accept"],
@@ -10,7 +10,10 @@ import * as fs from 'fs';
import * as path from 'path';
import * as shx from 'shelljs';
shx.cd(path.join(process.env['TEST_SRCDIR'] !, 'angular', 'packages', 'common', 'npm_package'));
// Resolve the "npm_package" directory by using the runfile resolution. Note that we need to
// resolve the "package.json" of the package since otherwise NodeJS would resolve the "main"
// file, which is not necessarily at the root of the "npm_package".
shx.cd(path.dirname(require.resolve('angular/packages/common/npm_package/package.json')));
describe('@angular/common ng_package', () => {
describe('should have the locales files', () => {
@@ -10,9 +10,10 @@ import {fixmeIvy, ivyEnabled, obsoleteInIvy} from '@angular/private/testing';
import * as path from 'path';
import * as shx from 'shelljs';
const corePackagePath =
path.join(process.env['TEST_SRCDIR'] !, 'angular', 'packages', 'core', 'npm_package');
shx.cd(corePackagePath);
// Resolve the "npm_package" directory by using the runfile resolution. Note that we need to
// resolve the "package.json" of the package since otherwise NodeJS would resolve the "main"
// file, which is not necessarily at the root of the "npm_package".
shx.cd(path.dirname(require.resolve('angular/packages/core/npm_package/package.json')));
/**
* Utility functions that allows me to create fs paths
File diff suppressed because one or more lines are too long
@@ -10,14 +10,20 @@ import {createPatch} from 'diff';
import * as fs from 'fs';
import * as path from 'path';
/** Directory in the Angular repo where package gold tests live. */
const TEST_DIR = path.resolve(path.join('packages', 'bazel', 'test', 'ng_package'));
type TestPackage = {
dir: string; goldPath: string
displayName: string; packagePath: string; goldenFilePath: string;
};
const packagesToTest: TestPackage[] = [
{dir: 'example', goldPath: 'example_package.golden'},
{
displayName: 'Example NPM package',
// Resolve the "npm_package" directory by using the runfile resolution. Note that we need to
// resolve the "package.json" of the package since otherwise NodeJS would resolve the "main"
// file, which is not necessarily at the root of the "npm_package".
packagePath: path.dirname(
require.resolve('angular/packages/bazel/test/ng_package/example/npm_package/package.json')),
goldenFilePath: require.resolve('./example_package.golden')
},
];
/**
@@ -32,9 +38,9 @@ function getIndentedDirectoryStructure(directoryPath: string, depth = 0): string
const result: string[] = [];
if (fs.statSync(directoryPath).isDirectory()) {
fs.readdirSync(directoryPath).forEach(f => {
const filePath = path.posix.join(directoryPath, f);
result.push(
' '.repeat(depth) + path.join(directoryPath, f),
...getIndentedDirectoryStructure(path.join(directoryPath, f), depth + 1));
' '.repeat(depth) + filePath, ...getIndentedDirectoryStructure(filePath, depth + 1));
});
}
return result;
@@ -51,9 +57,12 @@ function getDescendantFilesContents(directoryPath: string): string[] {
const result: string[] = [];
if (fs.statSync(directoryPath).isDirectory()) {
fs.readdirSync(directoryPath).forEach(dir => {
result.push(...getDescendantFilesContents(path.join(directoryPath, dir)));
result.push(...getDescendantFilesContents(path.posix.join(directoryPath, dir)));
});
} else {
}
// Note that we don't want to include ".map" files in the golden file since these are not
// consistent across different environments (e.g. path delimiters)
else if (path.extname(directoryPath) !== '.map') {
result.push(`--- ${directoryPath} ---`, '', fs.readFileSync(directoryPath, 'utf-8'), '');
}
return result;
@@ -61,11 +70,8 @@ function getDescendantFilesContents(directoryPath: string): string[] {
/** Accepts the current package output by overwriting the gold file in source control. */
function acceptNewPackageGold(testPackage: TestPackage) {
const goldenFile = path.join(TEST_DIR, testPackage.goldPath);
process.chdir(path.join(TEST_DIR, `${testPackage.dir}`, 'npm_package'));
const actual = getCurrentPackageContent();
fs.writeFileSync(require.resolve(goldenFile), actual, 'utf-8');
process.chdir(testPackage.packagePath);
fs.writeFileSync(testPackage.goldenFilePath, getCurrentPackageContent(), 'utf-8');
}
/** Gets the content of the current package. Depends on the current working directory. */
@@ -77,21 +83,22 @@ function getCurrentPackageContent() {
/** Compares the current package output to the gold file in source control in a jasmine test. */
function runPackageGoldTest(testPackage: TestPackage) {
const goldenFile = path.join(TEST_DIR, testPackage.goldPath);
process.chdir(path.join(TEST_DIR, `${testPackage.dir}`, 'npm_package'));
const {displayName, packagePath, goldenFilePath} = testPackage;
process.chdir(packagePath);
// Gold file content from source control. We expect that the output of the package matches this.
const expected = fs.readFileSync(goldenFile, 'utf-8');
const expected = fs.readFileSync(goldenFilePath, 'utf-8');
// Actual file content generated from the rule.
const actual = getCurrentPackageContent();
// Without the `--accept` flag, compare the actual to the expected in a jasmine test.
it(`Package "${testPackage.dir}"`, () => {
it(`Package "${displayName}"`, () => {
if (actual !== expected) {
// Compute the patch and strip the header
let patch =
createPatch(goldenFile, expected, actual, 'Golden file', 'Generated file', {context: 5});
let patch = createPatch(
goldenFilePath, expected, actual, 'Golden file', 'Generated file', {context: 5});
const endOfHeader = patch.indexOf('\n', patch.indexOf('\n') + 1) + 1;
patch = patch.substring(endOfHeader);
@@ -108,55 +115,19 @@ function runPackageGoldTest(testPackage: TestPackage) {
});
}
/** Gets all errors for missing golden files or packages. Typically missing from the bazel rule. */
function getDependencyErrors(testPackage: TestPackage): string[] {
const errors = [];
if (require.main === module) {
const args = process.argv.slice(2);
const acceptingNewGold = (args[0] === '--accept');
const goldenFile = path.join(TEST_DIR, testPackage.goldPath);
if (!fs.existsSync(goldenFile)) {
errors.push(
`The golden file "${testPackage.goldPath}" cannot be found. ` +
`Ensure that the file exists and is added to the 'data' attribute of the test rule`);
}
if (!fs.existsSync(path.join(TEST_DIR, `${testPackage.dir}`, 'npm_package'))) {
errors.push(
`The package output for "${testPackage.dir}" cannot be found. Ensure that ` +
`the an ng_package named "npm_package" exists in the "${testPackage.dir }" directory ` +
`and that it is added to the "data" attribute of the test rule.`);
}
return errors;
}
// If there are any dependency errors, emit the errors and set the exit code.
let hasError = false;
for (let p of packagesToTest) {
const dependencyErrors = getDependencyErrors(p);
if (dependencyErrors.length) {
console.error(dependencyErrors.join('\n\n'));
hasError = true;
}
}
if (!hasError) {
if (require.main === module) {
const args = process.argv.slice(2);
const acceptingNewGold = (args[0] === '--accept');
if (acceptingNewGold) {
for (let p of packagesToTest) {
acceptNewPackageGold(p);
}
if (acceptingNewGold) {
for (let p of packagesToTest) {
acceptNewPackageGold(p);
}
} else {
describe('Comparing test packages to golds', () => {
for (let p of packagesToTest) {
runPackageGoldTest(p);
}
});
}
} else {
describe('Comparing test packages to golds', () => {
for (let p of packagesToTest) {
runPackageGoldTest(p);
}
});
}
process.exitCode = hasError ? 1 : 0;