Skip to content

Commit 7cac7bb

Browse files
Y1D7NGRafaelGSS
authored andcommitted
assert: fix CallTracker wraps the function causes the length to be lost
PR-URL: #42909Fixes: #40484 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 0eb32ed commit 7cac7bb

2 files changed

Lines changed: 67 additions & 15 deletions

File tree

‎lib/internal/assert/calltracker.js‎

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {
44
ArrayPrototypePush,
55
Error,
66
FunctionPrototype,
7+
Proxy,
78
ReflectApply,
89
SafeSet,
910
}=primordials;
@@ -46,20 +47,23 @@ class CallTracker {
4647
constcallChecks=this.#callChecks;
4748
callChecks.add(context);
4849

49-
returnfunction(){
50-
context.actual++;
51-
if(context.actual===context.exact){
52-
// Once function has reached its call count remove it from
53-
// callChecks set to prevent memory leaks.
54-
callChecks.delete(context);
55-
}
56-
// If function has been called more than expected times, add back into
57-
// callchecks.
58-
if(context.actual===context.exact+1){
59-
callChecks.add(context);
60-
}
61-
returnReflectApply(fn,this,arguments);
62-
};
50+
returnnewProxy(fn,{
51+
__proto__: null,
52+
apply(fn,thisArg,argList){
53+
context.actual++;
54+
if(context.actual===context.exact){
55+
// Once function has reached its call count remove it from
56+
// callChecks set to prevent memory leaks.
57+
callChecks.delete(context);
58+
}
59+
// If function has been called more than expected times, add back into
60+
// callchecks.
61+
if(context.actual===context.exact+1){
62+
callChecks.add(context);
63+
}
64+
returnReflectApply(fn,thisArg,argList);
65+
},
66+
});
6367
}
6468

6569
report(){

‎test/parallel/test-assert-calltracker-calls.js‎

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
require('../common');
2+
constcommon=require('../common');
33
constassert=require('assert');
44

55
// This test ensures that assert.CallTracker.calls() works as intended.
@@ -78,3 +78,51 @@ assert.throws(
7878
callsNoop();
7979
tracker.verify();
8080
}
81+
82+
{
83+
functionfunc(){}
84+
consttracker=newassert.CallTracker();
85+
constcallsfunc=tracker.calls(func);
86+
assert.strictEqual(callsfunc.length,0);
87+
}
88+
89+
{
90+
functionfunc(a,b,c=2){}
91+
consttracker=newassert.CallTracker();
92+
constcallsfunc=tracker.calls(func);
93+
assert.strictEqual(callsfunc.length,2);
94+
}
95+
96+
{
97+
functionfunc(a,b,c=2){}
98+
deletefunc.length;
99+
consttracker=newassert.CallTracker();
100+
constcallsfunc=tracker.calls(func);
101+
assert.strictEqual(Object.hasOwn(callsfunc,'length'),false);
102+
}
103+
104+
{
105+
constArrayIteratorPrototype=Reflect.getPrototypeOf(
106+
Array.prototype.values()
107+
);
108+
const{ next }=ArrayIteratorPrototype;
109+
ArrayIteratorPrototype.next=common.mustNotCall(
110+
'%ArrayIteratorPrototype%.next'
111+
);
112+
Object.prototype.get=common.mustNotCall('%Object.prototype%.get');
113+
114+
constcustomPropertyValue=Symbol();
115+
functionfunc(a,b,c=2){
116+
returna+b+c;
117+
}
118+
func.customProperty=customPropertyValue;
119+
Object.defineProperty(func,'length',{get: common.mustNotCall()});
120+
consttracker=newassert.CallTracker();
121+
constcallsfunc=tracker.calls(func);
122+
assert.strictEqual(Object.hasOwn(callsfunc,'length'),true);
123+
assert.strictEqual(callsfunc.customProperty,customPropertyValue);
124+
assert.strictEqual(callsfunc(1,2,3),6);
125+
126+
ArrayIteratorPrototype.next=next;
127+
deleteObject.prototype.get;
128+
}

0 commit comments

Comments
 (0)