Giter VIP home page Giter VIP logo

remap-istanbul's Introduction

remap-istanbul

Build Status codecov.io npm version dependencies Status devDependencies Status

Average time to resolve an issue Percentage of issues still open

A package that provides the ability to remap Istanbul code coverage information to its original source positions based on a JavaScript Source Maps v3.

remap-istanbul requires Node.js 8 or later.

Important Information

This package adds remapping functionality for the deprecated 0.x version of Istanbul. The newer and actively maintained IstanbulJS includes remapping functionality directly, so this package (remap-istanbul) is not needed for anyone working with IstanbulJS. We strongly encourage developers to leverage IstanbulJS, and only use this package (remap-istanbul) when needing to support legacy versions of Istanbul.

How to get Help

This is covered in depth in the CONTRIBUTING.md document in the repo.

Usage

For information on how to use remap-istanbul with common testing frameworks, please visit the wiki.

There are three main modules that constitute the remap-istanbul package:

  • lib/loadCoverage - does the basic loading of a Istanbul JSON coverage files. It can "merge" several coverage files, for example if you are collecting remote coverage from other environments and combining it together.
  • lib/remap - does the remapping of the coverage information. It iterates through all the files in the coverage information and looks for JavaScript Source Maps which it will then use to remap the coverage information to the original source.
  • lib/writeReport - a wrapper for the Istanbul report writers to output the any final coverage reports.

Command Line

The package includes a command line interface which should be placed into the ./node_modules/.bin/remap-istanbul when the package is installed. The command line interface understands the following argument flags:

Flag Description
-i or --input The path to the coverage input file. For example remap-istanbul --input coverage.json. If omitted, input will be taken from stdin.
-o or --output The path to the remapped coverage output file. For example remap-istanbul --output coverage-final.json. If omitted, json output will be sent to stdout.
-t or --type The type of report the output should be. For example remap-istanbul --output html-report --type html. If omitted, output defaults to json.
-b or --basePath When remapping the source files, instead of using the path in the source map, substitute this path.
-e or --exclude Pass in a comma seperated string of patterns (exact strings or regexps) to exclude from the output. For example remap-istanbul --output coverage-final.json --exclude node_modules,tests

An example of piping a coverage file to the CLI and writing it out to a file:

$ cat coverage-final.json | ./node_modules/.bin/remap-istanbul -o coverage-remapped.json

An example of generating an HTML report off of remapped coverage:

$ ./node_modules/.bin/remap-istanbul -i coverage-final.json -o html-report -t html

An example of taking the stdin and writing the stdout in the CLI:

$ cat coverage-final.json | ./node_modules/.bin/remap-istanbul > coverage-remap.json

Basic JavaScript

The main CommonJS module provided combines the modules above into a single API which basic usage can look like this:

var remapIstanbul = require('remap-istanbul');
remapIstanbul('coverage-final.json', {
	'json': 'coverage-final.json'
});

This would take the coverage file provided. The function accepts the following arguments:

Argument Type Description
sources Array, string Either an array of strings or a string the represent the JSON Istanbul files to be remapped
reports Object A hash of reports, where the keys are the Istanbul report types and the values are the destination for the report. To send output to the console use the destination null.
returns Promise A promise that is resolved when all the reports are written

AMD

The main modules are provided in AMD for usage (although they utilize amdefine to allow transparent loading by a CommonJS loader such as NodeJS's require - see blow).

lib/loadCoverage

The lib/loadCoverage module would be used something like this:

require([ 'remap-istanbul/lib/loadCoverage' ], function (loadCoverage) {
	var coverage = loadCoverage('coverage-final.json');
	/* or if you have multiple files you want to merge */
	coverage = loadCoverage([ 'coverage-ie.json', 'coverage-chrome.json', 'coverage-firefox.json' ]);
});

The argument signature for loadCoverage is:

Argument Type Description
coverage Array/string Either an array of strings or a string representing the file path to the coverage file(s).
options Object? An object that allows providing alternative methods, mainly used for integration with other systems (e.g. Grunt)
returns Object A coverage object that is ready to be remapped

The options argument can take the following optional properties:

Property Type Default Description
readJSON Function JSON.parse(fs.readFileSync) A function that will synchronously read a file and return a POJO based on the JSON data in the file
warn Function console.warn A function that logs warning messages

lib/remap

Usage of the lib/remap module would look something like this:

require([
	'remap-istanbul/lib/loadCoverage',
	'remap-istanbul/lib/remap'
], function (loadCoverage, remap) {
	var coverage = loadCoverage('coverage-final.json');
	var collector = remap(coverage); /* collector now contains the remapped coverage */
});

If the source map no longer points properly at the source files, you can utilize the basePath option to override the path retrieved from the source map:

require([
	'remap-istanbul/lib/loadCoverage',
	'remap-istanbul/lib/remap'
], function (loadCoverage, remap) {
	var coverage = loadCoverage('coverage-final.json');
	var collector = remap(coverage, {
		basePath: 'some/other/path/to/sources'
	});
});

The argument signature for remap is:

Argument Type Description
coverage Array/Object Either an array of coverage objects or a single coverage object.
options Object? An object that allows providing alternative methods, mainly used for integration with other systems (e.g. Grunt)
returns istanbul/lib/collector An Istanbul coverage collector that is ready to be output

The argument of options can contain the following properties:

Property Type Default Description
basePath String Path found in source map A string to use as the base path for the source locations
exclude String/RegEx/Function undefined If the filename of the source coverage file matches the String or RegEx, it will be skipped while mapping the coverage. Optionally, you can use a function that accepts the filename as the argument, and returns true if the file should be skipped.
mapFileName Function A function that takes a single string argument that is the remapped file name and returns a string which represents the filename that should be in the mapped coverage.
readFile Function fs.readFileSync A function that will synchronously read a file
readJSON Function JSON.parse(fs.readFileSync) A function that will synchronously read a file and return a POJO based on the JSON data in the file
warn Function console.warn A function that logs warning messages

lib/writeReport

The lib/writeReport module would be used something like this:

require([
	'remap-istanbul/lib/loadCoverage',
	'remap-istanbul/lib/remap',
	'remap-istanbul/lib/writeReport'
], function (loadCoverage, remap, writeReport) {
	var collector = remap(loadCoverage('coverage-final.json'));
	writeReport(collector, 'json', 'coverage-final.json').then(function () {
		/* do something else now */
	});
});

The writeReport function can take the following arguments:

Argument Type Description
collector istanbul/lib/collector This is an Istanbul coverage collector (usually returned from remap which is to be written out in a report)
reportType string The type of the report. Valid values are: clover, cobertura, html, json-summary, json, file, lcovonly, teamcity, text-lcov, text-summary or text
reportOptions object Options object of key/value pairs to pass to the reporter
dest string, Function The destination file, directory or console logging function that is the destination of the report. Only text-lcov takes the logging function and will default to console.log if no value is passed.
returns Promise A promise that is resolved when the report is written.

CommonJS

If you are not using an AMD loader, that is not a problem for consuming the modules. They also can be loaded in a CommonJS environment:

var loadCoverage = require('remap-istanbul/lib/loadCoverage');
var remap = require('remap-istanbul/lib/remap');
var writeReport = require('remap-istanbul/lib/writeReport');

Grunt Task

You can utilize this package as a Grunt task. After installing it as a package, you need to add the following to your Gruntfile.js:

grunt.loadNpmTasks('remap-istanbul');

The task is a multi-target task and a basic configuration for the task would look something like this:

grunt.initConfig({
	remapIstanbul: {
		build: {
			src: 'coverage-final.json',
			options: {
				reports: {
					'lcovhtml': 'html-report',
					'json': 'coverage-final.json'
				}
			}
		}
	}
});

This would take in coverage-final.json, remap it and then output the Istanbul HTML report to html-report and overwrite the original coverage-final.json.

The task also recognizes an abbreviated version of configuration:

grunt.initConfig({
	remapIstanbul: {
		build: {
			files: [ {
				src: 'coverage.json',
				dest: 'tmp/coverage.json',
				type: 'json'
			} ]
		}
	}
});

By default, the grunt task will log warnings/errors to the grunt.log.error. If instead you wish the grunt task to grunt.fail.warn which will require --force to ensure the task does not fail the whole build, you should supply the fail option in the task configuration:

grunt.initConfig({
	remapIstanbul: {
		build: {
			src: 'coverage-final.json',
			options: {
				fail: true
			}
		}
	}
});

Gulp Plugin

You can utilize this package as a gulp plugin. There are two main ways it can be used. Just taking a coverage file, remapping and outputting it would look like this:

var gulp = require('gulp');
var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

gulp.task('remap-istanbul', function () {
	return gulp.src('coverage-final.json')
		.pipe(remapIstanbul())
		.pipe(gulp.dest('coverage-remapped.json'));
});

Another way is to utilize the plugin is to have the plugin write out the Istanbul reports directly. This can be accomplished by passing a reports property in the options. For example, to have the JSON coverage report output in addition to the HTML coverage report, at task would look like this:

var gulp = require('gulp');
var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

gulp.task('remap-istanbul', function () {
	return gulp.src('coverage-final.json')
		.pipe(remapIstanbul({
			reports: {
				'json': 'coverage.json',
				'html': 'html-report'
			}
		}));
});

By default, errors in the gulp task will be considered non-fatal and will just be logged to the console. If you wish errors to be emitted and fail the task, you need to supply the task with fail being truthy:

var gulp = require('gulp');
var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

gulp.task('remap-istanbul', function () {
	return gulp.src('coverage-final.json')
		.pipe(remapIstanbul({
			fail: true
		}));
});

Intern Reporter

The package comes with an Intern reporter that makes it easy to output the coverage.json from a test run. The most common usage from the command line would be something like:

node_modules/.bin/intern-runner config=tests/intern reporters=Console reporters=node_modules/remap-istanbul/lib/intern-reporters/JsonCoverage

This will output a coverage-final.json in the root of your project, which you can use with the rest of remap-istanbul to remap it back to the source files.

remap-istanbul's People

Contributors

arma-gast avatar cexbrayat avatar chrismwendt avatar dantup avatar demurgos avatar devcrossnet avatar dominionized avatar dylans avatar ebaker avatar guybedford avatar heycalmdown avatar hirse avatar ianstarz avatar janb87 avatar jdonaghue avatar jvanoostveen avatar kcjmowright avatar kinday avatar kitsonk avatar lukeapage avatar m-a-r-c-e-l-i-n-o avatar mattlewis92 avatar meowtec avatar messman avatar msssk avatar nainslie avatar protectator avatar thetric avatar trysound avatar zxbodya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

remap-istanbul's Issues

Coverage doesn't return the right file path

Gulp task

gulp.task('istanbul', () => {
    return gulp.src([paths.output + '**/*.js'])
        .pipe(istanbul({
            includeUntested: true
        }))
        .pipe(istanbul.hookRequire());
});

gulp.task('remap-istanbul', () => {
    return gulp.src(paths.coverage + 'coverage-final.json')
        .pipe(remapIstanbul({
            reports: {
                'json': paths.coverage + 'coverage.json',
                'lcovreport': paths.coverage + 'html-report'
            }
        }));
});

gulp.task('mocha', ['istanbul'], () => {
    return gulp.src([paths.test], {read: false})
        .pipe(mocha({
            reporter: 'spec',
            timeout: 5000,
            bail: false
        }))
        .pipe(istanbul.writeReports({
            reporters: ['json']
        }))
        .on('error', gulpUtil.log);
});

gulp.task('test', function(callback) {
    return runSequence('mocha', 'remap-istanbul', callback);
});

The Istanbul task puts the right paths into the coverage file. "path":"E:\\Github\\<project-name>\\node\\dist\\test.js", however, the remap-istanbul task changes this path to "path":"/source/test.ts". Is this a bug or can this be solved in a different way?

Console Output

The documentation needs to be updated to reflect that if you want to have console output written from text/text-summary, you need to pass a null filename. This caused much strife trying to figure things out today!

WeakMap is not defined

I'm getting the following error when trying to use the gulp plugin (under Visual Studio 2015). I've upgraded to the latest node.js version and it's still an issue.

cmd.exe /c gulp --tasks-simple
ReferenceError: WeakMap is not defined
    at Object.<anonymous> (C:\Users\hipwells\Git\gk-online\src\app\node_modules\remap-istanbul\lib\remap.js:18:21)
    at runFactory (C:\Users\hipwells\Git\gk-online\src\app\node_modules\remap-istanbul\node_modules\amdefine\amdefine.js:183:30)
    at define (C:\Users\hipwells\Git\gk-online\src\app\node_modules\remap-istanbul\node_modules\amdefine\amdefine.js:277:13)
    at Object.<anonymous> (C:\Users\hipwells\Git\gk-online\src\app\node_modules\remap-istanbul\lib\remap.js:4:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at req (C:\Users\hipwells\Git\gk-online\src\app\node_modules\remap-istanbul\node_modules\amdefine\amdefine.js:144:31)

Error: Unable to find entry for [...]

I'm trying to use the gulp plugin and it doesn't seem to work.

gulp.task('test:remap-istanbul', function() {
  var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');
  return gulp.src('coverage/coverage.json')
    .pipe(remapIstanbul({
      reports: {
        'html': 'coverage/html-report',
      }
    }));
});

Throws this error:

gulp test:remap-istanbul
[11:32:05] Requiring external module ts-node/register
[11:32:07] Using gulpfile ~/1/hot-reload-example/gulpfile.ts
[11:32:07] Starting 'test:remap-istanbul'...

/.../node_modules/remap-istanbul/node_modules/istanbul/lib/store/memory.js:38
            throw new Error('Unable to find entry for [' + key + ']');
                  ^
Error: Unable to find entry for [src/components/BannerComponent-spec.tsx]
    at MemoryStore.Store.mix.get (/.../node_modules/remap-istanbul/node_modules/istanbul/lib/store/memory.js:38:19)
    at HtmlReport.Report.mix.writeDetailPage (/.../node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:411:67)
    at /.../node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:489:26
    at SyncFileWriter.extend.writeFile (/.../node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:57:9)
    at FileWriter.extend.writeFile (/.../node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:147:23)
    at /.../node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:488:24
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (/.../node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:482:23)
    at /.../node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:484:22
    at Array.forEach (native)

However, from command line with everything else being the same, it works wonderfully:

$ ./node_modules/.bin/remap-istanbul -i coverage/coverage.json -o coverage/html-report -t html

What am I doing wrong?

remap-istanbul binary doesn't use inline sources

Assume G:\src\libjass is the root of my project, TypeScript source files are under src/ (eg: G:\src\libjass\src\parser\index.ts), the transpiled JS being instrumented and its sourcemap are under lib/ (G:\src\libjass\lib\libjass.js and G:\src\libjass\lib\libjass.js.map), and the coverage file generated with the intern reporter is at G:\src\libjass\coverage-final.json

The coverage file and sourcemap are at https://gist.github.com/Arnavion/0c3c71eaafdcf60de145 . As you can see, the sourcemap contains filenames relative to G:\src\libjass\src (eg: parser/index.ts) and corresponding source contents.

Now I run remap-istanbul in the G:\src\libjass directory as ./node_modules/.bin/remap-istanbul -i ./coverage-final.json -t html -o html-report and the html reporter complains about being unable to find G:\src\libjass\lib\index.ts. It's correct that that file does not exist (it's looking under lib/, not src/) and I could fix this by passing in -b ./src, but it shouldn't need to look for the files anyway since they're inlined in the sourcemap.


The remap-istanbul binary calls writeReport as

if (output) {
    return writeReport(collector, reportType || 'json', output);
}

which is missing the fourth parameter to writeReport - the source store parameter. As a result the HtmlReport reporter creates an fslookup source store which expects the source files to exist.

I changed the binary to use a memory Store for the options.sources property so that remap would populate it:

var Store = require('../node_modules/istanbul/lib/store');
...
var sourceStore = Store.create('memory');
...
var collector = remap(coverage, basePath ? {
    basePath: basePath
} : { sources: sourceStore }); // <--
/* istanbul ignore else: too hard to test writing to stdout */
if (output) {
    return writeReport(collector, reportType || 'json', output, sourceStore); // <--
}

The next problem is that the store is loaded with full paths as the keys in remap:

sourceStore.set(path.join(sourceMapDir, sourceMap.sources[idx]), source);
// The result of path.join is an absolute path like "G:\src\libjass\lib\parser\index.ts" because sourceMapDir is the absolute path "G:\src\libjass\lib". Note that this doesn't point to the original file which is under src/

... but the html reporter later looks them up using relative keys. It gets these relative paths from the collector's store which is also populated in remap but in a different way:

collector.add(srcCoverage);
// All the keys of srcCoverage are relative paths like "lib\parser\index.ts" because that's how it's populated in getSourceCoverage()

So again it fails to find the files in the in-memory source store and complains.

Changing the sourceStore.set line to not use path.join doesn't help because then the collector contains keys with \ as the path separator (from getMapping because it uses path.relative) and the reporter looks up keys with / as the path separator (from the store).

So I changed it to sourceStore.set(path.relative('.', path.join(sourceMapDir, sourceMap.sources[idx])), source); and it works* but makes me want to wash my hands with soap.

(*) The coverage report lists all the TS files as if they're under lib/ instead of src/, but it has no way of knowing otherwise so I don't mind.

Mocha how-to?

I arrived here looking for TypeScript coverage for my server-side code and my test runner is Mocha. Anyone know the easiest way to get coverage reports? If it helps, my mocha.opts looks like this:

--compilers ts:espower-typescript/guess
--require mocha.conf.ts

inlineSources true, generates output in wrong location

when inlining source with map-file the output gets spred out over multiple folders and report page css stops working. here is the index page

_Changed to running remap in a gulp task since karma couldn't remap on first run..._

image

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "inlineSources": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir": "./wwwroot/app/"
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

karma:

        preprocessors: {
            "wwwroot/**/!(*spec).js": "coverage"
        },


        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ["progress", "coverage"],

        // default value
        coverageReporter:
        {
            includeAllSources: true,
            type: "json",
            dir: "coverage",
            subdir: "json",
            file: "coverage-final.json"
        },

gulp:

gulp.task("remap-to-typescript", function() {
    gulp.src("coverage/json/coverage-final.json")
        .pipe(remapIstanbul({
            reports: {
                html: "coverage/html"
            }
        }));
});

inlineSource will cause html pages from typescript files to be written in strange folder locations.

---ApplicationFolder
    |---app(generated by remap-istanbul *other source files deeper in the tree*)
    |---src 
         |---app(generated by remap-istanbul)
              |---BackendApi
                   |---backendCaller.service.ts.html
         |---Name of App       
              |---coverage
              |---json
                   |---coverage-final.json
              |---html
                   |---index.html
              |---wwwroot
                   |---BackendApi
                        |---backendCaller.service.js
                        |---backendCaller.service.js.map
              |---app
                   |---BackendApi
                        |---backendCaller.service.ts

Without inlineSources:

---ApplicationFolder
    |---src 
         |---Name of App       
              |---coverage
              |---json
                   |---coverage-final.json
              |---html
                   |---app(generated by remap-istanbul *follows app structure*)
                        |---BackendApi
                             |---backendCaller.service.ts.html
                   |---index.html
              |---wwwroot
                   |---BackendApi
                        |---backendCaller.service.js
                        |---backendCaller.service.js.map
              |---app
                   |---BackendApi
                        |---backendCaller.service.ts

map file with inlineSource:
n":3,"file":"backendCaller.service.js","sourceRoot":"","sources":["../../../app/BackendApi/backendCaller.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;YASA;gBAEI,uBAAoB,IAAU;oBAFlC,iBAwCC;oBAtCuB,SAAI,GAAJ,IAAI,CAAM;oBAGvB,SAAI,GAAG,UAAC,CAAiB;wBAC5B,MAAM,CAAC,IAAI,CAAC;oBAChB,CAAC,CAAC;oBAEK,cAAS,GAAG,UAAU,KAAsB;wBAC/C,IAAI,SAAS,GAAG,KAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACpC,IAAI,GAAG,GAAG,eAAa,SAAW,CAAC;wBACnC,MAAM,CAAC,KAAI,CAAC,QAAQ,CAAU,GAAG,EAAE,KAAK,CAAC,CAAC;oBAC9C,CAAC,CAAC;oBAEK,gBAAW,GAAG,UAAC,OAAiB;wBACnC,IAAI,WAAW,GAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBACxC,IAAI,GAAG,GAAG,iBAAe,WAAa,CAAC;wBACvC,MAAM,CAAC,KAAI,CAAC,QAAQ,CAAkB,GAAG,EAAE,OAAO,CAAC,CAAC;oBACxD,CAAC,CAAC;oBAEM,aAAQ,GAAG,UAAU,GAAW,EAAE,IAAS;wBAC/C,IAAI,UAAU,GAAG,KAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAI,CAAC,MAAM,EAAE,CAAC;6BACpE,GAAG,CAAU,UAAA,QAAQ,IAAI,OAAA,QAAQ,CAAC,IAAI,EAAE,EAAf,CAAe,CAAC,CAAC;wBAC/C,MAAM,CAAC,UAAU,CAAC;oBACtB,CAAC,CAAC;oBAEM,YAAO,GAAG,UAAC,MAAW;wBAC1B,IAAI,KAAK,GAAG,oBAAoB,CAAC;wBACjC,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;wBAC1D,MAAM,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;oBAC7D,CAAC,CAAC;oBAEM,WAAM,GAAG;wBACb,IAAI,OAAO,GAAG,IAAI,cAAO,EAAE,CAAC;wBAC5B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;wBACnD,MAAM,CAAC,IAAI,qBAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBACpD,CAAC,CAAC;gBAlCF,CAAC;gBAJL;oBAAC,iBAAU,EAAE;;iCAAA;gBAyCb,oBAAC;YAAD,CAAC,AAxCD,IAwCC;YAxCD,yCAwCC,CAAA","sourcesContent":["import {Injectable} from \"angular2/core\";\r\nimport {Http, Headers, RequestOptions} from \"angular2/http\";\r\nimport {Observable} from \"rxjs/Observable\";\r\nimport \"rxjs/Rx\";\r\nimport {IQuery} from \"../GeneratedFiles/IQuery\";\r\nimport {ICommand} from \"../GeneratedFiles/ICommand\";\r\nimport {CommandResponse} from \"../GeneratedFiles/CommandResponse\";\r\n\r\n@Injectable()\r\nexport class BackendCaller {\r\n\r\n constructor(private http: Http) {\r\n }\r\n\r\n public test = (q: IQuery<string>): Observable<string> => {\r\n return null;\r\n };\r\n\r\n public sendQuery = <TResult>(query: IQuery<TResult>): Observable<TResult> => {\r\n var queryName = this.getName(query);\r\n var url =api/query/${queryName};\r\n return this.httpPost<TResult>(url, query);\r\n };\r\n\r\n public sendCommand = (command: ICommand): Observable<CommandResponse> => {\r\n var commandName = this.getName(command);\r\n var url =api/command/${commandName};\r\n return this.httpPost<CommandResponse>(url, command);\r\n };\r\n\r\n private httpPost = <TResult>(url: string, data: any): Observable<TResult> => {\r\n var observable = this.http.post(url, JSON.stringify(data), this.header())\r\n .map<TResult>(response => response.json());\r\n return observable;\r\n };\r\n\r\n private getName = (action: any): string => {\r\n var regex = /function (.{1,})\\(/;\r\n var results = (regex).exec(action.constructor.toString());\r\n return (results && results.length > 1) ? results[1] : \"\";\r\n };\r\n\r\n private header = () => {\r\n var headers = new Headers();\r\n headers.append(\"Content-Type\", \"application/json\");\r\n return new RequestOptions({ headers: headers });\r\n };\r\n\r\n\r\n}"]}

map-file without inlineSource:
{"version":3,"file":"backendCaller.service.js","sourceRoot":"","sources":["../../../app/BackendApi/backendCaller.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;YASA;gBAEI,uBAAoB,IAAU;oBAFlC,iBAwCC;oBAtCuB,SAAI,GAAJ,IAAI,CAAM;oBAGvB,SAAI,GAAG,UAAC,CAAiB;wBAC5B,MAAM,CAAC,IAAI,CAAC;oBAChB,CAAC,CAAC;oBAEK,cAAS,GAAG,UAAU,KAAsB;wBAC/C,IAAI,SAAS,GAAG,KAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;wBACpC,IAAI,GAAG,GAAG,eAAa,SAAW,CAAC;wBACnC,MAAM,CAAC,KAAI,CAAC,QAAQ,CAAU,GAAG,EAAE,KAAK,CAAC,CAAC;oBAC9C,CAAC,CAAC;oBAEK,gBAAW,GAAG,UAAC,OAAiB;wBACnC,IAAI,WAAW,GAAG,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBACxC,IAAI,GAAG,GAAG,iBAAe,WAAa,CAAC;wBACvC,MAAM,CAAC,KAAI,CAAC,QAAQ,CAAkB,GAAG,EAAE,OAAO,CAAC,CAAC;oBACxD,CAAC,CAAC;oBAEM,aAAQ,GAAG,UAAU,GAAW,EAAE,IAAS;wBAC/C,IAAI,UAAU,GAAG,KAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAI,CAAC,MAAM,EAAE,CAAC;6BACpE,GAAG,CAAU,UAAA,QAAQ,IAAI,OAAA,QAAQ,CAAC,IAAI,EAAE,EAAf,CAAe,CAAC,CAAC;wBAC/C,MAAM,CAAC,UAAU,CAAC;oBACtB,CAAC,CAAC;oBAEM,YAAO,GAAG,UAAC,MAAW;wBAC1B,IAAI,KAAK,GAAG,oBAAoB,CAAC;wBACjC,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;wBAC1D,MAAM,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;oBAC7D,CAAC,CAAC;oBAEM,WAAM,GAAG;wBACb,IAAI,OAAO,GAAG,IAAI,cAAO,EAAE,CAAC;wBAC5B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;wBACnD,MAAM,CAAC,IAAI,qBAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;oBACpD,CAAC,CAAC;gBAlCF,CAAC;gBAJL;oBAAC,iBAAU,EAAE;;iCAAA;gBAyCb,oBAAC;YAAD,CAAC,AAxCD,IAwCC;YAxCD,yCAwCC,CAAA"}

Error during remaping and sourcemap not found

Hello,

I'm trying to migrate a Angular/JSPM project from old istambul instrumenters to remap-istambul, but we are facing an error and don't find any help on the documentation or previously opened ticket.

All the source of the project I'm talking about are available at the following url : https://github.com/davinkevin/angularjs-jspm-seed/tree/remap-istanbul
I've created a special branch with the modification made for this migration.

I have my Karma config like that :

module.exports = function (config) {
  config.set({
    frameworks: ['jspm', 'jasmine', 'jasmine-matchers'],

    files: [
      '../node_modules/karma-babel-preprocessor/node_modules/babel-core/browser-polyfill.js'
    ],

    preprocessors: {
      'app/**/!(*.spec).js': ['babel', 'coverage']
    },

    babelPreprocessor: {
      options: {
        stage: 0,
        sourceMap: 'inline'
      }
    },

    basePath: 'public',

    jspm: {
      config: 'config.js',
      loadFiles: ['app/app.js', '**/*.spec.js'],
      serveFiles: ['**/*.+(js|html|css)'],
      stripExtension: true
    },

    proxies: {
      '/app/': '/base/app/',
      '/jspm_packages/': '/base/jspm_packages/'
    },

    reporters: ['dots', 'coverage'],

    coverageReporter: {
      dir: '../reports/coverage/',
      subdir: '.',
      reporters: [
        {type: 'html'}, {type: 'json'}, {type: 'lcov'}, {type: 'text-summary'}
      ]
    },

    browsers: ['PhantomJS'],
    singleRun : false,
    browserNoActivityTimeout: 75000
  });
};

And when I running all my test, all is ok, with the following results :

karma start karma.config.js --single-run
03 03 2016 10:07:37.804:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
03 03 2016 10:07:37.810:INFO [launcher]: Starting browser PhantomJS
03 03 2016 10:07:39.120:INFO [PhantomJS 1.9.8 (Mac OS X 0.0.0)]: Connected on socket /#3dcSXTFW9HzSPpfnAAAA with id 33417987
PhantomJS 1.9.8 (Mac OS X 0.0.0) INFO: 'Running app.func1 ...'
..............................
PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 30 of 30 SUCCESS (0.032 secs / 0.033 secs)

=============================== Coverage summary ===============================
Statements   : 92.06% ( 290/315 )
Branches     : 82.1% ( 133/162 )
Functions    : 86.89% ( 53/61 )
Lines        : 95.22% ( 239/251 )
================================================================================

The lack of coverage is due to the transpilation of Babel, so it's for that I want to use remap-istanbul.
When I use the command node_modules/.bin/remap-istanbul -i reports/coverage/coverage-final.json -o coverage-mapped.json, I have the following result :

[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/app.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/decorators.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/messages/messages.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/common/service/customLogService.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/route/route.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/messages/message/message.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/config.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/bootstrap/bootstrap.js"]

But, in my Babel preprocessor config, I have defined the sourcemap as 'inline' or even 'both'.

And when I try to generate the html with the command ; node_modules/.bin/remap-istanbul -i reports/coverage/coverage-final.json -t html -o html-report, I have the same errors at the beginning and after an error linked to istanbul itself.

[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/app.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/decorators.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/messages/messages.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/common/service/customLogService.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/route/route.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/messages/message/message.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/config.js"]
[Error: Could not find source map for: "/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/public/app/config/bootstrap/bootstrap.js"]
/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:241
            text = structuredText[startLine].text;
                                            ^

TypeError: Cannot read property 'text' of undefined
    at /Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:241:45
    at Array.forEach (native)
    at annotateFunctions (/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:224:26)
    at HtmlReport.Report.mix.writeDetailPage (/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:427:9)
    at /Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:489:26
    at SyncFileWriter.extend.writeFile (/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:57:9)
    at FileWriter.extend.writeFile (/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:147:23)
    at /Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:488:24
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (/Users/kdavin/Workspace/GitHub/angularjs-jspm-seed/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:482:23)

So, could you help us to understand where the problem come from ?

Thanks

/cc @aubm

Failing with 'Line must be greater than or equal to 1, got '

My project is failing to remap a particular file. It's a file that's extending the Error class - when I don't extend the Error class, it remaps fine.

I suspect that this isn't a remap-istanbul error, but would appreciate any suggestions as to why it may be failing. I've spent most of today looking at this

Thanks

The full error is...

/Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/node_modules/source-map/lib/source-map-consumer.js:538
        throw new TypeError('Line must be greater than or equal to 1, got '
        ^

TypeError: Line must be greater than or equal to 1, got 0
    at SourceMapConsumer_findMapping [as _findMapping] (/Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/node_modules/source-map/lib/source-map-consumer.js:538:15)
    at SourceMapConsumer_originalPositionFor [as originalPositionFor] (/Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/node_modules/source-map/lib/source-map-consumer.js:603:24)
    at getMapping (/Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/lib/remap.js:64:25)
    at /Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/lib/remap.js:213:20
    at Array.forEach (native)
    at /Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/lib/remap.js:211:37
    at Array.forEach (native)
    at /Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/lib/remap.js:173:22
    at Array.forEach (native)
    at remap (/Users/semms/Documents/Development/Cromwell/cromwell-api-services/node_modules/remap-istanbul/lib/remap.js:172:12)

The class it's trying to remap is...

'use strict';

class IOCException extends Error {
    constructor(message) {
        super();

        this.name = 'IOCException';
        this.message = message;

        Error.captureStackTrace(this, this.constructor.name);
    }
}

export default IOCException;

The JSON that's failing to remap

{"path":"/Users/semms/Documents/Development/Cromwell/cromwell-api-services/__build__/src/node_modules/lib/ioc/IOCException.js","s":{"1":1,"2":0,"3":0,"4":1,"5":1,"6":0,"7":0,"8":1,"9":0,"10":0,"11":0,"12":1,"13":1,"14":0,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":0,"22":0,"23":1,"24":1,"25":1},"b":{"1":[1,0],"2":[1,1],"3":[0,0],"4":[0,0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0,0],"9":[0,0],"10":[0,1],"11":[1,0],"12":[0,0],"13":[1,1],"14":[1,0],"15":[1,0]},"f":{"1":0,"2":0,"3":0,"4":0,"5":1,"6":1,"7":0},"fnMap":{"1":{"name":"(anonymous_1)","skip":true,"loc":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"line":3},"2":{"name":"(anonymous_2)","skip":true,"loc":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"line":3},"3":{"name":"_classCallCheck","loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":48}},"line":9},"4":{"name":"_possibleConstructorReturn","loc":{"start":{"line":9,"column":0},"end":{"line":9,"column":48}},"line":15},"5":{"name":"_inherits","loc":{"start":{"line":11,"column":0},"end":{"line":11,"column":41}},"line":21},"6":{"name":"(anonymous_6)","loc":{"start":{"line":13,"column":19},"end":{"line":13,"column":37}},"line":27},"7":{"name":"IOCException","loc":{"start":{"line":16,"column":4},"end":{"line":16,"column":28}},"line":30}},"statementMap":{"1":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"2":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"3":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"4":{"start":{"line":3,"column":0},"end":{"line":3,"column":0}},"5":{"start":{"line":7,"column":0},"end":{"line":7,"column":0}},"6":{"start":{"line":7,"column":50},"end":{"line":7,"column":50}},"7":{"start":{"line":7,"column":92},"end":{"line":7,"column":90}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":0}},"9":{"start":{"line":9,"column":50},"end":{"line":9,"column":50}},"10":{"start":{"line":9,"column":63},"end":{"line":9,"column":61}},"11":{"start":{"line":9,"column":50},"end":{"line":9,"column":48}},"12":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"13":{"start":{"line":11,"column":43},"end":{"line":11,"column":43}},"14":{"start":{"line":11,"column":106},"end":{"line":11,"column":104}},"15":{"start":{"line":11,"column":43},"end":{"line":11,"column":41}},"16":{"start":{"line":11,"column":41},"end":{"line":11,"column":374}},"17":{"start":{"line":11,"column":390},"end":{"line":11,"column":374}},"18":{"start":{"line":13,"column":0},"end":{"line":13,"column":4}},"19":{"start":{"line":14,"column":4},"end":{"line":13,"column":37}},"20":{"start":{"line":16,"column":4},"end":{"line":16,"column":4}},"21":{"start":{"line":17,"column":8},"end":{"line":16,"column":28}},"22":{"start":{"line":19,"column":8},"end":{"line":16,"column":28}},"23":{"start":{"line":22,"column":4},"end":{"line":13,"column":37}},"24":{"start":{"line":33,"column":0},"end":{"line":33,"column":0}},"25":{"start":{"line":34,"column":0},"end":{"line":34,"column":0}}},"branchMap":{"1":{"line":3,"type":"cond-expr","locations":[{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true}]},"2":{"line":3,"type":"binary-expr","locations":[{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true}]},"3":{"line":3,"type":"cond-expr","locations":[{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true}]},"4":{"line":3,"type":"binary-expr","locations":[{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true}]},"5":{"line":10,"type":"if","locations":[{"start":{"line":7,"column":50},"end":{"line":7,"column":50}},{"start":{"line":7,"column":50},"end":{"line":7,"column":50}}]},"6":{"line":16,"type":"if","locations":[{"start":{"line":9,"column":50},"end":{"line":9,"column":50}},{"start":{"line":9,"column":50},"end":{"line":9,"column":50}}]},"7":{"line":18,"type":"cond-expr","locations":[{"start":{"line":9,"column":226},"end":{"line":9,"column":159}},{"start":{"line":9,"column":233},"end":{"line":9,"column":159}}]},"8":{"line":18,"type":"binary-expr","locations":[{"start":{"line":9,"column":159},"end":{"line":9,"column":159}},{"start":{"line":9,"column":168},"end":{"line":9,"column":168}},{"start":{"line":9,"column":196},"end":{"line":9,"column":196}}]},"9":{"line":18,"type":"cond-expr","locations":[{"start":{"line":9,"column":175},"end":{"line":9,"column":175}},{"start":{"line":9,"column":175},"end":{"line":9,"column":175}}]},"10":{"line":22,"type":"if","locations":[{"start":{"line":11,"column":43},"end":{"line":11,"column":43}},{"start":{"line":11,"column":43},"end":{"line":11,"column":43}}]},"11":{"line":22,"type":"binary-expr","locations":[{"start":{"line":11,"column":47},"end":{"line":11,"column":47}},{"start":{"line":11,"column":83},"end":{"line":11,"column":83}}]},"12":{"line":23,"type":"cond-expr","locations":[{"start":{"line":11,"column":194},"end":{"line":11,"column":194}},{"start":{"line":11,"column":194},"end":{"line":11,"column":194}}]},"13":{"line":24,"type":"binary-expr","locations":[{"start":{"line":11,"column":244},"end":{"line":11,"column":244}},{"start":{"line":11,"column":258},"end":{"line":11,"column":258}}]},"14":{"line":24,"type":"if","locations":[{"start":{"line":11,"column":41},"end":{"line":11,"column":41}},{"start":{"line":11,"column":41},"end":{"line":11,"column":41}}]},"15":{"line":24,"type":"cond-expr","locations":[{"start":{"line":11,"column":414},"end":{"line":11,"column":390}},{"start":{"line":11,"column":460},"end":{"line":11,"column":460}}]}},"l":{"0":1,"3":1,"7":1,"9":1,"11":1,"13":1,"14":1,"16":1,"17":0,"19":0,"22":1,"33":1,"34":1}}

Remap is not working properly when using source map files from webpack

This issue is most likely related to other similar issues I've seen in your queue. I wanted to log it to hopefully provide a bit more info to give some more use cases. We are trying to use Webpack to build typescript and then test with karma and then use remap to show coverage on our typescript.

Using 0.6.4 of remap poses issues in doing so. Here is a sample repo that will demonstrate the issue: https://github.com/matt-schrader/typescript_code_coverage

I have made changes on my box to make it work for me. I'll post those changes, but by no means am I recommending them as solutions as I'm not sure they are correct for the community. The changes I made are after the //MATT comment.

First run the build

npm install
npm run build
npm run test
npm run coverage

The last the step should give an error like

Error: EACCES: permission denied, mkdir '/src'
    at Error (native)
    at Object.fs.mkdirSync (fs.js:794:18)
    at Function.sync (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/node_modules/mkdirp/index.js:71:13)
    at SyncFileWriter.extend.writeFile (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:55:16)
    at FileWriter.extend.writeFile (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:147:23)
    at HtmlReport.Report.mix.writeFiles (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:479:16)
    at /Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:484:22
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:482:23)
    at HtmlReport.Report.mix.writeReport (/Users/j1014252/Playground/typescript/getting_started_with_webpack/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:566:14)

To fix this I changed node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.writeFiles to be:

writeFiles: function (writer, node, dir, collector) {
        var that = this,
            indexFile = path.resolve(dir, 'index.html'),
            childFile;
        if (this.opts.verbose) { console.error('Writing ' + indexFile); }
        writer.writeFile(indexFile, function (contentWriter) {
            that.writeIndexPage(contentWriter, node);
        });
        node.children.forEach(function (child) {

            if (child.kind === 'dir') {
                //MATT
                var childDir = child.relativeName;
                if (childDir.charAt(0) === '/') {
                  childDir = childDir.substring(1);
                }
                that.writeFiles(writer, child, path.resolve(dir, childDir), collector);
            } else {
                childFile = path.resolve(dir, child.relativeName + '.html');
                if (that.opts.verbose) { console.error('Writing ' + childFile); }
                writer.writeFile(childFile, function (contentWriter) {
                    that.writeDetailPage(contentWriter, child, collector.fileCoverageFor(child.fullPath()));
                });
            }
        });
    }

Then I ran into an issue where the links and style includes from the html reports were incorrect. The links included a '/' and the style includes had an extra '../' causing the source code coverage to not work at all. To fix this I changed node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.cleanPath to be

function cleanPath(name) {
  //MATT
  var pathToClean = name;

  if (pathToClean.charAt(0) === '/') {
    pathToClean = pathToClean.substring(1);
  }
    var SEP = path.sep || '/';
    return (SEP !== '/') ? pathToClean.split(SEP).join('/') : pathToClean;
}

After these two changes I am seeing coverage properly.

remap-istanbul and karma or browserify

I have a TypeScript project which I would like to generate coverage reports for. Karma is set up to use browserify as preprocessor (using karma-browserify). By adding browserify-istanbul as browserify transform, I managed to generate coverage reports which display the TypeScript code, but with (what it seems to be) coverage for the generated JavaScript:

image

Can remap-istanbul be used to correct the coverage mapping? Any pointers how I can integrate it with karma and/or browserify?

karma.conf.js:

module.exports = function(config) {
  config.set({
    frameworks: ['browserify', 'source-map-support', 'mocha', 'chai'],
    files: [
      'typings/tsd.d.ts',
      'test/**/*.ts',
      'src/**/*.ts'
    ],
    preprocessors: {
      'typings/tsd.d.ts': ['browserify'],
      'test/**/*.ts': ['browserify'],
      'src/**/*.ts': ['browserify']
    },
    browserify: {
      debug: true,
      plugin: ['tsify'],
      transform: [require('browserify-istanbul')]
    },
    browsers: [
      'Chrome'
    ],
    client: {
      mocha: {
        reporter: 'html',
        ui: 'bdd'
      }
    },
    reporters: ['progress', 'coverage'],
    coverageReporter: {
      type: 'html',
      dir: 'coverage',
      subdir: function (browser) {
        return browser.toLowerCase().split(/[ /-]/)[0];
      }
    }
  });
};

CLI produces json instead of lcovonly when piping (not using `output`)

I hope the following transcript is self-explanatory. CLI is producing the proper "lcovonly" format when using the --output option, but it's producing "json" when piped to e.g. coveralls.

$ ./node_modules/.bin/remap-istanbul --input coverage/coverage.json --type lcovonly > output1
$ ./node_modules/.bin/remap-istanbul --input coverage/coverage.json --type lcovonly | cat > output2
$ ./node_modules/.bin/remap-istanbul --input coverage/coverage.json --type lcovonly --output output3
$ diff output1 output2
$ diff output1 output3 | head
1c1,43
< {"my-module.coffee":{"path":"my-module.coffee","statementMap":{"1":{"start":{"line":4,"column":0}...

---
> TN:
> SF:my-module.coffee
> FN:4,(anonymous_1)
> FN:11,(anonymous_2)
> FN:20,(anonymous_3)
> FN:34,(anonymous_4)
> FNF:4

Hardcoded path

Hello, I have noticed that even if I change the basePath property remap-istanbul still adds 'source/' between the basePath and the files. Any ideas how can I disable/configure it?

remap.js - False negatives due to improper handling of embedded source code

In lib/remap.js there's a line of code that detects whether or not source code is embedded and if so uses that code. However, it assumes this property is a string (e.g. in the fixture for the corresponding test). This is incorrect as code is an array.

As a consequence, when the source map regex is tested against this proper, the array is stringified and as a result, a , may be appended to what would be considered the "source map name" if there are extra newlines at the end of the file. This results in remap-istanbul reporting that it cannot find the file.

This is probably occurring due to a version update from istanbul that they considered backwards-compatible. You could support this in a backwards-compatible way by adding the following to remap.js:

var jsText = fileCoverage.code || readFile(filePath); /* line 189 @ f4b09bc */ 
if (Array.isArray(jsText)) {
  jsText = jsText.join('\n');
}
// ...

I'd be happy to submit this PR myself but TBH it could probably be fixed by the time I went through the song and dance of getting your CLA signed off on :)

In the meantime, a workaround for tools like karma might be to have their coverage preprocessor tell istanbul to disable embedding source code.

Error with multiple sourceMappingURL directives

When compiling typescript files and bundling everything with webpack there may be cases of generated files with multiple sourceMappingURL directives (see s-panferov/awesome-typescript-loader#60 and webpack/webpack#273).

This leads to non existing source maps files being loaded by remap-istanbul and causing an error:

/my/path/project/node_modules/remap-istanbul/lib/remap.js:133
                throw new Error('Could not find file: "' + filePath + '"');
                ^

Error: Could not find file: "/my/path/project/.tmp/index.module.js.map"
    at readJSON (/my/path/project/node_modules/remap-istanbul/lib/remap.js:133:11)
    at /my/path/project/node_modules/remap-istanbul/lib/remap.js:172:21
    at Array.forEach (native)
    at /my/path/project/node_modules/remap-istanbul/lib/remap.js:153:22
    at Array.forEach (native)
    at remap (/my/path/project/node_modules/remap-istanbul/lib/remap.js:152:12)
    at DestroyableTransform._transform (/my/path/project/node_modules/remap-istanbul/lib/gulpRemapIstanbul.js:31:20)
    at DestroyableTransform.Transform._read (/my/path/project/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:10)
    at DestroyableTransform.Transform._write (/my/path/project/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:160:12)
    at doWrite (/my/path/project/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:333:12)
    at writeOrBuffer (/my/path/project/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:319:5)
    at DestroyableTransform.Writable.write (/my/path/project/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:246:11)
    at write (/my/path/project/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_readable.js:623:24)
    at flow (/my/path/project/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_readable.js:632:7)
    at DestroyableTransform.pipeOnReadable (/my/path/project/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_readable.js:664:5)
    at emitNone (events.js:67:13)

The error is due to how you select the source map directive at https://github.com/SitePen/remap-istanbul/blob/master/lib%2Fremap.js#L169, trusting that there is only one of those.
Is there a way we can change or customise the match selection through proper options? I think this might be straightforward and could easily be implemented in a PR, if you agree with the purpose of the change.

Thanks.

Provide only a sourcemaps v3 for processing

In my use case, using jspm, I have to create two additional files (the transpiled file and source map) just to have remap() find them. In other words, I have a physical source file, which then gets transpiled and a source map is generated, but for the last two (transpiled and source map file ), I have already access to them in memory and they don't need to be a physical file for any other reason. Since sourcemaps v3 supports the sourcesContent property, it would be ideal if I could just pass in an array of v3 source maps to remap() (along with the coverage object), and have remap() granted immediate access to the source map and the source's content (via the sourcesContent property), without them having to be physically on the system. If this sounds reasonable to you guys, I would be happy to help with that effort.

HTML Report issue on Windows.

Well, I was trying to remap a report but I am getting this weird report error with html

events.js:141
      throw er; // Unhandled 'error' event
      ^
 TypeError: Cannot read property 'split' of null
    at HtmlReport.Report.mix.writeDetailPage (K:\platform\node_modules\istanbul\lib\report\html.js:412:30)
    at K:\platform\node_modules\istanbul\lib\report\html.js:489:26
    at SyncFileWriter.extend.writeFile (K:\platform\node_modules\istanbul\lib\util\file-writer.js:57:9)
    at FileWriter.extend.writeFile (K:\platform\node_modules\istanbul\lib\util\file-writer.js:147:23)
    at K:\platform\node_modules\istanbul\lib\report\html.js:488:24
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (K:\platform\node_modules\istanbul\lib\report\html.js:482:23)
    at K:\platform\node_modules\istanbul\lib\report\html.js:484:22
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (K:\platform\node_modules\istanbul\lib\report\html.js:482:23)

but when I tried to text...

--------------------|----------|----------|----------|----------|----------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
--------------------|----------|----------|----------|----------|----------------|
 /source/main/core\ |       12 |        0 |        0 |       12 |                |
  application.ts    |       12 |        0 |        0 |       12 |... 127,134,135 |
 /source/main\      |    66.67 |       50 |       25 |    66.67 |                |
  bootstrap.ts      |       60 |      100 |       25 |       60 |    63,64,72,79 |
  index.ts          |       80 |       50 |      100 |       80 |             32 |
--------------------|----------|----------|----------|----------|----------------|
All files           |     32.5 |       25 |     9.09 |     32.5 |                |
--------------------|----------|----------|----------|----------|----------------|

This also made directories in weird places (K:\source\main**), and lastly incomplete in project (K:\platform\coverage\reports\html), with config below:

  @Task("test/remap", ["test/analyze"])
  testReMap() {
    return gulp
      .src("./coverage/reports/json/coverage.json")
      .pipe(remapIstanbul({
        fail: true,
        reports: {
          'html': './coverage/reports/html',
          'text': null,
        }
      }));
  }

Also a note, an excerpt from coverage.json looks like this:

{
  "K:\\platform\\coverage\\src\\main\\index.js": {
    "path": "K:\\platform\\coverage\\src\\main\\index.js",
    "s": {}
  }
}

Versions:
"gulp-istanbul": "^0.10.4",
"remap-istanbul": "^0.6.4"

TypeError: fs.existsSync is not a function

Hi all,

we are integrating remap-istanbul in our workflow to have coverage report on our ts files; however, when executed it always throws this exception:

myApp\node_modules\remap-istanbul\lib\remap.js:139
                        if (!fs.existsSync(filePath)) {
                                ^

TypeError: fs.existsSync is not a function
    at readFile (myApp\node_modules\remap-istanbul\lib\remap.js:139:12)
    at myApp\node_modules\remap-istanbul\lib\remap.js:155:18
    at Array.forEach (native)
    at myApp\node_modules\remap-istanbul\lib\remap.js:153:22
    at Array.forEach (native)
    at remap (myApp\node_modules\remap-istanbul\lib\remap.js:152:12)
    at DestroyableTransform._transform (myApp\node_modules\remap-istanbul\lib\gulpRemapIstanbul.js:31:20)
    at DestroyableTransform.Transform._read (myApp\node_modules\readable-stream\lib\_stream_transform.js:172:10)
    at DestroyableTransform.Transform._write (myApp\node_modules\readable-stream\lib\_stream_transform.js:160:12)
    at doWrite (myApp\node_modules\readable-stream\lib\_stream_writable.js:333:12)
    at writeOrBuffer (myApp\node_modules\readable-stream\lib\_stream_writable.js:319:5)
    at DestroyableTransform.Writable.write (myApp\node_modules\readable-stream\lib\_stream_writable.js:246:11)
    at write (myApp\node_modules\vinyl-fs\node_modules\readable-stream\lib\_stream_readable.js:623:24)
    at flow (myApp\node_modules\vinyl-fs\node_modules\readable-stream\lib\_stream_readable.js:632:7)
    at DestroyableTransform.pipeOnReadable (myApp\node_modules\vinyl-fs\node_modules\readable-stream\lib\_stream_readable.js:664:5)
    at emitNone (events.js:67:13)

We lauch it with gulp:

var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

gulp.task('coverage', ['test'], function () {
  return gulp.src('test/coverage/coverage.json')
    .pipe(remapIstanbul({
      reports: {
        'text' : 'test/coverage-ts/coverage.txt',
        'lcovonly' : 'test/coverage-ts/lcov.dat',
        'json': 'test/coverage-ts/coverage.json',
        'html': 'test/coverage-ts/html-report'
      },
      basePath : './app/'
    }));
    //.pipe(remapIstanbul())
    //.pipe(gulp.dest('test/coverage-ts'));
});

We tried with nodejs 4.1.0, 4.2.2 and 5.1.0.
The version of remap-istanbul is 0.4.0.

With the following change in the remap.js everything works as expected:

var nodeFS = require('fs'); // ADD THIS LINE HERE

if (typeof define !== 'function') { /* istanbul ignore next */ var define = require('amdefine')(module); }
define([
    'require',
    'exports',
    './node!istanbul/lib/collector',
    './node!path',
    './node!fs',
    './node!source-map/lib/source-map-consumer'
], function (require, exports, Collector, path, fs, smc) {
    /* global WeakMap */

  fs = nodeFS;  // ADD THIS LINE HERE
  ...

support ignore comments

The instanbul library has a system to ignore certain parts of the code (see). This doesn't work correctly after the remap.

I inspected the coverage.json files and a location entry has in addition to start and end also a skip property.

original coverage.json

"locations":[{"start":{"line":1,"column":11},"end":{"line":1,"column":19}},{"start":{"line":31,"column":1},"end":{"line":null,"column":-1}}]}

remapped coverage.json

"locations":[{"start":{"line":32,"column":18},"end":{"line":32,"column":30}},{"start":{"line":32,"column":74},"end":{"line":32,"column":91},"skip":true}]}

I suspect the only thing missing for this to work, is to transfer the skip property.

HTML report files in wrong location

For some reason, when I run the remap task it outputs the generated HTML files in three separate folders. Though the links between the files work, the CSS, JS, and other assets can't be found.

Here is what I'm seeing:

code

Notice coverage/original has the original Istanbul output. That works great.

coverage/remapped has the output from remapIstanbul.

The arrows point to the three separate locations that the generated files get output too.

Here is the relevant portion of my Gruntfile:

    mocha_istanbul: {
      coverage: {
        src: files.tests,
        options: {
          coverageFolder: 'coverage/original/',
          recursive: true,
          timeout: 20000,
          reporter: 'spec'
        }
      }
    },
    remapIstanbul: {
      build: {
        src: 'coverage/original/coverage.json',
        options: {
          reports: {
            html: 'coverage/remapped/html-report/',
            json: 'coverage/remapped/coverage-final.json'
          }
        }
      }
    },

I'd love to see everything output to coverage/remapped/html-report/src but I'm not sure what is going on. Any ideas?

Sourcemaps Error - Line must be Greater than or Equal to 1, Got 0

Situation:

  • Using latest version of gulp, babel, gulp-istanbul, and attempting to remap coverage outputs. Istanbul is able to process code as expected, and generates its own reports - albiet with the offsets wrong due to the babel transpilation.
  • Running the gulp task for remap-istanbul causes horrible errors and death, specifically:

Stack trace:

TypeError: Line must be greater than or equal to 1, got 0
at SourceMapConsumer_findMapping as _findMapping
at SourceMapConsumer_originalPositionFor as originalPositionFor
at getMapping (/Users/steveg/Desktop/workspace/steve-standards/node_modules/remap-istanbul/lib/remap.js:66:25)
at /Users/steveg/Desktop/workspace/steve-standards/node_modules/remap-istanbul/lib/remap.js:264:20
at Array.forEach (native)
at /Users/steveg/Desktop/workspace/steve-standards/node_modules/remap-istanbul/lib/remap.js:262:44
at Array.forEach (native)
at /Users/steveg/Desktop/workspace/steve-standards/node_modules/remap-istanbul/lib/remap.js:182:22
at Array.forEach (native)
at remap (/Users/steveg/Desktop/workspace/steve-standards/node_modules/remap-istanbul/lib/remap.js:181:12)

Cover task:

    import * as isparta from 'isparta';
    import istanbul from 'gulp-istanbul';
    import gulp from 'gulp';

    export default () =>
    gulp.src(['./dist/**/*.js'])
        .pipe(istanbul({
        includeUntested: true,
        instrumenter: isparta.Instrumenter,
        }))
        .pipe(gulp.dest('./docs/coverage/instrumented'))
        .pipe(istanbul.hookRequire());

Test task:

    import istanbul from 'gulp-istanbul';
    import mocha from 'gulp-mocha';
    import gulp from 'gulp';
    import remapIstanbul from 'remap-istanbul/lib/gulpRemapIstanbul';

    export default () =>
    gulp.src(['./tests/**/*.spec.js'])
        .pipe(mocha({
        reporter: 'mochawesome',
        reporterOptions: {
            inlineAssets: true,
            reportTitle: 'Unit Test Report',
            reportDir: './docs/unit-tests',
        },
        }))
        .pipe(istanbul.writeReports({
        dir: './docs/coverage',
        reporters: ['json'],
        }))
        .on('end', () => gulp.src('./docs/coverage/coverage-final.json')
            .pipe(remapIstanbul({
            'json': './docs/coverage/coverage.json',
            'html': './docs/coverage/html-report'
            }))
            .pipe(gulp.dest('.')));

Instrumented code:

        const x = 5;

        function imNeverRun() {
        if (x >= 7) {
            return 2;
        } else {
            return 5;
        }
        }

        export default x;

Babel intermediate:

  "use strict";

  Object.defineProperty(exports, "__esModule", {
    value: true
  });

  var _sourceMapSupport2 = require("source-map-support");

  (0, _sourceMapSupport2.install)();
  var x = 5;

  function imNeverRun() {
    if (x >= 7) {
      return 2;
    } else {
      return 5;
    }
  }

  exports.default = x;
  module.exports = exports['default'];
  //# sourceMappingURL=index.js.map

The sourcemap:

    {"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;;;AAAA,IAAM,IAAI,CAAV;;AAEA,SAAS,UAAT,GAAsB;AACpB,MAAI,KAAK,CAAT,EAAY;AACV,WAAO,CAAP;AACD,GAFD,MAEO;AACL,WAAO,CAAP;AACD;AACF;;kBAEc,C","file":"index.js","sourcesContent":["const x = 5;\n\nfunction imNeverRun() {\n  if (x >= 7) {\n    return 2;\n  } else {\n    return 5;\n  }\n}\n\nexport default x;\n"]}

And then the coverage-final that's generated:

    {
    "/Users/steveg/Desktop/workspace/steve-standards/dist/index.js":{"path":"/Users/steveg/Desktop/workspace/steve-standards/dist/index.js","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":1,"8":0,"9":0,"10":0,"11":0,"12":0},"b":{"1":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"imNeverRun","loc":{"start":{"line":12,"column":0},"end":{"line":12,"column":22}},"line":15}},"statementMap":{"1":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"2":{"start":{"line":0,"column":0},"end":{"line":0,"column":0},"skip":true},"3":{"end":{"line":3,"column":0},"start":{"line":3,"column":0}},"4":{"end":{"line":7,"column":0},"start":{"line":7,"column":0}},"5":{"end":{"line":9,"column":0},"start":{"line":9,"column":0}},"6":{"end":{"line":10,"column":0},"start":{"line":10,"column":0}},"7":{"end":{"line":18,"column":1},"start":{"line":12,"column":0}},"8":{"end":{"line":17,"column":3},"start":{"line":13,"column":2}},"9":{"end":{"line":14,"column":4},"start":{"line":14,"column":4}},"10":{"end":{"line":16,"column":4},"start":{"line":16,"column":4}},"11":{"end":{"line":20,"column":0},"start":{"line":20,"column":0}},"12":{"end":{"line":21,"column":0},"start":{"line":21,"column":0}}},"branchMap":{"1":{"line":16,"type":"if","locations":[{"end":{"line":13,"column":2},"start":{"line":13,"column":2}},{"end":{"line":13,"column":2},"start":{"line":13,"column":2}}]}},"l":{"0":1,"3":0,"7":0,"9":0,"10":0,"12":1,"13":0,"14":0,"16":0,"20":0,"21":0}}}

How to display coverage report in stdout

Hi,

I'm using gulp and remap-istanbul to generate test coverage. I would like to know how to display the test coverage report in stdout, like the report generated by gulp-istanbul.

Thanks,
Jerry

basePath in gulp

Code:

gulp.task( 'test:istanbul', [ 'pre-test', 'test:mocha' ], () =>
    gulp.src( 'coverage/coverage-final.json' )
    .pipe( remapIstanbul( {
        fail: true,
        basePath: 'src',
        reports: {
            lcovonly: 'coverage/lcov.info',
            json: 'coverage/coverage-final.json'
        }
    } ) )
);

Expected: source paths output as /src/foo.ts
Actual: source paths output as /source/foo.ts

verbose output option for cli?

While running remap-istanbul on CI, could observe intermittent failures like below

remap-istanbul -i coverage/coverage.json -o coverage/coverage-remapped.json && remap-istanbul -i coverage/coverage.json -o coverage/coverage-remapped.lcov -t lcovonly && remap-istanbul -i coverage/coverage.json -o coverage/coverage-remapped -t html
The command "npm test && npm run cover" exited with 0.
cache.2
store build cache
1.71snothing changed, not updating cache
after_script
0.31s$ cat ./coverage/coverage-remapped.lcov  | ./node_modules/coveralls/bin/coveralls.js
cat: ./coverage/coverage-remapped.lcov: No such file or directory
[error] "2015-10-30T17:17:58.950Z"  'error from lcovParse: ' 'Failed to parse string'
[error] "2015-10-30T17:17:58.952Z"  'input: ' ''
[error] "2015-10-30T17:17:58.953Z"  'error from convertLcovToCoveralls'

remapped output is not produced. Trying to triage issue but there isn't any messages from remap-istanbul, hard to find where to start. Is there any way to check behaviors?

js files without source-map to change from absolute path to relative

We're using remapIstnabul for coverage of a project with js and ts files, I'd like the js files coverage, (which aren't with a source-map) path to be relative to my process.cwd() (or to take an argument)

I'd change in remap.js:
srcCoverage[filePath] = fileCoverage;
to:
srcCoverage[path.relative(process.cwd(), filePath)] = fileCoverage;

How to pass reporter options

We use some custom reporter options for the threshold colors, and I was wondering how I pass these to the remap-istanbul to the reports. As after the remap, the coverage color thresholds are back to the defaults.

Now the 'normal' istanbul is called (instanbul.writeReports(config.istanbul.reports)) with the following as the value of the config.istanbul.reports:

{
  dir: 'build/report',
  reporters: [
    'lcov',
    'json'
  ],
  reportOpts: {
    watermarks: {
      statements: [75, 100],
      lines: [75, 100],
      functions: [75, 100],
      branches: [75, 100]
    }
  }
}

Is it possible to pass the options for the reporters when remapping the output? And if so, how?

BTW: I'm using the gulp remap-istanbul.

Incorrect remapping for sourcemaps with relative source paths

Hi, I have caught an issue while remapping coverage report with source maps with relative source paths inside.

Issue appears when there are files nested at more than one level, deep:

lib/
├── Router.js
├── Router.js.map
├── ....
├── expressions
│   ├── compile.js           <----- files like this one would be remapped with incorrect paths
│   ├── compile.js.map
│   ├── ....
src/
├── Router.js
├── ....
├── expressions
│   ├── compile.js
│   ├── ....

file lib/expressions/compile.js happens to be remaped to path ../../src/expressions/compile.js instead of ../src/expressions/compile.js

This results in incorrect coverage info posted on codecov.io and broken html report like in issue #49

Project where you can reproduce this can be found here: https://github.com/zxbodya/router1

Missing folder structure in html output

Hi,

I am using inline source maps with ts-loader, the remapping is working however the folders are missing instead all my files are appearing under root

screen shot 2016-04-26 at 17 55 27

You can find my coverage report here as well: Link

Gulp Plugin - enforceThresholds

The gulp plugin requires an enforceThresholds capability, similiar to gulp-istanbul. Without this people have to write custom code in the on('end') for their pipe, and then reload the lcov data to make the determination about coverage.

remap-istanbul throws error for non-compiled source

Our project includes mostly typescript compiled to javascript, with sourcemaps generated by TypeScript. When I use remap-istanbul for a pure-typescript project it works just fine. However, when running against coverage data that also includes a plain javascript file, and hence no source map for that file, I get [Error: Could not find source map for: "/path/to/file.js" ]. The coverage is generated with istanbul cover command for a node project. The plain javascript module is imported with require().

Remapping html reports

Hi,

Great module! I'm getting the following exception when 'reports' is configured to 'html' in the remapping task.

/project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:203
                endCol = structuredText[startLine].text.originalLength();
                                                  ^
TypeError: Cannot read property 'text' of undefined
    at /project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:203:51
    at Array.forEach (native)
    at annotateStatements (/project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:188:33)
    at HtmlReport.Report.mix.writeDetailPage (/project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:423:9)
    at /project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:484:26
    at SyncFileWriter.extend.writeFile (/project/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:57:9)
    at FileWriter.extend.writeFile (/project/node_modules/remap-istanbul/node_modules/istanbul/lib/util/file-writer.js:147:23)
    at /project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:483:24
    at Array.forEach (native)
    at HtmlReport.Report.mix.writeFiles (/project/node_modules/remap-istanbul/node_modules/istanbul/lib/report/html.js:477:23)

Btw, the library is not on npm yet :(

Thank you!

Add a CLI

It would be amazing if this could integrate with current Istanbul usages using the CLI to do something like:

istanbul cover node_modules/mocha/bin/_mocha -- dist/**/*.spec.ts --require typescript-node/register -R spec --bail && remap-istanbul

Where the CLI remap-istanbul assumes default output from istanbul by default to rewrite and can optionally accept a path, etc. to override the assumption.

Edit: Not that the code coverage works with that yet, that's another issue to fix with istanbul.

Gulp: No such file or directory

I'm running remap-instanbul via Gulp with the configuration below:

Gulp tasks

gulp.task('remap-istanbul', function () {
    return gulp.src('coverage/json/coverage-js.json')
        .pipe(remapIstanbul({
            reports: {
                json: 'coverage/json/coverage-ts.json',
                html: 'coverage/html-report'
            }
        }));
});

This is how I transpile my TypeScript to JavaScript. Note that I move the transpiled code to /build folder.

gulp.task('ts', function() {
    var tsResult = gulp.src('src/**/*.ts')
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.typescript(tsProject));

    return tsResult
        .js
        .pipe(plugins.sourcemaps.write())
        .pipe(gulp.dest('build/js'));
});

For some reason the plugin changes my working directory to C:\source which isn't correct. The correct directory structure should be something like: C:\myproject\src\app\main.ts.

Console

[15:20:24] Starting 'remap-istanbul'...
fs.js:549
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENOENT: no such file or directory, open 'C:\source\app\main.ts'
    at Error (native)
    at Object.fs.openSync (fs.js:549:18)
    at Object.fs.readFileSync (fs.js:397:15)
    at LookupStore.Store.mix.get (C:\agent-ui\SCP_WD_MCA_UI_Seed\node_modules\remap-istanbul\node_modules\istanbul\lib\store\fslookup.js:40:19)

Am I missing something?

TypeError: Cannot convert undefined or null to object

Error output as below when processing a coverage file from TypeScrupt-compiled js that uses --outFile, plus a couple of non-sourcemapped .js files. I had attempted to integrate this project a while back but had issues and moved on/didn't get coverage reports working. Trying again. I just wanted to make sure this gets reported and help debug this issue further if it's not a known issue.

Input:

$ cat coverage/coverage.json | ./node_modules/.bin/remap-istanbul -o coverage/coverage-remap.json

Output:

TypeError: Cannot convert undefined or null to object
    at <My Project Directory>/node_modules/remap-istanbul/lib/remap.js:182:11
    at Array.forEach (native)
    at remap (<My Project Directory>/node_modules/remap-istanbul/lib/remap.js:181:12)
    at <My Project Directory>/node_modules/remap-istanbul/bin/remap-istanbul:131:19
    at process._tickCallback (internal/process/next_tick.js:103:7)

Environment:

  • typescript: 1.8.9
    • occurs with both --inlineSourceMaps and --sourceMap flags
  • node: 6.0.0
  • OS: OS X El Capitan 10.11.4
  • istanbul: 0.4.3
    • using instanbul cover command
  • remap-istanbul: 0.6.3

I'm not authorized to spend work hours on this without confirmation that the issue is unreported and unknown, so please get back to me if you need more info. Thank you.

I get weird paths

I have a project using Typescript and to test it, I transpile all source and tests like:

temp/foo/foo.js
temp/foo/foo.js.map
temp/foo/foo.spec.js

A bunch of folders like that.

Original files are:

src/foo/foo.ts
src/foo/foo.spec.ts

I put karma-coverage and it works perfectly by running it against that temp folder (to process only .js file and not spec nor map files).

My coverage-final has path like:

"/Users/myuser/code/ng2/folder/anotherfolder/temp/foo/foo.js":{"path":"/Users/myuser/code/ng2/folder/anotherfolder/temp/foo/foo.js"

And the .map for that concrete file starts with:

{"version":3,"sources":["foo/foo.ts"]

When I run this tool (via CLI or gulp) I get in the result json:

"../../../../../../source/foo/foo.ts":{"path":"../../../../../../source/foo/foo.ts"

Notice all that ../ and then that source folder that comes from nowhere. Transpiled code is in temp and real source is in src.

Then if I try to convert this to html, it fails on the path.

Not sure if I am using this wrong or there is a bug.

Node loader plugin loads modules that clobber the standard library

If https://www.npmjs.com/package/path is installed next to remap-istanbul it'll be loaded instead of the normal path module. This is unexpected behavior, normal require usage wouldn't load that dependency.

I think it's due to this line

var localModulePath = module._findPath(id, module._nodeModulePaths(contextRequire.toUrl('.')));
which uses private API's to resolve the module path. I think this should be replaced by require.resolve().

(And no I didn't choose to install that dependency, it's probably an accidental dependency of another dependency's dependency's dependency, flattened by npm@3.)

Impossible to test code should be ignored

When re-mapping typescript coverage the module branch is never covered, as this code is impossible to test with typescript unit tests there should be an option to ignore module declarations.

Option for excluding mappings

Hi

let me explain what Im doing at the moment. I have a quite large electron app written in typescript. The only way to run tests for me in electron as a karma "browser" (at moment of writing) is to bundle all tests files. Im using webpack for this. This works great so far. Now I want to add coverage statistics to my test setup and remap-istanbul comes over the rainbow. Great tool so far. 👍

Passing the json output of karma-coverage to remap-istanbul produces the following html output:
bildschirmfoto 2016-04-29 um 16 26 02
The only entry thats interesting is src/utils/. The json generated by karma-coverage contains only one entry and this is my generated test bundle.

What I want to do is:
remap-istanbul --exclude-mapping=~/,tests/,webpack,__root__/
The generated html would only contain one entry for src/utils/

Is there a way to archive this?

Thank you :)

Another thought on this:
The generated json by remap-istanbul contains all files listed in the picture above. Can I execute a reporter based on this json? So it would be possible to "clean" the json from undesired files.

Incorrect Mapping

I'm looking at the source code now but just in case this is something I'm doing wrong the mapping is completely off. I have one concatenated typescript file with all sourcemaps 64base encoded at the bottom. The first record in the source map appears to be:

"components/log/log.service.ts"

But in the remapped json it appears as:

"../../../../../../app/components/log/log.service.ts"

I'm not sure why this is. But hopefully I can figure that out soon. Here is my gulp task to run remap-istanbul:

var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

module.exports = function (gulp, config) {

   gulp.task('coverage', [
      //'test'
   ], function() {
      return gulp.src(config.paths.coverage)
        .pipe(remapIstanbul({
          reports: {
            json: './coverage/coverage-final.json',
            html: './coverage/html-report'
          }
        }));
   });

};

Error: Invalid store [fslookup], allowed values are

I'm trying to get the coverage configured for a React + Typescript + Webpack project. I'm following the instruction from here. But when Html report is configured in remap-instalbul, the following error occurs.

Any pointers would be helpful.

Error: Invalid store [fslookup], allowed values are
    at Object.Factory.create (E:\APPS\node_modules\remap-istanbul\node_modules\istanbul\lib\util\factory.js:47:28)
    at new HtmlReport (E:\APPS\node_modules\remap-istanbul\node_modules\istanbul\lib\report\html.js:350:15)
    at E:\APPS\node_modules\remap-istanbul\lib\writeReport.js:76:20
    at E:\APPS\node_modules\amdefine\amdefine.js:125:34
    at nextTickCallbackWith0Args (node.js:453:9)
    at process._tickCallback (node.js:382:13)

Karma config with Webpack configuration:

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['mocha', 'chai', 'sinon', 'source-map-support'],
    files: [
      './shell/apps/**/*.spec.tsx'
    ],
    plugins: ["karma-*"],
    preprocessors: {
      './shell/apps/**/.tsx': ['webpack', 'sourcemap', 'coverage'],
      './shell/apps/**/*.spec.tsx': ['webpack']
    },
    webpack: {
      devtool: 'inline-source-map',
      module: {
        loaders: [
          {
            test: /\.(ts|tsx)$/,
            exclude: /node_modules/,
            loader: 'awesome-typescript-loader'
          },
          {
            test: /\.json$/,
            loader: 'json'
          },
          {
            test: /\.((woff2?|svg)(\?v=[0-9]\.[0-9]\.[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/,
            loader: 'url?limit=10000'
          }
        ],
        postLoaders: [
          /**
           * Instruments TS source files for subsequent code coverage.
           * See https://github.com/deepsweet/istanbul-instrumenter-loader
           */
          {
            test: /\.(ts|tsx)$/,
            loader: 'istanbul-instrumenter-loader',
            exclude: [
              /node_modules/,
              /tests/,
              /\.(e2e|spec)\.tsx$/
            ]
          }
        ]
      },
      resolve: {
        //Added .json extension required by cheerio (enzyme dependency)
        extensions: ['', '.js', '.ts', '.tsx', '.json']
      },
      //Configuration required by enzyme
      externals: {
        'react/lib/ExecutionEnvironment': true,
        'react/lib/ReactContext': 'window',
        'cheerio': 'window',
        'react/addons': true,
      }
    },
    /**
     * Make dev server silent.
     */
    webpackServer: { noInfo: true },
    reporters: ['progress', 'coverage', 'karma-remap-istanbul'],
    /**
     * Simple summary (printed to the console) and JSON file which we will remap back to TypeScript.
     */
    coverageReporter: {
      dir: 'coverage',
      reporters: [
        { type: 'text-summary' },
        {
          type: 'json',
          subdir: '.',
          file: 'coverage-final.json'
        }
      ]
    },

    /**
     * Map code coverage result back to TypeScript using `karma-remap-istanbul`.
     */
    remapIstanbulReporter: {
      src: 'coverage/coverage-final.json',
      reports: {
        lcovonly: 'coverage/lcov.info',
        html: 'coverage/report'
      },
      timeoutNotCreated: 5000,
      timeoutNoMoreFiles: 5000
    },
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['PhantomJS'],
    singleRun: true,
    concurrency: Infinity,
    client: {
      captureConsole: true
    }
  })
}

cannot cope with inline sourcemaps when the path is absolute

After upgrading from 0.4.0 I get these kind of messages

Fatal error: Unable to find entry for [src\file.js]

from the html report, when it generates the output.

Its like after 0.4.0 it is looking for the source files relative to a different directory?

any ideas?
Its either broken by this module or istanbuls 0.4.1 release..

Searches for many, non-existant source maps; doesn't use existing source map

  1. I bundle the tests for an app using Rollup, yielding a single bundle (dist/app-tests.js) and source map dist/app-tests.js.map) with all source contents inlined.
  2. I run istanbul cover _mocha -- dist/app-tests.js yielding a coverage/coverage.json file.
  3. The coverage file is remapped successfully to coverage/coverage-remapped.json with a basePath set to the directory of the bundled code. All file paths are relative to the coverage file.
  4. But, when I try to generate a report:
remap-istanbul -i coverage/coverage-remapped.json -o html-report -t html

remap-istanbul outputs a long list of warnings

[Error: Could not find source map for: "../node_modules/lodash-es/noop.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isObject.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isFunction.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/toNumber.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/toInteger.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/rest.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/spread.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/eq.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isLength.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isArrayLike.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isObjectLike.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isArrayLikeObject.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isArguments.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/isArray.js"]
[Error: Could not find source map for: "../node_modules/lodash-es/assign.js"]
[Error: Could not find source map for: "../src/a.js"]
[Error: Could not find source map for: "../src/b.js"]
...
fs.js:584
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENOENT: no such file or directory, open '../main.js'
    at Error (native)
    at Object.fs.openSync (fs.js:584:18)
    at Object.fs.readFileSync (fs.js:431:33)
    ...

Any thoughts as to why remap-istanbul is searching for all these source map files instead of the dist/app-tests.js.map that actually exists? Is it somehow related to #33?

Allow for filtering files from a bundle when remapping

The karma-coverage module allows the developer to specify a file glob to indicate which files are going to be instrumented. However, if we are running against a bundle we cannot specify which modules inside of the bundle are to be instrumented. It would be nice if remap-instanbul allowed us to specify a file glob and when remapping the coverage report from a bundle it would only include mapped files that matched the glob.

If sourceRoot is set in map file html report fails

If the sourceRoot value is set to anything except an empty string in the map file the html report can't be created. The map file works fine in Chrome and I'd like to go back to the default behavior as it make debugging easier.

grunt task cannot set basePath

The sourcemap I'm working with needs the basePath set, preferably from grunt. Not sure if anyone else has wants this but since I accidentally sent the pull from my branch to SitePen master, I figured I'd submit an issue too. Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.