Skip to content

Commit 6274af3

Browse files
committed
wip(spec): migrate the two object-* fixtures in component.test.ts; ask each key at its own door in the binding pins
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
1 parent e47157c commit 6274af3

2 files changed

Lines changed: 34 additions & 21 deletions

File tree

packages/spec/src/ui/component.test.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,12 +2653,16 @@ describe('#7751 — object-* block props schemas', () => {
26532653
});
26542654

26552655
it('the corrected #7750 node (my-work.page.ts, post-fix) parses GREEN and retains its filter', () => {
2656+
// The node as the showcase authors it since #15442 / #15449: the
2657+
// `ViewFilterRule` array (ui#6206-B). The AST tuple this pin carried
2658+
// before is refused at `filter.0` now — pinned in the object-* filter
2659+
// describe below.
26562660
const parsed = ComponentPropsMap['object-grid'].parse({
26572661
objectName: 'showcase_task',
26582662
columns: ['title', 'project', 'status', 'priority', 'due_date'],
2659-
filter: [['owner_id', '=', '{current_user_id}']],
2663+
filter: [{ field: 'owner_id', operator: 'equals', value: '{current_user_id}' }],
26602664
});
2661-
expect(parsed.filter).toEqual([['owner_id', '=', '{current_user_id}']]);
2665+
expect(parsed.filter).toEqual([{ field: 'owner_id', operator: 'equals', value: '{current_user_id}' }]);
26622666
});
26632667

26642668
it("object-grid `data` takes the ViewDataSchema provider object — the ui#6207 convergence (Option A)", () => {
@@ -2733,10 +2737,13 @@ describe('#7751 — object-* block props schemas', () => {
27332737
it('every object-metric node of the showcase corpus parses GREEN (the clean-corpus control)', () => {
27342738
// Copies of all three my-work.page.ts metrics + the command-center shape
27352739
// (variant/format) — the exact nodes the lint must NOT start warning on.
2740+
// The three filters are the `ViewFilterRule` arrays the showcase authors
2741+
// since #15442 / #15449 (ui#6206-B); the records they replaced are refused
2742+
// at `filter` now (pinned in the object-* filter describe above).
27362743
const nodes = [
2737-
{ objectName: 'showcase_task', label: 'Open Tasks', icon: 'list-checks', colorVariant: 'blue', description: 'not done', aggregate: { field: 'id', function: 'count' }, filter: { status: { $ne: 'done' } } },
2738-
{ objectName: 'showcase_task', label: 'In Review', icon: 'eye', colorVariant: 'warning', description: 'awaiting review', aggregate: { field: 'id', function: 'count' }, filter: { status: 'in_review' } },
2739-
{ objectName: 'showcase_project', label: 'At-Risk Projects', icon: 'alert-triangle', colorVariant: 'danger', description: 'health red', aggregate: { field: 'id', function: 'count' }, filter: { health: 'red' } },
2744+
{ objectName: 'showcase_task', label: 'Open Tasks', icon: 'list-checks', colorVariant: 'blue', description: 'not done', aggregate: { field: 'id', function: 'count' }, filter: [{ field: 'status', operator: 'not_equals', value: 'done' }] },
2745+
{ objectName: 'showcase_task', label: 'In Review', icon: 'eye', colorVariant: 'warning', description: 'awaiting review', aggregate: { field: 'id', function: 'count' }, filter: [{ field: 'status', operator: 'equals', value: 'in_review' }] },
2746+
{ objectName: 'showcase_project', label: 'At-Risk Projects', icon: 'alert-triangle', colorVariant: 'danger', description: 'health red', aggregate: { field: 'id', function: 'count' }, filter: [{ field: 'health', operator: 'equals', value: 'red' }] },
27402747
{ objectName: 'showcase_task', label: 'Tasks', colorVariant: 'purple', variant: 'bare', aggregate: { field: 'id', function: 'count' }, format: '0,0' },
27412748
];
27422749
for (const node of nodes) {

packages/spec/src/ui/page.test.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
type ElementDataSource,
1616
type InterfacePageConfig,
1717
} from './page.zod';
18+
import { ComponentPropsMap } from './component.zod';
1819

1920
describe('PageComponentSchema', () => {
2021
it('should accept valid minimal component', () => {
@@ -666,6 +667,9 @@ describe('ElementDataSourceSchema `filter` — one filter orthography platform-w
666667
/** The issues a parse raised under `key` (top-level), whatever else it raised. */
667668
const issuesUnder = (r: ParseResult, key: string) =>
668669
r.success ? [] : r.error!.issues.filter((i) => i.path[0] === key);
670+
/** The issues located EXACTLY at `path` (dotted) — `filter` is not `filter.0`. */
671+
const issuesAt = (r: ParseResult, path: string) =>
672+
r.success ? [] : r.error!.issues.filter((i) => i.path.join('.') === path);
669673

670674
it('accepts a ViewFilterRule[] filter — the acceptance criterion', () => {
671675
// Before #15442 this exact value was REFUSED here (`invalid_type`, expected
@@ -727,34 +731,36 @@ describe('ElementDataSourceSchema `filter` — one filter orthography platform-w
727731
// seventeen off-spec authors at the pin are the seat's objectui follow-up.
728732
const r = ElementDataSourceSchema.safeParse({ object: 'account', filter: TUPLE_ARRAY });
729733
expect(r.success).toBe(false);
730-
expect(issuesUnder(r, 'filter')).toEqual([]);
731-
const atElement = r.error!.issues.filter((i) => i.path.join('.') === 'filter.0');
732-
expect(atElement.map((i) => i.code)).toEqual(['invalid_type']);
734+
expect(issuesAt(r, 'filter')).toEqual([]);
735+
expect(issuesAt(r, 'filter.0').map((i) => i.code)).toEqual(['invalid_type']);
736+
expect(issuesAt(r, 'filter.0')[0]).toMatchObject({ expected: 'object' });
733737
});
734738

735739
it('shares the array orthography with the props-map `filter` doors — one value, two keys, the same verdicts', () => {
736740
// `element:record_picker` was the node that carried two orthographies at
737741
// two keys (`properties.filter` the array, `dataSource.filter` the record)
738-
// resolved through one `??` in the renderer. The same rule array now raises
739-
// no issue at either key, and the same record is refused at both with the
740-
// same code — measured through the real `PageComponentSchema`, the door an
741-
// authored page actually passes.
742-
const both = PageComponentSchema.safeParse({
742+
// resolved through one `??` in the renderer. Each key is asked at ITS
743+
// door: the binding through the real `PageComponentSchema` (which parses
744+
// `dataSource` and leaves `properties` a bag — the props-map dispatch is
745+
// the lint's, warning tier), and the props key through the picker's own
746+
// `ComponentPropsMap` entry. The same rule array raises no issue at either;
747+
// the same record is refused at both with the same code.
748+
const binding = PageComponentSchema.safeParse({
743749
type: 'element:record_picker',
744750
properties: { object: 'account', filter: RULES },
745751
dataSource: { object: 'account', filter: RULES },
746752
});
747-
expect(both.success).toBe(true);
748-
const bothRecords = PageComponentSchema.safeParse({
753+
expect(binding.success).toBe(true);
754+
const bindingRecord = PageComponentSchema.safeParse({
749755
type: 'element:record_picker',
750-
properties: { object: 'account', filter: RECORD_FORM },
756+
properties: { object: 'account', filter: RULES },
751757
dataSource: { object: 'account', filter: RECORD_FORM },
752758
});
753-
expect(bothRecords.success).toBe(false);
754-
const codesAt = (path: string) =>
755-
bothRecords.error!.issues.filter((i) => i.path.join('.') === path).map((i) => i.code);
756-
expect(codesAt('dataSource.filter')).toEqual(['invalid_type']);
757-
expect(codesAt('properties.filter')).toEqual(codesAt('dataSource.filter'));
759+
expect(issuesAt(bindingRecord, 'dataSource.filter').map((i) => i.code)).toEqual(['invalid_type']);
760+
const picker = ComponentPropsMap['element:record_picker'];
761+
expect(issuesAt(picker.safeParse({ object: 'account', filter: RULES }), 'filter')).toEqual([]);
762+
expect(issuesAt(picker.safeParse({ object: 'account', filter: RECORD_FORM }), 'filter').map((i) => i.code))
763+
.toEqual(issuesAt(bindingRecord, 'dataSource.filter').map((i) => i.code));
758764
});
759765
});
760766

0 commit comments

Comments
 (0)