import { vol } from 'memfs'; import { getConfigFilePaths, modifyConfigAsync } from '../Config'; import { getDynamicConfig, getStaticConfig } from '../getConfig'; const mockConfigContext = {} as any; jest.mock('fs'); describe(modifyConfigAsync, () => { beforeAll(async () => { vol.fromJSON( { 'package.json': JSON.stringify({}), }, 'no-config' ); vol.fromJSON( { 'package.json': JSON.stringify({}), 'app.config.js': 'export default {};', 'app.config.json': JSON.stringify({}), }, 'dynamic-and-static' ); vol.fromJSON( { 'app.config.json': JSON.stringify( { name: 'app-config-json', slug: 'app-config-json', version: '1.0.0', platforms: [], }, null, 2 ), 'app.json': JSON.stringify( { name: 'app-json', }, null, 2 ), 'package.json': JSON.stringify({}), }, 'static-override' ); }); afterAll(() => { vol.reset(); }); it(`can write to a static only config`, async () => { const { type, config } = await modifyConfigAsync( 'static-override', { foo: 'bar' } as any, { skipSDKVersionRequirement: true }, { dryRun: true } ); expect(type).toBe('success'); // @ts-ignore: foo property is not defined expect(config.foo).toBe('bar'); }); it(`cannot write to a dynamic config`, async () => { const { type, config } = await modifyConfigAsync( 'dynamic-and-static', {}, { skipSDKVersionRequirement: true }, { dryRun: true } ); expect(type).toBe('warn'); expect(config).toBe(null); }); it(`cannot write to a project without a config`, async () => { const { type, config } = await modifyConfigAsync( 'no-config', {}, { skipSDKVersionRequirement: true }, { dryRun: true } ); expect(type).toBe('fail'); expect(config).toBe(null); }); }); const invalidConfig = `/* eslint-disable */ module.exports = { name: 'app', > slug: 'app', }`; describe(getDynamicConfig, () => { beforeAll(async () => { vol.fromJSON( { 'exports-function.app.config.js': `export default function (config) { return { ...config }; }`, 'exports-object.app.config.js': `export default {};`, }, 'dynamic-export-types' ); vol.fromJSON( { // This file exists to test that an invalid app.config.ts // gets used instead of defaulting to a valid app.config.js 'app.config.js': `export default {};`, // This is a syntax error: 'app.config.ts': invalidConfig, }, 'syntax-error' ); vol.fromJSON( { // This is a missing import 'app.config.ts': [`import 'foobar'`, 'module.exports = {}'].join('\n'), }, 'missing-import-error' ); }); afterAll(() => { vol.reset(); }); it(`exports a function`, () => { expect( getDynamicConfig('dynamic-export-types/exports-function.app.config.js', mockConfigContext) .exportedObjectType ).toBe('function'); }); it(`exports an object`, () => { expect( getDynamicConfig('dynamic-export-types/exports-object.app.config.js', mockConfigContext) .exportedObjectType ).toBe('object'); }); // This tests error are thrown properly and ensures that a more specific // config is used instead of defaulting to a valid substitution. it(`throws a useful error for dynamic configs with a syntax error`, () => { const paths = getConfigFilePaths('syntax-error'); expect(() => getDynamicConfig(paths.dynamicConfigPath!, mockConfigContext)).toThrowError( /Error .* \(5:7\)/ ); }); // This tests error are thrown properly and ensures that a more specific // config is used instead of defaulting to a valid substitution. it(`throws a useful error for dynamic configs with a missing import`, () => { const paths = getConfigFilePaths('missing-import-error'); expect(() => getDynamicConfig(paths.dynamicConfigPath!, mockConfigContext)).toThrowError( /Require stack/ ); }); }); describe(getStaticConfig, () => { beforeAll(async () => { vol.fromJSON( { 'package.json': JSON.stringify({}), 'app.json': JSON.stringify( { name: 'app-json', }, null, 2 ), 'app.config.json': JSON.stringify( { name: 'app-config-json', slug: 'app-config-json', version: '1.0.0', platforms: [], }, null, 2 ), }, 'static-override' ); }); afterAll(() => { vol.reset(); }); // This tests error are thrown properly and ensures that a more specific // config is used instead of defaulting to a valid substitution. it(`uses app.config.json instead of app.json if both exist`, () => { const paths = getConfigFilePaths('static-override'); expect(paths.staticConfigPath).toMatch(/app\.config\.json/); expect(getStaticConfig(paths.staticConfigPath!).name).toBe('app-config-json'); }); });