ResultProcessor.test.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. jest.mock('@grafana/ui/src/utils/moment_wrapper', () => ({
  2. dateTime: (ts: any) => {
  3. return {
  4. valueOf: () => ts,
  5. fromNow: () => 'fromNow() jest mocked',
  6. format: (fmt: string) => 'format() jest mocked',
  7. };
  8. },
  9. }));
  10. import { ResultProcessor } from './ResultProcessor';
  11. import { ExploreItemState, ExploreMode } from 'app/types/explore';
  12. import TableModel from 'app/core/table_model';
  13. import { toFixed, TimeSeries, LogRowModel, LogsMetaItem } from '@grafana/ui';
  14. const testContext = (options: any = {}) => {
  15. const response = [
  16. {
  17. target: 'A-series',
  18. alias: 'A-series',
  19. datapoints: [[39.91264531864214, 1559038518831], [40.35179822906545, 1559038519831]],
  20. refId: 'A',
  21. },
  22. {
  23. columns: [
  24. {
  25. text: 'Time',
  26. },
  27. {
  28. text: 'Message',
  29. },
  30. {
  31. text: 'Description',
  32. },
  33. {
  34. text: 'Value',
  35. },
  36. ],
  37. rows: [
  38. [1559038518831, 'This is a message', 'Description', 23.1],
  39. [1559038519831, 'This is a message', 'Description', 23.1],
  40. ],
  41. refId: 'B',
  42. },
  43. ];
  44. const defaultOptions = {
  45. mode: ExploreMode.Metrics,
  46. replacePreviousResults: true,
  47. result: { data: response },
  48. graphResult: [] as TimeSeries[],
  49. tableResult: new TableModel(),
  50. logsResult: { hasUniqueLabels: false, rows: [] as LogRowModel[] },
  51. };
  52. const combinedOptions = { ...defaultOptions, ...options };
  53. const state = ({
  54. mode: combinedOptions.mode,
  55. graphResult: combinedOptions.graphResult,
  56. tableResult: combinedOptions.tableResult,
  57. logsResult: combinedOptions.logsResult,
  58. queryIntervals: { intervalMs: 10 },
  59. } as any) as ExploreItemState;
  60. const resultProcessor = new ResultProcessor(state, combinedOptions.replacePreviousResults, combinedOptions.result);
  61. return {
  62. result: combinedOptions.result,
  63. resultProcessor,
  64. };
  65. };
  66. describe('ResultProcessor', () => {
  67. describe('constructed without result', () => {
  68. describe('when calling getRawData', () => {
  69. it('then it should return an empty array', () => {
  70. const { resultProcessor } = testContext({ result: null });
  71. const theResult = resultProcessor.getRawData();
  72. expect(theResult).toEqual([]);
  73. });
  74. });
  75. describe('when calling getGraphResult', () => {
  76. it('then it should return an empty array', () => {
  77. const { resultProcessor } = testContext({ result: null });
  78. const theResult = resultProcessor.getGraphResult();
  79. expect(theResult).toEqual([]);
  80. });
  81. });
  82. describe('when calling getTableResult', () => {
  83. it('then it should return an empty TableModel', () => {
  84. const { resultProcessor } = testContext({ result: null });
  85. const theResult = resultProcessor.getTableResult();
  86. expect(theResult).toEqual(new TableModel());
  87. });
  88. });
  89. describe('when calling getLogsResult', () => {
  90. it('then it should return null', () => {
  91. const { resultProcessor } = testContext({ result: null });
  92. const theResult = resultProcessor.getLogsResult();
  93. expect(theResult).toBeNull();
  94. });
  95. });
  96. });
  97. describe('constructed with a result that is a DataQueryResponse', () => {
  98. describe('when calling getRawData', () => {
  99. it('then it should return result.data', () => {
  100. const { result, resultProcessor } = testContext();
  101. const theResult = resultProcessor.getRawData();
  102. expect(theResult).toEqual(result.data);
  103. });
  104. });
  105. describe('when calling getGraphResult', () => {
  106. it('then it should return correct graph result', () => {
  107. const { resultProcessor } = testContext();
  108. const theResult = resultProcessor.getGraphResult();
  109. expect(theResult).toEqual([
  110. {
  111. alias: 'A-series',
  112. aliasEscaped: 'A-series',
  113. bars: {
  114. fillColor: '#7EB26D',
  115. },
  116. hasMsResolution: true,
  117. id: 'A-series',
  118. label: 'A-series',
  119. legend: true,
  120. stats: {},
  121. color: '#7EB26D',
  122. datapoints: [[39.91264531864214, 1559038518831], [40.35179822906545, 1559038519831]],
  123. unit: undefined,
  124. valueFormater: toFixed,
  125. },
  126. ]);
  127. });
  128. });
  129. describe('when calling getTableResult', () => {
  130. it('then it should return correct table result', () => {
  131. const { resultProcessor } = testContext();
  132. const theResult = resultProcessor.getTableResult();
  133. expect(theResult).toEqual({
  134. columnMap: {},
  135. columns: [{ text: 'Time' }, { text: 'Message' }, { text: 'Description' }, { text: 'Value' }],
  136. rows: [
  137. [1559038518831, 'This is a message', 'Description', 23.1],
  138. [1559038519831, 'This is a message', 'Description', 23.1],
  139. ],
  140. type: 'table',
  141. });
  142. });
  143. });
  144. describe('when calling getLogsResult', () => {
  145. it('then it should return correct logs result', () => {
  146. const { resultProcessor } = testContext({ mode: ExploreMode.Logs, observerResponse: null });
  147. const theResult = resultProcessor.getLogsResult();
  148. expect(theResult).toEqual({
  149. hasUniqueLabels: false,
  150. meta: [],
  151. rows: [
  152. {
  153. entry: 'This is a message',
  154. hasAnsi: false,
  155. labels: undefined,
  156. logLevel: 'unknown',
  157. raw: 'This is a message',
  158. searchWords: [] as string[],
  159. timeEpochMs: 1559038519831,
  160. timeFromNow: 'fromNow() jest mocked',
  161. timeLocal: 'format() jest mocked',
  162. timestamp: 1559038519831,
  163. uniqueLabels: {},
  164. },
  165. {
  166. entry: 'This is a message',
  167. hasAnsi: false,
  168. labels: undefined,
  169. logLevel: 'unknown',
  170. raw: 'This is a message',
  171. searchWords: [] as string[],
  172. timeEpochMs: 1559038518831,
  173. timeFromNow: 'fromNow() jest mocked',
  174. timeLocal: 'format() jest mocked',
  175. timestamp: 1559038518831,
  176. uniqueLabels: {},
  177. },
  178. ],
  179. series: [
  180. {
  181. alias: 'A-series',
  182. datapoints: [[39.91264531864214, 1559038518831], [40.35179822906545, 1559038519831]],
  183. meta: undefined,
  184. refId: 'A',
  185. target: 'A-series',
  186. unit: undefined,
  187. },
  188. ],
  189. });
  190. });
  191. });
  192. });
  193. describe('constructed with result that is a DataQueryResponse and merging with previous results', () => {
  194. describe('when calling getRawData', () => {
  195. it('then it should return result.data', () => {
  196. const { result, resultProcessor } = testContext();
  197. const theResult = resultProcessor.getRawData();
  198. expect(theResult).toEqual(result.data);
  199. });
  200. });
  201. describe('when calling getGraphResult', () => {
  202. it('then it should return correct graph result', () => {
  203. const { resultProcessor } = testContext({
  204. replacePreviousResults: false,
  205. graphResult: [
  206. {
  207. alias: 'A-series',
  208. aliasEscaped: 'A-series',
  209. bars: {
  210. fillColor: '#7EB26D',
  211. },
  212. hasMsResolution: true,
  213. id: 'A-series',
  214. label: 'A-series',
  215. legend: true,
  216. stats: {},
  217. color: '#7EB26D',
  218. datapoints: [[19.91264531864214, 1558038518831], [20.35179822906545, 1558038519831]],
  219. unit: undefined,
  220. valueFormater: toFixed,
  221. },
  222. ],
  223. });
  224. const theResult = resultProcessor.getGraphResult();
  225. expect(theResult).toEqual([
  226. {
  227. alias: 'A-series',
  228. aliasEscaped: 'A-series',
  229. bars: {
  230. fillColor: '#7EB26D',
  231. },
  232. hasMsResolution: true,
  233. id: 'A-series',
  234. label: 'A-series',
  235. legend: true,
  236. stats: {},
  237. color: '#7EB26D',
  238. datapoints: [
  239. [19.91264531864214, 1558038518831],
  240. [20.35179822906545, 1558038519831],
  241. [39.91264531864214, 1559038518831],
  242. [40.35179822906545, 1559038519831],
  243. ],
  244. unit: undefined,
  245. valueFormater: toFixed,
  246. },
  247. ]);
  248. });
  249. });
  250. describe('when calling getTableResult', () => {
  251. it('then it should return correct table result', () => {
  252. const { resultProcessor } = testContext({
  253. replacePreviousResults: false,
  254. tableResult: {
  255. columnMap: {},
  256. columns: [{ text: 'Time' }, { text: 'Message' }, { text: 'Description' }, { text: 'Value' }],
  257. rows: [
  258. [1558038518831, 'This is a previous message 1', 'Previous Description 1', 21.1],
  259. [1558038519831, 'This is a previous message 2', 'Previous Description 2', 22.1],
  260. ],
  261. type: 'table',
  262. },
  263. });
  264. const theResult = resultProcessor.getTableResult();
  265. expect(theResult).toEqual({
  266. columnMap: {},
  267. columns: [{ text: 'Time' }, { text: 'Message' }, { text: 'Description' }, { text: 'Value' }],
  268. rows: [
  269. [1558038518831, 'This is a previous message 1', 'Previous Description 1', 21.1],
  270. [1558038519831, 'This is a previous message 2', 'Previous Description 2', 22.1],
  271. [1559038518831, 'This is a message', 'Description', 23.1],
  272. [1559038519831, 'This is a message', 'Description', 23.1],
  273. ],
  274. type: 'table',
  275. });
  276. });
  277. });
  278. describe('when calling getLogsResult', () => {
  279. it('then it should return correct logs result', () => {
  280. const { resultProcessor } = testContext({
  281. mode: ExploreMode.Logs,
  282. replacePreviousResults: false,
  283. logsResult: {
  284. hasUniqueLabels: false,
  285. meta: [],
  286. rows: [
  287. {
  288. entry: 'This is a previous message 1',
  289. fresh: true,
  290. hasAnsi: false,
  291. labels: { cluster: 'some-cluster' },
  292. logLevel: 'unknown',
  293. raw: 'This is a previous message 1',
  294. searchWords: [] as string[],
  295. timeEpochMs: 1558038519831,
  296. timeFromNow: 'fromNow() jest mocked',
  297. timeLocal: 'format() jest mocked',
  298. timestamp: 1558038519831,
  299. uniqueLabels: {},
  300. },
  301. {
  302. entry: 'This is a previous message 2',
  303. fresh: true,
  304. hasAnsi: false,
  305. labels: { cluster: 'some-cluster' },
  306. logLevel: 'unknown',
  307. raw: 'This is a previous message 2',
  308. searchWords: [] as string[],
  309. timeEpochMs: 1558038518831,
  310. timeFromNow: 'fromNow() jest mocked',
  311. timeLocal: 'format() jest mocked',
  312. timestamp: 1558038518831,
  313. uniqueLabels: {},
  314. },
  315. ],
  316. series: [
  317. {
  318. alias: 'A-series',
  319. aliasEscaped: 'A-series',
  320. bars: {
  321. fillColor: '#7EB26D',
  322. },
  323. hasMsResolution: true,
  324. id: 'A-series',
  325. label: 'A-series',
  326. legend: true,
  327. stats: {},
  328. color: '#7EB26D',
  329. datapoints: [[37.91264531864214, 1558038518831], [38.35179822906545, 1558038519831]],
  330. unit: undefined,
  331. valueFormater: toFixed,
  332. },
  333. ],
  334. },
  335. });
  336. const theResult = resultProcessor.getLogsResult();
  337. const expected = {
  338. hasUniqueLabels: false,
  339. meta: [] as LogsMetaItem[],
  340. rows: [
  341. {
  342. entry: 'This is a previous message 1',
  343. fresh: false,
  344. hasAnsi: false,
  345. labels: { cluster: 'some-cluster' },
  346. logLevel: 'unknown',
  347. raw: 'This is a previous message 1',
  348. searchWords: [] as string[],
  349. timeEpochMs: 1558038519831,
  350. timeFromNow: 'fromNow() jest mocked',
  351. timeLocal: 'format() jest mocked',
  352. timestamp: 1558038519831,
  353. uniqueLabels: {},
  354. },
  355. {
  356. entry: 'This is a previous message 2',
  357. fresh: false,
  358. hasAnsi: false,
  359. labels: { cluster: 'some-cluster' },
  360. logLevel: 'unknown',
  361. raw: 'This is a previous message 2',
  362. searchWords: [] as string[],
  363. timeEpochMs: 1558038518831,
  364. timeFromNow: 'fromNow() jest mocked',
  365. timeLocal: 'format() jest mocked',
  366. timestamp: 1558038518831,
  367. uniqueLabels: {},
  368. },
  369. {
  370. entry: 'This is a message',
  371. fresh: true,
  372. hasAnsi: false,
  373. labels: undefined,
  374. logLevel: 'unknown',
  375. raw: 'This is a message',
  376. searchWords: [] as string[],
  377. timeEpochMs: 1559038519831,
  378. timeFromNow: 'fromNow() jest mocked',
  379. timeLocal: 'format() jest mocked',
  380. timestamp: 1559038519831,
  381. uniqueLabels: {},
  382. },
  383. {
  384. entry: 'This is a message',
  385. fresh: true,
  386. hasAnsi: false,
  387. labels: undefined,
  388. logLevel: 'unknown',
  389. raw: 'This is a message',
  390. searchWords: [] as string[],
  391. timeEpochMs: 1559038518831,
  392. timeFromNow: 'fromNow() jest mocked',
  393. timeLocal: 'format() jest mocked',
  394. timestamp: 1559038518831,
  395. uniqueLabels: {},
  396. },
  397. ],
  398. series: [
  399. {
  400. alias: 'A-series',
  401. aliasEscaped: 'A-series',
  402. bars: {
  403. fillColor: '#7EB26D',
  404. },
  405. hasMsResolution: true,
  406. id: 'A-series',
  407. label: 'A-series',
  408. legend: true,
  409. stats: {},
  410. color: '#7EB26D',
  411. datapoints: [
  412. [37.91264531864214, 1558038518831],
  413. [38.35179822906545, 1558038519831],
  414. [39.91264531864214, 1559038518831],
  415. [40.35179822906545, 1559038519831],
  416. ],
  417. unit: undefined as string,
  418. valueFormater: toFixed,
  419. },
  420. ],
  421. };
  422. expect(theResult).toEqual(expected);
  423. });
  424. });
  425. });
  426. });