Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coverage map doesn't line up #230

Closed
lukescott opened this issue May 22, 2017 · 7 comments
Closed

Coverage map doesn't line up #230

lukescott opened this issue May 22, 2017 · 7 comments

Comments

@lukescott
Copy link

lukescott commented May 22, 2017

I think this may be related to #211 in some way. I put together a transformer (separate from ts-jest) that "works", but the coverage information doesn't line up with the code.

Here is the transformer:

const tsc = require("typescript")
const tsConfig = require("./tsconfig.json") || {}
const babel = require('babel-core')
const jestPreset = require('babel-preset-jest')
const convert = require("convert-source-map");

const createTransformer = (options) => {
	options = Object.assign({}, options, {
		plugins: (options && options.plugins) || [],
		presets: ((options && options.presets) || []).concat([jestPreset]),
		retainLines: true
	});
	delete options.cacheDirectory;
	delete options.filename;

	return {
		canInstrument: true,
		process(src, filename, config, transformOptions) {
			let inputSourceMap
			if (filename.endsWith(".ts") || filename.endsWith(".tsx")) {
				let compilerOptions = Object.assign({},
					tsConfig.compilerOptions, {
						inlineSourceMap: true
						//sourceMap: true
					}
				)
				let transpileOut = tsc.transpileModule(src, {
					fileName: filename,
					compilerOptions
				});
				src = transpileOut.outputText
				inputSourceMap = convert.fromSource(src);
				//inputSourceMap = JSON.parse(transpileOut.sourceMapText)
			}
			const theseOptions = Object.assign({
				filename,
				inputSourceMap,
			}, options);
			if (transformOptions && transformOptions.instrument) {
				theseOptions.auxiliaryCommentBefore = ' istanbul ignore next ';
				// Copied from jest-runtime transform.js
				theseOptions.plugins = theseOptions.plugins.concat([
					[
						require('babel-plugin-istanbul').default, {
							// files outside `cwd` will not be instrumented
							cwd: config.rootDir,
							exclude: []
						}
					]
				]);
			}
			let babelOut = babel.transform(src, theseOptions);
			return babelOut.code;
		}
	};
};

module.exports = createTransformer();
module.exports.createTransformer = createTransformer;

I've tried:

  • Every combination I can think of w/ TypeScript + Babel. Fails to line up properly. I am passing the source map from TypeScript into Babel.

  • Babel by itself. It lines up correctly.

  • TypeScript by itself. It doesn't line up, but also doesn't show highlights.

I'm at a loss at this point. As far as I can tell Babel/Istanbul does not like TypeScript's source maps.

@GeeWee
Copy link
Collaborator

GeeWee commented May 23, 2017

What happens if you simply run it through tsc and pass it through babel? If this bug also happens with tsc, I feel like we need to raise this issue in another repro.

@kulshekhar
Copy link
Owner

@lukescott can you create a minimal repo that reproduces this issue?

@lukescott
Copy link
Author

I think it is an issue with babel-plugin-istanbul. I opened an issue here istanbuljs/babel-plugin-istanbul#108. I posted a reproducible repo there. This issue may be relevant to you as ts-jest may suffer from the same problem.

@GeeWee
Copy link
Collaborator

GeeWee commented May 24, 2017

Excellent, I'm hoping they will fix it and it's not an issue on our end.

@lukescott
Copy link
Author

lukescott commented May 27, 2017

Ok, so I was able to figure it out. Not sure if this is the final solution, but you need to:

1 - Pass inputSourceMap to babel from typescript (I do that in the code above).
2 - You have to have mapCoverage set to true in your global Jest config, otherwise it won't call transformCoverage, which actually uses the inputSourceMap. Without it inputSourceMap is ignored.

I have no idea why this even an option in Jest. If you're doing a coverage report I would assume this should always be called.

Interestingly enough you have to return .code. If you give Jest the .map it will break again (but differently), even with the above.

@GeeWee
Copy link
Collaborator

GeeWee commented May 31, 2017

Huh, that's really strange. Do you know where the switch is inside jest that makes it ignore the inputsourcemap?

@kulshekhar
Copy link
Owner

It's my understanding that inline sourcemaps work as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants