diff --git a/public/app/features/transformers/extractFields/extractFields.test.ts b/public/app/features/transformers/extractFields/extractFields.test.ts index 1895e57bead..053a2802ba7 100644 --- a/public/app/features/transformers/extractFields/extractFields.test.ts +++ b/public/app/features/transformers/extractFields/extractFields.test.ts @@ -1,5 +1,14 @@ -import { DataFrame, Field, FieldType } from '@grafana/data'; +import { + DataFrame, + DataTransformerConfig, + DataTransformerID, + Field, + FieldType, + transformDataFrame, +} from '@grafana/data'; import { toDataFrame } from '@grafana/data/src/dataframe/processDataFrame'; +import { SortByTransformerOptions, sortByTransformer } from '@grafana/data/src/transformations/transformers/sortBy'; +import { mockTransformationsRegistry } from '@grafana/data/src/utils/tests/mockTransformationsRegistry'; import { extractFieldsTransformer } from './extractFields'; import { ExtractFieldsOptions, FieldExtractorID } from './types'; @@ -233,6 +242,121 @@ describe('Fields from JSON', () => { length: 2, }); }); + + it('works with different value sizes', async () => { + const extractConfig: ExtractFieldsOptions = { + source: 'line', + replace: false, + }; + const sortConfig: DataTransformerConfig = { + id: DataTransformerID.sortBy, + options: { + sort: [ + { + field: 'time', + }, + ], + }, + }; + mockTransformationsRegistry([sortByTransformer]); + const ctx = { interpolate: (v: string) => v }; + + const testDataFrame: DataFrame = { + fields: [ + { config: {}, name: 'Time', type: FieldType.time, values: [1, 2] }, + { config: {}, name: 'line', type: FieldType.other, values: ['{"foo":"bar"}', '{"baz":"bar"}'] }, + ], + length: 2, + }; + + const expected = { + fields: [ + { + config: {}, + name: 'Time', + type: 'time', + values: [1, 2], + state: { + displayName: 'Time', + multipleFrames: false, + }, + }, + { + config: {}, + name: 'line', + state: { + displayName: 'line', + multipleFrames: false, + }, + type: 'other', + values: ['{"foo":"bar"}', '{"baz":"bar"}'], + }, + { + name: 'foo', + state: { + displayName: 'foo', + multipleFrames: false, + }, + values: ['bar', undefined], + type: 'string', + config: {}, + }, + { + name: 'baz', + state: { + displayName: 'baz', + multipleFrames: false, + }, + values: [undefined, 'bar'], + type: 'string', + config: {}, + }, + ], + length: 2, + meta: { + transformations: ['sortBy'], + }, + }; + + const frames = extractFieldsTransformer.transformer(extractConfig, ctx)([testDataFrame]); + + await expect(transformDataFrame([sortConfig], frames)).toEmitValuesWith((received) => { + expect(received[0][0].fields[2]).toMatchInlineSnapshot(` + { + "config": {}, + "name": "foo", + "state": { + "displayName": "foo", + "multipleFrames": false, + }, + "type": "string", + "values": [ + "bar", + undefined, + ], + } + `); + + expect(received[0][0].fields[3]).toMatchInlineSnapshot(` + { + "config": {}, + "name": "baz", + "state": { + "displayName": "baz", + "multipleFrames": false, + }, + "type": "string", + "values": [ + undefined, + "bar", + ], + } + `); + }); + + expect(frames.length).toEqual(1); + expect(frames[0]).toEqual(expected); + }); }); const testFieldTime: Field = { diff --git a/public/app/features/transformers/extractFields/extractFields.ts b/public/app/features/transformers/extractFields/extractFields.ts index b2f39319960..2175adf4ac8 100644 --- a/public/app/features/transformers/extractFields/extractFields.ts +++ b/public/app/features/transformers/extractFields/extractFields.ts @@ -86,7 +86,7 @@ export function addExtractedFields(frame: DataFrame, options: ExtractFieldsOptio for (const [key, val] of Object.entries(obj)) { let buffer = values.get(key); if (buffer == null) { - buffer = new Array(count); + buffer = new Array(count).fill(undefined); values.set(key, buffer); names.push(key); }