Update test specs to use Jasmine 3 (#2089)

* Updated Karma and Jasmine versions

* Added DOMObserver class. Supports promise-based testing of DOM changes

Update asynchronous test specs to use promises or done() instead of waitsFor/runs

* Modified ActionCapability to duplicate context object properties as own properties for better object equality comparisons

* Global find + replace to fix syntax issues

* Fixed various issues caused by non-deterministic runtime order of tests in Jasmine 3. Fixed issues caused by changes to determination of object equality

* Addressed review comments

* Resolved merge conflicts with master

* Fixed style errors

* Use spy.calls.count() instead of manually tracking
This commit is contained in:
Andrew Henry
2018-06-29 17:32:59 -07:00
committed by Pete Richards
parent 013eba744d
commit 433dee0314
305 changed files with 2866 additions and 3324 deletions

View File

@@ -44,8 +44,8 @@ define(
["requestTelemetry", "subscribe"]
),
unsubscribe = jasmine.createSpy("unsubscribe" + index);
provider.requestTelemetry.andReturn({ someKey: key });
provider.subscribe.andReturn(unsubscribe);
provider.requestTelemetry.and.returnValue({ someKey: key });
provider.subscribe.and.returnValue(unsubscribe);
// Store to verify interactions later
mockUnsubscribes[index] = unsubscribe;
@@ -54,7 +54,7 @@ define(
beforeEach(function () {
mockQ = jasmine.createSpyObj("$q", ["all"]);
mockQ.all.andReturn(mockPromise([]));
mockQ.all.and.returnValue(mockPromise([]));
mockUnsubscribes = [];
mockProviders = ["a", "b", "c"].map(makeMockProvider);
@@ -79,7 +79,7 @@ define(
it("merges results from all providers", function () {
var capture = jasmine.createSpy("capture");
mockQ.all.andReturn(mockPromise([
mockQ.all.and.returnValue(mockPromise([
{ someKey: "some value" },
{ someOtherKey: "some other value" }
]));

View File

@@ -63,13 +63,13 @@ define(
mockReject = jasmine.createSpyObj("reject", ["then"]);
mockUnsubscribe = jasmine.createSpy("unsubscribe");
mockInjector.get.andReturn(mockTelemetryService);
mockInjector.get.and.returnValue(mockTelemetryService);
mockQ.when.andCallFake(mockPromise);
mockQ.reject.andReturn(mockReject);
mockQ.when.and.callFake(mockPromise);
mockQ.reject.and.returnValue(mockReject);
mockDomainObject.getId.andReturn("testId");
mockDomainObject.getModel.andReturn({
mockDomainObject.getId.and.returnValue("testId");
mockDomainObject.getModel.and.returnValue({
telemetry: {
source: "testSource",
key: "testKey"
@@ -77,12 +77,12 @@ define(
});
mockTelemetryService.requestTelemetry
.andReturn(mockPromise({}));
.and.returnValue(mockPromise({}));
mockTelemetryService.subscribe
.andReturn(mockUnsubscribe);
.and.returnValue(mockUnsubscribe);
// Bubble up...
mockReject.then.andReturn(mockReject);
mockReject.then.and.returnValue(mockReject);
mockTelemetryAPI = jasmine.createSpyObj("telemetryAPI", [
"getMetadata",
@@ -97,7 +97,7 @@ define(
'values'
]);
mockMetadata.valuesForHints.andCallFake(function (hints) {
mockMetadata.valuesForHints.and.callFake(function (hints) {
var hint = hints[0];
var metadatum = {
key: 'default' + hint
@@ -106,7 +106,7 @@ define(
return [metadatum];
});
mockTelemetryAPI.getMetadata.andReturn(mockMetadata);
mockTelemetryAPI.getMetadata.and.returnValue(mockMetadata);
mockAPI = {
telemetry: mockTelemetryAPI,
@@ -167,7 +167,7 @@ define(
it("provides an empty series when telemetry is missing", function () {
var series;
mockTelemetryService.requestTelemetry.andReturn(mockPromise({}));
mockTelemetryService.requestTelemetry.and.returnValue(mockPromise({}));
telemetry.requestData({}).then(function (s) {
series = s;
});
@@ -189,7 +189,7 @@ define(
it("uses domain object as a key if needed", function () {
// Don't include key in telemetry
mockDomainObject.getModel.andReturn({
mockDomainObject.getModel.and.returnValue({
telemetry: { source: "testSource" }
});
@@ -208,7 +208,7 @@ define(
it("warns if no telemetry service can be injected", function () {
mockInjector.get.andCallFake(function () {
mockInjector.get.and.callFake(function () {
throw "";
});
@@ -222,14 +222,14 @@ define(
it("if a new style telemetry source is available, use it", function () {
var mockProvider = {};
mockTelemetryAPI.findSubscriptionProvider.andReturn(mockProvider);
mockTelemetryAPI.findSubscriptionProvider.and.returnValue(mockProvider);
telemetry.subscribe(noop, {});
expect(mockTelemetryService.subscribe).not.toHaveBeenCalled();
expect(mockTelemetryAPI.subscribe).toHaveBeenCalled();
});
it("if a new style telemetry source is not available, revert to old API", function () {
mockTelemetryAPI.findSubscriptionProvider.andReturn(undefined);
mockTelemetryAPI.findSubscriptionProvider.and.returnValue(undefined);
telemetry.subscribe(noop, {});
expect(mockTelemetryAPI.subscribe).not.toHaveBeenCalled();
expect(mockTelemetryService.subscribe).toHaveBeenCalled();
@@ -248,9 +248,8 @@ define(
prop3: "val6"
}];
var mockProvider = {};
var dunzo = false;
mockMetadata.values.andReturn([
mockMetadata.values.and.returnValue([
{
key: 'defaultrange',
source: 'prop1'
@@ -265,19 +264,12 @@ define(
}
]);
mockTelemetryAPI.findRequestProvider.andReturn(mockProvider);
mockTelemetryAPI.request.andReturn(Promise.resolve(mockTelemetry));
mockTelemetryAPI.findRequestProvider.and.returnValue(mockProvider);
mockTelemetryAPI.request.and.returnValue(Promise.resolve(mockTelemetry));
telemetry.requestData({}).then(function (data) {
return telemetry.requestData({}).then(function (data) {
returnedTelemetry = data;
dunzo = true;
});
waitsFor(function () {
return dunzo;
});
runs(function () {
expect(returnedTelemetry.getPointCount).toBeDefined();
expect(returnedTelemetry.getDomainValue).toBeDefined();
expect(returnedTelemetry.getRangeValue).toBeDefined();
@@ -319,7 +311,7 @@ define(
// Check that the callback gets invoked
expect(mockCallback).not.toHaveBeenCalled();
mockTelemetryService.subscribe.mostRecentCall.args[0]({
mockTelemetryService.subscribe.calls.mostRecent().args[0]({
testSource: { testKey: { someKey: "some value" } }
});
expect(mockCallback).toHaveBeenCalledWith(

View File

@@ -68,23 +68,23 @@ define(
);
mockUnsubscribe = jasmine.createSpy("unsubscribe");
mockQ.when.andCallFake(mockPromise);
mockQ.all.andReturn(mockPromise([mockDomainObject]));
mockQ.when.and.callFake(mockPromise);
mockQ.all.and.returnValue(mockPromise([mockDomainObject]));
mockDomainObject.getId.andReturn("testId");
mockDomainObject.getModel.andReturn({ name: "TEST" });
mockDomainObject.useCapability.andReturn([]);
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockTelemetry);
mockDomainObject.getId.and.returnValue("testId");
mockDomainObject.getModel.and.returnValue({ name: "TEST" });
mockDomainObject.useCapability.and.returnValue([]);
mockDomainObject.hasCapability.and.returnValue(true);
mockDomainObject.getCapability.and.returnValue(mockTelemetry);
mockTelemetry.getMetadata.andReturn({
mockTelemetry.getMetadata.and.returnValue({
source: "testSource",
key: "testKey"
});
mockTelemetry.requestData.andReturn(mockPromise({
mockTelemetry.requestData.and.returnValue(mockPromise({
telemetryKey: "some value"
}));
mockTelemetry.subscribe.andReturn(mockUnsubscribe);
mockTelemetry.subscribe.and.returnValue(mockUnsubscribe);
controller = new TelemetryController(
mockScope,
@@ -113,7 +113,7 @@ define(
// Tick the clock; should issue a new request, with
// the new interval
mockTimeout.mostRecentCall.args[0]();
mockTimeout.calls.mostRecent().args[0]();
expect(mockTimeout).toHaveBeenCalledWith(
jasmine.any(Function),
@@ -123,23 +123,23 @@ define(
it("requests data from domain objects", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(mockTelemetry.requestData).toHaveBeenCalled();
});
it("logs a warning if no telemetry capability exists", function () {
mockDomainObject.getCapability.andReturn(undefined);
mockDomainObject.getCapability.and.returnValue(undefined);
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(mockLog.warn).toHaveBeenCalled();
});
it("provides telemetry metadata", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(controller.getMetadata()).toEqual([
{ source: "testSource", key: "testKey" }
@@ -148,7 +148,7 @@ define(
it("provides telemetry-possessing domain objects", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(controller.getTelemetryObjects())
.toEqual([mockDomainObject]);
@@ -156,7 +156,7 @@ define(
it("provides telemetry data", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(controller.getResponse())
.toEqual([{telemetryKey: "some value"}]);
@@ -164,7 +164,7 @@ define(
it("provides telemetry data per-id", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
expect(controller.getResponse("testId"))
.toEqual({telemetryKey: "some value"});
@@ -176,7 +176,7 @@ define(
it("allows a request to be specified", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
controller.requestData({ someKey: "some request" });
@@ -187,7 +187,7 @@ define(
it("allows an object to be removed from scope", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](undefined);
mockScope.$watch.calls.mostRecent().args[1](undefined);
expect(controller.getTelemetryObjects())
.toEqual([]);
@@ -195,14 +195,14 @@ define(
it("broadcasts when telemetry is available", function () {
// Push into the scope...
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
controller.requestData({ someKey: "some request" });
// Verify precondition
expect(mockScope.$broadcast).not.toHaveBeenCalled();
// Call the broadcast timeout
mockTimeout.mostRecentCall.args[0]();
mockTimeout.calls.mostRecent().args[0]();
// Should have broadcast a telemetryUpdate
expect(mockScope.$broadcast)
@@ -211,12 +211,12 @@ define(
it("subscribes for streaming telemetry updates", function () {
// Push into scope to create subscriptions
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
// Should have subscribed
expect(mockTelemetry.subscribe)
.toHaveBeenCalledWith(jasmine.any(Function));
// Invoke the subscriber function (for coverage)
mockTelemetry.subscribe.mostRecentCall.args[0]({});
mockTelemetry.subscribe.calls.mostRecent().args[0]({});
});
it("listens for scope destruction to clean up", function () {
@@ -224,15 +224,15 @@ define(
"$destroy",
jasmine.any(Function)
);
mockScope.$on.mostRecentCall.args[1]();
mockScope.$on.calls.mostRecent().args[1]();
});
it("unsubscribes when destroyed", function () {
// Push into scope to create subscriptions
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject);
// Invoke "$destroy" listener
mockScope.$on.mostRecentCall.args[1]();
mockScope.$on.calls.mostRecent().args[1]();
// Should have unsubscribed
expect(mockUnsubscribe).toHaveBeenCalled();

View File

@@ -37,13 +37,13 @@ define(
"parse",
"format"
]);
mockFormatService.getFormat.andReturn(mockFormat);
mockFormatService.getFormat.and.returnValue(mockFormat);
formatter = new TelemetryFormatter(mockFormatService);
});
it("formats domains using the formatService", function () {
var testValue = 12321, testResult = "some result";
mockFormat.format.andReturn(testResult);
mockFormat.format.and.returnValue(testResult);
expect(formatter.formatDomainValue(testValue))
.toEqual(testResult);

View File

@@ -68,7 +68,7 @@ define(
mockCallback = jasmine.createSpy('callback');
// Simulate $q.all, at least for asPromise-provided promises
mockQ.all.andCallFake(function (values) {
mockQ.all.and.callFake(function (values) {
return values.map(function (v) {
var r;
asPromise(v).then(function (value) {
@@ -77,14 +77,14 @@ define(
return r;
});
});
mockQ.when.andCallFake(asPromise);
mockQ.when.and.callFake(asPromise);
mockSubscription.getTelemetryObjects
.andReturn([mockDomainObject]);
.and.returnValue([mockDomainObject]);
mockSubscription.promiseTelemetryObjects
.andReturn(asPromise([mockDomainObject]));
mockDomainObject.getId.andReturn('testId');
mockDomainObject.getCapability.andReturn(mockTelemetry);
mockTelemetry.requestData.andReturn(asPromise(mockSeries));
.and.returnValue(asPromise([mockDomainObject]));
mockDomainObject.getId.and.returnValue('testId');
mockDomainObject.getCapability.and.returnValue(mockTelemetry);
mockTelemetry.requestData.and.returnValue(asPromise(mockSeries));
handle = new TelemetryHandle(mockQ, mockSubscription);
});
@@ -121,7 +121,7 @@ define(
it("provides access to the datum objects by index", function () {
var testDatum = { a: 1, b: 2 }, testIndex = 42;
mockSubscription.makeDatum.andReturn(testDatum);
mockSubscription.makeDatum.and.returnValue(testDatum);
handle.request({});
expect(handle.getDatum(mockDomainObject, testIndex))
.toEqual(testDatum);

View File

@@ -56,7 +56,7 @@ define(
]
);
mockSubscriber.subscribe.andReturn(mockSubscription);
mockSubscriber.subscribe.and.returnValue(mockSubscription);
handler = new TelemetryHandler(mockQ, mockSubscriber);
});

View File

@@ -45,8 +45,8 @@ define(
mockCallback = jasmine.createSpy("callback");
mockPromise = jasmine.createSpyObj("promise", ["then"]);
mockQ.when.andReturn(mockPromise);
mockPromise.then.andReturn(mockPromise);
mockQ.when.and.returnValue(mockPromise);
mockPromise.then.and.returnValue(mockPromise);
subscriber = new TelemetrySubscriber(mockQ, mockTimeout);
});

View File

@@ -70,25 +70,25 @@ define(
["getPointCount", "getDomainValue", "getRangeValue"]
);
mockQ.when.andCallFake(mockPromise);
mockQ.when.and.callFake(mockPromise);
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andCallFake(function (c) {
mockDomainObject.hasCapability.and.returnValue(true);
mockDomainObject.getCapability.and.callFake(function (c) {
return {
telemetry: mockTelemetry,
mutation: mockMutation
}[c];
});
mockDomainObject.getId.andReturn('test-id');
mockDomainObject.getId.and.returnValue('test-id');
mockTelemetry.subscribe.andReturn(mockUnsubscribe);
mockTelemetry.getMetadata.andReturn(testMetadata);
mockTelemetry.subscribe.and.returnValue(mockUnsubscribe);
mockTelemetry.getMetadata.and.returnValue(testMetadata);
mockMutation.listen.andReturn(mockUnlisten);
mockMutation.listen.and.returnValue(mockUnlisten);
mockSeries.getPointCount.andReturn(42);
mockSeries.getDomainValue.andReturn(123456);
mockSeries.getRangeValue.andReturn(789);
mockSeries.getPointCount.and.returnValue(42);
mockSeries.getDomainValue.and.returnValue(123456);
mockSeries.getRangeValue.and.returnValue(789);
subscription = new TelemetrySubscription(
mockQ,
@@ -112,40 +112,40 @@ define(
// Callback fires when telemetry objects become available,
// so track initial call count instead of verifying that
// it hasn't been called at all.
var initialCalls = mockCallback.calls.length;
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
var initialCalls = mockCallback.calls.count();
mockTelemetry.subscribe.calls.mostRecent().args[0](mockSeries);
// This gets fired via a timeout, so trigger that
expect(mockTimeout).toHaveBeenCalledWith(
jasmine.any(Function),
0
);
mockTimeout.mostRecentCall.args[0]();
mockTimeout.calls.mostRecent().args[0]();
// Should have triggered the callback to alert that
// new data was available
expect(mockCallback.calls.length).toEqual(initialCalls + 1);
expect(mockCallback.calls.count()).toEqual(initialCalls + 1);
});
it("fires subscription callbacks once per cycle", function () {
var i;
// Verify precondition - one call for telemetryObjects
expect(mockCallback.calls.length).toEqual(1);
expect(mockCallback.calls.count()).toEqual(1);
for (i = 0; i < 100; i += 1) {
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
mockTelemetry.subscribe.calls.mostRecent().args[0](mockSeries);
}
// This gets fired via a timeout, so trigger any of those
mockTimeout.calls.forEach(function (call) {
mockTimeout.calls.all().forEach(function (call) {
call.args[0]();
});
// Should have only triggered the
expect(mockCallback.calls.length).toEqual(2);
expect(mockCallback.calls.count()).toEqual(2);
});
it("reports its latest observed data values", function () {
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
mockTelemetry.subscribe.calls.mostRecent().args[0](mockSeries);
// This gets fired via a timeout, so trigger that
mockTimeout.mostRecentCall.args[0]();
mockTimeout.calls.mostRecent().args[0]();
// Verify that the last sample was looked at
expect(mockSeries.getDomainValue).toHaveBeenCalledWith(41);
expect(mockSeries.getRangeValue).toHaveBeenCalledWith(41);
@@ -183,10 +183,10 @@ define(
);
// Track calls at this point
initialCalls = mockCallback.calls.length;
initialCalls = mockCallback.calls.count();
// Snapshot getDomainValue, getRangeValue at time of callback
mockCallback.andCallFake(function () {
mockCallback.and.callFake(function () {
domains.push(subscription.getDomainValue(mockDomainObject));
ranges.push(subscription.getRangeValue(mockDomainObject));
});
@@ -194,19 +194,19 @@ define(
// Send 100 updates
for (i = 0; i < 100; i += 1) {
// Return different values to verify later
mockSeries.getDomainValue.andReturn(i);
mockSeries.getRangeValue.andReturn(i * 2);
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
mockSeries.getDomainValue.and.returnValue(i);
mockSeries.getRangeValue.and.returnValue(i * 2);
mockTelemetry.subscribe.calls.mostRecent().args[0](mockSeries);
}
// Fire all timeouts that get scheduled
while (mockTimeout.mostRecentCall !== lastCall) {
lastCall = mockTimeout.mostRecentCall;
while (mockTimeout.calls.mostRecent() !== lastCall) {
lastCall = mockTimeout.calls.mostRecent();
lastCall.args[0]();
}
// Should have only triggered the
expect(mockCallback.calls.length).toEqual(100 + initialCalls);
expect(mockCallback.calls.count()).toEqual(100 + initialCalls);
});
it("provides domain object metadata", function () {
@@ -215,7 +215,7 @@ define(
});
it("fires callback when telemetry objects are available", function () {
expect(mockCallback.calls.length).toEqual(1);
expect(mockCallback.calls.count()).toEqual(1);
});
it("exposes a promise for telemetry objects", function () {
@@ -227,13 +227,13 @@ define(
});
it("reinitializes on mutation", function () {
expect(mockTelemetry.subscribe.calls.length).toEqual(1);
expect(mockTelemetry.subscribe.calls.count()).toEqual(1);
// Notify of a mutation which appears to change composition
mockMutation.listen.mostRecentCall.args[0]({
mockMutation.listen.calls.mostRecent().args[0]({
composition: ['Z']
});
// Use subscribe call as an indication of reinitialization
expect(mockTelemetry.subscribe.calls.length).toEqual(2);
expect(mockTelemetry.subscribe.calls.count()).toEqual(2);
});
it("stops listening for mutation on unsubscribe", function () {
@@ -249,14 +249,14 @@ define(
return testDatum[key];
}
mockSeries.getDomainValue.andCallFake(lookup);
mockSeries.getRangeValue.andCallFake(lookup);
mockSeries.getDomainValue.and.callFake(lookup);
mockSeries.getRangeValue.and.callFake(lookup);
testMetadata.domains = [{ key: 'a' }, { key: 'b'}];
testMetadata.ranges = [{ key: 'c' }, { key: 'd'}];
mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries);
mockTimeout.mostRecentCall.args[0]();
mockTelemetry.subscribe.calls.mostRecent().args[0](mockSeries);
mockTimeout.calls.mostRecent().args[0]();
expect(subscription.getDatum(mockDomainObject))
.toEqual(testDatum);