Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

istanbul instrumentation function.toString() #310

Open
paulhoconnor opened this issue Feb 8, 2015 · 6 comments
Open

istanbul instrumentation function.toString() #310

paulhoconnor opened this issue Feb 8, 2015 · 6 comments

Comments

@paulhoconnor
Copy link

any downstream interpretation of function.toString(), as instrumented by istanbul, sees instrumentation code, interprets as garbage, and throws a ReferenceError. An example of this is eval'ing functions into different threads.

/* istanbul ignore next */ should cause the next 'thing' not to be instrumented

@gotwarlost
Copy link
Owner

ignore is just reporting fakery now. Doesn't mean "do not instrument". Need to look into this

@ioncreature
Copy link

Have the same problem.

I send function to MongoDB like:

function filter(){
 ...
}

User.find({
    $where: filter.toString()
}, function( error, users ){
    // MongoError: ReferenceError: __cov_G1RH9TezwmrgBKIjkjZ4FQ is not defined
});

Do you know any way to avoid this?

@fritx
Copy link

fritx commented Feb 28, 2016

+1 met the same issue.
the fn is passed into another process and becomes

'function (){__cov_gjt0lukdoxUzQSDPHovUcQ.f[\'66\']++;__cov_gjt0lukdoxUzQSDPHovUcQ.s[\'219\']++;return document.title;}'

but there is no __con_* in that different context

Unhandled rejection ReferenceError: __cov_gjt0lukdoxUzQSDPHovUcQ is not defined

@fritx
Copy link

fritx commented Feb 28, 2016

My solution:

fnstr = fnstr.replace(/__cov_(.+?)\+\+;?/g, '')

@tagyoureit
Copy link

tagyoureit commented Jan 24, 2017

Brilliant!! I was having the same problem, and this is a beautiful solution.

I made one addition...

fnstr = fnstr.replace(/__cov_(.+?)\+\+[,;]?/g, '')

I changed the ? to [,?].

This is because my .toString() result included an if statement with multiple items
if (address > -1 && program >= 1 && program <= 4) {

Istanbul generated:

((__cov_x3uoF3uO18CbkEPjMSjaKw.b['9'][0]++,address>-1)&&(__cov_x3uoF3uO18CbkEPjMSjaKw.b['9'][1]++,program>=1)&&(__cov_x3uoF3uO18CbkEPjMSjaKw.b['9'][2]++,program<=4)){__cov_x3uoF3uO18CbkEPjMSjaKw.b['8'][0]++;__cov_x3uoF3uO18CbkEPjMSjaKw.s['24']++;if((__cov_x3uoF3uO18CbkEPjMSjaKw.b['11'][0]++,speed<=450)||(__cov_x3uoF3uO18CbkEPjMSjaKw.b['11'][1]++,speed>=3450)||(__cov_x3uoF3uO18CbkEPjMSjaKw.b['11'][2]++,isNaN(speed))||(__cov_x3uoF3uO18CbkEPjMSjaKw.b['11'][3]++,speed==null))

Notice the __cov_x3uoF3uO18CbkEPjMSjaKw.b['9'][0]++, ending , instead of ;.

Original regex resulted in
if ((, address > -1) && (, program >= 1) && (, program <= 4)) {

With the modification the result is clean, running code.

Thanks @fritx !

@andrew-aladev
Copy link

Another workaround is to have 2 same functions: first with ignore and second one without it.

export function fn () { ... }

// istanbul ignore next
function fnCopy () { ... }

... fnCopy.toString() ...

fn exported and covered, fnCopy used inside another context without istanbul.

But this workaround is ugly and I don't like it.

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

No branches or pull requests

7 participants