processDataFrame.test.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import {
  2. isDataFrame,
  3. toLegacyResponseData,
  4. isTableData,
  5. toDataFrame,
  6. guessFieldTypes,
  7. guessFieldTypeFromValue,
  8. sortDataFrame,
  9. } from './processDataFrame';
  10. import { FieldType, TimeSeries, TableData, DataFrameDTO } from '../types/index';
  11. import { dateTime } from '../datetime/moment_wrapper';
  12. import { MutableDataFrame } from './MutableDataFrame';
  13. describe('toDataFrame', () => {
  14. it('converts timeseries to series', () => {
  15. const input1 = {
  16. target: 'Field Name',
  17. datapoints: [[100, 1], [200, 2]],
  18. };
  19. let series = toDataFrame(input1);
  20. expect(series.fields[0].name).toBe(input1.target);
  21. const v0 = series.fields[0].values;
  22. const v1 = series.fields[1].values;
  23. expect(v0.length).toEqual(2);
  24. expect(v1.length).toEqual(2);
  25. expect(v0.get(0)).toEqual(100);
  26. expect(v0.get(1)).toEqual(200);
  27. expect(v1.get(0)).toEqual(1);
  28. expect(v1.get(1)).toEqual(2);
  29. // Should fill a default name if target is empty
  30. const input2 = {
  31. // without target
  32. target: '',
  33. datapoints: [[100, 1], [200, 2]],
  34. };
  35. series = toDataFrame(input2);
  36. expect(series.fields[0].name).toEqual('Value');
  37. });
  38. it('assumes TimeSeries values are numbers', () => {
  39. const input1 = {
  40. target: 'time',
  41. datapoints: [[100, 1], [200, 2]],
  42. };
  43. const data = toDataFrame(input1);
  44. expect(data.fields[0].type).toBe(FieldType.number);
  45. });
  46. it('keeps dataFrame unchanged', () => {
  47. const input = toDataFrame({
  48. datapoints: [[100, 1], [200, 2]],
  49. });
  50. expect(input.length).toEqual(2);
  51. // If the object is alreay a DataFrame, it should not change
  52. const again = toDataFrame(input);
  53. expect(again).toBe(input);
  54. });
  55. it('migrate from 6.3 style rows', () => {
  56. const oldDataFrame = {
  57. fields: [{ name: 'A' }, { name: 'B' }, { name: 'C' }],
  58. rows: [[100, 'A', 1], [200, 'B', 2], [300, 'C', 3]],
  59. };
  60. const data = toDataFrame(oldDataFrame);
  61. expect(data.length).toBe(oldDataFrame.rows.length);
  62. });
  63. it('Guess Colum Types from value', () => {
  64. expect(guessFieldTypeFromValue(1)).toBe(FieldType.number);
  65. expect(guessFieldTypeFromValue(1.234)).toBe(FieldType.number);
  66. expect(guessFieldTypeFromValue(3.125e7)).toBe(FieldType.number);
  67. expect(guessFieldTypeFromValue(true)).toBe(FieldType.boolean);
  68. expect(guessFieldTypeFromValue(false)).toBe(FieldType.boolean);
  69. expect(guessFieldTypeFromValue(new Date())).toBe(FieldType.time);
  70. expect(guessFieldTypeFromValue(dateTime())).toBe(FieldType.time);
  71. });
  72. it('Guess Colum Types from strings', () => {
  73. expect(guessFieldTypeFromValue('1')).toBe(FieldType.number);
  74. expect(guessFieldTypeFromValue('1.234')).toBe(FieldType.number);
  75. expect(guessFieldTypeFromValue('3.125e7')).toBe(FieldType.number);
  76. expect(guessFieldTypeFromValue('True')).toBe(FieldType.boolean);
  77. expect(guessFieldTypeFromValue('FALSE')).toBe(FieldType.boolean);
  78. expect(guessFieldTypeFromValue('true')).toBe(FieldType.boolean);
  79. expect(guessFieldTypeFromValue('xxxx')).toBe(FieldType.string);
  80. });
  81. it('Guess Colum Types from series', () => {
  82. const series = new MutableDataFrame({
  83. fields: [
  84. { name: 'A (number)', values: [123, null] },
  85. { name: 'B (strings)', values: [null, 'Hello'] },
  86. { name: 'C (nulls)', values: [null, null] },
  87. { name: 'Time', values: ['2000', 1967] },
  88. ],
  89. });
  90. const norm = guessFieldTypes(series);
  91. expect(norm.fields[0].type).toBe(FieldType.number);
  92. expect(norm.fields[1].type).toBe(FieldType.string);
  93. expect(norm.fields[2].type).toBe(FieldType.other);
  94. expect(norm.fields[3].type).toBe(FieldType.time); // based on name
  95. });
  96. });
  97. describe('SerisData backwards compatibility', () => {
  98. it('can convert TimeSeries to series and back again', () => {
  99. const timeseries = {
  100. target: 'Field Name',
  101. datapoints: [[100, 1], [200, 2]],
  102. };
  103. const series = toDataFrame(timeseries);
  104. expect(isDataFrame(timeseries)).toBeFalsy();
  105. expect(isDataFrame(series)).toBeTruthy();
  106. const roundtrip = toLegacyResponseData(series) as TimeSeries;
  107. expect(isDataFrame(roundtrip)).toBeFalsy();
  108. expect(roundtrip.target).toBe(timeseries.target);
  109. });
  110. it('can convert empty table to DataFrame then back to legacy', () => {
  111. const table = {
  112. columns: [],
  113. rows: [],
  114. };
  115. const series = toDataFrame(table);
  116. const roundtrip = toLegacyResponseData(series) as TableData;
  117. expect(roundtrip.columns.length).toBe(0);
  118. });
  119. it('converts TableData to series and back again', () => {
  120. const table = {
  121. columns: [{ text: 'a', unit: 'ms' }, { text: 'b', unit: 'zz' }, { text: 'c', unit: 'yy' }],
  122. rows: [[100, 1, 'a'], [200, 2, 'a']],
  123. };
  124. const series = toDataFrame(table);
  125. expect(isTableData(table)).toBeTruthy();
  126. expect(isDataFrame(series)).toBeTruthy();
  127. expect(series.fields[0].config.unit).toEqual('ms');
  128. const roundtrip = toLegacyResponseData(series) as TimeSeries;
  129. expect(isTableData(roundtrip)).toBeTruthy();
  130. expect(roundtrip).toMatchObject(table);
  131. });
  132. it('can convert empty TableData to DataFrame', () => {
  133. const table = {
  134. columns: [],
  135. rows: [],
  136. };
  137. const series = toDataFrame(table);
  138. expect(series.fields.length).toBe(0);
  139. });
  140. it('can convert DataFrame to TableData to series and back again', () => {
  141. const json: DataFrameDTO = {
  142. refId: 'Z',
  143. meta: {
  144. somethign: 8,
  145. },
  146. fields: [
  147. { name: 'T', type: FieldType.time, values: [1, 2, 3] },
  148. { name: 'N', type: FieldType.number, config: { filterable: true }, values: [100, 200, 300] },
  149. { name: 'S', type: FieldType.string, config: { filterable: true }, values: ['1', '2', '3'] },
  150. ],
  151. };
  152. const series = toDataFrame(json);
  153. const table = toLegacyResponseData(series) as TableData;
  154. expect(table.refId).toBe(series.refId);
  155. expect(table.meta).toEqual(series.meta);
  156. const names = table.columns.map(c => c.text);
  157. expect(names).toEqual(['T', 'N', 'S']);
  158. });
  159. });
  160. describe('sorted DataFrame', () => {
  161. const frame = toDataFrame({
  162. fields: [
  163. { name: 'fist', type: FieldType.time, values: [1, 2, 3] },
  164. { name: 'second', type: FieldType.string, values: ['a', 'b', 'c'] },
  165. { name: 'third', type: FieldType.number, values: [2000, 3000, 1000] },
  166. ],
  167. });
  168. it('Should sort numbers', () => {
  169. const sorted = sortDataFrame(frame, 0, true);
  170. expect(sorted.length).toEqual(3);
  171. expect(sorted.fields[0].values.toJSON()).toEqual([3, 2, 1]);
  172. expect(sorted.fields[1].values.toJSON()).toEqual(['c', 'b', 'a']);
  173. });
  174. it('Should sort strings', () => {
  175. const sorted = sortDataFrame(frame, 1, true);
  176. expect(sorted.length).toEqual(3);
  177. expect(sorted.fields[0].values.toJSON()).toEqual([3, 2, 1]);
  178. expect(sorted.fields[1].values.toJSON()).toEqual(['c', 'b', 'a']);
  179. });
  180. });