Skip to content

Commit 9829c5e

Browse files
filipesilvabenlesh
authored andcommittedAug 7, 2019
refactor: test for side effects, and remove existing ones (#4769) (#4953)
* test: add test for side-effects * refactor: remove toplevel property access
1 parent b6eea10 commit 9829c5e

32 files changed

+782
-302
lines changed
 

‎.circleci/config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
steps:
5151
- attach_workspace: *attach_options
5252
- run: npm test
53+
- run: npm run test:side-effects
5354

5455
dtslint:
5556
<<: *defaults

‎.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
integration/side-effects/snapshots/

‎.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ spec-build/
2424
# Misc
2525
npm-debug.log
2626
.DS_STORE
27+
28+
# The check-side-effects package generates and deletes this file.
29+
# If the process is killed, it will be left behind.
30+
check-side-effects.tmp-input.js

‎integration/side-effects/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
This test checks if the side effects for loading RxJs packages have changed using <https://github.com/filipesilva/check-side-effects>.
2+
3+
Running `npm test:side-effects` will check all ES modules listed in `side-effects.json`.
4+
5+
Running `npm test:side-effects:update` will update any changed side effects.
6+
7+
To add a new ES module to this test, add a new entry in `side-effects.json`.
8+
9+
Usually the ESM and FESM should have the same output, but retained objects that were renamed during the flattening step will leave behind a different name.
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"tests": [
3+
{
4+
"esModules": "../../dist/esm5/index.js",
5+
"expectedOutput": "./snapshots/esm5/index.js"
6+
},
7+
{
8+
"esModules": "../../dist/esm2015/index.js",
9+
"expectedOutput": "./snapshots/esm2015/index.js"
10+
},
11+
{
12+
"esModules": "../../dist/esm5/ajax/index.js",
13+
"expectedOutput": "./snapshots/esm5/ajax.js"
14+
},
15+
{
16+
"esModules": "../../dist/esm2015/ajax/index.js",
17+
"expectedOutput": "./snapshots/esm2015/ajax.js"
18+
},
19+
{
20+
"esModules": "../../dist/esm5/fetch/index.js",
21+
"expectedOutput": "./snapshots/esm5/fetch.js"
22+
},
23+
{
24+
"esModules": "../../dist/esm2015/fetch/index.js",
25+
"expectedOutput": "./snapshots/esm2015/fetch.js"
26+
},
27+
{
28+
"esModules": "../../dist/esm5/operators/index.js",
29+
"expectedOutput": "./snapshots/esm5/operators.js"
30+
},
31+
{
32+
"esModules": "../../dist/esm2015/operators/index.js",
33+
"expectedOutput": "./snapshots/esm2015/operators.js"
34+
},
35+
{
36+
"esModules": "../../dist/esm5/testing/index.js",
37+
"expectedOutput": "./snapshots/esm5/testing.js"
38+
},
39+
{
40+
"esModules": "../../dist/esm2015/testing/index.js",
41+
"expectedOutput": "./snapshots/esm2015/testing.js"
42+
},
43+
{
44+
"esModules": "../../dist/esm5/webSocket/index.js",
45+
"expectedOutput": "./snapshots/esm5/websocket.js"
46+
},
47+
{
48+
"esModules": "../../dist/esm2015/webSocket/index.js",
49+
"expectedOutput": "./snapshots/esm2015/websocket.js"
50+
}
51+
]
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var NotificationKind;
2+
3+
(function(NotificationKind) {
4+
NotificationKind["NEXT"] = "N";
5+
NotificationKind["ERROR"] = "E";
6+
NotificationKind["COMPLETE"] = "C";
7+
})(NotificationKind || (NotificationKind = {}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var NotificationKind;
2+
3+
(function(NotificationKind) {
4+
NotificationKind["NEXT"] = "N";
5+
NotificationKind["ERROR"] = "E";
6+
NotificationKind["COMPLETE"] = "C";
7+
})(NotificationKind || (NotificationKind = {}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var NotificationKind;
2+
3+
(function(NotificationKind) {
4+
NotificationKind["NEXT"] = "N";
5+
NotificationKind["ERROR"] = "E";
6+
NotificationKind["COMPLETE"] = "C";
7+
})(NotificationKind || (NotificationKind = {}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var NotificationKind;
2+
3+
(function(NotificationKind) {
4+
NotificationKind["NEXT"] = "N";
5+
NotificationKind["ERROR"] = "E";
6+
NotificationKind["COMPLETE"] = "C";
7+
})(NotificationKind || (NotificationKind = {}));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "tslib";

‎package-lock.json

+570-230
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+4
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@
101101
"test:cover": "nyc npm test",
102102
"test:circular": "dependency-cruise --validate .dependency-cruiser.json -x \"^node_modules\" dist/esm5",
103103
"test:systemjs": "node integration/systemjs/systemjs-compatibility-spec.js",
104+
"test:side-effects": "check-side-effects --test integration/side-effects/side-effects.json",
105+
"test:side-effects:update": "npm run test:side-effects -- --update",
104106
"tests2png": "mkdirp docs_app/content/img && mocha --opts spec/support/tests2png.opts \"spec/**/*-spec.ts\"",
105107
"compat_build_all": "npm-run-all compat_clean_dist compat_build_cjs compat_build_esm5 compat_build_esm2015 compat_build_esm5_for_rollup compat_build_umd compat_generate_packages",
106108
"compat_build_closure": "node ./tools/make-closure-compat.js",
@@ -187,6 +189,7 @@
187189
"benchmark": "2.1.0",
188190
"benchpress": "2.0.0-beta.1",
189191
"chai": "4.1.2",
192+
"check-side-effects": "0.0.20",
190193
"color": "3.0.0",
191194
"colors": "1.1.2",
192195
"commitizen": "2.9.6",
@@ -238,6 +241,7 @@
238241
"tsconfig-paths": "3.2.0",
239242
"tslint": "5.9.1",
240243
"tslint-etc": "1.2.6",
244+
"tslint-no-toplevel-property-access": "0.0.2",
241245
"tslint-no-unused-expression-chai": "0.0.3",
242246
"typescript": "^3.0.1",
243247
"validate-commit-msg": "2.14.0",

‎src/internal/observable/ConnectableObservable.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,20 @@ export class ConnectableObservable<T> extends Observable<T> {
5555
}
5656
}
5757

58-
const connectableProto = <any>ConnectableObservable.prototype;
59-
60-
export const connectableObservableDescriptor: PropertyDescriptorMap = {
61-
operator: { value: null },
62-
_refCount: { value: 0, writable: true },
63-
_subject: { value: null, writable: true },
64-
_connection: { value: null, writable: true },
65-
_subscribe: { value: connectableProto._subscribe },
66-
_isComplete: { value: connectableProto._isComplete, writable: true },
67-
getSubject: { value: connectableProto.getSubject },
68-
connect: { value: connectableProto.connect },
69-
refCount: { value: connectableProto.refCount }
70-
};
58+
export const connectableObservableDescriptor: PropertyDescriptorMap = (() => {
59+
const connectableProto = <any>ConnectableObservable.prototype;
60+
return {
61+
operator: { value: null as null },
62+
_refCount: { value: 0, writable: true },
63+
_subject: { value: null as null, writable: true },
64+
_connection: { value: null as null, writable: true },
65+
_subscribe: { value: connectableProto._subscribe },
66+
_isComplete: { value: connectableProto._isComplete, writable: true },
67+
getSubject: { value: connectableProto.getSubject },
68+
connect: { value: connectableProto.connect },
69+
refCount: { value: connectableProto.refCount }
70+
};
71+
})();
7172

7273
class ConnectableSubscriber<T> extends SubjectSubscriber<T> {
7374
constructor(destination: Subject<T>,

‎src/internal/observable/dom/AjaxObservable.ts

+15-13
Original file line numberDiff line numberDiff line change
@@ -486,19 +486,21 @@ export interface AjaxErrorCtor {
486486
new(message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError;
487487
}
488488

489-
function AjaxErrorImpl(this: any, message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError {
490-
Error.call(this);
491-
this.message = message;
492-
this.name = 'AjaxError';
493-
this.xhr = xhr;
494-
this.request = request;
495-
this.status = xhr.status;
496-
this.responseType = xhr.responseType || request.responseType;
497-
this.response = parseXhrResponse(this.responseType, xhr);
498-
return this;
499-
}
500-
501-
AjaxErrorImpl.prototype = Object.create(Error.prototype);
489+
const AjaxErrorImpl = (() => {
490+
function AjaxErrorImpl(this: any, message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError {
491+
Error.call(this);
492+
this.message = message;
493+
this.name = 'AjaxError';
494+
this.xhr = xhr;
495+
this.request = request;
496+
this.status = xhr.status;
497+
this.responseType = xhr.responseType || request.responseType;
498+
this.response = parseXhrResponse(this.responseType, xhr);
499+
return this;
500+
}
501+
AjaxErrorImpl.prototype = Object.create(Error.prototype);
502+
return AjaxErrorImpl;
503+
})();
502504

503505
export const AjaxError: AjaxErrorCtor = AjaxErrorImpl as any;
504506

‎src/internal/observable/dom/ajax.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,4 @@ import { AjaxObservable, AjaxCreationMethod } from './AjaxObservable';
7979
*
8080
* ```
8181
*/
82-
export const ajax: AjaxCreationMethod = AjaxObservable.create;
82+
export const ajax: AjaxCreationMethod = (() => AjaxObservable.create)();

‎src/internal/observable/fromEvent.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { isFunction } from '../util/isFunction';
44
import { Subscriber } from '../Subscriber';
55
import { map } from '../operators/map';
66

7-
const toString: Function = Object.prototype.toString;
7+
const toString: Function = (() => Object.prototype.toString)();
88

99
export interface NodeStyleEventEmitter {
1010
addListener: (eventName: string | symbol, handler: NodeEventHandler) => this;

‎src/internal/symbol/observable.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ declare global {
88
}
99

1010
/** Symbol.observable or a string "@@observable". Used for interop */
11-
export const observable = typeof Symbol === 'function' && Symbol.observable || '@@observable';
11+
export const observable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();

‎src/internal/symbol/rxSubscriber.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/** @deprecated do not use, this is no longer checked by RxJS internals */
2-
export const rxSubscriber =
2+
export const rxSubscriber = (() =>
33
typeof Symbol === 'function'
44
? Symbol('rxSubscriber')
5-
: '@@rxSubscriber_' + Math.random();
5+
: '@@rxSubscriber_' + Math.random())();
66

77
/**
88
* @deprecated use rxSubscriber instead

‎src/internal/util/ArgumentOutOfRangeError.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ export interface ArgumentOutOfRangeErrorCtor {
55
new(): ArgumentOutOfRangeError;
66
}
77

8-
function ArgumentOutOfRangeErrorImpl(this: any) {
9-
Error.call(this);
10-
this.message = 'argument out of range';
11-
this.name = 'ArgumentOutOfRangeError';
12-
return this;
13-
}
8+
const ArgumentOutOfRangeErrorImpl = (() => {
9+
function ArgumentOutOfRangeErrorImpl(this: any) {
10+
Error.call(this);
11+
this.message = 'argument out of range';
12+
this.name = 'ArgumentOutOfRangeError';
13+
return this;
14+
}
15+
16+
ArgumentOutOfRangeErrorImpl.prototype = Object.create(Error.prototype);
1417

15-
ArgumentOutOfRangeErrorImpl.prototype = Object.create(Error.prototype);
18+
return ArgumentOutOfRangeErrorImpl;
19+
})();
1620

1721
/**
1822
* An error thrown when an element was queried at a certain index of an

‎src/internal/util/EmptyError.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ export interface EmptyErrorCtor {
55
new(): EmptyError;
66
}
77

8-
function EmptyErrorImpl(this: any) {
9-
Error.call(this);
10-
this.message = 'no elements in sequence';
11-
this.name = 'EmptyError';
12-
return this;
13-
}
8+
const EmptyErrorImpl = (() => {
9+
function EmptyErrorImpl(this: any) {
10+
Error.call(this);
11+
this.message = 'no elements in sequence';
12+
this.name = 'EmptyError';
13+
return this;
14+
}
15+
16+
EmptyErrorImpl.prototype = Object.create(Error.prototype);
1417

15-
EmptyErrorImpl.prototype = Object.create(Error.prototype);
18+
return EmptyErrorImpl;
19+
})();
1620

1721
/**
1822
* An error thrown when an Observable or a sequence was queried but has no

‎src/internal/util/ObjectUnsubscribedError.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ export interface ObjectUnsubscribedErrorCtor {
55
new(): ObjectUnsubscribedError;
66
}
77

8-
function ObjectUnsubscribedErrorImpl(this: any) {
9-
Error.call(this);
10-
this.message = 'object unsubscribed';
11-
this.name = 'ObjectUnsubscribedError';
12-
return this;
13-
}
8+
const ObjectUnsubscribedErrorImpl = (() => {
9+
function ObjectUnsubscribedErrorImpl(this: any) {
10+
Error.call(this);
11+
this.message = 'object unsubscribed';
12+
this.name = 'ObjectUnsubscribedError';
13+
return this;
14+
}
15+
16+
ObjectUnsubscribedErrorImpl.prototype = Object.create(Error.prototype);
1417

15-
ObjectUnsubscribedErrorImpl.prototype = Object.create(Error.prototype);
18+
return ObjectUnsubscribedErrorImpl;
19+
})();
1620

1721
/**
1822
* An error thrown when an action is invalid because the object has been

‎src/internal/util/TimeoutError.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ export interface TimeoutErrorCtor {
55
new(): TimeoutError;
66
}
77

8-
function TimeoutErrorImpl(this: any) {
9-
Error.call(this);
10-
this.message = 'Timeout has occurred';
11-
this.name = 'TimeoutError';
12-
return this;
13-
}
8+
const TimeoutErrorImpl = (() => {
9+
function TimeoutErrorImpl(this: any) {
10+
Error.call(this);
11+
this.message = 'Timeout has occurred';
12+
this.name = 'TimeoutError';
13+
return this;
14+
}
15+
16+
TimeoutErrorImpl.prototype = Object.create(Error.prototype);
1417

15-
TimeoutErrorImpl.prototype = Object.create(Error.prototype);
18+
return TimeoutErrorImpl;
19+
})();
1620

1721
/**
1822
* An error thrown when duetime elapses.

‎src/internal/util/UnsubscriptionError.ts

+13-9
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ export interface UnsubscriptionErrorCtor {
66
new(errors: any[]): UnsubscriptionError;
77
}
88

9-
function UnsubscriptionErrorImpl(this: any, errors: any[]) {
10-
Error.call(this);
11-
this.message = errors ?
12-
`${errors.length} errors occurred during unsubscription:
9+
const UnsubscriptionErrorImpl = (() => {
10+
function UnsubscriptionErrorImpl(this: any, errors: any[]) {
11+
Error.call(this);
12+
this.message = errors ?
13+
`${errors.length} errors occurred during unsubscription:
1314
${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n ')}` : '';
14-
this.name = 'UnsubscriptionError';
15-
this.errors = errors;
16-
return this;
17-
}
15+
this.name = 'UnsubscriptionError';
16+
this.errors = errors;
17+
return this;
18+
}
19+
20+
UnsubscriptionErrorImpl.prototype = Object.create(Error.prototype);
1821

19-
UnsubscriptionErrorImpl.prototype = Object.create(Error.prototype);
22+
return UnsubscriptionErrorImpl;
23+
})();
2024

2125
/**
2226
* An error thrown when one or more errors have occurred during the

‎src/internal/util/isArray.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const isArray = Array.isArray || (<T>(x: any): x is T[] => x && typeof x.length === 'number');
1+
export const isArray = (() => Array.isArray || (<T>(x: any): x is T[] => x && typeof x.length === 'number'))();

‎tslint.json

+13-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
"no-var-keyword": true,
2323
"no-empty": true,
2424
"no-unused-expression-chai": true,
25-
"no-unused-variable": true,
26-
"no-use-before-declare": true,
2725
"no-var-requires": true,
2826
"no-require-imports": true,
2927
"one-line": [
@@ -59,9 +57,21 @@
5957
"check-operator",
6058
"check-separator",
6159
"check-type"
60+
],
61+
"no-toplevel-property-access": [
62+
true,
63+
"src/index.ts",
64+
"src/ajax/",
65+
"src/fetch/",
66+
"src/internal/",
67+
"src/internal-compatibility/",
68+
"src/operators/",
69+
"src/testing/",
70+
"src/webSocket/"
6271
]
6372
},
6473
"rulesDirectory": [
65-
"tslint-no-unused-expression-chai"
74+
"tslint-no-unused-expression-chai",
75+
"node_modules/tslint-no-toplevel-property-access/rules"
6676
]
6777
}

0 commit comments

Comments
 (0)
Please sign in to comment.