widget.spec.ts 6.0 KB

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