d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
/**
|
|
* @vitest-environment node
|
|
*/
|
|
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
dedupeOverlappingWorkflowSearchMatches,
|
|
workflowSearchMatchMatchesQuery,
|
|
} from '@/lib/workflows/search-replace/resources/resolvers'
|
|
import type { WorkflowSearchMatch } from '@/lib/workflows/search-replace/types'
|
|
|
|
function createMatch(overrides: Partial<WorkflowSearchMatch>): WorkflowSearchMatch {
|
|
return {
|
|
id: 'match',
|
|
blockId: 'block-1',
|
|
blockName: 'Block',
|
|
blockType: 'function',
|
|
subBlockId: 'code',
|
|
canonicalSubBlockId: 'code',
|
|
subBlockType: 'code',
|
|
valuePath: [],
|
|
target: { kind: 'subblock' },
|
|
kind: 'text',
|
|
rawValue: '',
|
|
searchText: '',
|
|
editable: true,
|
|
navigable: true,
|
|
protected: false,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
describe('dedupeOverlappingWorkflowSearchMatches', () => {
|
|
it('keeps the narrower text hit when a partial literal query overlaps an inline reference', () => {
|
|
const textMatch = createMatch({
|
|
id: 'text-partial',
|
|
kind: 'text',
|
|
rawValue: '<start.h',
|
|
searchText: "return '<start.hello>'",
|
|
range: { start: 8, end: 16 },
|
|
})
|
|
const referenceMatch = createMatch({
|
|
id: 'workflow-reference',
|
|
kind: 'workflow-reference',
|
|
rawValue: '<start.hello>',
|
|
searchText: 'start.hello',
|
|
range: { start: 8, end: 21 },
|
|
resource: { kind: 'workflow-reference', token: '<start.hello>', key: 'start.hello' },
|
|
})
|
|
|
|
expect(dedupeOverlappingWorkflowSearchMatches([textMatch, referenceMatch])).toEqual([textMatch])
|
|
})
|
|
|
|
it('keeps the inline reference when it covers the same span as a text hit', () => {
|
|
const textMatch = createMatch({
|
|
id: 'text-full',
|
|
kind: 'text',
|
|
rawValue: '<start.hello>',
|
|
searchText: "return '<start.hello>'",
|
|
range: { start: 8, end: 21 },
|
|
})
|
|
const referenceMatch = createMatch({
|
|
id: 'workflow-reference',
|
|
kind: 'workflow-reference',
|
|
rawValue: '<start.hello>',
|
|
searchText: 'start.hello',
|
|
range: { start: 8, end: 21 },
|
|
resource: { kind: 'workflow-reference', token: '<start.hello>', key: 'start.hello' },
|
|
})
|
|
|
|
expect(dedupeOverlappingWorkflowSearchMatches([textMatch, referenceMatch])).toEqual([
|
|
referenceMatch,
|
|
])
|
|
})
|
|
|
|
it('uses kind priority rather than iteration order for equal-span non-text matches', () => {
|
|
const workflowReferenceMatch = createMatch({
|
|
id: 'workflow-reference',
|
|
kind: 'workflow-reference',
|
|
rawValue: '{{API_KEY}}',
|
|
searchText: 'API_KEY',
|
|
range: { start: 0, end: 11 },
|
|
resource: { kind: 'workflow-reference', token: '{{API_KEY}}', key: 'API_KEY' },
|
|
})
|
|
const environmentMatch = createMatch({
|
|
id: 'environment',
|
|
kind: 'environment',
|
|
rawValue: '{{API_KEY}}',
|
|
searchText: 'API_KEY',
|
|
range: { start: 0, end: 11 },
|
|
resource: { kind: 'environment', token: '{{API_KEY}}', key: 'API_KEY' },
|
|
})
|
|
|
|
expect(
|
|
dedupeOverlappingWorkflowSearchMatches([workflowReferenceMatch, environmentMatch])
|
|
).toEqual([workflowReferenceMatch])
|
|
expect(
|
|
dedupeOverlappingWorkflowSearchMatches([environmentMatch, workflowReferenceMatch])
|
|
).toEqual([workflowReferenceMatch])
|
|
})
|
|
|
|
it('does not collapse matches from different fields', () => {
|
|
const firstMatch = createMatch({
|
|
id: 'first',
|
|
range: { start: 0, end: 4 },
|
|
valuePath: ['first'],
|
|
})
|
|
const secondMatch = createMatch({
|
|
id: 'second',
|
|
range: { start: 0, end: 4 },
|
|
valuePath: ['second'],
|
|
})
|
|
|
|
expect(dedupeOverlappingWorkflowSearchMatches([firstMatch, secondMatch])).toEqual([
|
|
firstMatch,
|
|
secondMatch,
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('workflowSearchMatchMatchesQuery', () => {
|
|
it('does not keep structured resource matches alive from only block or field label text', () => {
|
|
const selectorMatch = createMatch({
|
|
id: 'selector-resource',
|
|
blockName: 'Testy',
|
|
fieldTitle: 'Select Presentation',
|
|
subBlockId: 'presentationId',
|
|
subBlockType: 'file-selector',
|
|
kind: 'file',
|
|
rawValue: 'opaque-presentation-id',
|
|
searchText: 'opaque-presentation-id',
|
|
range: undefined,
|
|
resource: { kind: 'file', key: 'opaque-presentation-id' },
|
|
})
|
|
|
|
expect(
|
|
workflowSearchMatchMatchesQuery({ ...selectorMatch, displayLabel: 'Gucci Case' }, 'Test')
|
|
).toBe(false)
|
|
expect(
|
|
workflowSearchMatchMatchesQuery({ ...selectorMatch, displayLabel: 'Gucci Case' }, 'Gucci')
|
|
).toBe(true)
|
|
})
|
|
})
|