diff --git a/packages/app/src/cli/models/app/app.test-data.ts b/packages/app/src/cli/models/app/app.test-data.ts index f9933958bf..83ec2c58cc 100644 --- a/packages/app/src/cli/models/app/app.test-data.ts +++ b/packages/app/src/cli/models/app/app.test-data.ts @@ -478,6 +478,7 @@ function defaultFunctionConfiguration(): FunctionConfigType { type: 'product_discounts', build: { command: 'echo "hello world"', + watch: ['src/**/*.rs'], }, api_version: '2022-07', configuration_ui: true, diff --git a/packages/app/src/cli/services/dev/app-events/app-event-watcher.test.ts b/packages/app/src/cli/services/dev/app-events/app-event-watcher.test.ts index a25c8b0b0f..59cb7cd4c8 100644 --- a/packages/app/src/cli/services/dev/app-events/app-event-watcher.test.ts +++ b/packages/app/src/cli/services/dev/app-events/app-event-watcher.test.ts @@ -11,7 +11,7 @@ import { } from '../../../models/app/app.test-data.js' import {ExtensionInstance} from '../../../models/extensions/extension-instance.js' import {loadApp, reloadApp} from '../../../models/app/loader.js' -import {AppInterface} from '../../../models/app/app.js' +import {AppLinkedInterface} from '../../../models/app/app.js' import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest' import {AbortSignal, AbortController} from '@shopify/cli-kit/node/abort' import {flushPromises} from '@shopify/cli-kit/node/promises' @@ -260,7 +260,6 @@ describe('app-event-watcher', () => { const mockManager = new MockESBuildContextManager() const mockFileWatcher = new MockFileWatcher(app, outputOptions, [fileWatchEvent]) - const watcher = new AppEventWatcher(app, 'url', buildOutputPath, mockManager, mockFileWatcher) const emitSpy = vi.spyOn(watcher, 'emit') await watcher.start({stdout, stderr, signal: abortController.signal}) @@ -290,6 +289,7 @@ describe('app-event-watcher', () => { extensionEvents: expect.arrayContaining(extensionEvents), startTime: expect.anything(), path: expect.anything(), + appWasReloaded: needsAppReload, }) const initialEvents = app.realExtensions.map((eve) => ({ @@ -426,7 +426,7 @@ class MockFileWatcher extends FileWatcher { private readonly events: WatcherEvent[] private listener?: (events: WatcherEvent[]) => void - constructor(app: AppInterface, options: OutputContextOptions, events: WatcherEvent[]) { + constructor(app: AppLinkedInterface, options: OutputContextOptions, events: WatcherEvent[]) { super(app, options) this.events = events } diff --git a/packages/app/src/cli/services/dev/app-events/file-watcher.test.ts b/packages/app/src/cli/services/dev/app-events/file-watcher.test.ts index 8ea8537248..07f9f3e6c6 100644 --- a/packages/app/src/cli/services/dev/app-events/file-watcher.test.ts +++ b/packages/app/src/cli/services/dev/app-events/file-watcher.test.ts @@ -1,9 +1,9 @@ import {FileWatcher, OutputContextOptions, WatcherEvent} from './file-watcher.js' import { - testApp, testAppAccessConfigExtension, testAppConfigExtensions, testAppLinked, + testFunctionExtension, testUIExtension, } from '../../../models/app/app.test-data.js' import {flushPromises} from '@shopify/cli-kit/node/promises' @@ -12,10 +12,12 @@ import chokidar from 'chokidar' import {AbortSignal} from '@shopify/cli-kit/node/abort' import {inTemporaryDirectory, mkdir, writeFile} from '@shopify/cli-kit/node/fs' import {joinPath} from '@shopify/cli-kit/node/path' +import {sleep} from '@shopify/cli-kit/node/system' const extension1 = await testUIExtension({type: 'ui_extension', handle: 'h1', directory: '/extensions/ui_extension_1'}) const extension1B = await testUIExtension({type: 'ui_extension', handle: 'h2', directory: '/extensions/ui_extension_1'}) const extension2 = await testUIExtension({type: 'ui_extension', directory: '/extensions/ui_extension_2'}) +const functionExtension = await testFunctionExtension({dir: '/extensions/my-function'}) const posExtension = await testAppConfigExtensions() const appAccessExtension = await testAppAccessConfigExtension() @@ -30,7 +32,7 @@ interface TestCaseSingleEvent { name: string fileSystemEvent: string path: string - expectedEvent: WatcherEvent + expectedEvent?: WatcherEvent } /** @@ -127,6 +129,12 @@ const singleEventTestCases: TestCaseSingleEvent[] = [ startTime: expect.any(Array), }, }, + { + name: 'change in function extension is ignored if not in watch list', + fileSystemEvent: 'change', + path: '/extensions/my-function/src/cargo.lock', + expectedEvent: undefined, + }, ] const multiEventTestCases: TestCaseMultiEvent[] = [ @@ -167,8 +175,8 @@ const multiEventTestCases: TestCaseMultiEvent[] = [ ] const outputOptions: OutputContextOptions = {stdout: process.stdout, stderr: process.stderr, signal: new AbortSignal()} -const defaultApp = testApp({ - allExtensions: [extension1, extension1B, extension2, posExtension, appAccessExtension], +const defaultApp = testAppLinked({ + allExtensions: [extension1, extension1B, extension2, posExtension, appAccessExtension, functionExtension], directory: '/', configuration: {scopes: '', extension_directories: ['/extensions'], path: '/shopify.app.toml'}, }) @@ -205,17 +213,7 @@ describe('file-watcher events', () => { // Then expect(watchSpy).toHaveBeenCalledWith([joinPath(dir, '/shopify.app.toml'), joinPath(dir, '/extensions')], { - ignored: [ - '**/node_modules/**', - '**/.git/**', - '**/*.test.*', - '**/dist/**', - '**/*.swp', - '**/generated/**', - joinPath(dir, '/extensions/ext1/a_folder'), - joinPath(dir, '/extensions/ext1/a_file.txt'), - joinPath(dir, '/extensions/ext1/**/nested/**'), - ], + ignored: ['**/node_modules/**', '**/.git/**', '**/*.test.*', '**/dist/**', '**/*.swp', '**/generated/**'], ignoreInitial: true, persistent: true, }) @@ -244,12 +242,17 @@ describe('file-watcher events', () => { await flushPromises() // use waitFor to so that we can test the debouncers and timeouts - await vi.waitFor( - () => { - expect(onChange).toHaveBeenCalledWith([expectedEvent]) - }, - {timeout: 2000, interval: 100}, - ) + if (expectedEvent) { + await vi.waitFor( + () => { + expect(onChange).toHaveBeenCalledWith([expectedEvent]) + }, + {timeout: 2000, interval: 100}, + ) + } else { + await sleep(0.01) + expect(onChange).not.toHaveBeenCalled() + } }, )