/** * Copyright (c) 2026, Salesforce, Inc., * All rights reserved. * For full license text, see the LICENSE.txt file */ import { buildSchema, type GraphQLSchema } from "graphql"; import { describe, expect, it } from "vitest"; import { dispatchQueryCommand } from "../../commands/query.js"; import { applyCommand } from "../apply-command.js"; import { renderQuery } from "../query-builder.js"; import { createSession, saveSession, loadSession } from "../session.js"; import { primeSchemaCache } from "../walker.js"; const SCHEMA: GraphQLSchema = buildSchema(` type Query { uiapi: UIAPI! } type UIAPI { query: RecordQuery! } type RecordQuery { Case(first: Int, after: String, where: Case_Filter, orderBy: Case_OrderBy): CaseConnection! } input Case_Filter { Status: PicklistOperators, Subject: StringOperators } input Case_OrderBy { CreatedDate: OrderByClause } input PicklistOperators { eq: String, ne: String, in: [String!] } input StringOperators { eq: String, like: String } input OrderByClause { order: Order! } enum Order { ASC DESC } type CaseConnection { edges: [CaseEdge!]!, pageInfo: PageInfo! } type CaseEdge { node: Case! } type PageInfo { hasNextPage: Boolean!, endCursor: String } type Case { Id: ID!, Subject: StringValue, Status: StringValue } type StringValue { value: String } `); const ORG = "test-parity"; const ORG_URL = "https://test-parity.my.salesforce.com"; primeSchemaCache(ORG, SCHEMA); primeSchemaCache(ORG_URL, SCHEMA); // Each case = a sequence of commands run through BOTH engines; we compare the // final rendered query. All set commands use an absolute field-path prefix // (raw sessions never `cd`, so prefix-less forms are out of scope by design). const CASES: { name: string; commands: string[] }[] = [ { name: "select dotted leaf", commands: ["select uiapi/query/Case/edges/node/Subject/value"] }, { name: "select with alias", commands: ["select uiapi/query/Case/edges/node/Subject/value:subj"], }, { name: "select multiple leaves", commands: ["select uiapi/query/Case/edges/node/Id uiapi/query/Case/edges/node/Subject/value"], }, { name: "set scalar arg", commands: ["set uiapi/query/Case first=5"] }, { name: "set where shorthand → JSON", commands: ["set uiapi/query/Case where.Status=New"] }, { name: "set where like on % wildcard", commands: ["set uiapi/query/Case where.Subject=Acme%"] }, { name: "set orderBy shorthand", commands: ["set uiapi/query/Case orderBy=CreatedDate:DESC"] }, { name: "set where=$var deferred binding", commands: ["set uiapi/query/Case where.Status=$status"], }, { name: "set multiple specs", commands: ["set uiapi/query/Case first=5 where.Status=New"] }, { name: "var declare+bind", commands: ["var $status uiapi/query/Case/@args/where/Status/eq"] }, { name: "select + set + var sequence", commands: [ "select uiapi/query/Case/edges/node/Subject/value", "set uiapi/query/Case first=10", "var $status uiapi/query/Case/@args/where/Status/eq", ], }, ]; function viaApplyCommand(commands: string[]): string { const session = createSession(ORG, "query", ORG_URL); for (const cmd of commands) applyCommand(session, SCHEMA, cmd); return renderQuery(session); } async function viaDispatcher(commands: string[]): Promise { const session = createSession(ORG, "query", ORG_URL); saveSession(session); const id = session.id; for (const cmd of commands) { const [verb, ...rest] = cmd.split(/\s+/); await dispatchQueryCommand(id, verb, rest, {}); } return renderQuery(loadSession(id)); } describe("lib/apply-command — parity with CLI dispatcher", () => { for (const c of CASES) { it(`renders identically: ${c.name}`, async () => { const fromApply = viaApplyCommand(c.commands); const fromDispatch = await viaDispatcher(c.commands); expect(fromApply).toEqual(fromDispatch); }); } });