Skip to content

Commit 3b49661

Browse files
committed
fix(datepicker): rxjs throws error on component destroy
* The datepicker expects the `backdropClick()` observable to emit one value before the observable completes. If no click happened and the component gets destroyed RxJS throws an error because no value got emitted. * Monkey-patches Angular's TestBed to properly report errors on component destroy.
1 parent 549d622 commit 3b49661

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/lib/datepicker/datepicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ export class MdDatepicker<D> implements OnDestroy {
257257
this._ngZone.onStable.first().subscribe(() => this._popupRef.updatePosition());
258258
}
259259

260-
this._popupRef.backdropClick().first().subscribe(() => this.close());
260+
this._popupRef.backdropClick().subscribe(() => this.close());
261261
}
262262

263263
/** Create the popup. */

test/karma-test-shim.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,38 @@ function configureTestBed() {
8787

8888
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
8989

90-
testing.TestBed.initTestEnvironment(
90+
var testBed = testing.TestBed.initTestEnvironment(
9191
testingBrowser.BrowserDynamicTestingModule,
9292
testingBrowser.platformBrowserDynamicTesting()
9393
);
94+
95+
applyAngularTestingPatches(testBed);
96+
});
97+
}
98+
99+
/** Applies patches and workarounds to Angular's testing package. */
100+
function applyAngularTestingPatches(testBed) {
101+
// Original resetTestingModule function of the TestBed.
102+
var _resetTestingModule = testBed.resetTestingModule;
103+
104+
// Monkey-patch the resetTestingModule to destroy fixtures outside of a try/catch block.
105+
// With https://github.com/angular/angular/commit/2c5a67134198a090a24f6671dcdb7b102fea6eba
106+
// errors when destroying components are no longer causing Jasmine to fail.
107+
testBed.resetTestingModule = function() {
108+
try {
109+
this._activeFixtures.forEach(function (fixture) { fixture.destroy(); });
110+
} finally {
111+
this._activeFixtures = [];
112+
// Regardless of errors or not, run the original reset testing module function.
113+
_resetTestingModule.call(this);
114+
}
115+
};
116+
117+
// Angular's testing package resets the testing module before each test. This is bad because
118+
// it doesn't allow developers to see what test actually failed. Fixing this by resetting
119+
// the testing module after each test.
120+
// https://github.com/angular/angular/blob/master/packages/core/testing/src/before_each.ts#L25
121+
afterEach(function() {
122+
testBed.resetTestingModule();
94123
});
95124
}

0 commit comments

Comments
 (0)