ResultProcessor.test.ts 14 KB

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