utils.test.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. import { Diff, getDiffOperationText, getDiffText, jsonDiff } from './utils';
  2. describe('getDiffOperationText', () => {
  3. const cases = [
  4. ['add', 'added'],
  5. ['remove', 'deleted'],
  6. ['replace', 'changed'],
  7. ['byDefault', 'changed'],
  8. ];
  9. test.each(cases)('it returns the correct verb for an operation', (operation, expected) => {
  10. expect(getDiffOperationText(operation)).toBe(expected);
  11. });
  12. });
  13. type DiffTextCase = [Partial<Diff>, string];
  14. describe('getDiffText', () => {
  15. const addEmptyArray: DiffTextCase = [
  16. { op: 'add', value: [], path: ['annotations', 'list'], startLineNumber: 24 },
  17. 'added list',
  18. ];
  19. const addArrayNumericProp: DiffTextCase = [
  20. {
  21. op: 'add',
  22. value: ['tag'],
  23. path: ['panels', '3'],
  24. },
  25. 'added item 3',
  26. ];
  27. const addArrayProp: DiffTextCase = [
  28. {
  29. op: 'add',
  30. value: [{ name: 'dummy target 1' }, { name: 'dummy target 2' }],
  31. path: ['panels', '3', 'targets'],
  32. },
  33. 'added 2 targets',
  34. ];
  35. const addValueNumericProp: DiffTextCase = [
  36. {
  37. op: 'add',
  38. value: 'foo',
  39. path: ['panels', '3'],
  40. },
  41. 'added item 3',
  42. ];
  43. const addValueProp: DiffTextCase = [
  44. {
  45. op: 'add',
  46. value: 'foo',
  47. path: ['panels', '3', 'targets'],
  48. },
  49. 'added targets',
  50. ];
  51. const removeEmptyArray: DiffTextCase = [
  52. { op: 'remove', originalValue: [], path: ['annotations', 'list'], startLineNumber: 24 },
  53. 'deleted list',
  54. ];
  55. const removeArrayNumericProp: DiffTextCase = [
  56. {
  57. op: 'remove',
  58. originalValue: ['tag'],
  59. path: ['panels', '3'],
  60. },
  61. 'deleted item 3',
  62. ];
  63. const removeArrayProp: DiffTextCase = [
  64. {
  65. op: 'remove',
  66. originalValue: [{ name: 'dummy target 1' }, { name: 'dummy target 2' }],
  67. path: ['panels', '3', 'targets'],
  68. },
  69. 'deleted 2 targets',
  70. ];
  71. const removeValueNumericProp: DiffTextCase = [
  72. {
  73. op: 'remove',
  74. originalValue: 'foo',
  75. path: ['panels', '3'],
  76. },
  77. 'deleted item 3',
  78. ];
  79. const removeValueProp: DiffTextCase = [
  80. {
  81. op: 'remove',
  82. originalValue: 'foo',
  83. path: ['panels', '3', 'targets'],
  84. },
  85. 'deleted targets',
  86. ];
  87. const replaceValueNumericProp: DiffTextCase = [
  88. {
  89. op: 'replace',
  90. originalValue: 'foo',
  91. value: 'bar',
  92. path: ['panels', '3'],
  93. },
  94. 'changed item 3',
  95. ];
  96. const replaceValueProp: DiffTextCase = [
  97. {
  98. op: 'replace',
  99. originalValue: 'foo',
  100. value: 'bar',
  101. path: ['panels', '3', 'targets'],
  102. },
  103. 'changed targets',
  104. ];
  105. const cases = [
  106. addEmptyArray,
  107. addArrayNumericProp,
  108. addArrayProp,
  109. addValueNumericProp,
  110. addValueProp,
  111. removeEmptyArray,
  112. removeArrayNumericProp,
  113. removeArrayProp,
  114. removeValueNumericProp,
  115. removeValueProp,
  116. replaceValueNumericProp,
  117. replaceValueProp,
  118. ];
  119. test.each(cases)(
  120. 'returns a semantic message based on the type of diff, the values and the location of the change',
  121. (diff: Partial<Diff>, expected: string) => {
  122. expect(getDiffText(diff as unknown as Diff)).toBe(expected);
  123. }
  124. );
  125. });
  126. describe('jsonDiff', () => {
  127. it('returns data related to each change', () => {
  128. const lhs = {
  129. annotations: {
  130. list: [
  131. {
  132. builtIn: 1,
  133. datasource: '-- Grafana --',
  134. enable: true,
  135. hide: true,
  136. iconColor: 'rgba(0, 211, 255, 1)',
  137. name: 'Annotations & Alerts',
  138. type: 'dashboard',
  139. },
  140. ],
  141. },
  142. editable: true,
  143. gnetId: null,
  144. graphTooltip: 0,
  145. id: 141,
  146. links: [],
  147. panels: [],
  148. schemaVersion: 27,
  149. style: 'dark',
  150. tags: [],
  151. templating: {
  152. list: [],
  153. },
  154. time: {
  155. from: 'now-6h',
  156. to: 'now',
  157. },
  158. timepicker: {},
  159. timezone: '',
  160. title: 'test dashboard',
  161. uid: '_U4zObQMz',
  162. version: 2,
  163. };
  164. const rhs = {
  165. annotations: {
  166. list: [
  167. {
  168. builtIn: 1,
  169. datasource: '-- Grafana --',
  170. enable: true,
  171. hide: true,
  172. iconColor: 'rgba(0, 211, 255, 1)',
  173. name: 'Annotations & Alerts',
  174. type: 'dashboard',
  175. },
  176. ],
  177. },
  178. description: 'a description',
  179. editable: true,
  180. gnetId: null,
  181. graphTooltip: 1,
  182. id: 141,
  183. links: [],
  184. panels: [
  185. {
  186. type: 'graph',
  187. },
  188. ],
  189. schemaVersion: 27,
  190. style: 'dark',
  191. tags: ['the tag'],
  192. templating: {
  193. list: [],
  194. },
  195. time: {
  196. from: 'now-6h',
  197. to: 'now',
  198. },
  199. timepicker: {
  200. refresh_intervals: ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d', '2d'],
  201. },
  202. timezone: 'utc',
  203. title: 'My favourite dashboard',
  204. uid: '_U4zObQMz',
  205. version: 3,
  206. };
  207. const expected = {
  208. description: [
  209. {
  210. op: 'add',
  211. originalValue: undefined,
  212. path: ['description'],
  213. startLineNumber: 14,
  214. value: 'a description',
  215. },
  216. ],
  217. graphTooltip: [
  218. {
  219. op: 'replace',
  220. originalValue: 0,
  221. path: ['graphTooltip'],
  222. startLineNumber: 17,
  223. value: 1,
  224. },
  225. ],
  226. panels: [
  227. {
  228. op: 'add',
  229. originalValue: undefined,
  230. path: ['panels', '0'],
  231. startLineNumber: 21,
  232. value: {
  233. type: 'graph',
  234. },
  235. },
  236. ],
  237. tags: [
  238. {
  239. op: 'add',
  240. originalValue: undefined,
  241. path: ['tags', '0'],
  242. startLineNumber: 28,
  243. value: 'the tag',
  244. },
  245. ],
  246. timepicker: [
  247. {
  248. op: 'add',
  249. originalValue: undefined,
  250. path: ['timepicker', 'refresh_intervals'],
  251. startLineNumber: 38,
  252. value: ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d', '2d'],
  253. },
  254. ],
  255. timezone: [
  256. {
  257. op: 'replace',
  258. originalValue: '',
  259. path: ['timezone'],
  260. startLineNumber: 52,
  261. value: 'utc',
  262. },
  263. ],
  264. title: [
  265. {
  266. op: 'replace',
  267. originalValue: 'test dashboard',
  268. path: ['title'],
  269. startLineNumber: 53,
  270. value: 'My favourite dashboard',
  271. },
  272. ],
  273. version: [
  274. {
  275. op: 'replace',
  276. originalValue: 2,
  277. path: ['version'],
  278. startLineNumber: 55,
  279. value: 3,
  280. },
  281. ],
  282. };
  283. expect(jsonDiff(lhs, rhs)).toStrictEqual(expected);
  284. });
  285. });