diff --git a/package/expo-package/src/optionalDependencies/AudioVideo.ts b/package/expo-package/src/optionalDependencies/AudioVideo.ts index 538e341683..783155eb34 100644 --- a/package/expo-package/src/optionalDependencies/AudioVideo.ts +++ b/package/expo-package/src/optionalDependencies/AudioVideo.ts @@ -9,10 +9,4 @@ try { // do nothing } -if (!AudioComponent) { - console.log( - 'The audio library is currently not installed. To allow in-app audio playback, install the "expo-av" package.', - ); -} - export { AudioComponent, RecordingObject }; diff --git a/package/expo-package/src/optionalDependencies/Sound.ts b/package/expo-package/src/optionalDependencies/Sound.ts index 5dc0a1835e..600d4a496e 100644 --- a/package/expo-package/src/optionalDependencies/Sound.ts +++ b/package/expo-package/src/optionalDependencies/Sound.ts @@ -13,6 +13,13 @@ try { // do nothing } +// Playback and recording use expo-audio, or the deprecated expo-av when only that is installed. +if (!ExpoAudioComponent && !AudioComponent) { + console.log( + 'The audio library is currently not installed. To allow in-app audio playback and voice recording, install the "expo-audio" package.', + ); +} + export const Sound = { // Always try to prioritize expo-audio if it's there. initializeSound: ExpoAudioComponent diff --git a/package/expo-package/src/optionalDependencies/__tests__/Sound.test.ts b/package/expo-package/src/optionalDependencies/__tests__/Sound.test.ts new file mode 100644 index 0000000000..34f697a95c --- /dev/null +++ b/package/expo-package/src/optionalDependencies/__tests__/Sound.test.ts @@ -0,0 +1,48 @@ +// A missing module is a mock whose factory throws, as `require` does for a package that isn't installed. +const mockOptionalModule = (name: string, exports?: object) => + jest.doMock( + name, + () => { + if (!exports) { + throw new Error(`Cannot find module '${name}'`); + } + return exports; + }, + { virtual: true }, + ); + +const audioLibraryLogsOnLoad = () => { + const log = jest.spyOn(console, 'log').mockImplementation(() => undefined); + require('../Sound'); + return log.mock.calls + .flat() + .filter((message) => typeof message === 'string' && message.includes('audio library')); +}; + +describe('expo Sound', () => { + afterEach(() => { + jest.resetModules(); + jest.restoreAllMocks(); + }); + + it('asks for no audio library when only expo-audio is installed', () => { + mockOptionalModule('expo-audio', { AudioModule: {}, createAudioPlayer: jest.fn() }); + mockOptionalModule('expo-av'); + + expect(audioLibraryLogsOnLoad()).toEqual([]); + }); + + it('asks for no audio library when only expo-av is installed', () => { + mockOptionalModule('expo-audio'); + mockOptionalModule('expo-av', { Audio: {} }); + + expect(audioLibraryLogsOnLoad()).toEqual([]); + }); + + it('asks for expo-audio when no audio library is installed', () => { + mockOptionalModule('expo-audio'); + mockOptionalModule('expo-av'); + + expect(audioLibraryLogsOnLoad()).toEqual([expect.stringContaining('"expo-audio"')]); + }); +});