// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
//
//
///
///
///
module SplitViewTests {
"use strict";
var SplitViewPaneToggle = WinJS.UI.SplitViewPaneToggle;
var testRoot: HTMLElement;
var Utils = SplitViewTests.Utilities;
var createSplitView: (options?: any) => WinJS.UI.PrivateSplitView;
var createSplitViewPaneToggle: (element?: HTMLButtonElement, options?: any) => WinJS.UI.PrivateSplitViewPaneToggle;
function makeCreateSplitViewPaneToggle(testRoot) {
function createSplitViewPaneToggle(element?: HTMLButtonElement, options?: any): WinJS.UI.PrivateSplitViewPaneToggle {
var splitViewPaneToggle = new SplitViewPaneToggle(element, options);
testRoot.appendChild(splitViewPaneToggle.element);
return splitViewPaneToggle;
}
return createSplitViewPaneToggle;
}
function assertHasClass(element: HTMLElement, className: string, msg: string): void {
LiveUnit.Assert.isTrue(WinJS.Utilities.hasClass(element, className), msg);
}
// Taking the registration mechanism as a parameter allows us to use this code to test both
// DOM level 0 (e.g. oninvoked) and DOM level 2 (e.g. addEventListener) events.
function testEvents(registerForEvent: (splitViewPaneToggle: WinJS.UI.PrivateSplitViewPaneToggle, eventName: string, handler: Function) => void) {
var splitViewPaneToggle = createSplitViewPaneToggle();
var counter = 0;
registerForEvent(splitViewPaneToggle, "invoked", () => {
LiveUnit.Assert.areEqual(1, counter, "invoked fired out of order");
counter++;
});
LiveUnit.Assert.areEqual(0, counter, "before click: wrong number of events fired");
counter++;
splitViewPaneToggle._invoked();
LiveUnit.Assert.areEqual(2, counter, "after click: wrong number of events fired");
}
function testTogglingPaneState(args: {
firesInvokedEvent: boolean;
togglePaneState: (splitViewPaneToggle: WinJS.UI.PrivateSplitViewPaneToggle, splitView: WinJS.UI.PrivateSplitView) => void;
}) {
var invokedFired;
var onInvoked = () => {
invokedFired = true;
};
var verifyInvokedEvent = () => {
if (args.firesInvokedEvent) {
LiveUnit.Assert.isTrue(invokedFired, "SplitViewPaneToggle's invoked event should have fired");
} else {
LiveUnit.Assert.isFalse(invokedFired, "SplitViewPaneToggle's invoked event should not have fired");
}
};
var splitView = Utils.useSynchronousAnimations(createSplitView());
var splitViewPaneToggle = createSplitViewPaneToggle(null, {
splitView: splitView.element,
oninvoked: onInvoked
});
LiveUnit.Assert.isFalse(splitView.paneOpened, "Test expected SplitView to start out closed");
LiveUnit.Assert.areEqual("false", splitViewPaneToggle.element.getAttribute("aria-expanded"),
"Test expected SplitViewPaneToggle's aria-expanded attribute to start out 'false'");
invokedFired = false;
args.togglePaneState(splitViewPaneToggle, splitView);
verifyInvokedEvent();
LiveUnit.Assert.isTrue(splitView.paneOpened, "SplitView should have been opened by SplitViewPaneToggle");
LiveUnit.Assert.areEqual("true", splitViewPaneToggle.element.getAttribute("aria-expanded"),
"SplitViewPaneToggle's aria-expanded attribute should be 'true'");
invokedFired = false;
args.togglePaneState(splitViewPaneToggle, splitView);
verifyInvokedEvent();
LiveUnit.Assert.isFalse(splitView.paneOpened, "SplitView should have been closed by SplitViewPaneToggle");
LiveUnit.Assert.areEqual("false", splitViewPaneToggle.element.getAttribute("aria-expanded"),
"SplitViewPaneToggle's aria-expanded attribute should be 'false'");
}
export class SplitViewPaneToggleTests {
setUp() {
testRoot = document.createElement("div");
// Give it an id so that we can use it in styles to make sure our styles win over the defaults.
// We encourage apps to do the same.
testRoot.id = "test-root";
createSplitView = Utils.makeCreateSplitView(testRoot);
createSplitViewPaneToggle = makeCreateSplitViewPaneToggle(testRoot);
document.body.appendChild(testRoot);
}
tearDown() {
WinJS.Utilities.disposeSubTree(testRoot);
Helper.removeElement(testRoot);
}
testDomLevel0Events() {
testEvents((splitViewPaneToggle: WinJS.UI.PrivateSplitViewPaneToggle, eventName: string, handler: Function) => {
splitViewPaneToggle["on" + eventName] = handler;
});
}
testDomLevel2Events() {
testEvents((splitViewPaneToggle: WinJS.UI.PrivateSplitViewPaneToggle, eventName: string, handler: Function) => {
splitViewPaneToggle.addEventListener(eventName, handler);
});
}
// Verify that if we don't pass an element to the SplitViewPaneToggle's constructor, it creates
// one for us and initializes its DOM structure correctly.
testInitializationWithoutElement() {
var splitViewPaneToggle = createSplitViewPaneToggle();
LiveUnit.Assert.areEqual("BUTTON", splitViewPaneToggle.element.tagName, "SplitViewPaneToggle's element should be a button");
assertHasClass(splitViewPaneToggle.element, SplitViewPaneToggle._ClassNames.splitViewPaneToggle, "splitViewPaneToggle.element is missing class");
LiveUnit.Assert.isFalse(splitViewPaneToggle.element.hasAttribute("aria-controls"),
"SplitViewPaneToggle shouldn't have aria-controls attribute because it isn't paired with a SplitView");
LiveUnit.Assert.isFalse(splitViewPaneToggle.element.hasAttribute("aria-expanded"),
"SplitViewPaneToggle shouldn't have aria-expanded attribute because it isn't paired with a SplitView");
}
// Verify that if we pass an element containing markup to the SplitViewPaneToggle's constructor, it correctly
// initializes its DOM.
testInitializationWithElement() {
var element = document.createElement("button");
element.className = "myCustomClass";
var splitViewPaneToggle = createSplitViewPaneToggle(element);
LiveUnit.Assert.areEqual(element, splitViewPaneToggle.element, "SplitViewPaneToggle should have used the element that was passed to it");
LiveUnit.Assert.areEqual("BUTTON", element.tagName, "SplitViewPaneToggle's element should be a button");
assertHasClass(element, SplitViewPaneToggle._ClassNames.splitViewPaneToggle, "splitViewPaneToggle.element is missing class");
assertHasClass(element, "myCustomClass", "splitViewPaneToggle.element is missing class");
LiveUnit.Assert.isFalse(element.hasAttribute("aria-controls"),
"SplitViewPaneToggle shouldn't have aria-controls attribute because it isn't paired with a SplitView");
LiveUnit.Assert.isFalse(element.hasAttribute("aria-expanded"),
"SplitViewPaneToggle shouldn't have aria-expanded attribute because it isn't paired with a SplitView");
}
testInitializingProperties() {
var splitView = Utils.useSynchronousAnimations(createSplitView());
var splitViewPaneToggle = createSplitViewPaneToggle(null, {
splitView: splitView.element
});
LiveUnit.Assert.areEqual(splitView.element, splitViewPaneToggle.splitView, "splitView property has wrong value after initialization");
LiveUnit.Assert.areEqual(splitView.element.id, splitViewPaneToggle.element.getAttribute("aria-controls"),
"SplitViewPaneToggle has wrong value for aria-controls attribute");
LiveUnit.Assert.areEqual("false", splitViewPaneToggle.element.getAttribute("aria-expanded"),
"SplitViewPaneToggle's aria-expanded attribute should be 'false'");
}
testChangingProperties() {
var splitView = Utils.useSynchronousAnimations(createSplitView());
var splitViewPaneToggle = createSplitViewPaneToggle();
splitViewPaneToggle.splitView = splitView.element;
LiveUnit.Assert.areEqual(splitView.element, splitViewPaneToggle.splitView, "splitView property has wrong value after setting it");
LiveUnit.Assert.areEqual(splitView.element.id, splitViewPaneToggle.element.getAttribute("aria-controls"),
"SplitViewPaneToggle has wrong value for aria-controls attribute");
LiveUnit.Assert.areEqual("false", splitViewPaneToggle.element.getAttribute("aria-expanded"),
"SplitViewPaneToggle's aria-expanded attribute should be 'false'");
}
// Verify that the SplitViewPaneToggle correctly syncs with the SplitView when the
// SplitViewPaneToggle is created before the SplitView. This may happen during
// WinJS.UI.processAll because instantiation order depends on the order in which
// the controls appear in the DOM.
testInitializingSplitViewPaneToggleBeforeSplitView() {
[false, true].forEach((paneOpenedInitially) => {
var paneOpenedInitiallyStr = paneOpenedInitially ? "true" : "false";
var splitViewElement = document.createElement("div");
testRoot.appendChild(splitViewElement);
var splitViewPaneToggle = createSplitViewPaneToggle(null, {
splitView: splitViewElement
});
var splitView = Utils.useSynchronousAnimations(new SplitView(splitViewElement, {
paneOpened: paneOpenedInitially
}));
LiveUnit.Assert.areEqual(paneOpenedInitially, splitView.paneOpened, "SplitView paneOpened wasn't initialized correctly");
LiveUnit.Assert.areEqual(paneOpenedInitiallyStr, splitViewPaneToggle.element.getAttribute("aria-expanded"),
"SplitViewPaneToggle has wrong value for aria-expanded attribute");
LiveUnit.Assert.areEqual(splitView.element.id, splitViewPaneToggle.element.getAttribute("aria-controls"),
"SplitViewPaneToggle has wrong value for aria-controls attribute");
});
}
// Simulates invoking the button with mouse/touch/keyboard.
testTogglingPaneStateWithInvoke() {
testTogglingPaneState({
firesInvokedEvent: true,
togglePaneState: function (splitViewPaneToggle, splitView) {
splitViewPaneToggle._invoked();
}
});
}
testTogglingPaneStateWithAriaExpanded() {
testTogglingPaneState({
firesInvokedEvent: false,
togglePaneState: function (splitViewPaneToggle, splitView) {
var ariaExpanded = splitViewPaneToggle.element.getAttribute("aria-expanded") === "true";
splitViewPaneToggle.element.setAttribute("aria-expanded", ariaExpanded ? "false" : "true");
// Mutation observers notify asynchronously. Simulate synchronous notification
// so the test can be synchronous.
splitViewPaneToggle._onAriaExpandedPropertyChanged([{
type: "attributes",
target: splitViewPaneToggle.element,
attributeName: "aria-expanded"
}]);
}
});
}
testTogglingPaneStateWithSplitView() {
testTogglingPaneState({
firesInvokedEvent: false,
togglePaneState: function (splitViewPaneToggle, splitView) {
splitView.paneOpened = !splitView.paneOpened;
}
});
}
testDispose() {
function failEventHandler(eventName) {
return function () {
LiveUnit.Assert.fail(eventName + ": shouldn't have run due to control being disposed");
};
}
var splitView = Utils.useSynchronousAnimations(createSplitView());
var splitViewPaneToggle = createSplitViewPaneToggle(null, {
splitView: splitView.element,
oninvoked: failEventHandler("invoked")
});
LiveUnit.Assert.isFalse(splitView.paneOpened, "Test expected SplitView to start out closed");
splitViewPaneToggle.dispose();
LiveUnit.Assert.isTrue(splitViewPaneToggle._disposed, "SplitViewPaneToggle didn't mark itself as disposed");
splitViewPaneToggle._invoked();
LiveUnit.Assert.isFalse(splitView.paneOpened, "SplitView should still be closed");
splitViewPaneToggle.dispose();
}
}
}
LiveUnit.registerTestClass("SplitViewTests.SplitViewPaneToggleTests");