Show:
                            YUI.add('aui-menu-tests', function(Y) {
                            
                                var suite = new Y.Test.Suite('aui-menu');
                            
                                suite.add(new Y.Test.Case({
                                    name: 'Menu Tests',
                            
                                    _should: {
                                        // Ignore the following tests in mobile devices, as the features they
                                        // test don't exist in those.
                                        ignore: {
                                            'should trigger item selection via shortcuts': Y.UA.mobile
                                        }
                                    },
                            
                                    init: function() {
                                        this._originalViewportRegion = Y.DOM.viewportRegion;
                                    },
                            
                                    tearDown: function() {
                                        if (this._menu) {
                                            this._menu.destroy();
                                        }
                            
                                        Y.DOM.viewportRegion = this._originalViewportRegion;
                                    },
                            
                                    /**
                                     * Creates a Menu instance.
                                     *
                                     * @method _createMenu
                                     * @param {Object} Optional config params to override the default values.
                                     * @protected
                                     */
                                    _createMenu: function(config) {
                                        this._menu = new Y.Menu(Y.merge({
                                            items: [
                                                {
                                                    content: '<a>Menu Item 1</a>',
                                                    submenu: {
                                                        items: [
                                                            {
                                                                content: '<a>Menu Item 1.1</a>'
                                                            },
                                                            {
                                                                content: '<a>Menu Item 1.2</a>',
                                                                submenu: {
                                                                    items: [
                                                                        {
                                                                            content: '<a>Menu Item 1.2.1</a>'
                                                                        }
                                                                    ]
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    content: '<a>Menu Item 2</a>'
                                                },
                                                {
                                                    divider: true
                                                },
                                                {
                                                    content: '<a>Menu Item 3</a>',
                                                    disabled: true
                                                },
                                                {
                                                    content: '<a>Menu Item 4</a>',
                                                    submenu: {
                                                        items: [
                                                            {
                                                                content: '<a>Menu Item 4.1</a>'
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }, config)).render('#container');
                                    },
                            
                                    /**
                                     * Simulates a window resize event.
                                     *
                                     * @method _simulateResize
                                     * @param {Function} callback Function to be called when the simulation has finished.
                                     * @protected
                                     */
                                    _simulateResize: function(callback) {
                                        if (Y.UA.ie === 8) {
                                            // Can't simulate a resize on IE8's window object, so
                                            // calling the function directly here.
                                            this._menu._afterWindowResize();
                                        }
                                        else {
                                            Y.one(Y.config.win).simulate('resize');
                                        }
                            
                                        this.wait(function() {
                                            callback();
                                        }, Y.config.windowResizeDelay || 100);
                                    },
                            
                                    /**
                                     * Stubs the Y.DOM.viewportRegion function to return specific values.
                                     *
                                     * @method _stubViewportSize
                                     * @param {Boolean} small If the width of the viewport should be small.
                                     * @protected
                                     */
                                    _stubViewportSize: function(small) {
                                        Y.DOM.viewportRegion = function() {
                                            return {
                                                width: small ? 767 : 768
                                            };
                                        };
                                    },
                            
                                    'should render menu': function() {
                                        this._createMenu();
                            
                                        Y.Assert.areEqual(
                                            0,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The menu should not be rendered until it\'s open for the first time'
                                        );
                            
                                        this._menu.open();
                                        Y.Assert.areEqual(
                                            5,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The menu should have been rendered with its 4 menu items'
                                        );
                                    },
                            
                                    'should update items': function() {
                                        this._createMenu();
                            
                                        this._menu.set('items', [{}, {}]);
                                        Y.Assert.areEqual(
                                            2,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The menu should have been rendered with its new menu items'
                                        );
                                    },
                            
                                    'should convert items to MenuItem instances when needed': function() {
                                        var content = 'Test Content',
                                            item = new Y.MenuItem();
                            
                                        this._createMenu({
                                            items: [
                                                {
                                                    content: content
                                                },
                                                item
                                            ],
                                        });
                            
                                        Y.Assert.isTrue(
                                            Y.instanceOf(this._menu.get('items')[0], Y.MenuItem),
                                            'Items should match'
                                        );
                                        Y.Assert.areEqual(
                                            content,
                                            this._menu.get('items')[0].get('content'),
                                            'Items should match'
                                        );
                                        Y.Assert.areSame(
                                            item,
                                            this._menu.get('items')[1],
                                            'Items should match'
                                        );
                                    },
                            
                                    'should show subitems on hover when on overlay layout': function() {
                                        var instance = this,
                                            item,
                                            item2,
                                            item3,
                                            menuNode;
                            
                                        this._stubViewportSize(false);
                                        this._createMenu();
                                        this._menu.open();
                            
                                        item = this._menu.get('items')[0];
                                        item2 = this._menu.get('items')[1];
                                        item3 = this._menu.get('items')[4];
                                        menuNode = this._menu.get('boundingBox');
                            
                                        Y.Assert.isNull(
                                            menuNode.one('.menu-item-submenu'),
                                            'The submenu shouldn\'t have been rendered yet'
                                        );
                            
                                        item2.get('node').simulate('mouseover');
                                        Y.Assert.isNull(
                                            menuNode.one('.menu-item-submenu'),
                                            'The submenu shouldn\'t have been rendered yet'
                                        );
                            
                                        item.get('node').simulate('mouseover');
                            
                                        this.wait(function() {
                                            Y.Assert.isNotNull(
                                                menuNode.one('.menu-item-submenu'),
                                                'The submenu should have been rendered'
                                            );
                                            Y.Assert.isTrue(
                                                item.isSubmenuOpen(),
                                                'The submenu should have been opened'
                                            );
                            
                                            item3.get('node').simulate('mouseover');
                                            instance.wait(function() {
                                                Y.Assert.isFalse(
                                                    item.isSubmenuOpen(),
                                                    'The submenu should have been closed'
                                                );
                                                Y.Assert.isTrue(
                                                    item3.isSubmenuOpen(),
                                                    'The submenu should have been opened'
                                                );
                                            }, Y.Menu.HIDE_SUBMENU_DELAY);
                                        }, Y.Menu.HIDE_SUBMENU_DELAY);
                                    },
                            
                                    'should not hide submenu when quickly mousing out and back again': function() {
                                        var item,
                                            itemNode,
                                            itemNode2;
                            
                                        this._stubViewportSize(false);
                                        this._createMenu();
                                        this._menu.open();
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                                        itemNode2 = this._menu.get('items')[1].get('node');
                            
                                        itemNode.simulate('mouseover');
                                        itemNode2.simulate('mouseover');
                                        itemNode.simulate('mouseover');
                                        this.wait(function() {
                                            Y.Assert.isTrue(
                                                item.isSubmenuOpen(),
                                                'The submenu should not have been closed'
                                            );
                                        }, Y.Menu.HIDE_SUBMENU_DELAY);
                                    },
                            
                                    'should show subitems on click when on inline layout': function() {
                                        var item,
                                            itemNode,
                                            menuNode;
                            
                                        this._stubViewportSize(true);
                                        this._createMenu();
                                        this._menu.open();
                            
                                        menuNode = this._menu.get('boundingBox');
                            
                                        Y.Assert.isNull(
                                            menuNode.one('.menu-item-submenu'),
                                            'The submenu shouldn\'t have been rendered yet'
                                        );
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                            
                                        itemNode.simulate('mouseover');
                                        Y.Assert.isNull(
                                            menuNode.one('.menu-item-submenu'),
                                            'The submenu shouldn\'t have been opened on mouseover'
                                        );
                            
                                        itemNode.simulate('click');
                                        Y.Assert.isNotNull(
                                            menuNode.one('.menu-item-submenu'),
                                            'The submenu should have been rendered'
                                        );
                                        Y.Assert.isTrue(
                                            item.isSubmenuOpen(),
                                            'The submenu should have been opened'
                                        );
                            
                                        itemNode.simulate('mouseout');
                                        Y.Assert.isTrue(
                                            item.isSubmenuOpen(),
                                            'The submenu should not have been closed on mouseout'
                                        );
                            
                                        itemNode.simulate('click');
                                        Y.Assert.isFalse(
                                            item.isSubmenuOpen(),
                                            'The submenu should have been closed'
                                        );
                                    },
                            
                                    'should update layout mode on window resize': function() {
                                        var instance = this;
                            
                                        this._createMenu();
                            
                                        this._stubViewportSize(false);
                                        this._simulateResize(function() {
                                            Y.Assert.areEqual(
                                                'overlay',
                                                instance._menu.get('layoutMode'),
                                                'Layout should be overlay'
                                            );
                            
                                            instance._stubViewportSize(true);
                                            instance._simulateResize(function() {
                                                Y.Assert.areEqual(
                                                    'inline',
                                                    instance._menu.get('layoutMode'),
                                                    'Layout should be inline'
                                                );
                                            });
                                        });
                                    },
                            
                                    'should hide submenus when changing from inline to overlay layout mode': function() {
                                        var instance = this,
                                            item,
                                            itemNode;
                            
                                        instance._stubViewportSize(true);
                                        this._createMenu();
                                        this._menu.open();
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                                        itemNode.simulate('click');
                            
                                        Y.Assert.isTrue(
                                            item.isSubmenuOpen(),
                                            'The submenu should have closed when the layout became overlay'
                                        );
                            
                                        this._stubViewportSize(false);
                                        this._simulateResize(function() {
                                            Y.Assert.isFalse(
                                                item.isSubmenuOpen(),
                                                'The submenu should have closed when the layout became overlay'
                                            );
                                        });
                                    },
                            
                                    'should fire event when items are clicked': function() {
                                        var item,
                                            itemNode,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                                        this._menu.open();
                            
                                        item = this._menu.get('items')[1];
                                        itemNode = item.get('node');
                            
                                        mock.onItemSelected = function(event) {
                                            Y.Assert.areSame(
                                                item,
                                                event.item,
                                                'Items should match'
                                            );
                                        };
                                        Y.Mock.expect(mock, {
                                            callCount: 1,
                                            method: 'onItemSelected',
                                            args: [Y.Mock.Value.Object]
                                        });
                                        this._menu.on('itemSelected', mock.onItemSelected);
                            
                                        itemNode.simulate('click');
                                        Y.Mock.verify(mock);
                                    },
                            
                                    'should not fire event when items with submenus are clicked': function() {
                                        var item,
                                            itemNode,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                            
                                        Y.Mock.expect(mock, {
                                            callCount: 0,
                                            method: 'onItemSelected'
                                        });
                                        this._menu.on('itemSelected', mock.onItemSelected);
                            
                                        itemNode.simulate('click');
                                        Y.Mock.verify(mock);
                                    },
                            
                                    'should not fire event when divider items are clicked': function() {
                                        var item,
                                            itemNode,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                            
                                        item = this._menu.get('items')[2];
                                        itemNode = item.get('node');
                            
                                        Y.Mock.expect(mock, {
                                            callCount: 0,
                                            method: 'onItemSelected'
                                        });
                                        this._menu.on('itemSelected', mock.onItemSelected);
                            
                                        itemNode.simulate('click');
                                        Y.Mock.verify(mock);
                                    },
                            
                                    'should not fire event when disabled items are clicked': function() {
                                        var item,
                                            itemNode,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                            
                                        item = this._menu.get('items')[3];
                                        itemNode = item.get('node');
                            
                                        Y.Mock.expect(mock, {
                                            callCount: 0,
                                            method: 'onItemSelected'
                                        });
                                        this._menu.on('itemSelected', mock.onItemSelected);
                            
                                        itemNode.simulate('click');
                                        Y.Mock.verify(mock);
                                    },
                            
                                    'should hide open submenus when item is clicked on overlay mode': function() {
                                        var item,
                                            itemNode,
                                            submenuItem,
                                            submenuItemNode;
                            
                                        this._stubViewportSize(false);
                                        this._createMenu();
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                                        itemNode.simulate('mouseover');
                            
                                        submenuItem = item.get('submenu').get('items')[0];
                                        submenuItemNode = submenuItem.get('node');
                            
                                        submenuItemNode.simulate('click');
                                        Y.Assert.isFalse(
                                            item.isSubmenuOpen(),
                                            'The submenu should have been closed'
                                        );
                                    },
                            
                                    'should not hide open submenus when item is clicked on inline mode': function() {
                                        var item,
                                            itemNode,
                                            submenuItem,
                                            submenuItemNode;
                            
                                        this._stubViewportSize(true);
                                        this._createMenu();
                                        this._menu.open();
                            
                                        item = this._menu.get('items')[0];
                                        itemNode = item.get('node');
                                        itemNode.simulate('click');
                            
                                        submenuItem = item.get('submenu').get('items')[0];
                                        submenuItemNode = submenuItem.get('node');
                            
                                        submenuItemNode.simulate('click');
                                        Y.Assert.isTrue(
                                            item.isSubmenuOpen(),
                                            'The submenu should have not been closed'
                                        );
                                    },
                            
                                    'should create menu from existing markup': function() {
                                        this._menu = new Y.Menu({
                                            contentBox: '#menu'
                                        }).render();
                            
                                        Y.Assert.areEqual(
                                            2,
                                            this._menu.get('items').length,
                                            'Menu should have 2 items'
                                        );
                                    },
                            
                                    'should add items': function() {
                                        var content = 'New Item';
                            
                                        this._createMenu();
                                        this._menu.addItem({
                                            content: content
                                        });
                            
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('items').length,
                                            'The new item should have been added to the list'
                                        );
                                        Y.Assert.areEqual(
                                            content,
                                            this._menu.get('items')[5].get('content'),
                                            'The sixth item should have the given content'
                                        );
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The new item should have been rendered'
                                        );
                                    },
                            
                                    'should add items that are already MenuItem instances': function() {
                                        var content = 'New Item';
                            
                                        this._createMenu();
                                        this._menu.addItem(new Y.MenuItem({
                                            content: content
                                        }));
                            
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('items').length,
                                            'The new item should have been added to the list'
                                        );
                                        Y.Assert.areEqual(
                                            content,
                                            this._menu.get('items')[5].get('content'),
                                            'The sixth item should have the given content'
                                        );
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The new item should have been rendered'
                                        );
                                    },
                            
                                    'should add items at the requested position': function() {
                                        var content = 'New Item';
                            
                                        this._createMenu();
                                        this._menu.addItem({
                                            content: content
                                        }, 1);
                            
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('items').length,
                                            'The new item should have been added to the list'
                                        );
                                        Y.Assert.areEqual(
                                            content,
                                            this._menu.get('items')[1].get('content'),
                                            'The fifth item should have the given content'
                                        );
                                        Y.Assert.areEqual(
                                            6,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The new item should have been rendered'
                                        );
                                    },
                            
                                    'should remove items': function() {
                                        var item;
                            
                                        this._createMenu();
                                        item = this._menu.get('items')[1];
                                        this._menu.removeItem(item);
                            
                                        Y.Assert.areEqual(
                                            4,
                                            this._menu.get('items').length,
                                            'The requested item should have been removed from the list'
                                        );
                                        Y.Assert.areNotSame(
                                            item,
                                            this._menu.get('items')[1],
                                            'The requested item should have been removed from the list'
                                        );
                                        Y.Assert.areEqual(
                                            4,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The requested item should have been removed from the DOM'
                                        );
                                    },
                            
                                    'should remove items at the requested position': function() {
                                        var item;
                            
                                        this._createMenu();
                                        item = this._menu.get('items')[1];
                                        this._menu.removeItemAtIndex(1);
                            
                                        Y.Assert.areEqual(
                                            4,
                                            this._menu.get('items').length,
                                            'The requested item should have been removed from the list'
                                        );
                                        Y.Assert.areNotSame(
                                            item,
                                            this._menu.get('items')[1],
                                            'The requested item should have been removed from the list'
                                        );
                                        Y.Assert.areEqual(
                                            4,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'The requested item should have been removed from the DOM'
                                        );
                                    },
                            
                                    'should ignore requests to remove items at invalid positions': function() {
                                        this._createMenu();
                                        this._menu.open();
                            
                                        this._menu.removeItemAtIndex(-1);
                                        Y.Assert.areEqual(
                                            5,
                                            this._menu.get('items').length,
                                            'No items should have been removed from the list'
                                        );
                                        Y.Assert.areEqual(
                                            5,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'No items should have been removed from the DOM'
                                        );
                            
                                        this._menu.removeItemAtIndex(10);
                                        Y.Assert.areEqual(
                                            5,
                                            this._menu.get('items').length,
                                            'No items should have been removed from the list'
                                        );
                                        Y.Assert.areEqual(
                                            5,
                                            this._menu.get('boundingBox').all('.menu-item').size(),
                                            'No items should have been removed from the DOM'
                                        );
                                    },
                            
                                    'should trigger item selection via shortcuts': function() {
                                        var item,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                                        item = this._menu.get('items')[1];
                            
                                        mock.onItemSelected = function(event) {
                                            Y.Assert.areSame(
                                                item,
                                                event.item,
                                                'Items should match'
                                            );
                                        };
                                        Y.Mock.expect(mock, {
                                            callCount: 1,
                                            method: 'onItemSelected',
                                            args: [Y.Mock.Value.Object]
                                        });
                                        this._menu.once('itemSelected', mock.onItemSelected);
                            
                                        item.fire('shortcut');
                                        Y.Mock.verify(mock);
                                    },
                            
                                    'should trigger item selection via keypress': function() {
                                        var item,
                                            mock = new Y.Mock();
                            
                                        this._createMenu();
                                        this._menu.open();
                                        item = this._menu.get('items')[1];
                            
                                        mock.onItemSelected = function(event) {
                                            Y.Assert.areSame(
                                                item,
                                                event.item,
                                                'Items should match'
                                            );
                                        };
                                        Y.Mock.expect(mock, {
                                            callCount: 1,
                                            method: 'onItemSelected',
                                            args: [Y.Mock.Value.Object]
                                        });
                                        this._menu.once('itemSelected', mock.onItemSelected);
                            
                                        item.get('node').simulate('keypress', { keyCode: 13 });
                                        Y.Mock.verify(mock);
                                    }
                                }));
                            
                                Y.Test.Runner.add(suite);
                            
                            }, '', {
                                requires: ['node-event-simulate', 'test', 'aui-menu']
                            });