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

Commit

Permalink
fix(node): node patched method should copy original delegate's symbol…
Browse files Browse the repository at this point in the history
… properties
  • Loading branch information
JiaLiPassion committed May 24, 2018
1 parent 1ba8519 commit 3af538c
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ sudo: false
dist: trusty
cache: yarn
node_js:
- 6
- 8
env:
global:
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
Expand Down
33 changes: 33 additions & 0 deletions lib/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,36 @@ export function patchClass(className: string) {
}
}

export function copySymbolProperties(src: any, dest: any) {
if (typeof (Object as any).getOwnPropertySymbols !== 'function') {
return;
}
const symbols: any = (Object as any).getOwnPropertySymbols(src);
symbols.forEach((symbol: any) => {
const desc = Object.getOwnPropertyDescriptor(src, symbol);
Object.defineProperty(dest, symbol, {
get: function () {
return src[symbol];
},
set: function (value: any) {
if (desc && (!desc.writable || typeof desc.set !== 'function')) {
// if src[symbol] is not writable or not have a setter, just return
return;
}
src[symbol] = value;
},
enumerable: desc ? desc.enumerable : true,
configurable: desc ? desc.configurable : true
});
});
}

let shouldCopySymbolProperties = false;

export function setShouldCopySymbolProperties(flag: boolean) {
shouldCopySymbolProperties = flag;
}

export function patchMethod(
target: any, name: string,
patchFn: (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) =>
Expand All @@ -360,6 +390,9 @@ export function patchMethod(
return patchDelegate(this, arguments as any);
};
attachOriginToPatched(proto[name], delegate);
if (shouldCopySymbolProperties) {
copySymbolProperties(delegate, proto[name]);
}
}
}
return delegate;
Expand Down
9 changes: 2 additions & 7 deletions lib/node/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@
* found in the LICENSE file at https://angular.io/license
*/

import './node_util';
import './events';
import './fs';

import {findEventTasks} from '../common/events';
import {patchTimer} from '../common/timers';
import {ArraySlice, bindArguments, isMix, patchMacroTask, patchMethod, patchMicroTask, patchOnProperties} from '../common/utils';
import {ArraySlice, isMix, patchMacroTask, patchMicroTask} from '../common/utils';

const set = 'set';
const clear = 'clear';

Zone.__load_patch('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchOnProperties = patchOnProperties;
api.patchMethod = patchMethod;
api.bindArguments = bindArguments;
});

Zone.__load_patch('node_timers', (global: any, Zone: ZoneType) => {
// Timers
let globalUseTimeoutFromTimer = false;
Expand Down
16 changes: 16 additions & 0 deletions lib/node/node_util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {setShouldCopySymbolProperties, patchOnProperties, patchMethod, bindArguments} from '../common/utils';

Zone.__load_patch('node_util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchOnProperties = patchOnProperties;
api.patchMethod = patchMethod;
api.bindArguments = bindArguments;
setShouldCopySymbolProperties(true);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"dependencies": {},
"devDependencies": {
"@types/jasmine": "2.2.33",
"@types/node": "^6.0.96",
"@types/node": "^8.10.17",
"@types/systemjs": "^0.19.30",
"assert": "^1.4.1",
"bluebird": "^3.5.1",
Expand Down
59 changes: 58 additions & 1 deletion test/node/fs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/

import {exists, unlink, unwatchFile, watch, watchFile, writeFile} from 'fs';
import {exists, read, unlink, unwatchFile, watch, write, watchFile, writeFile, openSync, fstatSync, closeSync, unlinkSync} from 'fs';
import * as util from 'util';

describe('nodejs file system', () => {
describe('async method patch test', () => {
Expand Down Expand Up @@ -88,4 +89,60 @@ describe('nodejs file system', () => {
});
});
});
});

describe('util.promisify', () => {
it('fs.exists should work with util.promisify', (done: DoneFn) => {
const promisifyExists = util.promisify(exists);
promisifyExists(__filename).then(r => {
expect(r).toBe(true);
done();
}, err => {
fail(`should not be here with error: ${err}`);
});
});

it('fs.read should work with util.promisify', (done: DoneFn) => {
const promisifyRead = util.promisify(read);
const fd = openSync(__filename, 'r');
const stats = fstatSync(fd);
const bufferSize = stats.size;
const chunkSize = 512;
const buffer = new Buffer(bufferSize);
let bytesRead = 0;
// fd, buffer, offset, length, position, callback
promisifyRead(fd, buffer, bytesRead, chunkSize, bytesRead).then(
(value) => {
expect(value.bytesRead).toBe(chunkSize);
closeSync(fd);
done();
}, err => {
closeSync(fd);
fail(`should not be here with error: ${error}.`);
});
});

it('fs.write should work with util.promisify', (done: DoneFn) => {
const promisifyWrite = util.promisify(write);
const dest = __filename + 'write';
const fd = openSync(dest, 'a');
const stats = fstatSync(fd);
const chunkSize = 512;
const buffer = new Buffer(chunkSize);
for (let i = 0; i < chunkSize; i++) {
buffer[i] = 0;
}
// fd, buffer, offset, length, position, callback
promisifyWrite(fd, buffer, 0, chunkSize, 0).then(
(value) => {
expect(value.bytesWritten).toBe(chunkSize);
closeSync(fd);
unlinkSync(dest);
done();
}, err => {
closeSync(fd);
unlinkSync(dest);
fail(`should not be here with error: ${error}.`);
});
});
});
30 changes: 30 additions & 0 deletions test/node/timer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { promisify } from 'util';

describe('node timer', () => {
it('util.promisify should work with setTimeout', (done: DoneFn) => {
const setTimeoutPromise = promisify(setTimeout);
setTimeoutPromise(50, 'value').then(value => {
expect(value).toEqual('value');
done();
}, error => {
fail(`should not be here with error: ${error}.`);
});
});

it('util.promisify should work with setImmediate', (done: DoneFn) => {
const setImmediatePromise = promisify(setImmediate);
setImmediatePromise('value').then(value => {
expect(value).toEqual('value');
done();
}, error => {
fail(`should not be here with error: ${error}.`);
});
});
});
1 change: 1 addition & 0 deletions test/node_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ import './node/Error.spec';
import './node/crypto.spec';
import './node/http.spec';
import './node/console.spec';
import './node/timer.spec';
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
version "2.2.33"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.2.33.tgz#4715cfd2ca7fbd632fc7f1784f13e637bed028c5"

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

"@types/systemjs@^0.19.30":
version "0.19.33"
Expand Down

0 comments on commit 3af538c

Please sign in to comment.