Files
ionic-framework/test/unit/angular/service/history.unit.js
Adam Bradley 39951ca99a refactor(): navigation improvements, Angular 1.3
#### Refactor:

* **Navigation:** Refactored navigation for improved performance,
reduce DOM manipulations, increase transition FPS, cached views,
smoother transitions, platform specific transitions with added
configurable controls for transition animation and direction.
* **Cached Views:** Previously as a user navigated an app, each leaving
view’s element and scope would be destroyed. If the same view was
accessed again then the app would have to recreate the element. Views
can now be cached to improve performance. When a view is navigated away
from, its element is left in the DOM, and its scope is disconnected
from the cycle. When navigating to a view which is already cached, its
scope is reconnected, and the existing element which was left in the
DOM becomes the active view. This also allows for scroll position of
previous views to be maintained (without skippy jumps). Config
variables can be used to disable view caching (set to 0), or change the
maximum number of views to cache.
* **Angular v1.3:** Upgraded Ionic’s to work with Angular v1.3. In
general Ionic just works with the upgrade, but the required change was
that animations in v1.3 uses promise, whereas in v1.2 animations used
callbacks.

#### Features:

* **Platform Specific Transitions:** Transitions between views now
default to the transition style appropriate for each platform. For
example, iOS will move forward by transitioning the entering view from
right to center, and the leaving view from center to left. However,
Android will transition with the entering view going from bottom to
center, covering the previous view, which remains stationary. Platform
transitions are automatically applied by default, but config variables
and custom CSS allows these defaults to be easily overridden.
* **Override Transition Type and Direction:** As a user navigates the
app, Ionic automatically applies the appropriate transition type for
the platform, and the direction the user is navigating. However, both
can be overridden in numerous ways: config variable, view attribute,
stateProvider property, or attribute on the button/link that initiated
the transition.
* **enable-menu-with-back-views:** The `enable-menu-with-back-views`
attribute determines if the side menu is enabled when the back button
is showing. When set to `false`, any buttons/links with the
`menuToggle` directive will be hidden, and the user cannot swipe to
open the menu. When going back to the root page of the side menu (the
page without a back button visible), then any menuToggle buttons will
show again, and menus will be enabled again.
* **menuClose:** Closes a side menu which is currently opened.
Additionally, the menuClose directive will now cause transitions to not
animate between views while the menu is being closed.
* **ionNavBackButton:** The back button icon and text will
automatically update to platform config defaults, such as adjusting to
the platform back icon. To take advantage of this, the
`ionNavBackButton` directive now should be empty, such as
`<ion-nav-back-button></ion-nav-back-button>`. The back button can
still be fully customized like it could before, but without any inner
content it knows to style using platform configs.
* **navBar button primary/secondary sides:** Primary and secondary
sides are now the recommended values for the `side` attribute, such as
`<ion-nav-buttons side="primary">`. Primary buttons generally map to
the left side of the header, and secondary buttons are generally on the
right side. However, their exact locations are platform specific. For
example, in iOS the primary buttons are on the far left of the header,
and secondary buttons are on the far right, with the header title
centered between them. For Android however, both groups of buttons are
on the far right of the header, with the header title aligned left.
Recommendation is to always use `primary` and `secondary` so buttons
correctly map to the side familiar to users of a platform. However, in
cases where buttons should always be on an exact side, both `left` and
`right` sides are still available.
* **navDirection:** An attribute directive that sets the direction
which the nav view transition should animate.
* **navTransition:** An attribute directive that sets the transition
type which the nav view transition should use when it animates. Using
`none` will disable an animation.

#### Breaking Changes:

* **Animation CSS:** The CSS for view transitions have changed. This is
a breaking change only if Ionic apps had customized Ionic’s animation
CSS.
* **$ionicPlatformDefaults:** Platform config variables are no longer
in the $ionicPlatformDefaults constant, but within `$ionicConfig`.
* **$ionicViewService:** In the navigation refactoring,
$ionicViewService was split up into two factories, `$ionicViewSwitcher`
and `$ionicHistory`. The `$ionicHistory` is largely what
`$ionicViewService`, but between the two factories there is a better
separation of concerns for improved testing.
* **navClear:** The navClear directive was created to do what the new
side menu `enable-menu-with-back-views` attribute accomplishes.
Additionally, the new `navTransition` and `navDirection` directives are
more useful and granular than the navClear directive.
* **scrollView.rememberScrollPosition:** This method has been removed
since it is no longer needed with cached views.

#### Deprecated:

* **ionView.title:** The `ionView` directive used the `title`
attribute, but this can cause the tooltip to show up on desktop
browsers. The `title` attribute will still work for backwards
compatibility, but we now recommend using `view-title`, such as
`<ion-view view-title=”My Title”>`.
* **ionNavView animation attribute removed:** The animation attribute
is no longer used for nav views. Instead use `$ionicConfig`.
* **ionNavBar animation attribute removed:** The animation attribute is
no longer used for nav bars. Instead use `$ionicConfig`.
2014-11-11 14:43:10 -06:00

1072 lines
45 KiB
JavaScript

describe('Ionic History', function() {
var ionicHistory, rootScope, stateProvider, window;
beforeEach(module('ionic', function ($stateProvider, $provide) {
stateProvider = $stateProvider;
$stateProvider
.state('home', { url: "/" })
.state('home.item', { url: "front/:id" })
.state('about', { url: "/about" })
.state('about.person', { url: "/person" })
.state('about.person.item', { url: "/id" })
.state('about.sidebar', {})
.state('about.sidebar.item', {})
.state('contact', { url: "/contact" })
.state('info', { url: "/info" })
.state('tabs', { abstract: true })
.state('tabs.tab1view1', {})
.state('tabs.tab1view2', {})
.state('tabs.tab1view3', {})
.state('tabs.tab2view1', {})
.state('tabs.tab2view2', {})
.state('tabs.tab2view3', {})
.state('tabs.tab3view1', {})
.state('tabs.tab3view2', {})
.state('tabs.tab3view3', {});
}));
beforeEach(inject(function($ionicHistory, $rootScope, $window) {
ionicHistory = $ionicHistory;
rootScope = $rootScope;
window = $window;
window.history.go = function(val) { return val; };
}));
it('should create a new view', inject(function($location, $state) {
$location.url('/home');
var view1Scope = {};
var rsp = ionicHistory.register(view1Scope, false);
expect(rsp.action).toEqual('initialView');
expect(rsp.historyId).toEqual('root');
var currentView = ionicHistory.currentView();
expect(currentView.viewId).toBeDefined();
expect(currentView.index).toEqual(0);
expect(currentView.historyId).toBeDefined();
expect(currentView.backViewId).toEqual(null);
expect(currentView.forwardViewId).toEqual(null);
expect(currentView.url).toEqual('/home');
var hist = ionicHistory.viewHistory().histories.root;
expect(hist.cursor).toEqual(0);
expect(hist.stack.length).toEqual(1);
}));
it('should register two sequential views', inject(function($state) {
$state.go('home');
rootScope.$apply();
expect(ionicHistory.currentStateName()).toEqual('home');
var view1Scope = {};
var rsp = ionicHistory.register(view1Scope, false);
expect(ionicHistory.viewHistory().currentView.stateName).toEqual('home');
expect(rsp.viewId).not.toBeUndefined();
expect(ionicHistory.viewHistory().views[rsp.viewId].viewId).toEqual(rsp.viewId);
expect(ionicHistory.backView()).toEqual(null);
expect(ionicHistory.forwardView()).toEqual(null);
expect(ionicHistory.viewHistory().currentView.stateName).toEqual('home');
var currentView = ionicHistory.currentView();
expect(currentView.index).toEqual(0);
$state.go('about');
rootScope.$apply();
expect(ionicHistory.currentStateName()).toEqual('about');
rsp = ionicHistory.register({}, false);
expect(rsp.action).toEqual('newView');
expect(ionicHistory.currentView().stateName).toEqual('about');
expect(ionicHistory.backView().stateName).toEqual('home');
expect(ionicHistory.forwardView()).toEqual(null);
var hist = ionicHistory.viewHistory().histories.root;
expect(hist.cursor).toEqual(1);
expect(hist.stack.length).toEqual(2);
}));
it('should register views and go back to start', inject(function($state) {
$state.go('home');
rootScope.$apply();
var registerData = ionicHistory.register({}, false);
expect(ionicHistory.currentView().stateName).toEqual('home');
expect(ionicHistory.backView()).toEqual(null);
expect(ionicHistory.forwardView()).toEqual(null);
expect(registerData.direction).toEqual('none');
expect(registerData.action).toEqual('initialView');
var currentView = ionicHistory.currentView();
$state.go('about');
rootScope.$apply();
registerData = ionicHistory.register({}, false);
currentView = ionicHistory.currentView();
var backView = ionicHistory.backView();
var forwardView = ionicHistory.forwardView();
expect(currentView.stateName).toEqual('about');
expect(currentView.backViewId).toEqual(backView.viewId);
expect(backView.stateName).toEqual('home');
expect(forwardView).toEqual(null);
expect(registerData.direction).toEqual('forward');
expect(registerData.action).toEqual('newView');
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
$state.go('contact');
rootScope.$apply();
registerData = ionicHistory.register({}, false);
currentView = ionicHistory.currentView();
//Set test value for remembered scroll
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(backView.stateName).toEqual('about');
expect(currentView.backViewId).toEqual(backView.viewId);
expect(ionicHistory.forwardView()).toEqual(null);
expect(registerData.direction).toEqual('forward');
expect(registerData.action).toEqual('newView');
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(2);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(3);
$state.go('about');
rootScope.$apply();
registerData = ionicHistory.register({}, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.backViewId).toEqual(backView.viewId);
expect(currentView.forwardViewId).toEqual(forwardView.viewId);
expect(backView.stateName).toEqual('home');
expect(forwardView.stateName).toEqual('contact');
expect(registerData.direction).toEqual('back');
expect(registerData.action).toEqual('moveBack');
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(3);
$state.go('home');
rootScope.$apply();
registerData = ionicHistory.register({}, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.stateName).toEqual('home');
expect(currentView.forwardViewId).toEqual(forwardView.viewId);
expect(backView).toEqual(null);
expect(forwardView.stateName).toEqual('about');
expect(registerData.direction).toEqual('back');
expect(registerData.action).toEqual('moveBack');
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(3);
}));
it('should register four views, and not go back to the first', inject(function($state) {
var homeViewScope = {};
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('initialView');
expect(ionicHistory.currentStateName()).toEqual('home');
expect(ionicHistory.currentView().stateName).toEqual('home');
expect(ionicHistory.backView()).toEqual(null);
expect(ionicHistory.forwardView()).toEqual(null);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(1);
var aboutViewScope = {};
$state.go('about');
rootScope.$apply();
var aboutReg = ionicHistory.register(aboutViewScope, false);
var currentView = ionicHistory.currentView();
var backView = ionicHistory.backView();
var forwardView = ionicHistory.forwardView();
expect(aboutReg.action).toEqual('newView');
expect(currentView.viewId).toEqual(aboutReg.viewId);
expect(currentView.backViewId).toEqual(homeReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.viewId).toEqual(homeReg.viewId);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
var tab1Scope = {};
ionicHistory.registerHistory(tab1Scope);
var tab1view1Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1view1Scope, false);
expect(tab1view1Reg.action).toEqual('newView');
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].historyId).toEqual(tab1Scope.$historyId);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack[0].viewId).toEqual(tab1view1Reg.viewId);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.viewId).toEqual(tab1view1Reg.viewId);
expect(currentView.historyId).toEqual(tab1Scope.$historyId);
expect(currentView.historyId).toEqual(tab1view1Reg.historyId);
expect(currentView.backViewId).toEqual(aboutReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.viewId).toEqual(aboutReg.viewId);
expect(backView.forwardViewId).toEqual(currentView.viewId);
$state.go('home');
rootScope.$apply();
var home2reg = ionicHistory.register({}, false);
expect(home2reg.action).toEqual('newView');
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.backViewId).toEqual(tab1view1Reg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.viewId).toEqual(tab1view1Reg.viewId);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(2);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(3);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(1);
}));
it('should register views in the same history, go back, then overwrite the forward views', inject(function($state) {
var homeViewScope = {};
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(homeViewScope, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.viewId).toEqual(homeReg.viewId);
expect(currentView.backViewId).toEqual(null);
expect(currentView.forwardViewId).toEqual(null);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(1);
expect(homeReg.action).toEqual('initialView');
expect(homeReg.direction).toEqual('none');
var aboutScope = {};
$state.go('about');
rootScope.$apply();
var aboutReg = ionicHistory.register(aboutScope, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.viewId).toEqual(aboutReg.viewId);
expect(currentView.backViewId).toEqual(homeReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.viewId).toEqual(homeReg.viewId);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
expect(aboutReg.action).toEqual('newView');
expect(aboutReg.direction).toEqual('forward');
homeViewScope = {};
$state.go('home');
rootScope.$apply();
var homeReg2 = ionicHistory.register(homeViewScope, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.viewId).toEqual(homeReg.viewId);
expect(currentView.backViewId).toEqual(null);
expect(currentView.forwardViewId).toEqual(aboutReg.viewId);
expect(forwardView.viewId).toEqual(aboutReg.viewId);
expect(forwardView.backViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
expect(homeReg2.action).toEqual('moveBack');
expect(homeReg2.direction).toEqual('back');
// this should overwrite that we went to the "about" view
contactScope = {};
$state.go('contact');
rootScope.$apply();
var contactReg = ionicHistory.register(contactScope, false);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.backViewId).toEqual(homeReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(forwardView).toEqual(null);
expect(backView.viewId).toEqual(homeReg.viewId);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(2);
expect(contactReg.action).toEqual('newView');
expect(contactReg.direction).toEqual('forward');
}));
it('should start at root, go in to tabs, come out to root, go in to tabs, come out, and history should be at the root', inject(function($state) {
var rootViewContainer = {};
$state.go('home');
rootScope.$apply();
var registerData = ionicHistory.register(rootViewContainer, false);
expect(registerData.action).toEqual('initialView');
expect(registerData.direction).toEqual('none');
expect(registerData.historyId).toEqual('root');
// register the tabs container
var tabsContainer = { $parent: tabsContainer };
ionicHistory.registerHistory(tabsContainer);
var tabsHistoryId = tabsContainer.$historyId;
// put a view inside of the tabs container
var tabView1 = { $parent: tabsContainer };
// nav to the tab view
$state.go('tabs.tab1view1');
rootScope.$apply();
registerData = ionicHistory.register(tabView1, false);
var currentView = ionicHistory.currentView();
expect(registerData.action).toEqual('newView');
expect(registerData.direction).toEqual('enter');
expect(currentView.historyId).toEqual(tabsHistoryId);
// nav back to the root
$state.go('home');
rootScope.$apply();
registerData = ionicHistory.register(rootViewContainer, false);
currentView = ionicHistory.currentView();
expect(registerData.action).toEqual('moveBack');
expect(registerData.direction).toEqual('exit');
expect(currentView.historyId).toEqual('root');
// nav back to the tabs
$state.go('tabs.tab1view1');
rootScope.$apply();
registerData = ionicHistory.register(tabView1, false);
currentView = ionicHistory.currentView();
expect(registerData.action).toEqual('moveForward');
expect(registerData.direction).toEqual('enter');
expect(currentView.historyId).toEqual(tabsHistoryId);
// nav back to the root
$state.go('home');
rootScope.$apply();
registerData = ionicHistory.register(rootViewContainer, false);
currentView = ionicHistory.currentView();
expect(registerData.action).toEqual('moveBack');
expect(registerData.direction).toEqual('exit');
expect(currentView.historyId).toEqual('root');
}));
it('should go to a new history, come back out, go to same history and come back out', inject(function($state) {
var rootViewContainer = {};
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(rootViewContainer, false);
var currentView = ionicHistory.currentView();
expect(currentView.historyId).toEqual('root');
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(homeReg.action).toEqual('initialView');
expect(homeReg.historyId).toEqual('root');
// each tab gets its own history in the tabs directive
// create a new tab and its history
var tabs1Container = { $parent: rootViewContainer };
ionicHistory.registerHistory(tabs1Container);
expect(tabs1Container.$historyId).toBeDefined();
expect(rootViewContainer.$historyId).not.toEqual(tabs1Container.$historyId);
var originalTab1ViewId = tabs1Container.$historyId;
// the actual view within the tab renders
// nav to tab1 which has its own history
var tab1View = { $parent: tabs1Container };
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1View, false);
currentView = ionicHistory.currentView();
expect(currentView.historyId).toEqual(tabs1Container.$historyId);
expect(ionicHistory.viewHistory().histories[tabs1Container.$historyId].parentHistoryId).toEqual('root');
expect(ionicHistory.viewHistory().histories[tabs1Container.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tabs1Container.$historyId].stack.length).toEqual(1);
expect(tab1view1Reg.historyId).not.toEqual(homeReg.historyId);
expect(tab1view1Reg.action).toEqual('newView');
expect(tab1view1Reg.direction).toEqual('enter');
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.stateName).toEqual('tabs.tab1view1');
expect(currentView.viewId).toEqual(tab1view1Reg.viewId);
expect(currentView.backViewId).toEqual(homeReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.stateName).toEqual('home');
expect(backView.backViewId).toEqual(null);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(forwardView).toEqual(null);
// nav back to the home in the root history
homeViewScope = {};
$state.go('home');
rootScope.$apply();
homeReg = ionicHistory.register(homeViewScope, false);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(1);
expect(homeReg.historyId).toEqual('root');
expect(homeReg.action).toEqual('moveBack');
expect(homeReg.direction).toEqual('exit');
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.stateName).toEqual('home');
expect(currentView.backViewId).toEqual(null);
expect(currentView.forwardViewId).toEqual(tab1view1Reg.viewId);
expect(forwardView.stateName).toEqual('tabs.tab1view1');
expect(forwardView.viewId).toEqual(tab1view1Reg.viewId);
expect(forwardView.backViewId).toEqual(currentView.viewId);
expect(forwardView.forwardViewId).toEqual(null);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories.root.stack.length).toEqual(1);
// create a new tab and its history
tabs1Container = { $parent: rootViewContainer };
ionicHistory.registerHistory(tabs1Container);
expect(originalTab1ViewId).not.toEqual(tabs1Container.$historyId);
tab1View = { $parent: tabs1Container };
$state.go('tabs.tab1view1');
rootScope.$apply();
tab1view1Reg = ionicHistory.register(tab1View);
expect(tab1view1Reg.action).toEqual('moveForward');
expect(tab1view1Reg.direction).toEqual('enter');
expect(tab1view1Reg.historyId).toEqual(originalTab1ViewId);
expect(originalTab1ViewId).toEqual(tabs1Container.$historyId);
expect(tab1view1Reg.historyId).not.toEqual('root');
expect(ionicHistory.viewHistory().histories[tab1view1Reg.historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1view1Reg.historyId].stack.length).toEqual(1);
currentView = ionicHistory.currentView();
expect(currentView.historyId).toEqual(tabs1Container.$historyId);
expect(ionicHistory.viewHistory().histories[tabs1Container.$historyId].cursor).toEqual(0);
currentView = ionicHistory.currentView();
backView = ionicHistory.backView();
forwardView = ionicHistory.forwardView();
expect(currentView.stateName).toEqual('tabs.tab1view1');
expect(currentView.viewId).toEqual(tab1view1Reg.viewId);
expect(currentView.backViewId).toEqual(homeReg.viewId);
expect(currentView.forwardViewId).toEqual(null);
expect(backView.viewId).toEqual(homeReg.viewId);
expect(backView.stateName).toEqual('home');
expect(backView.backViewId).toEqual(null);
expect(backView.forwardViewId).toEqual(currentView.viewId);
expect(forwardView).toEqual(null);
expect(ionicHistory.viewHistory().histories.root.cursor).toEqual(0);
}));
it('should nav to a history, move around in it, and come back', inject(function($state) {
// go to the first page
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register({}, false);
// each tab gets its own history in the tabs directive
var tab1Scope = { };
var tab2Scope = { };
var tab3Scope = { };
ionicHistory.registerHistory(tab1Scope);
ionicHistory.registerHistory(tab2Scope);
ionicHistory.registerHistory(tab3Scope);
// the actual view renders
var tab1view1Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1ScopeReg = ionicHistory.register(tab1view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
expect(ionicHistory.backView().stateName).toEqual('home');
expect(ionicHistory.forwardView()).toEqual(null);
var lastView = ionicHistory.currentView();
expect(lastView.index).toEqual(0);
expect(tab1view1ScopeReg.viewId).toEqual(lastView.viewId);
expect(tab1view1ScopeReg.action).toEqual('newView');
expect(tab1view1ScopeReg.direction).toEqual('enter');
expect(ionicHistory.viewHistory().histories[tab1view1ScopeReg.historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1view1ScopeReg.historyId].stack.length).toEqual(1);
// inside first tab, go to another list inside the same tab
var tab1view2Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view2');
rootScope.$apply();
var tab1view2ScopeReg = ionicHistory.register(tab1view2Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view2');
expect(ionicHistory.backView().stateName).toEqual('tabs.tab1view1');
expect(ionicHistory.forwardView()).toEqual(null);
lastView = ionicHistory.currentView();
expect(lastView.index).toEqual(1);
expect(tab1view2ScopeReg.viewId).toEqual(lastView.viewId);
expect(tab1view2ScopeReg.action).toEqual('newView');
expect(tab1view2ScopeReg.direction).toEqual('forward');
expect(ionicHistory.viewHistory().histories[tab1view2ScopeReg.historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab1view2ScopeReg.historyId].stack.length).toEqual(2);
// go back one within the tab
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Scope2Reg = ionicHistory.register(tab1view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
expect(ionicHistory.backView().stateName).toEqual('home');
expect(ionicHistory.forwardView().stateName).toEqual('tabs.tab1view2');
lastView = ionicHistory.currentView();
expect(lastView.index).toEqual(0);
expect(tab1view1Scope2Reg.action).toEqual('moveBack');
expect(tab1view1Scope2Reg.direction).toEqual('back');
expect(ionicHistory.viewHistory().histories[tab1view1Scope2Reg.historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1view1Scope2Reg.historyId].stack.length).toEqual(2);
// go back again, and should break out of the tab's history
$state.go('home');
rootScope.$apply();
var homeReg2 = ionicHistory.register({}, false);
expect(ionicHistory.currentStateName()).toEqual('home');
expect(homeReg2.historyId).toEqual('root');
expect(homeReg2.action).toEqual('moveBack');
expect(homeReg2.direction).toEqual('exit');
expect(ionicHistory.viewHistory().histories[homeReg2.historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[homeReg2.historyId].stack.length).toEqual(1);
$state.go('about');
rootScope.$apply();
var aboutReg = ionicHistory.register({}, false);
expect(ionicHistory.currentStateName()).toEqual('about');
expect(aboutReg.historyId).toEqual('root');
expect(aboutReg.action).toEqual('newView');
expect(aboutReg.direction).toEqual('forward');
expect(ionicHistory.viewHistory().histories[aboutReg.historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[aboutReg.historyId].stack.length).toEqual(2);
}));
it('should init a view that has tabs in it, two registers, but one page load', inject(function($state) {
$state.go('tabs.tab1view1');
rootScope.$apply();
var rootViewScope = {};
var rootReg = ionicHistory.register(rootViewScope, false);
expect(rootReg.action).toEqual('initialView');
expect(rootReg.direction).toEqual('none');
var tab1Scope = {};
ionicHistory.registerHistory(tab1Scope);
var tab1view1Scope = { $parent: tab1Scope };
var registerData = ionicHistory.register(tab1view1Scope, false);
expect(registerData.action).toEqual('newView');
expect(registerData.direction).toEqual('none');
}));
it('should change to history that already exists, and go to its last current view', inject(function($state) {
// register tabs
var tab1Scope = {};
var tab2Scope = {};
ionicHistory.registerHistory(tab1Scope);
ionicHistory.registerHistory(tab2Scope);
var orgTab1HistoryId = tab1Scope.$historyId;
// render first view in tab1
var tab1view1Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view1');
rootScope.$apply();
var registerData = ionicHistory.register(tab1view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(1);
expect(registerData.action).toEqual('initialView');
expect(registerData.direction).toEqual('none');
// render second view in tab1
var tab1view2Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view2');
rootScope.$apply();
registerData = ionicHistory.register(tab1view2Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view2');
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(2);
expect(registerData.action).toEqual('newView');
expect(registerData.direction).toEqual('forward');
currentView = ionicHistory.currentView();
expect(currentView.viewId).toEqual(registerData.viewId);
// go back to the first view again in tab 1
tab1view1Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view1');
rootScope.$apply();
registerData = ionicHistory.register(tab1view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
currentView = ionicHistory.currentView();
expect(currentView.viewId).toEqual(registerData.viewId);
forwardView = ionicHistory.forwardView();
expect(currentView.forwardViewId).toEqual(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack[1].viewId);
expect(forwardView.backViewId).toEqual(currentView.viewId);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(2);
expect(registerData.action).toEqual('moveBack');
expect(registerData.direction).toEqual('back');
// render first view in tab2
var tab2view1Scope = { $parent: tab2Scope };
$state.go('tabs.tab2view1');
rootScope.$apply();
registerData = ionicHistory.register(tab2view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab2view1');
expect(ionicHistory.viewHistory().histories[tab2Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab2Scope.$historyId].stack.length).toEqual(1);
expect(registerData.action).toEqual('newView');
expect(registerData.direction).toEqual('swap');
var tab2view1ViewId = registerData.viewId;
// tab1's forward history should be destroyed
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack[0].forwardViewId).toEqual(registerData.viewId);
// go back to tab1, and it should load the first view of tab1
expect(tab1Scope.$historyId).toEqual(orgTab1HistoryId);
rootScope.$broadcast("$ionicHistory.change", { historyId: tab1Scope.$historyId, enableUrlChange: false });
rootScope.$apply();
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view1');
registerData = ionicHistory.register(tab1view1Scope, false);
var tab1view1ViewId = registerData.viewId;
expect(registerData.action).toEqual('moveBack');
expect(registerData.direction).toEqual('swap');
currentView = ionicHistory.currentView();
expect(currentView.viewId).toEqual(registerData.viewId);
expect(currentView.historyId).toEqual(orgTab1HistoryId);
expect(currentView.forwardViewId).toEqual(tab2view1ViewId);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(0);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(1);
currentView = ionicHistory.currentView();
expect(currentView.stateName).toEqual('tabs.tab1view1');
expect(currentView.historyId).toEqual(tab1Scope.$historyId);
// go to view 2 in tab 1
tab1view2Scope = { $parent: tab1Scope };
$state.go('tabs.tab1view2');
rootScope.$apply();
registerData = ionicHistory.register(tab1view2Scope, false);
expect(registerData.historyId).toEqual(orgTab1HistoryId);
var tab1view2ViewId = registerData.viewId;
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view2');
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].stack.length).toEqual(2);
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(1);
expect(registerData.action).toEqual('newView');
expect(registerData.direction).toEqual('forward');
expect(ionicHistory.viewHistory().views[tab1view2ViewId].backViewId).toEqual(tab1view1ViewId);
// go to view 1 in tab 2
tab2view1Scope = { $parent: tab2Scope };
$state.go('tabs.tab2view1');
rootScope.$apply();
registerData = ionicHistory.register(tab2view1Scope, false);
expect(ionicHistory.currentStateName()).toEqual('tabs.tab2view1');
expect(ionicHistory.viewHistory().histories[tab2Scope.$historyId].cursor).toEqual(0);
expect(registerData.action).toEqual('moveBack');
expect(registerData.direction).toEqual('swap');
currentView = ionicHistory.currentView();
expect(currentView.backViewId).toEqual(tab1view2ViewId);
expect(currentView.forwardViewId).toEqual(null);
// should be remembered at the tab 1 view 2
rootScope.$broadcast("$ionicHistory.change", { historyId: tab1Scope.$historyId });
rootScope.$apply();
expect(ionicHistory.currentStateName()).toEqual('tabs.tab1view2');
expect(ionicHistory.viewHistory().histories[tab1Scope.$historyId].cursor).toEqual(1);
}));
it('should go one level in tab1, vist tab2 and tab3, come back to tab1 and still be at spot', inject(function($state) {
var tab1Container = {};
var tab2Container = {};
var tab3Container = {};
ionicHistory.registerHistory(tab1Container);
ionicHistory.registerHistory(tab2Container);
ionicHistory.registerHistory(tab3Container);
// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(0);
// register tab1, view2
$state.go('tabs.tab1view2');
rootScope.$apply();
var tab1view2Reg = ionicHistory.register(tab1Container, false);
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(1);
currentView = ionicHistory.currentView();
expect(currentView.backViewId).toEqual(tab1view1Reg.viewId);
// register tab2, view1
$state.go('tabs.tab2view1');
rootScope.$apply();
var tab2view1Reg = ionicHistory.register(tab2Container, false);
// register tab3, view1
$state.go('tabs.tab3view1');
rootScope.$apply();
var tab3view1Reg = ionicHistory.register(tab3Container, false);
// register tab 1, view 2 again
$state.go('tabs.tab1view2');
rootScope.$apply();
var tab1view2Reg2 = ionicHistory.register(tab1Container, false);
expect(tab1view2Reg2.action).toEqual('moveBack');
expect(tab1view2Reg2.viewId).toEqual(tab1view2Reg.viewId);
var currentViewId = tab1view2Reg.viewId;
expect(ionicHistory.viewHistory().histories[tab1view2Reg.historyId].stack.length).toEqual(2);
backView = ionicHistory.backView();
expect(backView).toBeDefined();
expect( Object.keys(ionicHistory.viewHistory().views).length ).toEqual(4);
ionicHistory.clearHistory();
expect( Object.keys(ionicHistory.viewHistory().views).length ).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab1view2Reg.historyId].stack.length).toEqual(1);
backView = ionicHistory.backView();
expect(backView).toEqual(null);
currentView = ionicHistory.currentView();
expect(currentView.viewId).toEqual(currentViewId);
}));
it('should go one level in tab1, visit tab2, go to tab2 page2, visit, tab1, tab3, history still page 2 tab2', inject(function($state) {
var tab1Container = {};
var tab2Container = {};
var tab3Container = {};
ionicHistory.registerHistory(tab1Container);
ionicHistory.registerHistory(tab2Container);
ionicHistory.registerHistory(tab3Container);
// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('initialView');
expect(tab1view1Reg.direction).toEqual('none');
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].cursor).toEqual(0);
// register tab2, view1
$state.go('tabs.tab2view1');
rootScope.$apply();
var tab2view1Reg = ionicHistory.register(tab2Container, false);
expect(tab2view1Reg.action).toEqual('newView');
expect(tab2view1Reg.direction).toEqual('swap');
expect(ionicHistory.viewHistory().histories[tab1Container.$historyId].stack[0].forwardViewId).toEqual(tab2view1Reg.viewId);
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(0);
// register tab2, view2
$state.go('tabs.tab2view2');
rootScope.$apply();
var tab2view2Reg = ionicHistory.register(tab2Container, false);
expect(tab2view2Reg.action).toEqual('newView');
expect(tab2view2Reg.direction).toEqual('forward');
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].stack.length).toEqual(2);
// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('moveBack');
expect(tab1view1Reg.direction).toEqual('swap');
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].stack.length).toEqual(2);
// register tab3, view1
$state.go('tabs.tab3view1');
rootScope.$apply();
var tab3view1Reg = ionicHistory.register(tab3Container, false);
expect(tab3view1Reg.action).toEqual('newView');
expect(tab3view1Reg.direction).toEqual('swap');
var tab2Hist = ionicHistory.viewHistory().histories[ tab2Container.$historyId ];
currentView = ionicHistory.currentView();
expect(currentView).toBeDefined();
expect(currentView.historyId).not.toEqual(tab2Hist.historyId);
expect(tab2Hist.cursor).toEqual(1);
expect(tab2Hist.stack.length).toEqual(2);
expect(tab2Hist.cursor).toBeLessThan(tab2Hist.stack.length);
// register tab2, view2
$state.go('tabs.tab2view2');
rootScope.$apply();
var tab2view2RegAgain = ionicHistory.register(tab2Container, false);
expect(tab2view2RegAgain.historyId).toEqual(tab2view2Reg.historyId);
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].cursor).toEqual(1);
expect(ionicHistory.viewHistory().histories[tab2Container.$historyId].stack.length).toEqual(2);
}));
it('should go in and out of tabs and root with correct directions', inject(function($state) {
var tab1Container = {};
ionicHistory.registerHistory(tab1Container);
// register tab1, view1
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('initialView');
expect(tab1view1Reg.direction).toEqual('none');
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register({}, false);
expect(homeReg.action).toEqual('newView');
expect(homeReg.direction).toEqual('exit');
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('moveBack');
expect(tab1view1Reg.direction).toEqual('enter');
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register({}, false);
expect(homeReg.action).toEqual('moveForward');
expect(homeReg.direction).toEqual('exit');
}));
it('should start in home, go to tabs, exit back to home', inject(function($state) {
var homeViewScope = {};
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('initialView');
expect(homeReg.direction).toEqual('none');
var tab1Container = {};
ionicHistory.registerHistory(tab1Container);
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('newView');
expect(tab1view1Reg.direction).toEqual('enter');
$state.go('home');
rootScope.$apply();
homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('moveBack');
expect(homeReg.direction).toEqual('exit');
}));
it('should start in tabs1, switch to tabs2, exit to home, enter to tabs1', inject(function($state) {
var homeViewScope = {};
var tab1Container = {};
var tab2Container = {};
ionicHistory.registerHistory(tab1Container);
ionicHistory.registerHistory(tab2Container);
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('initialView');
expect(tab1view1Reg.direction).toEqual('none');
$state.go('tabs.tab2view1');
rootScope.$apply();
var tab2view1Reg = ionicHistory.register(tab2Container, false);
expect(tab2view1Reg.action).toEqual('newView');
expect(tab2view1Reg.direction).toEqual('swap');
$state.go('home');
rootScope.$apply();
homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('newView');
expect(homeReg.direction).toEqual('exit');
$state.go('tabs.tab1view1');
rootScope.$apply();
tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('moveBack');
expect(tab1view1Reg.direction).toEqual('enter');
}));
it('should start in tabs1, exit to home, move forward to info, enter to tabs1', inject(function($state) {
var homeViewScope = {};
var infoViewScope = {};
var tab1Container = {};
ionicHistory.registerHistory(tab1Container);
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('initialView');
expect(tab1view1Reg.direction).toEqual('none');
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('newView');
expect(homeReg.direction).toEqual('exit');
$state.go('info');
rootScope.$apply();
var infoReg = ionicHistory.register(infoViewScope, false);
expect(infoReg.action).toEqual('newView');
expect(infoReg.direction).toEqual('forward');
$state.go('tabs.tab1view1');
rootScope.$apply();
tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('moveBack');
expect(tab1view1Reg.direction).toEqual('enter');
}));
it('should start in home, go to tabs, switch to another tab, exit back to home', inject(function($state) {
var homeViewScope = {};
$state.go('home');
rootScope.$apply();
var homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('initialView');
expect(homeReg.direction).toEqual('none');
var tab1Container = {};
var tab2Container = {};
ionicHistory.registerHistory(tab1Container);
ionicHistory.registerHistory(tab2Container);
$state.go('tabs.tab1view1');
rootScope.$apply();
var tab1view1Reg = ionicHistory.register(tab1Container, false);
expect(tab1view1Reg.action).toEqual('newView');
expect(tab1view1Reg.direction).toEqual('enter');
$state.go('tabs.tab2view1');
rootScope.$apply();
var tab2view1Reg = ionicHistory.register(tab2Container, false);
expect(tab2view1Reg.action).toEqual('newView');
expect(tab2view1Reg.direction).toEqual('swap');
$state.go('home');
rootScope.$apply();
homeReg = ionicHistory.register(homeViewScope, false);
expect(homeReg.action).toEqual('moveBack');
expect(homeReg.direction).toEqual('exit');
}));
it('should be an abstract view', inject(function($document) {
var reg = ionicHistory.register({}, false);
expect(reg.action).not.toEqual('abstractView');
reg = ionicHistory.register({}, true);
expect(reg.action).toEqual('abstractView');
}));
it('should init root viewHistory data', inject(function() {
expect(ionicHistory.viewHistory().backView).toEqual(null);
expect(ionicHistory.viewHistory().currentView).toEqual(null);
expect(ionicHistory.viewHistory().forwardView).toEqual(null);
expect(ionicHistory.viewHistory().histories).toEqual({
root: { historyId: 'root', parentHistoryId: null, stack: [], cursor: -1 }
});
}));
it('should not error when clearing empty history', function() {
expect(function() {
ionicHistory.clearHistory();
}).not.toThrow();
});
it('should create a ionicHistory view', inject(function($location) {
var newView = ionicHistory.createView();
expect(newView).toEqual(null);
newView = ionicHistory.createView({ stateName: 'about', url: '/url' });
expect(newView.stateName).toEqual('about');
}));
it('should go() to a view', inject(function($location) {
var newView = ionicHistory.createView({ stateName: 'about' });
newView.go();
rootScope.$apply();
expect($location.url()).toEqual('/about');
$location.url('/nochange');
newView = ionicHistory.createView({ url: '/nochange' });
var result = newView.go();
expect(result).toEqual(null);
$location.url('/nochange');
newView = ionicHistory.createView({ url: '/nochange' });
result = newView.go();
expect(result).toEqual(null);
newView = ionicHistory.viewHistory().backView = ionicHistory.createView({ url: '/url' });
result = newView.go();
expect(result).toEqual(-1);
newView = ionicHistory.viewHistory().forwardView = ionicHistory.createView({ url: '/url' });
result = newView.go();
expect(result).toEqual(1);
newView = ionicHistory.createView({ url: '/url' });
newView.go();
expect($location.url()).toEqual('/url');
}));
it('should change history on event changeHistory', inject(function($location, $state) {
$location.url('/original');
rootScope.$broadcast("$ionicHistory.change");
expect($location.url()).toEqual('/original');
rootScope.$broadcast("$ionicHistory.change", { uiSref: 'about' });
expect($location.url()).toEqual('/about');
rootScope.$broadcast("$ionicHistory.change", { url: '/url' });
expect($location.url()).toEqual('/url');
ionicHistory.viewHistory().histories.h123 = { stack: [], cursor: -1 };
rootScope.$broadcast("$ionicHistory.change", { historyId: 'h123' });
expect($location.url()).toEqual('/url');
var newView = ionicHistory.createView({ stateName: 'about' });
ionicHistory.viewHistory().histories.h123.stack.push(newView);
ionicHistory.viewHistory().histories.h123.cursor++;
rootScope.$broadcast("$ionicHistory.change", { historyId: 'h123' });
rootScope.$apply();
expect($state.current.name).toEqual('about');
}));
it('should update document title', inject(function($document) {
$document[0].title = 'Original Title';
rootScope.$broadcast("viewState.viewEnter");
expect($document[0].title).toEqual('Original Title');
rootScope.$broadcast("viewState.viewEnter", {});
expect($document[0].title).toEqual('Original Title');
rootScope.$broadcast("viewState.viewEnter", { title: 'New Title' });
expect($document[0].title).toEqual('New Title');
}));
});