widget.spec.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import 'jest';
  4. import { Message, MessageLoop } from '@lumino/messaging';
  5. import { Widget } from '@lumino/widgets';
  6. import { simulate } from 'simulate-event';
  7. import { CodeEditor, CodeEditorWrapper } from '@jupyterlab/codeeditor';
  8. import { CodeMirrorEditor } from '@jupyterlab/codemirror';
  9. import { framePromise } from '@jupyterlab/testutils';
  10. class LogEditor extends CodeMirrorEditor {
  11. methods: string[] = [];
  12. events: string[] = [];
  13. handleEvent(event: Event): void {
  14. super.handleEvent(event);
  15. this.events.push(event.type);
  16. }
  17. refresh(): void {
  18. super.refresh();
  19. this.methods.push('refresh');
  20. }
  21. setSize(dims: CodeEditor.IDimension | null): void {
  22. super.setSize(dims);
  23. this.methods.push('setSize');
  24. }
  25. }
  26. class LogWidget extends CodeEditorWrapper {
  27. methods: string[] = [];
  28. protected onActivateRequest(msg: Message): void {
  29. super.onActivateRequest(msg);
  30. this.methods.push('onActivateRequest');
  31. }
  32. protected onAfterAttach(msg: Message): void {
  33. super.onAfterAttach(msg);
  34. this.methods.push('onAfterAttach');
  35. }
  36. protected onBeforeDetach(msg: Message): void {
  37. super.onBeforeDetach(msg);
  38. this.methods.push('onBeforeDetach');
  39. }
  40. protected onAfterShow(msg: Message): void {
  41. super.onAfterShow(msg);
  42. this.methods.push('onAfterShow');
  43. }
  44. protected onResize(msg: Widget.ResizeMessage): void {
  45. super.onResize(msg);
  46. this.methods.push('onResize');
  47. }
  48. }
  49. describe('CodeEditorWrapper', () => {
  50. let widget: LogWidget;
  51. const editorFactory = (options: CodeEditor.IOptions) => {
  52. options.uuid = 'foo';
  53. return new LogEditor(options);
  54. };
  55. beforeEach(() => {
  56. const model = new CodeEditor.Model();
  57. widget = new LogWidget({ factory: editorFactory, model });
  58. });
  59. afterEach(() => {
  60. widget.dispose();
  61. });
  62. describe('#constructor()', () => {
  63. it('should be a CodeEditorWrapper', () => {
  64. expect(widget).toBeInstanceOf(CodeEditorWrapper);
  65. });
  66. it('should add a focus listener', () => {
  67. widget.node.tabIndex = -1;
  68. simulate(widget.node, 'focus');
  69. const editor = widget.editor as LogEditor;
  70. expect(editor.events).toEqual(expect.arrayContaining(['focus']));
  71. });
  72. });
  73. describe('#editor', () => {
  74. it('should be a a code editor', () => {
  75. expect(widget.editor.getOption('lineNumbers')).toBe(false);
  76. });
  77. });
  78. describe('#dispose()', () => {
  79. it('should dispose of the resources used by the widget', () => {
  80. expect(widget.isDisposed).toBe(false);
  81. widget.dispose();
  82. expect(widget.isDisposed).toBe(true);
  83. widget.dispose();
  84. expect(widget.isDisposed).toBe(true);
  85. });
  86. it('should remove the focus listener', () => {
  87. const editor = widget.editor as LogEditor;
  88. expect(editor.isDisposed).toBe(false);
  89. widget.dispose();
  90. expect(editor.isDisposed).toBe(true);
  91. widget.node.tabIndex = -1;
  92. simulate(widget.node, 'focus');
  93. expect(editor.events).toEqual(expect.not.arrayContaining(['focus']));
  94. });
  95. });
  96. describe('#handleEvent()', () => {
  97. describe('focus', () => {
  98. it('should be a no-op if the editor was not resized', () => {
  99. Widget.attach(widget, document.body);
  100. const editor = widget.editor as LogEditor;
  101. editor.methods = [];
  102. simulate(editor.editor.getInputField(), 'focus');
  103. expect(editor.methods).toEqual([]);
  104. });
  105. it('should refresh if editor was resized', () => {
  106. Widget.attach(widget, document.body);
  107. const editor = widget.editor as LogEditor;
  108. MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);
  109. editor.methods = [];
  110. simulate(editor.editor.getInputField(), 'focus');
  111. expect(editor.methods).toEqual(['refresh']);
  112. });
  113. });
  114. });
  115. describe('#onActivateRequest()', () => {
  116. it('should focus the editor', () => {
  117. Widget.attach(widget, document.body);
  118. MessageLoop.sendMessage(widget, Widget.Msg.ActivateRequest);
  119. expect(widget.methods).toEqual(
  120. expect.arrayContaining(['onActivateRequest'])
  121. );
  122. expect(widget.editor.hasFocus()).toBe(true);
  123. });
  124. });
  125. describe('#onAfterAttach()', () => {
  126. it('should refresh the editor', async () => {
  127. Widget.attach(widget, document.body);
  128. const editor = widget.editor as LogEditor;
  129. await framePromise();
  130. expect(editor.methods).toEqual(expect.arrayContaining(['refresh']));
  131. });
  132. });
  133. describe('#onAfterShow()', () => {
  134. it('should refresh the editor', async () => {
  135. widget.hide();
  136. Widget.attach(widget, document.body);
  137. const editor = widget.editor as LogEditor;
  138. expect(editor.methods).toEqual(expect.not.arrayContaining(['refresh']));
  139. widget.show();
  140. expect(widget.methods).toEqual(expect.arrayContaining(['onAfterShow']));
  141. await framePromise();
  142. expect(editor.methods).toEqual(expect.arrayContaining(['refresh']));
  143. });
  144. });
  145. describe('#onResize()', () => {
  146. it('should set the size of the editor', () => {
  147. const msg = new Widget.ResizeMessage(10, 10);
  148. const editor = widget.editor as LogEditor;
  149. MessageLoop.sendMessage(widget, msg);
  150. expect(editor.methods).toEqual(expect.arrayContaining(['setSize']));
  151. });
  152. it('should refresh the editor', () => {
  153. const editor = widget.editor as LogEditor;
  154. Widget.attach(widget, document.body);
  155. editor.focus();
  156. editor.methods = [];
  157. MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);
  158. expect(editor.methods).toEqual(expect.arrayContaining(['refresh']));
  159. });
  160. it('should defer the refresh until focused', () => {
  161. const editor = widget.editor as LogEditor;
  162. Widget.attach(widget, document.body);
  163. editor.methods = [];
  164. MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);
  165. expect(editor.methods).toEqual([]);
  166. simulate(editor.editor.getInputField(), 'focus');
  167. expect(editor.methods).toEqual(['refresh']);
  168. });
  169. });
  170. });