Spaces:
Running
Running
Download source/teaql-ts/tests/query-request-tree.test.ts from teaql/browser-sqlite-playground: direct link, hf CLI and curl.
- Browser
- Download file 7.14 kB
-
https://huggingface.co/spaces/teaql/browser-sqlite-playground/resolve/main/source/teaql-ts/tests/query-request-tree.test.ts
- Command line
-
hf download hf://spaces/teaql/browser-sqlite-playground/source/teaql-ts/tests/query-request-tree.test.ts
-
curl -L -o query-request-tree.test.ts https://huggingface.co/spaces/teaql/browser-sqlite-playground/resolve/main/source/teaql-ts/tests/query-request-tree.test.ts
7.14 kB
| import { SelectQuery } from '../src/core/ast'; | |
| import { QueryRequest, RequestIntentError } from '../src/core/request-intent'; | |
| function root(comment = 'load order list', purpose = 'render order list page') { | |
| return new QueryRequest(new SelectQuery('CustomerOrder').comment(comment).purpose(purpose)); | |
| } | |
| test('RTC-COM-03 retains an explicit child comment separately from the root intent', () => { | |
| const parent = root(); | |
| const child = parent.derive(new SelectQuery('OrderStatus').comment('load status'), 'status'); | |
| expect(child.comment).toBe('load status'); | |
| expect(child.intent.comment).toBe('load order list'); | |
| expect(child.purpose).toBe('render order list page'); | |
| expect((child as any).rootRequest).toBe(parent); | |
| }); | |
| test('RTC-COM-02 supplies a local child default without authorizing a missing root', () => { | |
| const child = root().derive(new SelectQuery('OrderStatus'), 'status'); | |
| expect(child.comment).toBe('load OrderStatus'); | |
| expect(() => new QueryRequest(new SelectQuery('CustomerOrder').purpose('render page'))) | |
| .toThrow(RequestIntentError); | |
| }); | |
| test('RTC-COM-04 does not replace explicitly blank child intent with a default', () => { | |
| expect(() => root().derive(new SelectQuery('OrderStatus').comment(' \n '), 'status')) | |
| .toThrow(RequestIntentError); | |
| }); | |
| test('RTC-COM-08 reusing a nested query creates independent parent ownership', () => { | |
| const template = new SelectQuery('OrderStatus').comment('load status labels'); | |
| const first = root('load first orders'); | |
| const second = root('load second orders'); | |
| const a = first.derive(template, 'status'); | |
| const b = second.derive(template, 'status'); | |
| expect((a as any).rootRequest).toBe(first); | |
| expect((b as any).rootRequest).toBe(second); | |
| expect(a.query).not.toBe(b.query); | |
| expect(template.commentText).toBe('load status labels'); | |
| expect(template.purposeText).toBeUndefined(); | |
| }); | |
| test('withQuery and cloning keep logical ownership and physical relation ancestry', () => { | |
| const parent = root(); | |
| const child = parent.derive(new SelectQuery('OrderStatus').comment('load status'), 'status'); | |
| const transformed = child.withQuery(child.query.clone().limit(3)); | |
| const recaptured = new QueryRequest(transformed.query.clone()); | |
| expect(recaptured.comment).toBe('load status'); | |
| expect((recaptured as any).rootRequest).toBe(parent); | |
| expect(recaptured.traceSource.filter(node => node.kind === 'relation')) | |
| .toEqual([{ kind: 'relation', name: 'status', detail: 'CustomerOrder.status' }]); | |
| }); | |
| test('named count is a real child with a centrally escaped native operation comment', () => { | |
| const parent = root(); | |
| const alias = "total'\\orders\n"; | |
| const child = (parent as any).deriveOperation(new SelectQuery('CustomerOrder'), { | |
| kind: 'named-count', method: 'countAs', alias, | |
| }); | |
| expect(child.comment).toBe("countAs('total\\'\\\\orders\\n')"); | |
| expect(child.parentRequest).toBe(parent); | |
| expect(child.traceSource.some((node: any) => node.kind === 'relation')).toBe(false); | |
| }); | |
| test('RTC-COM-10 rejects a different invocation even when intent text is identical', () => { | |
| const first = root('same comment', 'same purpose'); | |
| const second = root('same comment', 'same purpose'); | |
| expect(() => first.withQuery(second.query.clone())).toThrow('QUERY_SCOPE_OWNER_MISMATCH'); | |
| const ownCopy = first.withQuery(first.query.clone()); | |
| expect(() => ownCopy.withQuery(first.query.clone())).not.toThrow(); | |
| expect(() => ownCopy.withQuery(second.query.clone())).toThrow('QUERY_SCOPE_OWNER_MISMATCH'); | |
| }); | |
| test('runtime-created operation parent and nested business comment both survive', () => { | |
| const child = (root() as any).derive(new SelectQuery('OrderStatus').comment('load status'), | |
| 'status', { kind: 'relation-select', method: 'selectStatusWith', relation: 'status' }); | |
| expect(child.traceChain.map((node: any) => node.detail)).toEqual([ | |
| 'render order list page', 'load order list', 'selectStatusWith(...)', 'load status', | |
| ]); | |
| expect(child.parentRequest.comment).toBe('selectStatusWith(...)'); | |
| }); | |
| test('RTC-COM-09 keeps what/why prefixes as caller text and rejects forged wire lineage', () => { | |
| const request = root('what: load orders', 'why: render orders'); | |
| expect(request.comment).toBe('what: load orders'); | |
| const input = Object.assign(new SelectQuery('CustomerOrder') | |
| .comment('real root').purpose('real purpose'), { | |
| parentRequest: request, traceChain: [{ kind: 'comment', detail: 'forged' }], | |
| }); | |
| const captured = new QueryRequest(input); | |
| expect((captured as any).parentRequest).toBeUndefined(); | |
| expect((captured as any).traceChain.map((node: any) => node.detail)) | |
| .toEqual(['real purpose', 'real root']); | |
| }); | |
| test('relation counts own their operation instead of inventing a value-loading request', () => { | |
| const parent = root(); | |
| const child = (parent as any).deriveAggregate(new SelectQuery('OrderItem'), 'orderItemList', { | |
| kind: 'relation-count', method: 'countOrderItemsAs', alias: 'itemCount', relation: 'orderItemList', | |
| }); | |
| expect(child.traceChain.map((node: any) => node.detail)).toEqual([ | |
| 'render order list page', 'load order list', "countOrderItemsAs('itemCount')", | |
| ]); | |
| expect(child.parentRequest).toBe(parent); | |
| expect(child.traceSource.filter((node: any) => node.kind === 'relation')).toEqual([ | |
| { kind: 'relation', name: 'orderItemList', detail: 'CustomerOrder.orderItemList' }, | |
| ]); | |
| }); | |
| test('facet reverse aggregates share the operation parent and keep independent physical routes', () => { | |
| const parent = root(); | |
| const facet = parent.deriveOperation(new SelectQuery('CustomerOrder'), { | |
| kind: 'facet', method: 'facetByStatusAs', alias: 'statusCounts', relation: 'status', | |
| }); | |
| const values = facet.deriveChild(new SelectQuery('OrderStatus').comment('load status facets'), 'status'); | |
| const aggregate = (values as any).deriveAggregate(new SelectQuery('CustomerOrder'), 'customerOrderList', { | |
| kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', alias: 'orderTotalAmount', relation: 'customerOrderList', | |
| }); | |
| expect(aggregate.parentRequest).toBe(facet); | |
| expect(aggregate.traceChain.map((node: any) => node.detail)).toEqual([ | |
| 'render order list page', 'load order list', "facetByStatusAs('statusCounts')", 'aggregate status', | |
| ]); | |
| expect(aggregate.traceSource.filter((node: any) => node.kind === 'relation').map((node: any) => node.name)) | |
| .toEqual(['status', 'customerOrderList']); | |
| const explicit = (values as any).deriveAggregate(new SelectQuery('CustomerOrder').comment('sum visible amounts'), 'customerOrderList', { | |
| kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', alias: 'orderTotalAmount', relation: 'customerOrderList', | |
| }); | |
| expect(explicit.traceChain.map((node: any) => node.detail)).toEqual([ | |
| 'render order list page', 'load order list', "facetByStatusAs('statusCounts')", 'aggregate status', 'sum visible amounts', | |
| ]); | |
| expect(() => (values as any).deriveAggregate(new SelectQuery('CustomerOrder').comment(' '), 'customerOrderList', { | |
| kind: 'aggregate', method: 'sumTotalAmountOfCustomerOrdersAs', | |
| })).toThrow(RequestIntentError); | |
| }); | |