router.spec.ts 4.7 KB

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