@@ -2,39 +2,29 @@ import fs from "node:fs/promises";
22import path from "node:path" ;
33import { describe , expect , it } from "vitest" ;
44import { MACOS_APP_SOURCES_DIR } from "../compat/legacy-names.js" ;
5- import { CronPayloadSchema } from "../gateway/protocol/schema.js" ;
5+ import { CronDeliverySchema } from "../gateway/protocol/schema.js" ;
66
77type SchemaLike = {
8- anyOf ?: Array < { properties ?: Record < string , unknown > } > ;
8+ anyOf ?: Array < { properties ?: Record < string , unknown > ; const ?: unknown } > ;
99 properties ?: Record < string , unknown > ;
1010 const ?: unknown ;
1111} ;
1212
13- type ProviderSchema = {
14- anyOf ?: Array < { const ?: unknown } > ;
15- } ;
16-
17- function extractCronChannels ( schema : SchemaLike ) : string [ ] {
18- const union = schema . anyOf ?? [ ] ;
19- const payloadWithChannel = union . find ( ( entry ) =>
20- Boolean ( entry ?. properties && "channel" in entry . properties ) ,
21- ) ;
22- const channelSchema = payloadWithChannel ?. properties
23- ? ( payloadWithChannel . properties . channel as ProviderSchema )
24- : undefined ;
25- const channels = ( channelSchema ?. anyOf ?? [ ] )
13+ function extractDeliveryModes ( schema : SchemaLike ) : string [ ] {
14+ const modeSchema = schema . properties ?. mode as SchemaLike | undefined ;
15+ return ( modeSchema ?. anyOf ?? [ ] )
2616 . map ( ( entry ) => entry ?. const )
2717 . filter ( ( value ) : value is string => typeof value === "string" ) ;
28- return channels ;
2918}
3019
3120const UI_FILES = [ "ui/src/ui/types.ts" , "ui/src/ui/ui-types.ts" , "ui/src/ui/views/cron.ts" ] ;
3221
33- const SWIFT_FILE_CANDIDATES = [ `${ MACOS_APP_SOURCES_DIR } /GatewayConnection.swift` ] ;
22+ const SWIFT_MODEL_CANDIDATES = [ `${ MACOS_APP_SOURCES_DIR } /CronModels.swift` ] ;
23+ const SWIFT_STATUS_CANDIDATES = [ `${ MACOS_APP_SOURCES_DIR } /GatewayConnection.swift` ] ;
3424
35- async function resolveSwiftFiles ( cwd : string ) : Promise < string [ ] > {
25+ async function resolveSwiftFiles ( cwd : string , candidates : string [ ] ) : Promise < string [ ] > {
3626 const matches : string [ ] = [ ] ;
37- for ( const relPath of SWIFT_FILE_CANDIDATES ) {
27+ for ( const relPath of candidates ) {
3828 try {
3929 await fs . access ( path . join ( cwd , relPath ) ) ;
4030 matches . push ( relPath ) ;
@@ -43,30 +33,32 @@ async function resolveSwiftFiles(cwd: string): Promise<string[]> {
4333 }
4434 }
4535 if ( matches . length === 0 ) {
46- throw new Error ( `Missing Swift cron definition. Tried: ${ SWIFT_FILE_CANDIDATES . join ( ", " ) } ` ) ;
36+ throw new Error ( `Missing Swift cron definition. Tried: ${ candidates . join ( ", " ) } ` ) ;
4737 }
4838 return matches ;
4939}
5040
5141describe ( "cron protocol conformance" , ( ) => {
52- it ( "ui + swift include all cron providers from gateway schema" , async ( ) => {
53- const channels = extractCronChannels ( CronPayloadSchema as SchemaLike ) ;
54- expect ( channels . length ) . toBeGreaterThan ( 0 ) ;
42+ it ( "ui + swift include all cron delivery modes from gateway schema" , async ( ) => {
43+ const modes = extractDeliveryModes ( CronDeliverySchema as SchemaLike ) ;
44+ expect ( modes . length ) . toBeGreaterThan ( 0 ) ;
5545
5646 const cwd = process . cwd ( ) ;
5747 for ( const relPath of UI_FILES ) {
5848 const content = await fs . readFile ( path . join ( cwd , relPath ) , "utf-8" ) ;
59- for ( const channel of channels ) {
60- expect ( content . includes ( `"${ channel } "` ) , `${ relPath } missing ${ channel } ` ) . toBe ( true ) ;
49+ for ( const mode of modes ) {
50+ expect ( content . includes ( `"${ mode } "` ) , `${ relPath } missing delivery mode ${ mode } ` ) . toBe (
51+ true ,
52+ ) ;
6153 }
6254 }
6355
64- const swiftFiles = await resolveSwiftFiles ( cwd ) ;
65- for ( const relPath of swiftFiles ) {
56+ const swiftModelFiles = await resolveSwiftFiles ( cwd , SWIFT_MODEL_CANDIDATES ) ;
57+ for ( const relPath of swiftModelFiles ) {
6658 const content = await fs . readFile ( path . join ( cwd , relPath ) , "utf-8" ) ;
67- for ( const channel of channels ) {
68- const pattern = new RegExp ( `\\bcase\\s+${ channel } \\b` ) ;
69- expect ( pattern . test ( content ) , `${ relPath } missing case ${ channel } ` ) . toBe ( true ) ;
59+ for ( const mode of modes ) {
60+ const pattern = new RegExp ( `\\bcase\\s+${ mode } \\b` ) ;
61+ expect ( pattern . test ( content ) , `${ relPath } missing case ${ mode } ` ) . toBe ( true ) ;
7062 }
7163 }
7264 } ) ;
@@ -78,7 +70,7 @@ describe("cron protocol conformance", () => {
7870 expect ( uiTypes . includes ( "jobs:" ) ) . toBe ( true ) ;
7971 expect ( uiTypes . includes ( "jobCount" ) ) . toBe ( false ) ;
8072
81- const [ swiftRelPath ] = await resolveSwiftFiles ( cwd ) ;
73+ const [ swiftRelPath ] = await resolveSwiftFiles ( cwd , SWIFT_STATUS_CANDIDATES ) ;
8274 const swiftPath = path . join ( cwd , swiftRelPath ) ;
8375 const swift = await fs . readFile ( swiftPath , "utf-8" ) ;
8476 expect ( swift . includes ( "struct CronSchedulerStatus" ) ) . toBe ( true ) ;
0 commit comments