jsaction
Version:
Google's event delegation library
1,072 lines (821 loc) • 30 kB
JavaScript
// Copyright 2008 Google Inc. All rights reserved.
/**
*/
/** @suppress {extraProvide} */
goog.provide('jsaction.ActionFlowTest');
goog.setTestOnly('jsaction.ActionFlowTest');
goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.object');
goog.require('goog.testing.MockClock');
goog.require('goog.testing.jsunit');
goog.require('jsaction.ActionFlow');
goog.require('jsaction.Branch');
/** @suppress {extraRequire} */
goog.require('jsaction.replayEvent');
var mockClock_;
var reportSent;
var reportTimingData;
var reportActionData;
var reportImpressionData;
var savedGlobal_;
var iframeDocument;
function setUpPage() {
var testHtml = '<body>' + document.body.innerHTML + '</body>';
var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
document.body.appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open();
doc.write(testHtml);
doc.close();
iframeDocument = doc;
}
function setUp() {
mockClock_ = new goog.testing.MockClock;
mockClock_.install();
goog.events.listen(
jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.DONE, reportHandler);
reportSent = false;
reportTimingData = {};
reportActionData = {};
reportImpressionData = {};
savedGlobal_ = null;
}
function tearDown() {
mockClock_.uninstall();
if (savedGlobal_) {
goog.global = savedGlobal_;
}
}
function reportHandler(e) {
reportSent = true;
reportTimingData['flowType'] = e.flow.getType();
reportTimingData['rtData'] = e.flow.timers();
reportTimingData['cadData'] = e.flow.getExtraData();
reportActionData = goog.object.clone(e.flow.getActionData());
reportImpressionData = goog.object.clone(e.flow.getImpressionData());
}
var CONSTRUCTION_TIME = 314;
var TICK_TIME = 415;
function testActionFlow() {
mockClock_.tick(CONSTRUCTION_TIME);
var createdFlow = null;
var creationListener = function(event) {
createdFlow = event.flow;
};
goog.events.listen(
jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.CREATED,
creationListener);
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
assertEquals(flow, createdFlow);
var beforeReportTriggered = false;
goog.events.listen(flow,
jsaction.ActionFlow.EventType.BEFOREDONE, function() {
assertFalse(reportSent);
beforeReportTriggered = true;
});
mockClock_.tick(TICK_TIME);
flow.tick('foo');
assertEquals(1, timers.length);
assertEquals('foo', timers[0][0]);
assertEquals(TICK_TIME, timers[0][1]);
assertEquals(TICK_TIME + CONSTRUCTION_TIME, flow.getTick('foo'));
assertArrayEquals(['start', 'foo'], flow.getTickNames());
flow.done(jsaction.Branch.MAIN);
assertTrue(beforeReportTriggered);
assertEquals('test', reportTimingData['flowType']);
assertEquals(timers, reportTimingData['rtData']);
}
function testCadDataWithDataRecordedOnBeforeDone() {
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
var beforeReportTriggered = false;
goog.events.listen(
flow, jsaction.ActionFlow.EventType.BEFOREDONE, function(e) {
e.flow.addExtraData('extra', 'foo');
beforeReportTriggered = true;
});
var actionData = null;
goog.events.listen(
jsaction.ActionFlow.report, jsaction.ActionFlow.EventType.DONE,
function() {
actionData = flow.getActionData();
});
flow.addExtraData('bar', 'baz');
flow.done(jsaction.Branch.MAIN);
assertTrue(beforeReportTriggered);
assertNotNull(actionData);
assertEquals('bar:baz,extra:foo', actionData['cad']);
}
function testOverrideStartTime() {
mockClock_.tick(CONSTRUCTION_TIME);
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
mockClock_.tick(TICK_TIME);
flow.tick('foo');
assertEquals(1, timers.length);
assertEquals('foo', timers[0][0]);
assertEquals(TICK_TIME + CONSTRUCTION_TIME - START_TIME, timers[0][1]);
assertEquals(TICK_TIME + CONSTRUCTION_TIME, flow.getTick('foo'));
assertArrayEquals(['start', 'foo'], flow.getTickNames());
}
function testTickKeepsTimersSorted() {
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
flow.tick('foo', {time: 10});
flow.tick('bar', {time: 5});
flow.tick('baz', {time: 20});
flow.tick('boo', {time: 3});
assertEquals(2, timers[0][1]);
assertArrayEquals(['start', 'boo', 'bar', 'foo', 'baz'],
flow.getTickNames());
assertEquals(20, flow.getMaxTickTime());
}
function testTickNotInMaxTime() {
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
flow.tick('foo', {time: 10});
flow.tick('bar', {time: 5});
flow.tick('baz', {time: 20});
flow.tick('superbaz', {time: 200, doNotIncludeInMaxTime: true});
flow.tick('boo', {time: 3});
assertEquals(2, timers[0][1]);
assertArrayEquals(['start', 'boo', 'bar', 'foo', 'baz', 'superbaz'],
flow.getTickNames());
assertEquals(20, flow.getMaxTickTime());
}
function testTickWithDoNotReportToServer() {
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
flow.tick('foo');
flow.tick('bar', {doNotReportToServer: true});
assertEquals('foo', timers[0][0]);
assertEquals(undefined, timers[0][2]);
assertEquals('bar', timers[1][0]);
assertEquals(true, timers[1][2]);
}
function testTickWithDoNotReportToServerDoesNotAffectMaxTickTime() {
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
flow.tick('foo', {time: 10});
flow.tick('bar', {time: 20, doNotReportToServer: true});
assertEquals('foo', timers[0][0]);
assertEquals(undefined, timers[0][2]);
assertEquals('bar', timers[1][0]);
assertEquals(true, timers[1][2]);
assertEquals(10, flow.getMaxTickTime());
assertNotNull(flow.getTick('foo'));
assertNotNull(flow.getTick('bar'));
assertEquals(20, flow.getTick('bar'));
}
function testNewBranchWithDoNotReportToServer() {
var START_TIME = 1;
var flow = new jsaction.ActionFlow('test', null, null, START_TIME);
var timers = flow.timers();
flow.tick('foo', {time: 10});
flow.branch('branch1', 'bar0', {time: 20, doNotReportToServer: true});
flow.done('branch1', 'bar1', {time: 30, doNotReportToServer: true});
assertEquals(10, flow.getMaxTickTime());
assertEquals('foo', timers[0][0]);
assertEquals('bar0', timers[1][0]);
assertEquals('bar1', timers[2][0]);
}
function testActionFlowAdoptDoesNothingOnNull() {
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
flow.adopt(null);
assertEquals(0, timers.length);
assertArrayEquals(['start'], flow.getTickNames());
}
function testActionFlowAdoptDoesNothingWithoutStart() {
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
flow.adopt({'foo': 10});
assertEquals(0, timers.length);
assertArrayEquals(['start'], flow.getTickNames());
}
function testActionFlowAdopt() {
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
flow.adopt({'start': 1, 'foo': 10});
assertEquals(1, timers.length);
assertEquals('foo', timers[0][0]);
assertEquals(9, timers[0][1]);
assertEquals(10, flow.getTick('foo'));
assertArrayEquals(['start', 'foo'], flow.getTickNames());
}
function testActionFlowAdoptAtStartZero() {
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
flow.adopt({'start': 0, 'foo': 10});
assertEquals(1, timers.length);
assertEquals(10, flow.getTick('foo'));
assertArrayEquals(['start', 'foo'], flow.getTickNames());
}
function testActionFlowAdoptDone() {
var flow = new jsaction.ActionFlow('test');
flow.adopt({'start': 1, 'foo': 10});
flow.done(jsaction.Branch.MAIN);
assertTrue('Adopt sends report with one done.', reportSent);
}
function testActionFlowAdoptDoneWithExpect() {
var flow = new jsaction.ActionFlow('test');
var mockBranches = {'branch1': 2};
mockBranches[jsaction.Branch.MAIN] = 1;
flow.adopt({'start': 1, 'foo': 10}, mockBranches);
flow.done('branch1');
assertFalse('Report incorrectly sent.', reportSent);
flow.done(jsaction.Branch.MAIN);
assertFalse('Report incorrectly sent.', reportSent);
flow.done('branch1');
assertTrue('Report not sent after the flow finished.', reportSent);
}
function testActionFlowMerge() {
var flow = new jsaction.ActionFlow('test', null, null, 3);
flow.tick('bar', {time: 20});
var timers = flow.timers();
jsaction.ActionFlow.merge(
flow, {'start': 1, 'foo': 10, 'baz': 5, 'boo': 30});
assertEquals(4, timers.length);
assertEquals(2, timers[0][1]);
assertEquals(7, timers[1][1]);
assertEquals(10, flow.getTick('foo'));
assertEquals(20, flow.getTick('bar'));
assertArrayEquals(['start', 'baz', 'foo', 'bar', 'boo'],
flow.getTickNames());
}
function testReportSendCalledWithoutTicks() {
var flow = new jsaction.ActionFlow('test');
flow.done(jsaction.Branch.MAIN);
assertTrue('ActionFlow reported without ticks.', reportSent);
}
function testTickWithoutDoneDoesNotSendReport() {
var flow = new jsaction.ActionFlow('test');
flow.tick('foo');
assertFalse('Tick never sends report.', reportSent);
}
function testActionFlowWithWeirdFlowNames() {
var flow = new jsaction.ActionFlow('t&s$tf#b~c');
flow.tick('foo');
flow.done(jsaction.Branch.MAIN);
assertEquals('t_s$tf#b_c', reportTimingData['flowType']);
}
function testOneBranch() {
var flow = new jsaction.ActionFlow('test');
flow.tick('foo');
flow.branch('branch1');
assertFalse(reportSent);
flow.done('branch1');
assertFalse(reportSent);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals(1, reportTimingData['rtData'].length);
}
function testMultipleBranches() {
var flow = new jsaction.ActionFlow('test');
flow.tick('foo');
flow.branch('branch1');
flow.branch('branch2');
flow.done('branch1');
assertFalse(reportSent);
flow.done(jsaction.Branch.MAIN);
assertFalse(reportSent);
flow.done('branch2');
assertTrue(reportSent);
assertEquals(1, reportTimingData['rtData'].length);
}
function testTickDoneShortcut() {
var flow = new jsaction.ActionFlow('test');
flow.done(jsaction.Branch.MAIN, 'bar');
assertTrue(reportSent);
assertEquals(1, reportTimingData['rtData'].length);
}
function testTickBranchShortcut() {
var flow = new jsaction.ActionFlow('test');
flow.branch('foobranch', 'footick');
flow.done('foobranch', 'bartick');
assertFalse(reportSent);
flow.done(jsaction.Branch.MAIN, 'baz');
assertTrue(reportSent);
assertEquals(3, reportTimingData['rtData'].length);
}
function testTrackedCallback() {
var flow = new jsaction.ActionFlow('test');
var callbackCalled = false;
var fn = function() {
callbackCalled = true;
};
var trackedCallback = flow.callback(fn, 'testbranch', 't0', 't1');
assertTrue(goog.isDef(flow.getTick('t0')));
jsaction.ActionFlow.done(flow, jsaction.Branch.MAIN);
assertFalse(reportSent);
trackedCallback();
assertTrue(goog.isDef(flow.getTick('t1')));
assertTrue(callbackCalled);
assertTrue(reportSent);
}
function testTrackedCallbackThrows() {
var flow = new jsaction.ActionFlow('test');
var callbackCalled = false;
var fn = function() {
callbackCalled = true;
throw 'foo';
};
var trackedCallback = flow.callback(fn, 'testbranch', 't0', 't1');
assertTrue(goog.isDef(flow.getTick('t0')));
jsaction.ActionFlow.done(flow, jsaction.Branch.MAIN);
assertFalse(reportSent);
try {
trackedCallback();
} catch (e) {
assertEquals('foo', e);
}
assertTrue(goog.isDef(flow.getTick('t1')));
assertTrue(callbackCalled);
assertTrue(reportSent);
}
function testIsOfType() {
var flow = new jsaction.ActionFlow('foo');
assertTrue(flow.isOfType('foo'));
assertFalse(flow.isOfType('bar'));
}
function testIsOfTypeWithWeirdNames() {
var flow = new jsaction.ActionFlow('t&est');
assertTrue(flow.isOfType('t&est'));
assertTrue(flow.isOfType('t_est'));
assertFalse(flow.isOfType('bar'));
}
function testSetEventId() {
var flow = new jsaction.ActionFlow('test');
flow.maybeSetEventId('abcdefg');
// No-op: already set.
flow.maybeSetEventId('other-event-id');
flow.done(jsaction.Branch.MAIN, 'done');
assertTrue(reportSent);
assertEquals('abcdefg', reportActionData['ei']);
}
function testAddActionDataWithTimers() {
var flow = new jsaction.ActionFlow('test');
flow.addExtraData('key1', 'value1');
flow.addExtraData('key2', 'value2');
flow.done(jsaction.Branch.MAIN, 'done');
assertTrue(reportSent);
assertEquals(reportTimingData['cadData']['key1'], 'value1');
assertEquals(reportTimingData['cadData']['key2'], 'value2');
}
function testDuplicateTicks() {
var flow = new jsaction.ActionFlow('test');
flow.tick('tick');
flow.tick('tick');
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('tick', reportTimingData['cadData']['dup']);
}
function testMultipleDuplicateTicks() {
var flow = new jsaction.ActionFlow('test');
flow.tick('tick1');
flow.tick('tick1');
flow.tick('tick2');
flow.tick('tick2');
flow.tick('tick1');
flow.tick('tick3');
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('tick1|tick2', reportTimingData['cadData']['dup']);
}
function testAction() {
var flow = new jsaction.ActionFlow('barAction');
var target = document.getElementById('bar2');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('barAction', reportActionData['ct']);
assertEquals(1, reportActionData['cd']);
assertEquals('oi:maps.foo.bar', reportActionData['cad']);
assertTrue(goog.object.isEmpty(reportImpressionData));
}
function testAction2() {
var flow = new jsaction.ActionFlow('barAction');
var target = document.getElementById('bar3');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('barAction', reportActionData['ct']);
assertEquals(2, reportActionData['cd']);
assertEquals('oi:maps.foo.bar', reportActionData['cad']);
assertTrue(goog.object.isEmpty(reportImpressionData));
}
function testActionWithoutOiData() {
var flow = new jsaction.ActionFlow('barAction');
var target = document.getElementById('foo2');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('barAction', reportActionData['ct']);
}
function testActionAcrossIframes() {
var flow = new jsaction.ActionFlow('barAction');
var target = iframeDocument.getElementById('bar2');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('barAction', reportActionData['ct']);
assertEquals(1, reportActionData['cd']);
assertEquals('oi:maps.foo.bar', reportActionData['cad']);
assertTrue(goog.object.isEmpty(reportImpressionData));
}
function testActionFromConstructor() {
// When the constructor is passed a node and a click event, action() is
// triggered from within the constructor.
var target = document.getElementById('bar2');
var clickEvent = jsaction.createEvent({type: 'click'});
var flow = new jsaction.ActionFlow('barAction', target, clickEvent);
flow.done(jsaction.Branch.MAIN);
assertEquals('barAction', reportActionData['ct']);
assertEquals(1, reportActionData['cd']);
assertEquals('oi:maps.foo.bar', reportActionData['cad']);
assertTrue(goog.object.isEmpty(reportImpressionData));
}
function testActionNestedEi() {
var flow = new jsaction.ActionFlow('nestedAction');
var target = document.getElementById('nested');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('eventid2', reportActionData['ei']);
assertFalse('ved' in reportActionData);
}
function testActionWithNoTracking() {
var flow = new jsaction.ActionFlow('fooAction');
var target = document.getElementById('foo1');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertEquals(undefined, reportActionData['ct']);
assertEquals(undefined, reportActionData['cd']);
assertEquals(undefined, reportActionData['cad']);
assertEquals(undefined, reportActionData['ei']);
assertEquals(undefined, reportActionData['ved']);
}
function testActionWithNoOi() {
var flow = new jsaction.ActionFlow('fooAction');
var target = document.getElementById('foo2');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('fooAction', reportActionData['ct']);
assertEquals(undefined, reportActionData['cd']);
assertEquals(undefined, reportActionData['cad']);
assertTrue(goog.object.isEmpty(reportImpressionData));
}
function testActionWithVed() {
var flow = new jsaction.ActionFlow('bazAction');
var target = document.getElementById('baz');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('bazAction', reportActionData['ct']);
assertEquals(0, reportActionData['cd']);
assertEquals('oi:maps2.baz2.baz3', reportActionData['cad']);
assertEquals('baz1', reportActionData['ved']);
assertEquals('eventid', reportActionData['ei']);
}
function testActionWithVet() {
var flow = new jsaction.ActionFlow('nestedAction');
var target = document.getElementById('nested');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('nestedAction', reportActionData['ct']);
assertEquals('vet2', reportActionData['vet']);
}
function testActionWithVetNoJstrack() {
var flow = new jsaction.ActionFlow('fooAction');
var target = document.getElementById('foo1');
flow.action(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('vet1', reportActionData['vet']);
}
function testAddActionData() {
var flow = new jsaction.ActionFlow('barAction');
var target = document.getElementById('bar2');
flow.action(target);
flow.addExtraData('key1', 'value1');
assertEquals('value1', flow.getExtraData()['key1']);
flow.addExtraData('key2', 'value2');
assertEquals('value2', flow.getExtraData()['key2']);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertEquals('oi:maps.foo.bar,key1:value1,key2:value2',
reportActionData['cad']);
}
function testImpressionWithTwoChildrenBothDisplayed() {
var flow = new jsaction.ActionFlow('test');
var target = document.getElementById('foo');
var bar = document.getElementById('bar1');
bar.style['display'] = '';
flow.impression(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertTrue(goog.object.isEmpty(reportActionData));
assertEquals(1, reportImpressionData['maps.foo']);
assertEquals(3, reportImpressionData['maps.foo.bar']);
}
function testImpressionWithOneChildDisplayedAndOneChildHidden() {
var flow = new jsaction.ActionFlow('test');
var target = document.getElementById('foo');
var bar = document.getElementById('bar1');
bar.style['display'] = 'none';
flow.impression(target);
flow.done(jsaction.Branch.MAIN);
assertTrue(reportSent);
assertTrue(goog.object.isEmpty(reportActionData));
assertEquals(1, reportImpressionData['maps.foo']);
assertEquals(2, reportImpressionData['maps.foo.bar']);
}
function testStaticTickBranchDone() {
var undefinedFlow = undefined;
jsaction.ActionFlow.tick(undefinedFlow, 'foo');
jsaction.ActionFlow.branch(undefinedFlow, 'branchfoo');
jsaction.ActionFlow.done(undefinedFlow, 'branchfoo');
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
jsaction.ActionFlow.tick(flow, 'tick', 0);
assertEquals(0, flow.getTick('tick'));
jsaction.ActionFlow.branch(flow, 'testbranch', 'branchtick');
assertTrue(goog.isDef(flow.getTick('tick')));
flow.done('testbranch');
assertFalse(reportSent);
jsaction.ActionFlow.done(flow, jsaction.Branch.MAIN, 'done');
assertEquals('start_tick_branchtick_done', flow.getTickNames().join('_'));
assertTrue(reportSent);
}
function testAbandonActionFlow() {
mockClock_.tick(CONSTRUCTION_TIME);
var flow = new jsaction.ActionFlow('test');
var timers = flow.timers();
var beforeReportTriggered = false;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.BEFOREDONE, function() {
assertFalse(reportSent);
beforeReportTriggered = true;
});
var abandonedTriggered = false;
goog.events.listen(flow,
jsaction.ActionFlow.EventType.ABANDONED, function() {
abandonedTriggered = true;
});
mockClock_.tick(TICK_TIME);
flow.tick('foo');
assertEquals(1, timers.length);
assertEquals('foo', timers[0][0]);
flow.abandon();
flow.done(jsaction.Branch.MAIN);
assertTrue(abandonedTriggered);
assertFalse(beforeReportTriggered);
assertFalse(reportSent);
assertUndefined(reportTimingData['flowType']);
assertUndefined(reportTimingData['rtData']);
assertUndefined(reportTimingData['cadData']);
}
function testGetType() {
var flow = new jsaction.ActionFlow('test');
assertEquals('test', flow.getType());
}
function testSetType() {
var flow = new jsaction.ActionFlow('foo');
assertEquals('foo', flow.getType());
assertEquals('foo', flow.flowType());
flow.setType('bar');
assertEquals('bar', flow.getType());
assertEquals('bar', flow.flowType());
}
function testErrorReportTriggeredOnBranchAfterFlowFinished() {
var flow = new jsaction.ActionFlow('test');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
errorEvent = e;
});
flow.tick('foo');
flow.addExtraData('key1', 'value1');
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.branch('wrongbranch');
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.BRANCH, errorEvent.error);
assertEquals('wrongbranch', errorEvent.branch);
assertEquals('test', errorEvent.flow.flowType());
assertTrue(errorEvent.finished);
assertEquals(reportTimingData['rtData'], errorEvent.flow.timers());
assertEquals(reportTimingData['cadData'], errorEvent.flow.getExtraData());
}
function testErrorReportTriggeredOnDoneAfterFlowFinished() {
var flow = new jsaction.ActionFlow('test');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
errorEvent = e;
});
flow.tick('foo');
flow.addExtraData('key1', 'value1');
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.done('wrongbranch', 'badtick');
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.DONE, errorEvent.error);
assertEquals('wrongbranch', errorEvent.branch);
assertTrue(errorEvent.finished);
assertEquals('badtick', errorEvent.tick);
assertEquals('test', errorEvent.flow.flowType());
assertEquals(reportTimingData['rtData'], errorEvent.flow.timers());
assertEquals(reportTimingData['cadData'], errorEvent.flow.getExtraData());
}
function testErrorReportTriggeredOnTickAfterFlowFinished() {
var flow = new jsaction.ActionFlow('errortest');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
errorEvent = e;
});
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.tick('badtick');
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.TICK, errorEvent.error);
assertUndefined(errorEvent.branch);
assertEquals('badtick', errorEvent.tick);
assertTrue(errorEvent.finished);
assertEquals('errortest', errorEvent.flow.flowType());
assertEquals(reportTimingData['rtData'], errorEvent.flow.timers());
assertEquals(reportTimingData['cadData'], errorEvent.flow.getExtraData());
assertTrue(goog.object.isEmpty(errorEvent.flow.branches()));
}
function testErrorReportTriggeredOnAddExtraDataAfterFlowFinished() {
var flow = new jsaction.ActionFlow('errortest');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
errorEvent = e;
});
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.addExtraData('badkey', 'bad value');
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.EXTRA_DATA, errorEvent.error);
assertUndefined(errorEvent.branch);
assertUndefined(errorEvent.tick);
assertTrue(errorEvent.finished);
assertEquals('errortest', errorEvent.flow.flowType());
assertTrue(goog.object.isEmpty(errorEvent.flow.branches()));
}
function testErrorReportTriggeredOnActionAfterFlowFinished() {
var target = document.getElementById('bar2');
var flow = new jsaction.ActionFlow('errortest');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
if (!errorEvent) {
errorEvent = e;
}
});
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.action(target);
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.ACTION, errorEvent.error);
assertUndefined(errorEvent.branch);
assertUndefined(errorEvent.tick);
assertTrue(errorEvent.finished);
assertEquals('errortest', errorEvent.flow.flowType());
assertTrue(goog.object.isEmpty(errorEvent.flow.branches()));
}
function testErrorReportTriggeredOnImpressionAfterFlowFinished() {
var target = document.getElementById('bar2');
var flow = new jsaction.ActionFlow('errortest');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
if (!errorEvent) {
errorEvent = e;
}
});
flow.done(jsaction.Branch.MAIN);
assertNull(errorEvent);
flow.impression(target);
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.IMPRESSION, errorEvent.error);
assertUndefined(errorEvent.branch);
assertUndefined(errorEvent.tick);
assertTrue(errorEvent.finished);
assertEquals('errortest', errorEvent.flow.flowType());
assertTrue(goog.object.isEmpty(errorEvent.flow.branches()));
}
function testErrorReportTriggeredOnDoneOnABranchNotPending() {
var flow = new jsaction.ActionFlow('errortest');
var errorEvent = null;
goog.events.listen(jsaction.ActionFlow.report,
jsaction.ActionFlow.EventType.ERROR, function(e) {
errorEvent = e;
});
flow.branch('branch1');
// branch2 was never opened.
flow.done('branch2');
flow.done(jsaction.Branch.MAIN);
assertNotNull(errorEvent);
assertEquals(jsaction.ActionFlow.Error.DONE, errorEvent.error);
assertEquals('branch2', errorEvent.branch);
assertUndefined(errorEvent.tick);
assertFalse(errorEvent.finished);
assertEquals('errortest', errorEvent.flow.flowType());
assertEquals(1, errorEvent.flow.branches()['branch1']);
}
function testJsActionFlow_Type_Node_Event_Values() {
var node = document.createElement('div');
node.foo = 1;
var event = jsaction.createEvent({type: 'click'});
var flowType = 'bar';
var flow = new jsaction.ActionFlow(flowType, node, event);
assertEquals(flowType, flow.flowType());
assertEquals(1, flow.value('foo'));
assertEquals(node, flow.node());
}
function testGetEventNodeNull() {
var flow = new jsaction.ActionFlow('baz', null, null);
assertNull(flow.event());
assertNull(flow.node());
}
function testDoneClearsNodeAndEvent() {
var node = document.createElement('div');
var event = jsaction.createEvent({type: 'click'});
var flow = new jsaction.ActionFlow('baz', node, event);
assertNotNull(flow.node());
assertNotNull(flow.event());
flow.done(jsaction.Branch.MAIN);
assertNull(flow.node());
assertNull(flow.event());
}
function testDoneClearsNodeAndEvent_MultipleBranches() {
var node = document.createElement('div');
var event = jsaction.createEvent({type: 'click'});
var flow = new jsaction.ActionFlow('test', node, event);
assertNotNull(flow.node());
assertNotNull(flow.event());
flow.branch('b1');
flow.branch('b2');
flow.done('b1');
assertNotNull(flow.node());
assertNotNull(flow.event());
flow.done('b2');
assertNotNull(flow.node_);
assertNotNull(flow.event_);
flow.done(jsaction.Branch.MAIN);
assertNull(flow.node());
assertNull(flow.event());
}
function testJsActionFlowCopiesEventObjectOnIEBefore9() {
// This is restored on tearDown so that it doesn't affect other tests if this
// one fails.
savedGlobal_ = goog.global;
// The event gets copied if there is no document.createEvent and we have
// document.createEventObject (see jsaction.event.maybeCopyEvent).
var mockDocument = {};
mockDocument.createEventObject = function() {
var retval = {};
for (var i in event) {
retval[i] = event[i];
}
return retval;
};
goog.global = {};
goog.global['document'] = mockDocument;
var node = {};
var event = {'type': '', 'foo': {}};
var flow = new jsaction.ActionFlow('foo', node, event);
// The event should be deep copied.
assertNotEquals(event, flow.event());
assertEquals(event['foo'], flow.event()['foo']);
}
function testGetNamespace() {
var node = document.createElement('div');
var event = jsaction.createEvent({type: 'click'});
var flowWithNamespace = new jsaction.ActionFlow('gna.fu', node, event);
assertEquals('gna', flowWithNamespace.actionNamespace());
var flowWithoutNamespace = new jsaction.ActionFlow('fu', node, event);
assertEquals('', flowWithoutNamespace.actionNamespace());
}
function testInstanceRegistry() {
var flow = new jsaction.ActionFlow('foo');
assertTrue(goog.array.contains(jsaction.ActionFlow.instances, flow));
flow.done(jsaction.Branch.MAIN);
assertFalse(goog.array.contains(jsaction.ActionFlow.instances, flow));
}