mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-28 04:02:21 -04:00
Merge pull request #17605 from ADITYATIWARI342005/fix/CompSugg
Some checks failed
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Build Prometheus for common architectures (push) Waiting to run
CI / Build Prometheus for all architectures (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Push README to Docker Hub / Push README to Docker Hub (push) Has been cancelled
Push README to Docker Hub / Push README to quay.io (push) Has been cancelled
Some checks failed
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Build Prometheus for common architectures (push) Waiting to run
CI / Build Prometheus for all architectures (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Push README to Docker Hub / Push README to Docker Hub (push) Has been cancelled
Push README to Docker Hub / Push README to quay.io (push) Has been cancelled
[BUGFIX] UI :Suppress duration unit autocomplete when unit already present in query selector
This commit is contained in:
commit
96d3d641e3
2 changed files with 91 additions and 2 deletions
|
|
@ -11,7 +11,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { analyzeCompletion, computeStartCompletePosition, ContextKind } from './hybrid';
|
||||
import { analyzeCompletion, computeStartCompletePosition, ContextKind, durationWithUnitRegexp } from './hybrid';
|
||||
import { createEditorState, mockedMetricsTerms, mockPrometheusServer } from '../test/utils-test';
|
||||
import { Completion, CompletionContext } from '@codemirror/autocomplete';
|
||||
import {
|
||||
|
|
@ -559,6 +559,18 @@ describe('analyzeCompletion test', () => {
|
|||
pos: 28,
|
||||
expectedContext: [{ kind: ContextKind.Duration }],
|
||||
},
|
||||
{
|
||||
title: 'do not autocomplete duration when unit already present in matrixSelector',
|
||||
expr: 'rate(foo[5m])',
|
||||
pos: 10,
|
||||
expectedContext: [],
|
||||
},
|
||||
{
|
||||
title: 'do not autocomplete duration when multi char unit already present in matrixSelector',
|
||||
expr: 'rate(foo[5ms])',
|
||||
pos: 10,
|
||||
expectedContext: [],
|
||||
},
|
||||
{
|
||||
title: 'autocomplete duration for a subQuery',
|
||||
expr: 'go[5d:5]',
|
||||
|
|
@ -630,6 +642,42 @@ describe('analyzeCompletion test', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('durationWithUnitRegexp test', () => {
|
||||
it('should match complete durations with units', () => {
|
||||
const testCases = [
|
||||
{ input: '5m', expected: true },
|
||||
{ input: '30s', expected: true },
|
||||
{ input: '1h', expected: true },
|
||||
{ input: '500ms', expected: true },
|
||||
{ input: '2d', expected: true },
|
||||
{ input: '1w', expected: true },
|
||||
{ input: '1y', expected: true },
|
||||
{ input: '1d2h', expected: true },
|
||||
{ input: '2h30m', expected: true },
|
||||
{ input: '1h2m3s', expected: true },
|
||||
{ input: '250ms2s', expected: true },
|
||||
{ input: '2h3m4s5ms', expected: true },
|
||||
{ input: '5', expected: false },
|
||||
{ input: '5m5', expected: false },
|
||||
{ input: 'm', expected: false },
|
||||
{ input: 'd', expected: false },
|
||||
{ input: '', expected: false },
|
||||
{ input: '1hms', expected: false },
|
||||
{ input: '2x', expected: false },
|
||||
];
|
||||
testCases.forEach(({ input, expected }) => {
|
||||
expect(durationWithUnitRegexp.test(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not match durations without units or partial units', () => {
|
||||
const testCases = ['5', '30', '100', '5m5', 'm', 'd'];
|
||||
testCases.forEach((input) => {
|
||||
expect(durationWithUnitRegexp.test(input)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('computeStartCompletePosition test', () => {
|
||||
const testCases = [
|
||||
{
|
||||
|
|
@ -1229,6 +1277,28 @@ describe('autocomplete promQL test', () => {
|
|||
validFor: undefined,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'offline do not autocomplete duration when unit already present in matrixSelector',
|
||||
expr: 'rate(foo[5m])',
|
||||
pos: 10,
|
||||
expectedResult: {
|
||||
options: [],
|
||||
from: 10,
|
||||
to: 10,
|
||||
validFor: /^[a-zA-Z0-9_:]+$/,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'offline do not autocomplete duration when multi char unit already present in matrixSelector',
|
||||
expr: 'rate(foo[5ms])',
|
||||
pos: 10,
|
||||
expectedResult: {
|
||||
options: [],
|
||||
from: 10,
|
||||
to: 10,
|
||||
validFor: /^[a-zA-Z0-9_:]+$/,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'offline autocomplete duration for a subQuery',
|
||||
expr: 'go[5d:5]',
|
||||
|
|
|
|||
|
|
@ -166,6 +166,19 @@ function arrayToCompletionResult(data: Completion[], from: number, to: number, i
|
|||
} as CompletionResult;
|
||||
}
|
||||
|
||||
// Matches complete PromQL durations, including compound units (e.g., 5m, 1d2h, 1h30m, etc.).
|
||||
// Duration units are a fixed, safe set (no regex metacharacters), so no escaping is needed.
|
||||
export const durationWithUnitRegexp = new RegExp(`^(\\d+(${durationTerms.map((term) => term.label).join('|')}))+$`);
|
||||
|
||||
// Determines if a duration already has a complete time unit to prevent autocomplete insertion (issue #15452)
|
||||
function hasCompleteDurationUnit(state: EditorState, node: SyntaxNode): boolean {
|
||||
if (node.from >= node.to) {
|
||||
return false;
|
||||
}
|
||||
const nodeContent = state.sliceDoc(node.from, node.to);
|
||||
return durationWithUnitRegexp.test(nodeContent);
|
||||
}
|
||||
|
||||
// computeStartCompleteLabelPositionInLabelMatcherOrInGroupingLabel calculates the start position only when the node is a LabelMatchers or a GroupingLabels
|
||||
function computeStartCompleteLabelPositionInLabelMatcherOrInGroupingLabel(node: SyntaxNode, pos: number): number {
|
||||
// Here we can have two different situations:
|
||||
|
|
@ -477,12 +490,18 @@ export function analyzeCompletion(state: EditorState, node: SyntaxNode, pos: num
|
|||
// Duration, Duration, ⚠(NumberLiteral)
|
||||
// )
|
||||
// So we should continue to autocomplete a duration
|
||||
result.push({ kind: ContextKind.Duration });
|
||||
if (!hasCompleteDurationUnit(state, node)) {
|
||||
result.push({ kind: ContextKind.Duration });
|
||||
}
|
||||
} else {
|
||||
result.push({ kind: ContextKind.Number });
|
||||
}
|
||||
break;
|
||||
case NumberDurationLiteralInDurationContext:
|
||||
if (!hasCompleteDurationUnit(state, node)) {
|
||||
result.push({ kind: ContextKind.Duration });
|
||||
}
|
||||
break;
|
||||
case OffsetExpr:
|
||||
result.push({ kind: ContextKind.Duration });
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue