utils.test.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { FieldConfig, FieldConfigSource, PanelPlugin, standardFieldConfigEditorRegistry } from '@grafana/data';
  2. import { setOptionImmutably, supportsDataQuery, updateDefaultFieldConfigValue } from './utils';
  3. describe('standardFieldConfigEditorRegistry', () => {
  4. const dummyConfig: FieldConfig = {
  5. displayName: 'Hello',
  6. min: 10,
  7. max: 10,
  8. decimals: 10,
  9. thresholds: {} as any,
  10. noValue: 'no value',
  11. unit: 'km/s',
  12. links: {} as any,
  13. };
  14. it('make sure all fields have a valid name', () => {
  15. standardFieldConfigEditorRegistry.list().forEach((v) => {
  16. if (!dummyConfig.hasOwnProperty(v.id)) {
  17. fail(`Registry uses unknown property: ${v.id}`);
  18. }
  19. });
  20. });
  21. });
  22. describe('supportsDataQuery', () => {
  23. describe('when called with plugin that supports queries', () => {
  24. it('then it should return true', () => {
  25. const plugin = { meta: { skipDataQuery: false } } as unknown as PanelPlugin;
  26. expect(supportsDataQuery(plugin)).toBe(true);
  27. });
  28. });
  29. describe('when called with plugin that does not support queries', () => {
  30. it('then it should return false', () => {
  31. const plugin = { meta: { skipDataQuery: true } } as unknown as PanelPlugin;
  32. expect(supportsDataQuery(plugin)).toBe(false);
  33. });
  34. });
  35. describe('when called without skipDataQuery', () => {
  36. it('then it should return false', () => {
  37. const plugin = { meta: {} } as unknown as PanelPlugin;
  38. expect(supportsDataQuery(plugin)).toBe(false);
  39. });
  40. });
  41. describe('when called without plugin', () => {
  42. it('then it should return false', () => {
  43. expect(supportsDataQuery(undefined)).toBe(false);
  44. });
  45. });
  46. });
  47. describe('updateDefaultFieldConfigValue', () => {
  48. it.each`
  49. property | isCustom | newValue | expected
  50. ${'a'} | ${false} | ${2} | ${{ a: 2, b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom' } } }}
  51. ${'b.c'} | ${false} | ${'nested default updated'} | ${{ a: 1, b: { c: 'nested default updated' }, custom: { d: 1, e: { f: 'nested custom' } } }}
  52. ${'a'} | ${false} | ${undefined} | ${{ b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom' } } }}
  53. ${'b'} | ${false} | ${undefined} | ${{ a: 1, custom: { d: 1, e: { f: 'nested custom' } } }}
  54. ${'b.c'} | ${false} | ${undefined} | ${{ a: 1, b: {}, custom: { d: 1, e: { f: 'nested custom' } } }}
  55. ${'d'} | ${true} | ${2} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 2, e: { f: 'nested custom' } } }}
  56. ${'e.f'} | ${true} | ${'nested custom updated'} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1, e: { f: 'nested custom updated' } } }}
  57. ${'d'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { e: { f: 'nested custom' } } }}
  58. ${'e'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1 } }}
  59. ${'e.f'} | ${true} | ${undefined} | ${{ a: 1, b: { c: 'nested default' }, custom: { d: 1, e: {} } }}
  60. `(
  61. 'when updating property:$property (is custom: $isCustom) with $newValue',
  62. ({ property, isCustom, newValue, expected }) => {
  63. const config = {
  64. defaults: {
  65. a: 1,
  66. b: {
  67. c: 'nested default',
  68. },
  69. custom: {
  70. d: 1,
  71. e: { f: 'nested custom' },
  72. },
  73. },
  74. overrides: [],
  75. };
  76. expect(updateDefaultFieldConfigValue(config as FieldConfigSource, property, newValue, isCustom).defaults).toEqual(
  77. expected
  78. );
  79. }
  80. );
  81. });
  82. describe('setOptionImmutably', () => {
  83. it.each`
  84. source | path | value | expected
  85. ${{}} | ${'a'} | ${1} | ${{ a: 1 }}
  86. ${{}} | ${'a.b.c'} | ${[1, 2]} | ${{ a: { b: { c: [1, 2] } } }}
  87. ${{ a: {} }} | ${'a.b.c'} | ${[1, 2]} | ${{ a: { b: { c: [1, 2] } } }}
  88. ${{ b: {} }} | ${'a.b.c'} | ${[1, 2]} | ${{ a: { b: { c: [1, 2] } }, b: {} }}
  89. ${{ a: { b: { c: 3 } } }} | ${'a.b.c'} | ${[1, 2]} | ${{ a: { b: { c: [1, 2] } } }}
  90. ${{}} | ${'a.b[2]'} | ${'x'} | ${{ a: { b: [undefined, undefined, 'x'] } }}
  91. ${{}} | ${'a[0]'} | ${1} | ${{ a: [1] }}
  92. ${{}} | ${'a[0].b.c'} | ${1} | ${{ a: [{ b: { c: 1 } }] }}
  93. ${{ a: [{ b: 1 }] }} | ${'a[0].c'} | ${2} | ${{ a: [{ b: 1, c: 2 }] }}
  94. `('property value:${value', ({ source, path, value, expected }) => {
  95. expect(setOptionImmutably(source, path, value)).toEqual(expected);
  96. });
  97. it('does not mutate object under a path', () => {
  98. const input = { a: { b: { c: { d: 1 }, e: { f: 1 } } }, aa: 1 };
  99. const result = setOptionImmutably(input, 'a.b.c', { d: 2 });
  100. expect(input.a).not.toEqual(result.a);
  101. expect(input.aa).toEqual(result.aa);
  102. expect(input.a.b).not.toEqual(result.a.b);
  103. expect(input.a.b.c).not.toEqual(result.a.b.c);
  104. expect(input.a.b.e).toEqual(result.a.b.e);
  105. });
  106. });