statedb.spec.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { StateDB } from '@jupyterlab/statedb';
  4. import { PromiseDelegate, ReadonlyJSONObject } from '@lumino/coreutils';
  5. describe('StateDB', () => {
  6. describe('#constructor()', () => {
  7. it('should create a state database', () => {
  8. const db = new StateDB();
  9. expect(db).toBeInstanceOf(StateDB);
  10. });
  11. it('should allow an overwrite data transformation', async () => {
  12. const connector = new StateDB.Connector();
  13. const key = 'foo';
  14. const correct = 'bar';
  15. const incorrect = 'baz';
  16. expect(await connector.fetch(key)).toBeUndefined();
  17. await connector.save(key, `{ "v": "${incorrect}"}`);
  18. expect(JSON.parse(await connector.fetch(key)).v).toBe(incorrect);
  19. const transform = new PromiseDelegate<StateDB.DataTransform>();
  20. const db = new StateDB({ connector, transform: transform.promise });
  21. const transformation: StateDB.DataTransform = {
  22. type: 'overwrite',
  23. contents: { [key]: correct }
  24. };
  25. transform.resolve(transformation);
  26. await transform.promise;
  27. expect(await db.fetch(key)).toBe(correct);
  28. expect(JSON.parse(await connector.fetch(key)).v).toBe(correct);
  29. });
  30. it('should allow a merge data transformation', async () => {
  31. const connector = new StateDB.Connector();
  32. const k1 = 'foo';
  33. const v1 = 'bar';
  34. const k2 = 'baz';
  35. const v2 = 'qux';
  36. expect(await connector.fetch(k1)).toBeUndefined();
  37. expect(await connector.fetch(k2)).toBeUndefined();
  38. await connector.save(k1, `{ "v": "${v1}"}`);
  39. expect(JSON.parse(await connector.fetch(k1)).v).toBe(v1);
  40. const transform = new PromiseDelegate<StateDB.DataTransform>();
  41. const db = new StateDB({ connector, transform: transform.promise });
  42. const transformation: StateDB.DataTransform = {
  43. type: 'merge',
  44. contents: { [k2]: v2 }
  45. };
  46. transform.resolve(transformation);
  47. await transform.promise;
  48. expect(await db.fetch(k1)).toBe(v1);
  49. expect(await db.fetch(k2)).toBe(v2);
  50. });
  51. });
  52. describe('#changed', () => {
  53. it('should emit changes when the database is updated', async () => {
  54. const db = new StateDB();
  55. const changes: StateDB.Change[] = [
  56. { id: 'foo', type: 'save' },
  57. { id: 'foo', type: 'remove' },
  58. { id: 'bar', type: 'save' },
  59. { id: 'bar', type: 'remove' }
  60. ];
  61. const recorded: StateDB.Change[] = [];
  62. db.changed.connect((_, change) => {
  63. recorded.push(change);
  64. });
  65. await db.save('foo', 0);
  66. await db.remove('foo');
  67. await db.save('bar', 1);
  68. await db.remove('bar');
  69. expect(recorded).toEqual(changes);
  70. });
  71. });
  72. describe('#clear()', () => {
  73. it('should empty the items in a state database', async () => {
  74. const connector = new StateDB.Connector();
  75. const db = new StateDB({ connector });
  76. expect((await connector.list()).ids).toHaveLength(0);
  77. await db.save('foo', 'bar');
  78. expect((await connector.list()).ids).toHaveLength(1);
  79. await db.clear();
  80. expect((await connector.list()).ids).toHaveLength(0);
  81. });
  82. });
  83. describe('#fetch()', () => {
  84. it('should fetch a stored key', async () => {
  85. const db = new StateDB();
  86. const key = 'foo:bar';
  87. const value = { baz: 'qux' };
  88. expect(await db.fetch(key)).toBeUndefined();
  89. await db.save(key, value);
  90. expect(await db.fetch(key)).toEqual(value);
  91. });
  92. });
  93. describe('#list()', () => {
  94. it('should fetch a stored namespace', async () => {
  95. const db = new StateDB();
  96. const keys = [
  97. 'foo:bar',
  98. 'foo:baz',
  99. 'foo:qux',
  100. 'abc:def',
  101. 'abc:ghi',
  102. 'abc:jkl',
  103. 'foo-two:bar',
  104. 'foo-two:baz',
  105. 'foo-two:qux'
  106. ];
  107. await Promise.all(keys.map(key => db.save(key, { value: key })));
  108. let fetched = await db.list('foo');
  109. expect(fetched.ids.length).toBe(3);
  110. expect(fetched.values.length).toBe(3);
  111. let sorted = fetched.ids.sort((a, b) => a.localeCompare(b));
  112. expect(sorted[0]).toBe(keys[0]);
  113. expect(sorted[1]).toBe(keys[1]);
  114. expect(sorted[2]).toBe(keys[2]);
  115. fetched = await db.list('abc');
  116. expect(fetched.ids.length).toBe(3);
  117. expect(fetched.values.length).toBe(3);
  118. sorted = fetched.ids.sort((a, b) => a.localeCompare(b));
  119. expect(sorted[0]).toBe(keys[3]);
  120. expect(sorted[1]).toBe(keys[4]);
  121. expect(sorted[2]).toBe(keys[5]);
  122. });
  123. });
  124. describe('#remove()', () => {
  125. it('should remove a stored key', async () => {
  126. const db = new StateDB();
  127. const key = 'foo:bar';
  128. const value = { baz: 'qux' };
  129. expect(await db.fetch(key)).toBeUndefined();
  130. await db.save(key, value);
  131. expect(await db.fetch(key)).toEqual(value);
  132. await db.remove(key);
  133. expect(await db.fetch(key)).toBeUndefined();
  134. });
  135. });
  136. describe('#save()', () => {
  137. it('should save a key and a value', async () => {
  138. const db = new StateDB();
  139. const key = 'foo:bar';
  140. const value = { baz: 'qux' };
  141. await db.save(key, value);
  142. expect(await db.fetch(key)).toEqual(value);
  143. });
  144. });
  145. describe('#toJSON()', () => {
  146. it('return the full contents of a state database', async () => {
  147. const db = new StateDB();
  148. const contents: ReadonlyJSONObject = {
  149. abc: 'def',
  150. ghi: 'jkl',
  151. mno: 1,
  152. pqr: {
  153. foo: { bar: { baz: 'qux' } }
  154. }
  155. };
  156. await Promise.all(
  157. Object.keys(contents).map(key => db.save(key, contents[key]))
  158. );
  159. const serialized = await db.toJSON();
  160. expect(serialized).toEqual(contents);
  161. });
  162. });
  163. });