Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 0a2f6ff

Browse files
JiaLiPassionmhevery
authored andcommitted
fix(node): node patched method should copy original delegate's symbol properties (#1095)
1 parent d7e0a31 commit 0a2f6ff

9 files changed

Lines changed: 145 additions & 13 deletions

File tree

‎.travis.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sudo: false
33
dist: trusty
44
cache: yarn
55
node_js:
6-
- 6
6+
- 8
77
env:
88
global:
99
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready

‎lib/common/utils.ts‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,36 @@ export function patchClass(className: string) {
334334
}
335335
}
336336

337+
exportfunctioncopySymbolProperties(src: any,dest: any){
338+
if(typeof(Objectasany).getOwnPropertySymbols!=='function'){
339+
return;
340+
}
341+
constsymbols: any=(Objectasany).getOwnPropertySymbols(src);
342+
symbols.forEach((symbol: any)=>{
343+
constdesc=Object.getOwnPropertyDescriptor(src,symbol);
344+
Object.defineProperty(dest,symbol,{
345+
get: function(){
346+
returnsrc[symbol];
347+
},
348+
set: function(value: any){
349+
if(desc&&(!desc.writable||typeofdesc.set!=='function')){
350+
// if src[symbol] is not writable or not have a setter, just return
351+
return;
352+
}
353+
src[symbol]=value;
354+
},
355+
enumerable: desc ? desc.enumerable : true,
356+
configurable: desc ? desc.configurable : true
357+
});
358+
});
359+
}
360+
361+
letshouldCopySymbolProperties=false;
362+
363+
exportfunctionsetShouldCopySymbolProperties(flag: boolean){
364+
shouldCopySymbolProperties=flag;
365+
}
366+
337367
exportfunctionpatchMethod(
338368
target: any,name: string,
339369
patchFn: (delegate: Function,delegateName: string,name: string)=>(self: any,args: any[])=>
@@ -360,6 +390,9 @@ export function patchMethod(
360390
returnpatchDelegate(this,argumentsasany);
361391
};
362392
attachOriginToPatched(proto[name],delegate);
393+
if(shouldCopySymbolProperties){
394+
copySymbolProperties(delegate,proto[name]);
395+
}
363396
}
364397
}
365398
returndelegate;

‎lib/node/node.ts‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,17 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import'./node_util';
910
import'./events';
1011
import'./fs';
1112

1213
import{findEventTasks}from'../common/events';
1314
import{patchTimer}from'../common/timers';
14-
import{ArraySlice,bindArguments,isMix,patchMacroTask,patchMethod,patchMicroTask,patchOnProperties}from'../common/utils';
15+
import{ArraySlice,isMix,patchMacroTask,patchMicroTask}from'../common/utils';
1516

1617
constset='set';
1718
constclear='clear';
1819

19-
Zone.__load_patch('node_util',(global: any,Zone: ZoneType,api: _ZonePrivate)=>{
20-
api.patchOnProperties=patchOnProperties;
21-
api.patchMethod=patchMethod;
22-
api.bindArguments=bindArguments;
23-
});
24-
2520
Zone.__load_patch('node_timers',(global: any,Zone: ZoneType)=>{
2621
// Timers
2722
letglobalUseTimeoutFromTimer=false;

‎lib/node/node_util.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import{setShouldCopySymbolProperties,patchOnProperties,patchMethod,bindArguments}from'../common/utils';
10+
11+
Zone.__load_patch('node_util',(global: any,Zone: ZoneType,api: _ZonePrivate)=>{
12+
api.patchOnProperties=patchOnProperties;
13+
api.patchMethod=patchMethod;
14+
api.bindArguments=bindArguments;
15+
setShouldCopySymbolProperties(true);
16+
});

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"dependencies": {},
6060
"devDependencies": {
6161
"@types/jasmine": "2.2.33",
62-
"@types/node": "^6.0.96",
62+
"@types/node": "^8.10.17",
6363
"@types/systemjs": "^0.19.30",
6464
"assert": "^1.4.1",
6565
"bluebird": "^3.5.1",

‎test/node/fs.spec.ts‎

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import{exists,unlink,unwatchFile,watch,watchFile,writeFile}from'fs';
9+
import{exists,read,unlink,unwatchFile,watch,write,watchFile,writeFile,openSync,fstatSync,closeSync,unlinkSync}from'fs';
10+
import*asutilfrom'util';
1011

1112
describe('nodejs file system',()=>{
1213
describe('async method patch test',()=>{
@@ -88,4 +89,60 @@ describe('nodejs file system', () => {
8889
});
8990
});
9091
});
92+
});
93+
94+
describe('util.promisify',()=>{
95+
it('fs.exists should work with util.promisify',(done: DoneFn)=>{
96+
constpromisifyExists=util.promisify(exists);
97+
promisifyExists(__filename).then(r=>{
98+
expect(r).toBe(true);
99+
done();
100+
},err=>{
101+
fail(`should not be here with error: ${err}`);
102+
});
103+
});
104+
105+
it('fs.read should work with util.promisify',(done: DoneFn)=>{
106+
constpromisifyRead=util.promisify(read);
107+
constfd=openSync(__filename,'r');
108+
conststats=fstatSync(fd);
109+
constbufferSize=stats.size;
110+
constchunkSize=512;
111+
constbuffer=newBuffer(bufferSize);
112+
letbytesRead=0;
113+
// fd, buffer, offset, length, position, callback
114+
promisifyRead(fd,buffer,bytesRead,chunkSize,bytesRead).then(
115+
(value)=>{
116+
expect(value.bytesRead).toBe(chunkSize);
117+
closeSync(fd);
118+
done();
119+
},err=>{
120+
closeSync(fd);
121+
fail(`should not be here with error: ${error}.`);
122+
});
123+
});
124+
125+
it('fs.write should work with util.promisify',(done: DoneFn)=>{
126+
constpromisifyWrite=util.promisify(write);
127+
constdest=__filename+'write';
128+
constfd=openSync(dest,'a');
129+
conststats=fstatSync(fd);
130+
constchunkSize=512;
131+
constbuffer=newBuffer(chunkSize);
132+
for(leti=0;i<chunkSize;i++){
133+
buffer[i]=0;
134+
}
135+
// fd, buffer, offset, length, position, callback
136+
promisifyWrite(fd,buffer,0,chunkSize,0).then(
137+
(value)=>{
138+
expect(value.bytesWritten).toBe(chunkSize);
139+
closeSync(fd);
140+
unlinkSync(dest);
141+
done();
142+
},err=>{
143+
closeSync(fd);
144+
unlinkSync(dest);
145+
fail(`should not be here with error: ${error}.`);
146+
});
147+
});
91148
});

‎test/node/timer.spec.ts‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import{promisify}from'util';
9+
10+
describe('node timer',()=>{
11+
it('util.promisify should work with setTimeout',(done: DoneFn)=>{
12+
constsetTimeoutPromise=promisify(setTimeout);
13+
setTimeoutPromise(50,'value').then(value=>{
14+
expect(value).toEqual('value');
15+
done();
16+
},error=>{
17+
fail(`should not be here with error: ${error}.`);
18+
});
19+
});
20+
21+
it('util.promisify should work with setImmediate',(done: DoneFn)=>{
22+
constsetImmediatePromise=promisify(setImmediate);
23+
setImmediatePromise('value').then(value=>{
24+
expect(value).toEqual('value');
25+
done();
26+
},error=>{
27+
fail(`should not be here with error: ${error}.`);
28+
});
29+
});
30+
});

‎test/node_tests.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ import './node/Error.spec';
1313
import'./node/crypto.spec';
1414
import'./node/http.spec';
1515
import'./node/console.spec';
16+
import'./node/timer.spec';

‎yarn.lock‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
version "2.2.33"
77
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.2.33.tgz#4715cfd2ca7fbd632fc7f1784f13e637bed028c5"
88

9-
"@types/node@^6.0.96":
10-
version "6.0.101"
11-
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.101.tgz#0c5911cfb434af4a51c0a499931fe6423207d921"
9+
"@types/node@^8.10.17":
10+
version "8.10.17"
11+
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.17.tgz#d48cf10f0dc6dcf59f827f5a3fc7a4a6004318d3"
1212

1313
"@types/systemjs@^0.19.30":
1414
version "0.19.33"

0 commit comments

Comments
 (0)