From f64aace8b34782571cda80667eed19d296e398cc Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Thu, 1 Dec 2016 19:05:56 -0600 Subject: [PATCH] feat(vanilla): Implement in-memory-only location api test(resolve): Put beforeEach router init inside describe block test(stateService): re-implement url-based tests using in-memory location API --- src/vanilla/hashLocation.ts | 16 ++- src/vanilla/index.ts | 27 +--- src/vanilla/memoryLocation.ts | 75 +++++++++++ src/vanilla/pushStateLocation.ts | 13 +- src/vanilla/utils.ts | 23 +++- test/_testUtils.ts | 11 +- test/_testingPlugin.ts | 34 +++++ test/pluginSpec.ts | 1 + test/resolveSpec.ts | 32 ++--- test/stateServiceSpec.ts | 219 +++++++++++-------------------- 10 files changed, 264 insertions(+), 187 deletions(-) create mode 100644 src/vanilla/memoryLocation.ts create mode 100644 test/_testingPlugin.ts diff --git a/src/vanilla/hashLocation.ts b/src/vanilla/hashLocation.ts index 9f9b224e..18001aef 100644 --- a/src/vanilla/hashLocation.ts +++ b/src/vanilla/hashLocation.ts @@ -1,6 +1,8 @@ -import {services, isDefined} from '../common/module'; -import {LocationConfig, LocationServices} from '../common/coreservices'; -import {splitHash, splitQuery, trimHashVal, getParams} from './utils'; +import { isDefined } from '../common/module'; +import { LocationConfig, LocationServices } from '../common/coreservices'; +import { splitHash, splitQuery, trimHashVal, getParams, locationPluginFactory } from './utils'; +import { UIRouter } from '../router'; +import { LocationPlugin } from "./interface"; let hashPrefix: string = ''; let baseHref: string = ''; @@ -34,5 +36,11 @@ export const hashLocationService: LocationServices = { setUrl: (url: string, replace: boolean = true) => { if (url) location.hash = url; }, - onChange: (cb: EventListener) => window.addEventListener("hashchange", cb, false) as any + onChange: (cb: EventListener) => { + window.addEventListener('hashchange', cb, false); + return () => window.removeEventListener('hashchange', cb); + } }; + +export const hashLocationPlugin: (router: UIRouter) => LocationPlugin = + locationPluginFactory('vanilla.hashBangLocation', hashLocationService, hashLocationConfig); diff --git a/src/vanilla/index.ts b/src/vanilla/index.ts index 9846b9f9..b5cfce78 100644 --- a/src/vanilla/index.ts +++ b/src/vanilla/index.ts @@ -5,11 +5,8 @@ */ /** */ import { UIRouter } from "../router"; -import { services, LocationServices, LocationConfig } from "../common/coreservices"; -import { LocationPlugin, ServicesPlugin } from "./interface"; -import { extend } from "../common/common"; -import { hashLocationService, hashLocationConfig } from "./hashLocation"; -import { pushStateLocationService, pushStateLocationConfig } from "./pushStateLocation"; +import { services } from "../common/coreservices"; +import { ServicesPlugin } from "./interface"; import { $q } from "./$q"; import { $injector } from "./$injector"; @@ -18,20 +15,10 @@ export { $q, $injector }; export function servicesPlugin(router: UIRouter): ServicesPlugin { services.$injector = $injector; services.$q = $q; - - return { name: "vanilla.services", $q, $injector }; -} - -const locationPluginFactory = (name: string, service: LocationServices, configuration: LocationConfig) => - (router: UIRouter) => { - extend(services.location, service); - extend(services.locationConfig, configuration); - return { name, service, configuration }; - }; -export const hashLocationPlugin: (router: UIRouter) => LocationPlugin = - locationPluginFactory("vanilla.hashBangLocation", hashLocationService, hashLocationConfig); - -export const pushStateLocationPlugin: (router: UIRouter) => LocationPlugin = - locationPluginFactory("vanilla.pushStateLocation", pushStateLocationService, pushStateLocationConfig); + return { name: "vanilla.services", $q, $injector, dispose: () => null }; +} +export * from "./hashLocation"; +export * from "./memoryLocation"; +export * from "./pushStateLocation"; diff --git a/src/vanilla/memoryLocation.ts b/src/vanilla/memoryLocation.ts new file mode 100644 index 00000000..3d6c43da --- /dev/null +++ b/src/vanilla/memoryLocation.ts @@ -0,0 +1,75 @@ +import { services, isDefined } from '../common/module'; +import { LocationConfig, LocationServices } from '../common/coreservices'; +import { splitQuery, trimHashVal, getParams, splitHash, locationPluginFactory } from './utils'; +import { removeFrom, unnestR } from "../common/common"; +import { UIRouter } from "../router"; +import { LocationPlugin } from "./interface"; +import { isArray } from "../common/predicates"; + +var mlc; +export const memoryLocationConfig: LocationConfig = mlc = { + _hashPrefix: '', + _baseHref: '', + _port: 80, + _protocol: "http", + _host: "localhost", + + port: () => mlc._port, + protocol: () => mlc._protocol, + host: () => mlc._host, + baseHref: () => mlc._baseHref, + html5Mode: () => false, + hashPrefix: (newprefix?: string): string => { + if (isDefined(newprefix)) { + mlc._hashPrefix = newprefix; + } + return mlc._hashPrefix; + } +}; + +var mls; +export const memoryLocationService: LocationServices = mls = { + _listeners: [], + _url: { + path: '', + search: {}, + hash: '' + }, + _changed: (newval, oldval) => { + if (newval === oldval) return; + let evt = new Event("locationchange"); + evt['url'] = newval; + mls._listeners.forEach(cb => cb(evt)); + }, + + url: () => { + let s = mls._url.search; + let hash = mls._url.hash; + let query = Object.keys(s).map(key => (isArray(s[key]) ? s[key] : [s[key]]) .map(val => key + "=" + val)) + .reduce(unnestR, []) + .join("&"); + + return mls._url.path + + (query ? "?" + query : "") + + (hash ? "#" + hash : ""); + }, + hash: () => mls._url.hash, + path: () => mls._url.path, + search: () => mls._url.search, + setUrl: (url: string, replace: boolean = false) => { + if (isDefined(url)) { + let path = splitHash(splitQuery(url)[0])[0]; + let hash = splitHash(url)[1]; + let search = getParams(splitQuery(splitHash(url)[0])[1]); + + let oldval = mls.url(); + mls._url = { path, search, hash }; + let newval = mls.url(); + mls._changed(newval, oldval); + } + }, + onChange: (cb: EventListener) => (mls._listeners.push(cb), () => removeFrom(mls._listeners, cb)) +}; + +export const memoryLocationPlugin: (router: UIRouter) => LocationPlugin = + locationPluginFactory("vanilla.memoryLocation", memoryLocationService, memoryLocationConfig); \ No newline at end of file diff --git a/src/vanilla/pushStateLocation.ts b/src/vanilla/pushStateLocation.ts index 6fc499df..25306e11 100644 --- a/src/vanilla/pushStateLocation.ts +++ b/src/vanilla/pushStateLocation.ts @@ -1,6 +1,8 @@ import { services, isDefined } from '../common/module'; import { LocationConfig, LocationServices } from '../common/coreservices'; -import { splitQuery, trimHashVal, getParams } from './utils'; +import { splitQuery, trimHashVal, getParams, locationPluginFactory } from './utils'; +import { LocationPlugin } from "./interface"; +import { UIRouter } from "../router"; let hashPrefix: string = ''; let baseHref: string = ''; @@ -42,5 +44,12 @@ export const pushStateLocationService: LocationServices = { else history.pushState(null, null, services.locationConfig.baseHref() + url); } }, - onChange: (cb: EventListener) => window.addEventListener("popstate", cb, false) as any + onChange: (cb: EventListener) => { + window.addEventListener("popstate", cb, false); + return () => window.removeEventListener("popstate", cb); + } }; + +export const pushStateLocationPlugin: (router: UIRouter) => LocationPlugin = + locationPluginFactory("vanilla.pushStateLocation", pushStateLocationService, pushStateLocationConfig); + diff --git a/src/vanilla/utils.ts b/src/vanilla/utils.ts index fe97c410..2f4f584f 100644 --- a/src/vanilla/utils.ts +++ b/src/vanilla/utils.ts @@ -1,4 +1,7 @@ import {isArray} from "../common/module"; +import { LocationServices, LocationConfig, services } from "../common/coreservices"; +import { UIRouter } from "../router"; +import { extend, pushTo, removeFrom } from "../common/common"; const beforeAfterSubstr = (char: string) => (str: string): string[] => { if (!str) return ["", ""]; @@ -24,4 +27,22 @@ export const keyValsToObjectR = (accum, [key, val]) => { }; export const getParams = (queryString: string): any => - queryString.split("&").map(splitEqual).reduce(keyValsToObjectR, {}); \ No newline at end of file + queryString.split("&").map(splitEqual).reduce(keyValsToObjectR, {}); + +export function locationPluginFactory(name: string, service: LocationServices, configuration: LocationConfig) { + let deregFns: Function[] = []; + function dispose() { + deregFns.forEach(fn => { + typeof fn === 'function' && fn(); + removeFrom(deregFns, fn); + }); + } + + return function(router: UIRouter) { + extend(services.locationConfig, configuration); + extend(services.location, service); + services.location.onChange = (cb: Function) => + pushTo(deregFns, service.onChange(cb)); + return { name, service, configuration, dispose }; + }; +} diff --git a/test/_testUtils.ts b/test/_testUtils.ts index f1dd964e..fb01aabf 100644 --- a/test/_testUtils.ts +++ b/test/_testUtils.ts @@ -1,5 +1,5 @@ -import {pick, forEach, omit} from "../src/index"; -import {map} from "../src/common/common"; +import { pick, forEach, omit } from "../src/index"; +import { map } from "../src/common/common"; let stateProps = ["resolve", "resolvePolicy", "data", "template", "templateUrl", "url", "name", "params"]; @@ -59,4 +59,9 @@ export function PromiseResult(promise?) { } } - +export const awaitTransition = (router) => new Promise(resolve => { + let dereg = router.transitionService.onSuccess({}, (trans) => { + dereg(); + resolve(trans); + }); +}); diff --git a/test/_testingPlugin.ts b/test/_testingPlugin.ts new file mode 100644 index 00000000..c1b273d5 --- /dev/null +++ b/test/_testingPlugin.ts @@ -0,0 +1,34 @@ +import { UIRouter } from "../src/router"; +import { UIRouterPluginBase } from "../src/interface"; +import * as vanilla from "../src/vanilla"; + +export class TestingPlugin extends UIRouterPluginBase { + name: string = 'testing'; + errorsCount: number = 0; + errorsThreshold: number = 1000; + + constructor(public router: UIRouter) { + super(); + router.plugin(vanilla.servicesPlugin); + router.plugin(vanilla.memoryLocationPlugin); + + this.addErrorLoopHandler(); + + this.startRouter(); + } + + startRouter() { + this.router.stateRegistry.stateQueue.autoFlush(this.router.stateService); + this.router.urlRouter.listen(); + } + + addErrorLoopHandler() { + let $transitions = this.router.transitionService; + $transitions.onCreate({}, trans => { + trans.promise.catch(() => this.errorsCount++); + if (this.errorsCount > this.errorsThreshold) { + throw new Error(`Over ${this.errorsThreshold} failures; creation of new transitions disabled`); + } + }); + } +} diff --git a/test/pluginSpec.ts b/test/pluginSpec.ts index ec60ad08..86d52654 100644 --- a/test/pluginSpec.ts +++ b/test/pluginSpec.ts @@ -26,6 +26,7 @@ describe('plugin api', function () { class FancyPluginClass implements UIRouterPlugin { name = "fancypluginclass"; constructor(public router: UIRouter) { } + dispose() {} } function FancyPluginConstructor(router: UIRouter, options: any) { diff --git a/test/resolveSpec.ts b/test/resolveSpec.ts index d8b0b4db..134c6eb9 100644 --- a/test/resolveSpec.ts +++ b/test/resolveSpec.ts @@ -5,6 +5,7 @@ import { tree2Array } from "./_testUtils"; import { UIRouter } from "../src/router"; import Spy = jasmine.Spy; +import { TestingPlugin } from "./_testingPlugin"; /////////////////////////////////////////////// @@ -61,21 +62,6 @@ function getStates() { }; } -beforeEach(function () { - router = new UIRouter(); - router.plugin(vanilla.servicesPlugin); - router.plugin(vanilla.hashLocationPlugin); - router.stateRegistry.stateQueue.autoFlush(router.stateService); - - counts = { _J: 0, _J2: 0, _K: 0, _L: 0, _M: 0, _Q: 0 }; - vals = { _Q: null }; - expectCounts = copy(counts); - - tree2Array(getStates(), false).forEach(state => router.stateRegistry.register(state)); - statesMap = router.stateRegistry.get() - .reduce((acc, state) => (acc[state.name] = state.$$state(), acc), statesMap); -}); - function makePath(names: string[]): PathNode[] { return names.map(name => new PathNode(statesMap[name])); } @@ -86,8 +72,22 @@ function getResolvedData(pathContext: ResolveContext) { .reduce((acc, resolvable) => { acc[resolvable.token] = resolvable.data; return acc; }, {}); } - describe('Resolvables system:', function () { + + afterEach(() => router.dispose()); + beforeEach(function () { + router = new UIRouter(); + router.plugin(TestingPlugin); + + counts = { _J: 0, _J2: 0, _K: 0, _L: 0, _M: 0, _Q: 0 }; + vals = { _Q: null }; + expectCounts = copy(counts); + + tree2Array(getStates(), false).forEach(state => router.stateRegistry.register(state)); + statesMap = router.stateRegistry.get() + .reduce((acc, state) => (acc[state.name] = state.$$state(), acc), statesMap); + }); + describe('Path.getResolvables', function () { it('should return Resolvables from the deepest element and all ancestors', () => { let path = makePath([ "A", "B", "C" ]); diff --git a/test/stateServiceSpec.ts b/test/stateServiceSpec.ts index 24bbd088..0b80de7c 100644 --- a/test/stateServiceSpec.ts +++ b/test/stateServiceSpec.ts @@ -1,6 +1,5 @@ import { UIRouter, TransitionService, StateService } from "../src/index"; -import * as vanilla from "../src/vanilla"; -import { tree2Array } from "./_testUtils"; +import { tree2Array, awaitTransition } from "./_testUtils"; import "./_matchers"; import { TransitionOptions } from "../src/transition/interface"; import { LocationServices, services } from "../src/common/coreservices"; @@ -10,6 +9,7 @@ import { State } from "../src/state/stateObject"; import { Transition } from "../src/transition/transition"; import { Param } from "../src/params/param"; import { RejectType } from "../src/transition/rejectFactory"; +import { TestingPlugin } from "./_testingPlugin"; describe('stateService', function () { let router: UIRouter; @@ -19,22 +19,23 @@ describe('stateService', function () { let $loc: LocationServices; const wait = (val?) => - new Promise((resolve) => setTimeout(() => resolve(val))); + new Promise((resolve) => setTimeout(() => resolve(val), 50)); async function initStateTo(state, params = {}) { await $state.transitionTo(state, params); expect($state.current).toBe(state); } + afterEach(() => router.dispose()); + beforeEach(() => { router = new UIRouter(); - router.plugin(vanilla.servicesPlugin); - router.plugin(vanilla.hashLocationPlugin); + router.plugin(TestingPlugin); + $loc = services.location; $state = router.stateService; $registry = router.stateRegistry; $transitions = router.transitionService; - router.stateRegistry.stateQueue.autoFlush($state); }); describe('transitionTo', () => { @@ -62,18 +63,22 @@ describe('stateService', function () { }); it("should handle redirects", ((done) => { - $transitions.onStart({ to: 'D'}, trans => (log.push('redirect'), trans.router.stateService.target('C'))); + $transitions.onStart({ to: 'D'}, trans => { + log.push('redirect'); + return trans.router.stateService.target('C'); + }); $transitions.onStart({ to: 'C'}, trans => { cOpts = trans.options(); }); - var log = [], transition = $state.go("D").transition; + var log = [], promise = $state.go("D"); var cOpts: TransitionOptions = {}; - wait().then(() => { + promise.then(() => { expect(log).toEqual(['redirect']); - expect(cOpts.redirectedFrom).toBe(transition); + expect(cOpts.redirectedFrom).toBe(promise.transition); expect(cOpts.source).toBe("redirect"); - }) - .then(done, done); + + done(); + }); })); it('should error after 20+ async redirects', (done) => { @@ -170,12 +175,10 @@ describe('stateService', function () { describe("dynamic transitions", function () { var dynlog, paramsChangedLog; var dynamicstate, childWithParam, childNoParam; - var cleanup; beforeEach(async function (done) { $loc.setUrl("asdfasfdasf"); dynlog = paramsChangedLog = ""; - cleanup = []; dynamicstate = { name: 'dyn', url: '^/dynstate/:path/:pathDyn?search&searchDyn', @@ -203,26 +206,28 @@ describe('stateService', function () { router.stateRegistry.register(childWithParam); router.stateRegistry.register(childNoParam); - const logChangedParams = (prefix, suffix) => - (trans: Transition, state: State) => { - trans.promise.then(() => { - let changed = Param.changed(state.parameters({ inherit: true }), trans.params("to"), trans.params("from")) - .map(param => param.id + "=" + trans.params("to")[param.id]) - .join(","); - if (changed) { - dynlog += prefix + changed + suffix + ";"; - } - }); - }; - - cleanup.push($transitions.onEnter({}, (trans, state) => dynlog += 'enter:' + state.name + ";")); - cleanup.push($transitions.onExit({}, (trans, state) => dynlog += 'exit:' + state.name + ";")); - cleanup.push($transitions.onSuccess({}, () => dynlog += 'success;')); - cleanup.push($transitions.onRetain({retained: 'dyn'}, logChangedParams('[', ']'))); - cleanup.push($transitions.onRetain({retained: 'dyn.child'}, logChangedParams('{', '}'))); - cleanup.push($transitions.onRetain({retained: 'dyn.noparams'}, logChangedParams('(', ')'))); + function logChangedParams(prefix, suffix) { + return (trans: Transition, state: State) => { + trans.onSuccess({}, () => { + let changed = Param.changed(state.parameters({ inherit: true }), trans.params("to"), trans.params("from")) + .map(param => param.id + "=" + trans.params("to")[param.id]) + .join(","); + if (changed) { + dynlog += prefix + changed + suffix + ";"; + } + }); + }; + } + + $transitions.onEnter({}, (trans, state) => dynlog += 'enter:' + state.name + ";"); + $transitions.onExit({}, (trans, state) => dynlog += 'exit:' + state.name + ";"); + $transitions.onSuccess({}, () => dynlog += 'success;', { priority: 1 }); + $transitions.onRetain({ retained: 'dyn' }, logChangedParams('[', ']')); + $transitions.onRetain({ retained: 'dyn.child' }, logChangedParams('{', '}')); + $transitions.onRetain({ retained: 'dyn.noparams' }, logChangedParams('(', ')')); await initStateTo(dynamicstate, { path: 'p1', pathDyn: 'pd1', search: 's1', searchDyn: 'sd1' }); + expect(dynlog).toBe('enter:dyn;success;'); expect($state.params).toEqualValues({ '#': null, path: 'p1', pathDyn: 'pd1', search: 's1', searchDyn: 'sd1' }); expect($loc.path()).toEqual('/dynstate/p1/pd1'); @@ -233,7 +238,6 @@ describe('stateService', function () { }); afterEach((done) => { - cleanup.forEach(fn => fn()); if (router.globals.transition) { router.globals.transition.promise.then(done, done) } else { @@ -359,23 +363,23 @@ describe('stateService', function () { done(); }); - // it('does not exit nor enter a state when only dynamic params change (triggered via url)', async (done) => { - // $loc.search({ search: 's1', searchDyn: 'sd2' }); - // $rootScope.$broadcast("$locationChangeSuccess"); - // $q.flush(); - // expect(dynlog).toBe('success;[searchDyn=sd2];') - // - // done(); - // }); - - // it('exits and enters a state when any non-dynamic params change (triggered via url)', async (done) => { - // $location.search({ search: 's2', searchDyn: 'sd2' }); - // $rootScope.$broadcast("$locationChangeSuccess"); - // $q.flush(); - // expect(dynlog).toBe('exit:dyn;enter:dyn;success;') - // - // done(); - // }); + it('does not exit nor enter a state when only dynamic params change (triggered via url)', (done) => { + awaitTransition(router).then(() => { + expect(dynlog).toBe('success;[searchDyn=sd2];'); + done(); + }); + + $loc.setUrl('/dynstate/p1/pd1?search=s1&searchDyn=sd2'); + }); + + it('exits and enters a state when any non-dynamic params change (triggered via url)', (done) => { + awaitTransition(router).then(() => { + expect(dynlog).toBe('exit:dyn;enter:dyn;success;'); + done(); + }); + + $loc.setUrl('/dynstate/p1/pd1?search=s2&searchDyn=sd2'); + }); it('does not exit nor enter a state when only dynamic params change (triggered via $state transition)', async (done) => { await $state.go('.', {searchDyn: 'sd2'}, { inherit: true }); @@ -393,14 +397,22 @@ describe('stateService', function () { done(); }); - // it('updates $stateParams and $location.search when only dynamic params change (triggered via url)', function () { - // $location.search({search: 's1', searchDyn: 'sd2'}); - // $rootScope.$broadcast("$locationChangeSuccess"); - // $q.flush(); - // expect($stateParams.search).toBe('s1'); - // expect($stateParams.searchDyn).toBe('sd2'); - // expect($location.search()).toEqual({search: 's1', searchDyn: 'sd2'}); - // }); + it('updates $stateParams and $location.search when only dynamic params change (triggered via url)', async (done) => { + let dereg = $transitions.onBefore({}, (trans) => { + trans.promise.then(expects, expects); + + function expects() { + expect($state.params['search']).toBe('s1'); + expect($state.params['searchDyn']).toBe('sd2'); + expect($loc.search()).toEqual({search: 's1', searchDyn: 'sd2'}); + + dereg(); + done(); + } + }); + + $loc.setUrl('/dynstate/p1/pd1?search=s1&searchDyn=sd2'); // {search: 's1', searchDyn: 'sd2'}); + }); it('updates $stateParams and $location.search when only dynamic params change (triggered via $state transition)', async (done) => { await $state.go('.', {searchDyn: 'sd2'}); @@ -413,70 +425,6 @@ describe('stateService', function () { done(); }); }); - // - // describe('[ uiOnParamsChanged ]', function() { - // it('should be called when dynamic parameter values change', function() { - // $state.go('.', { searchDyn: 'sd2' }); $q.flush(); - // expect(paramsChangedLog).toBe('searchDyn;'); - // }); - // - // it('should not be called if a non-dynamic parameter changes (causing the controller\'s state to exit/enter)', function() { - // $state.go('.', { search: 's2', searchDyn: 'sd2' }); $q.flush(); - // expect(paramsChangedLog).toBe(''); - // }); - // - // it('should not be called, when entering a new state, if no parameter values change', function() { - // $state.go(childNoParam); $q.flush(); - // expect(paramsChangedLog).toBe(''); - // }); - // - // it('should be called, when entering a new state, if any dynamic parameter value changed', function() { - // $state.go(childNoParam, { searchDyn: 'sd2' }); $q.flush(); - // expect(paramsChangedLog).toBe('searchDyn;'); - // }); - // - // it('should be called, when entering a new state, if a new parameter value is added', function() { - // $state.go(childWithParam, { config: 'c2' }); $q.flush(); - // expect(paramsChangedLog).toBe('config,configDyn;'); - // }); - // - // it('should be called, when reactivating the uiOnParamsChanged state, if a dynamic parameter changed', function() { - // initStateTo(childNoParam, { path: 'p1', pathDyn: 'pd1', search: 's1', searchDyn: 'sd1' }); - // dynlog = paramsChangedLog = ""; - // - // $state.go(dynamicstate, { pathDyn: 'pd2' }); $q.flush(); - // expect(paramsChangedLog).toBe('pathDyn;'); - // }); - // - // it('should not be called, when reactivating the uiOnParamsChanged state "dyn", if any of dyns non-dynamic parameters changed', function() { - // initStateTo(childNoParam, { path: 'p1', pathDyn: 'pd1', search: 's1', searchDyn: 'sd1' }); - // dynlog = paramsChangedLog = ""; - // - // $state.go(dynamicstate, { path: 'p2' }); $q.flush(); - // expect(paramsChangedLog).toBe(''); - // }); - // - // it('should be called with an object containing only the changed params', function() { - // $state.go(dynamicstate, { pathDyn: 'pd2' }); $q.flush(); - // expect(dynlog).toBe('success;[pathDyn=pd2];'); - // - // $state.go(dynamicstate, { pathDyn: 'pd3', searchDyn: 'sd2' }); $q.flush(); - // expect(dynlog).toBe('success;[pathDyn=pd2];success;[pathDyn=pd3,searchDyn=sd2];'); - // }); - // - // it('should be called on all active controllers that have a uiOnParamsChanged', function() { - // initStateTo(childWithParam, { path: 'p1', pathDyn: 'pd1', search: 's1', searchDyn: 'sd1', config: 'p1', configDyn: 'c1' }); - // dynlog = paramsChangedLog = ""; - // - // $state.go(childWithParam, { pathDyn: 'pd2' }); $q.flush(); - // expect(dynlog).toBe('success;[pathDyn=pd2];{pathDyn=pd2};'); - // - // dynlog = paramsChangedLog = ""; - // $state.go(childWithParam, { pathDyn: 'pd2', searchDyn: 'sd2', configDyn: 'cd2' }); $q.flush(); - // expect(dynlog).toBe('success;[configDyn=cd2,searchDyn=sd2];{configDyn=cd2,searchDyn=sd2};'); - // }); - // }); - }); describe("(with dynamic params because reloadOnSearch=false)", function () { @@ -495,13 +443,14 @@ describe('stateService', function () { $transitions.onEnter({entering: 'RS'}, function () { entered = true }); }); - // it('doesn\'t re-enter state (triggered by url change)', function () { - // $location.search({term: 'hello'}); - // $rootScope.$broadcast("$locationChangeSuccess"); - // $q.flush(); - // expect($location.search()).toEqual({term: 'hello'}); - // expect(entered).toBeFalsy(); - // }); + it('doesn\'t re-enter state (triggered by url change)', function (done) { + $loc.setUrl($loc.path() + "?term=hello"); + awaitTransition(router).then(() => { + expect($loc.search()).toEqual({term: 'hello'}); + expect(entered).toBeFalsy(); + done(); + }) + }); it('doesn\'t re-enter state (triggered by $state transition)', async (done) => { var promise = $state.go($state.current, {term: "hello"}); @@ -676,18 +625,6 @@ describe('stateService', function () { done(); }); - // it('uses the templateProvider to get template dynamically', ((done) =>{ - // $state.transitionTo('dynamicTemplate', { type: "Acme" }); - // $q.flush(); - // expect(template).toEqual("AcmeFooTemplate"); - // })); - - // it('uses the controllerProvider to get controller dynamically', ((done) =>{ - // $state.transitionTo('dynamicController', { type: "Acme" }); - // $q.flush(); - // expect(ctrlName).toEqual("AcmeController"); - // })); - it('updates the location #fragment, if specified', async(done) => { await $state.transitionTo('DD', { '#': 'frag' });