Prometheus: Fix typehead after binary operators (#21152)

- no longer do right-trim to prevent suggestions after space
- rely on splitting on syntax elements to identify relevant prefix
- added tests
This commit is contained in:
David
2019-12-18 13:35:31 +01:00
committed by GitHub
parent ff422be961
commit 34c1433ba4
2 changed files with 63 additions and 12 deletions

View File

@@ -12,6 +12,56 @@ describe('Language completion provider', () => {
getTimeRange: () => ({ start: 0, end: 1 }),
} as any) as PrometheusDatasource;
describe('cleanText', () => {
const cleanText = new LanguageProvider(datasource).cleanText;
it('does not remove metric or label keys', () => {
expect(cleanText('foo')).toBe('foo');
expect(cleanText('foo_bar')).toBe('foo_bar');
});
it('keeps trailing space but removes leading', () => {
expect(cleanText('foo ')).toBe('foo ');
expect(cleanText(' foo')).toBe('foo');
});
it('removes label syntax', () => {
expect(cleanText('foo="bar')).toBe('bar');
expect(cleanText('foo!="bar')).toBe('bar');
expect(cleanText('foo=~"bar')).toBe('bar');
expect(cleanText('foo!~"bar')).toBe('bar');
expect(cleanText('{bar')).toBe('bar');
});
it('removes previous operators', () => {
expect(cleanText('foo + bar')).toBe('bar');
expect(cleanText('foo+bar')).toBe('bar');
expect(cleanText('foo - bar')).toBe('bar');
expect(cleanText('foo * bar')).toBe('bar');
expect(cleanText('foo / bar')).toBe('bar');
expect(cleanText('foo % bar')).toBe('bar');
expect(cleanText('foo ^ bar')).toBe('bar');
expect(cleanText('foo and bar')).toBe('bar');
expect(cleanText('foo or bar')).toBe('bar');
expect(cleanText('foo unless bar')).toBe('bar');
expect(cleanText('foo == bar')).toBe('bar');
expect(cleanText('foo != bar')).toBe('bar');
expect(cleanText('foo > bar')).toBe('bar');
expect(cleanText('foo < bar')).toBe('bar');
expect(cleanText('foo >= bar')).toBe('bar');
expect(cleanText('foo <= bar')).toBe('bar');
});
it('removes aggregation syntax', () => {
expect(cleanText('(bar')).toBe('bar');
expect(cleanText('(foo,bar')).toBe('bar');
expect(cleanText('(foo, bar')).toBe('bar');
});
it('removes range syntax', () => {
expect(cleanText('[1m')).toBe('1m');
});
});
describe('empty query suggestions', () => {
it('returns no suggestions on empty context', async () => {
const instance = new LanguageProvider(datasource);
@@ -96,8 +146,9 @@ describe('Language completion provider', () => {
query: { refId: '1', expr: 'metric' },
},
];
let value = Plain.deserialize('a');
let value = Plain.deserialize('m');
value = value.setSelection({ anchor: { offset: 1 }, focus: { offset: 1 } });
// Even though no metric with `m` is present, we still get metric completion items, filtering is done by the consumer
const result = await instance.provideCompletionItems(
{ text: 'm', prefix: 'm', value, wrapperClasses: [] },
{ history }