router.spec.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { Router } from '@jupyterlab/application';
  4. import { CommandRegistry } from '@lumino/commands';
  5. import { Token } from '@lumino/coreutils';
  6. import { signalToPromise } from '@jupyterlab/testutils';
  7. const base = '/';
  8. describe('apputils', () => {
  9. describe('Router', () => {
  10. let commands: CommandRegistry;
  11. let router: Router;
  12. beforeEach(() => {
  13. commands = new CommandRegistry();
  14. router = new Router({ base, commands });
  15. });
  16. describe('#constructor()', () => {
  17. it('should construct a new router', () => {
  18. expect(router).toBeInstanceOf(Router);
  19. });
  20. });
  21. describe('#base', () => {
  22. it('should be the base URL of the application', () => {
  23. expect(router.base).toBe(base);
  24. });
  25. });
  26. describe('#commands', () => {
  27. it('should be the command registry used by the router', () => {
  28. expect(router.commands).toBe(commands);
  29. });
  30. });
  31. describe('#current', () => {
  32. it('should return the current window location as an object', () => {
  33. const path = '/';
  34. const request = path;
  35. const search = '';
  36. const hash = '';
  37. expect(router.current).toEqual({ hash, path, request, search });
  38. });
  39. });
  40. describe('#routed', () => {
  41. it('should emit a signal when a path is routed', async () => {
  42. let routed = false;
  43. commands.addCommand('a', {
  44. execute: () => {
  45. routed = true;
  46. }
  47. });
  48. router.register({ command: 'a', pattern: /.*/, rank: 10 });
  49. let called = false;
  50. router.routed.connect(() => {
  51. expect(routed).toBe(true);
  52. called = true;
  53. });
  54. await router.route();
  55. expect(called).toBe(true);
  56. });
  57. });
  58. describe('#stop', () => {
  59. it('should be a unique token', () => {
  60. expect(router.stop).toBeInstanceOf(Token);
  61. });
  62. it('should stop routing if returned by a routed command', async () => {
  63. const wanted = ['a', 'b'];
  64. const recorded: string[] = [];
  65. commands.addCommand('a', {
  66. execute: () => {
  67. recorded.push('a');
  68. }
  69. });
  70. commands.addCommand('b', {
  71. execute: () => {
  72. recorded.push('b');
  73. }
  74. });
  75. commands.addCommand('c', { execute: () => router.stop });
  76. commands.addCommand('d', {
  77. execute: () => {
  78. recorded.push('d');
  79. }
  80. });
  81. router.register({ command: 'a', pattern: /.*/, rank: 10 });
  82. router.register({ command: 'b', pattern: /.*/, rank: 20 });
  83. router.register({ command: 'c', pattern: /.*/, rank: 30 });
  84. router.register({ command: 'd', pattern: /.*/, rank: 40 });
  85. const promise = signalToPromise(router.routed);
  86. await router.route();
  87. await promise;
  88. expect(recorded).toEqual(wanted);
  89. });
  90. });
  91. describe('#navigate()', () => {
  92. it('cannot be tested since changing location is a security risk', () => {
  93. // Router#navigate() changes window.location.href but karma tests
  94. // disallow changing the window location.
  95. });
  96. });
  97. describe('#register()', () => {
  98. it('should register a command with a route pattern', async () => {
  99. const wanted = ['a'];
  100. const recorded: string[] = [];
  101. commands.addCommand('a', {
  102. execute: () => {
  103. recorded.push('a');
  104. }
  105. });
  106. router.register({ command: 'a', pattern: /.*/ });
  107. let called = false;
  108. router.routed.connect(() => {
  109. expect(recorded).toEqual(wanted);
  110. called = true;
  111. });
  112. await router.route();
  113. expect(called).toBe(true);
  114. });
  115. });
  116. describe('#route()', () => {
  117. it('should route the location to a command', async () => {
  118. const wanted = ['a'];
  119. const recorded: string[] = [];
  120. commands.addCommand('a', {
  121. execute: () => {
  122. recorded.push('a');
  123. }
  124. });
  125. router.register({ command: 'a', pattern: /#a/, rank: 10 });
  126. expect(recorded.length).toBe(0);
  127. // Change the hash because changing location is a security error.
  128. window.location.hash = 'a';
  129. let called = false;
  130. router.routed.connect(() => {
  131. expect(recorded).toEqual(wanted);
  132. window.location.hash = '';
  133. called = true;
  134. });
  135. await router.route();
  136. expect(called).toBe(true);
  137. });
  138. });
  139. });
  140. });