vdom.spec.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import 'jest';
  4. import { VDomModel, VDomRenderer } from '@jupyterlab/apputils';
  5. import { framePromise } from '@jupyterlab/testutils';
  6. import { Widget } from '@lumino/widgets';
  7. import * as React from 'react';
  8. class TestModel extends VDomModel {
  9. get value(): string {
  10. return this._value;
  11. }
  12. set value(newValue: string) {
  13. this._value = newValue;
  14. this.stateChanged.emit(void 0);
  15. }
  16. private _value = '';
  17. }
  18. class TestWidget extends VDomRenderer<TestModel> {
  19. protected render(): React.ReactElement<any> {
  20. return React.createElement('span', null, this.model.value);
  21. }
  22. }
  23. class TestWidgetNoModel extends VDomRenderer {
  24. protected render(): React.ReactElement<any> {
  25. return React.createElement('span', null, 'No model!');
  26. }
  27. }
  28. describe('@jupyterlab/apputils', () => {
  29. describe('VDomModel', () => {
  30. describe('#constructor()', () => {
  31. it('should create a VDomModel', () => {
  32. const model = new VDomModel();
  33. expect(model).toBeInstanceOf(VDomModel);
  34. });
  35. it('should create a TestModel', () => {
  36. const model = new TestModel();
  37. expect(model).toBeInstanceOf(TestModel);
  38. });
  39. it('should be properly disposed', () => {
  40. const model = new TestModel();
  41. model.dispose();
  42. expect(model.isDisposed).toBe(true);
  43. });
  44. });
  45. describe('#stateChanged()', () => {
  46. it('should fire the stateChanged signal on a change', () => {
  47. const model = new TestModel();
  48. let changed = false;
  49. model.stateChanged.connect(() => {
  50. changed = true;
  51. });
  52. model.value = 'newvalue';
  53. expect(changed).toBe(true);
  54. });
  55. });
  56. });
  57. describe('VDomRenderer', () => {
  58. describe('#constructor()', () => {
  59. it('should create a TestWidget', () => {
  60. const widget = new TestWidget(new TestModel());
  61. expect(widget).toBeInstanceOf(TestWidget);
  62. });
  63. it('should be properly disposed', () => {
  64. const widget = new TestWidget(new TestModel());
  65. widget.dispose();
  66. expect(widget.isDisposed).toBe(true);
  67. });
  68. });
  69. describe('#modelChanged()', () => {
  70. it('should fire the stateChanged signal on a change', () => {
  71. const model = new TestModel();
  72. const widget = new TestWidget(new TestModel());
  73. let changed = false;
  74. widget.modelChanged.connect(() => {
  75. changed = true;
  76. });
  77. widget.model = model;
  78. expect(changed).toBe(true);
  79. });
  80. });
  81. describe('#render()', () => {
  82. it('should render the contents after a model change', async () => {
  83. const widget = new TestWidget(new TestModel());
  84. const model = new TestModel();
  85. widget.model = model;
  86. model.value = 'foo';
  87. await framePromise();
  88. const span = widget.node.firstChild as HTMLElement;
  89. expect(span.textContent).toBe('foo');
  90. });
  91. });
  92. describe('#noModel()', () => {
  93. it('should work with a null model', async () => {
  94. const widget = new TestWidgetNoModel();
  95. Widget.attach(widget, document.body);
  96. await framePromise();
  97. const span = widget.node.firstChild as HTMLElement;
  98. expect(span.textContent).toBe('No model!');
  99. });
  100. });
  101. });
  102. });