Skip to content

Commit 17c2862

Browse files
authored
Merge pull request #393 from kulshekhar/logging
Logging
2 parents 4c3aaac + 19b2273 commit 17c2862

26 files changed

Lines changed: 165 additions & 55 deletions

File tree

.github/ISSUE_TEMPLATE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
[describe the expected behavior here]
1010

11+
- Output from your debug log
12+
[ You can activate the debug logger by setting the environment variable TS_JEST_DEBUG="true" before running yarn test. The output of the logger
13+
will be in **<your_project_dir>/node_modules/ts-jest/debug.txt** ]
1114

1215

1316
- Link to a minimal repo that reproduces this issue

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "ts-jest",
3-
"version": "22.0.1",
3+
"version": "22.0.2",
44
"main": "index.js",
55
"types": "./dist/index.d.ts",
66
"description": "A preprocessor with sourcemap support to help use Typescript with Jest",
77
"scripts": {
88
"build": "cpx index.d.ts dist/ && tsc -p .",
99
"build:watch": "cpx index.d.ts dist/ && tsc -p . -w",
10-
"clean": "rimraf dist/**/* && rimraf tests/simple/coverage && rimraf tests/simple-async/coverage",
10+
"clean": "rimraf dist/**/* && rimraf tests/simple/coverage && rimraf tests/simple-async/coverage && rimraf tests/**/*/debug.txt",
1111
"clean-build": "npm run clean && npm run build",
1212
"pretest": "npm run tslint && npm run clean-build",
1313
"test": "node scripts/tests.js",

scripts/tests.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,6 @@ createIntegrationMock();
6767

6868
const argv = process.argv.slice(2);
6969
argv.push('--no-cache');
70-
// Watch unless on CI
71-
if (!process.env.CI) {
72-
// argv.push('--watch');
73-
}
74-
// omit tests for watch cases if it runned on AppVeyor due to this issues:
75-
// https://github.com/kulshekhar/ts-jest/issues/53
76-
// http://help.appveyor.com/discussions/problems/5500-nodejs-child-process-with-watch-and-stderr-problem
77-
7870
argv.push('--testPathPattern', '^(?!(.*watch.spec.ts$)).*');
7971

8072
jest.run(argv);

src/logger.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as fs from 'fs';
2+
import * as path from 'path';
3+
4+
/**
5+
* Logger file that enables logging things just once. Does this by traversing the array of previously recorded
6+
* logs to see if the exact same message has already been logged
7+
* @type {any[]}
8+
*/
9+
10+
const logs: any[] = [];
11+
let logsFlushed: boolean = false;
12+
13+
function shouldLog(): boolean {
14+
// If the env variable is set and the logs have not already been flushed, log the line
15+
return process.env.TS_JEST_DEBUG && !logsFlushed;
16+
}
17+
18+
// Log function. Only logs prior to calls to flushLogs.
19+
export function logOnce(...thingsToLog: any[]) {
20+
if (!shouldLog()) {
21+
return;
22+
}
23+
logs.push(thingsToLog);
24+
}
25+
26+
// This function JSONifies logs and flushes them to disk.
27+
export function flushLogs() {
28+
if (!shouldLog()) {
29+
return; // only output stuff for the first invocation and if logging is enabled.
30+
}
31+
logsFlushed = true;
32+
const rootPath = path.resolve(__dirname, '../');
33+
const JSONifiedLogs = logs.map(convertToJSONIfPossible);
34+
const logString = JSONifiedLogs.join('\n');
35+
const filePath = path.resolve(rootPath, 'debug.txt');
36+
fs.writeFileSync(filePath, logString);
37+
}
38+
39+
function includes<T>(array: T[], subject: T) {
40+
return array.indexOf(subject) !== -1;
41+
}
42+
43+
function convertToJSONIfPossible(object: any): string {
44+
try {
45+
return JSON.stringify(object, null, 2);
46+
} catch {
47+
return object.toString(); // if unable to parse, simply return the string variant
48+
}
49+
}

src/postprocess.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
TransformOptions,
1515
TsJestConfig,
1616
} from './jest-types';
17+
import { logOnce } from './logger';
1718

1819
function createBabelTransformer(options: BabelTransformOptions) {
1920
options = {
@@ -62,19 +63,26 @@ export const getPostProcessHook = (
6263
tsJestConfig: TsJestConfig,
6364
): PostProcessHook => {
6465
if (tsJestConfig.skipBabel) {
66+
logOnce('Not using any postprocess hook.');
6567
return src => src; // Identity function
6668
}
6769

68-
const plugins = Array.from(tsJestConfig.babelConfig && tsJestConfig.babelConfig.plugins || []);
70+
const plugins = Array.from(
71+
(tsJestConfig.babelConfig && tsJestConfig.babelConfig.plugins) || [],
72+
);
6973
// If we're not skipping babel
7074
if (tsCompilerOptions.allowSyntheticDefaultImports) {
7175
plugins.push('transform-es2015-modules-commonjs');
7276
}
7377

74-
return createBabelTransformer({
78+
const babelOptions = {
7579
...tsJestConfig.babelConfig,
7680
babelrc: tsJestConfig.useBabelrc || false,
7781
plugins,
7882
presets: tsJestConfig.babelConfig ? tsJestConfig.babelConfig.presets : [],
79-
});
83+
};
84+
85+
logOnce('Using babel with options:', babelOptions);
86+
87+
return createBabelTransformer(babelOptions);
8088
};

src/preprocessor.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as crypto from 'crypto';
22
import * as tsc from 'typescript';
33
import { JestConfig, Path, TransformOptions } from './jest-types';
4+
import { flushLogs, logOnce } from './logger';
45
import { getPostProcessHook } from './postprocess';
56
import {
67
cacheFile,
@@ -22,6 +23,8 @@ export function process(
2223
transformOptions.instrument,
2324
);
2425

26+
logOnce('final compilerOptions:', compilerOptions);
27+
2528
const isTsFile = /\.tsx?$/.test(filePath);
2629
const isJsFile = /\.jsx?$/.test(filePath);
2730
const isHtmlFile = /\.html$/.test(filePath);
@@ -44,6 +47,7 @@ export function process(
4447
});
4548

4649
const tsJestConfig = getTSJestConfig(jestConfig.globals);
50+
logOnce('tsJestConfig: ', tsJestConfig);
4751

4852
const postHook = getPostProcessHook(
4953
compilerOptions,
@@ -63,7 +67,7 @@ export function process(
6367
tsTranspiled.outputText,
6468
outputText,
6569
);
66-
70+
flushLogs();
6771
return modified;
6872
}
6973

src/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as fsExtra from 'fs-extra';
44
import * as path from 'path';
55
import * as tsc from 'typescript';
66
import { JestConfig, TsJestConfig } from './jest-types';
7+
import { logOnce } from './logger';
78

89
export function getTSJestConfig(globals: any): TsJestConfig {
910
return globals && globals['ts-jest'] ? globals['ts-jest'] : {};
@@ -119,6 +120,7 @@ const tsConfigCache: { [key: string]: any } = {};
119120
// https://github.com/facebook/jest/issues/3524
120121
export function getTSConfig(globals, collectCoverage: boolean = false) {
121122
let configPath = getTSConfigPathFromConfig(globals);
123+
logOnce(`Reading tsconfig file from path ${configPath}`);
122124
const skipBabel = getTSJestConfig(globals).skipBabel;
123125

124126
// check cache before resolving configuration
@@ -134,6 +136,7 @@ export function getTSConfig(globals, collectCoverage: boolean = false) {
134136
}
135137

136138
const config = readCompilerOptions(configPath);
139+
logOnce('Original typescript config before modifications: ', config);
137140

138141
// ts-jest will map lines numbers properly if inlineSourceMap and
139142
// inlineSources are set to true. For testing, we don't need the

tests/__helpers__/runJest.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const JEST_PATH = 'jest';
1111
// return the result of the spawned proccess:
1212
// [ 'status', 'signal', 'output', 'pid', 'stdout', 'stderr',
1313
// 'envPairs', 'options', 'args', 'file' ]
14-
export default function runJest(dir: string, args: string[]) {
14+
export default function runJest(dir: string, args: string[], env = {}): Result {
1515
const isRelative = dir[0] !== '/';
1616

1717
if (isRelative) {
@@ -30,10 +30,28 @@ export default function runJest(dir: string, args: string[]) {
3030

3131
const result = spawnSync(JEST_PATH, args || [], {
3232
cwd: dir,
33+
env: { ...process.env, ...env }, // Add both process.env which is the standard and custom env variables
3334
});
3435

35-
result.stdout = result.stdout && result.stdout.toString();
36-
result.stderr = result.stderr && result.stderr.toString();
36+
// Call to string on byte arrays and strip ansi color codes for more accurate string comparison.
37+
result.stdout = result.stdout && stripAnsiColors(result.stdout.toString());
38+
result.stderr = result.stderr && stripAnsiColors(result.stderr.toString());
39+
result.output = result.output && stripAnsiColors(result.output.toString());
3740

3841
return result;
3942
}
43+
44+
// from https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings
45+
function stripAnsiColors(stringToStrip: String): String {
46+
return stringToStrip.replace(
47+
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
48+
'',
49+
);
50+
}
51+
52+
export interface Result {
53+
stdout: string;
54+
stderr: string;
55+
status: number;
56+
output: string;
57+
}

tests/__helpers__/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function linkJestPackage(packageName, cwd) {
3131
}
3232

3333
export function fileExists(filePath) {
34-
const F_OK = (fs.constants && fs.constants.F_OK) || (<number>fs['F_OK']);
34+
const F_OK = (fs.constants && fs.constants.F_OK) || <number>fs['F_OK'];
3535
try {
3636
fs.accessSync(filePath, F_OK);
3737
return true;

tests/__tests__/babel-config.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe('babelConfig flag', () => {
88

99
it('should fail for invalid babel configs', () => {
1010
const result = runJest('../babel-config-invalid', ['--no-cache', '-u']);
11-
const stderr = result.stderr.toString();
11+
const stderr = result.stderr;
1212
expect(result.status).toBe(1);
1313
expect(stderr).toContain('ReferenceError: [BABEL]');
1414
expect(stderr).toContain(
@@ -29,7 +29,7 @@ describe('babelConfig flag', () => {
2929
'--no-cache',
3030
'-u',
3131
]);
32-
const stderr = result.stderr.toString();
32+
const stderr = result.stderr;
3333
expect(result.status).toBe(1);
3434
expect(stderr).toContain(`Couldn't find preset "nonexistent"`);
3535
});

0 commit comments

Comments
 (0)