Merge pull request #13953 from miqh/fix/suppress-aggregation-suggestions

Handle suggestions for alternate syntax aggregation contexts
This commit is contained in:
David 2018-11-05 12:15:37 +01:00 committed by GitHub
commit 24e5922d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 12 deletions

View File

@ -156,7 +156,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
} }
getAggregationCompletionItems({ value }: TypeaheadInput): TypeaheadOutput { getAggregationCompletionItems({ value }: TypeaheadInput): TypeaheadOutput {
let refresher: Promise<any> = null; const refresher: Promise<any> = null;
const suggestions: CompletionItemGroup[] = []; const suggestions: CompletionItemGroup[] = [];
// Stitch all query lines together to support multi-line queries // Stitch all query lines together to support multi-line queries
@ -172,12 +172,30 @@ export default class PromQlLanguageProvider extends LanguageProvider {
return text; return text;
}, ''); }, '');
const leftSide = queryText.slice(0, queryOffset); // Try search for selector part on the left-hand side, such as `sum (m) by (l)`
const openParensAggregationIndex = leftSide.lastIndexOf('('); const openParensAggregationIndex = queryText.lastIndexOf('(', queryOffset);
const openParensSelectorIndex = leftSide.slice(0, openParensAggregationIndex).lastIndexOf('('); let openParensSelectorIndex = queryText.lastIndexOf('(', openParensAggregationIndex - 1);
const closeParensSelectorIndex = leftSide.slice(openParensSelectorIndex).indexOf(')') + openParensSelectorIndex; let closeParensSelectorIndex = queryText.indexOf(')', openParensSelectorIndex);
let selectorString = leftSide.slice(openParensSelectorIndex + 1, closeParensSelectorIndex); // Try search for selector part of an alternate aggregation clause, such as `sum by (l) (m)`
if (openParensSelectorIndex === -1) {
const closeParensAggregationIndex = queryText.indexOf(')', queryOffset);
closeParensSelectorIndex = queryText.indexOf(')', closeParensAggregationIndex + 1);
openParensSelectorIndex = queryText.lastIndexOf('(', closeParensSelectorIndex);
}
const result = {
refresher,
suggestions,
context: 'context-aggregation',
};
// Suggestions are useless for alternative aggregation clauses without a selector in context
if (openParensSelectorIndex === -1) {
return result;
}
let selectorString = queryText.slice(openParensSelectorIndex + 1, closeParensSelectorIndex);
// Range vector syntax not accounted for by subsequent parse so discard it if present // Range vector syntax not accounted for by subsequent parse so discard it if present
selectorString = selectorString.replace(/\[[^\]]+\]$/, ''); selectorString = selectorString.replace(/\[[^\]]+\]$/, '');
@ -188,14 +206,10 @@ export default class PromQlLanguageProvider extends LanguageProvider {
if (labelKeys) { if (labelKeys) {
suggestions.push({ label: 'Labels', items: labelKeys.map(wrapLabel) }); suggestions.push({ label: 'Labels', items: labelKeys.map(wrapLabel) });
} else { } else {
refresher = this.fetchSeriesLabels(selector); result.refresher = this.fetchSeriesLabels(selector);
} }
return { return result;
refresher,
suggestions,
context: 'context-aggregation',
};
} }
getLabelCompletionItems({ text, wrapperClasses, labelKey, value }: TypeaheadInput): TypeaheadOutput { getLabelCompletionItems({ text, wrapperClasses, labelKey, value }: TypeaheadInput): TypeaheadOutput {

View File

@ -269,5 +269,48 @@ describe('Language completion provider', () => {
}, },
]); ]);
}); });
it('returns no suggestions inside an unclear aggregation context using alternate syntax', () => {
const instance = new LanguageProvider(datasource, {
labelKeys: { '{__name__="metric"}': ['label1', 'label2', 'label3'] },
});
const value = Plain.deserialize('sum by ()');
const range = value.selection.merge({
anchorOffset: 8,
});
const valueWithSelection = value.change().select(range).value;
const result = instance.provideCompletionItems({
text: '',
prefix: '',
wrapperClasses: ['context-aggregation'],
value: valueWithSelection,
});
expect(result.context).toBe('context-aggregation');
expect(result.suggestions).toEqual([]);
});
it('returns label suggestions inside an aggregation context using alternate syntax', () => {
const instance = new LanguageProvider(datasource, {
labelKeys: { '{__name__="metric"}': ['label1', 'label2', 'label3'] },
});
const value = Plain.deserialize('sum by () (metric)');
const range = value.selection.merge({
anchorOffset: 8,
});
const valueWithSelection = value.change().select(range).value;
const result = instance.provideCompletionItems({
text: '',
prefix: '',
wrapperClasses: ['context-aggregation'],
value: valueWithSelection,
});
expect(result.context).toBe('context-aggregation');
expect(result.suggestions).toEqual([
{
items: [{ label: 'label1' }, { label: 'label2' }, { label: 'label3' }],
label: 'Labels',
},
]);
});
}); });
}); });