1082815dcSEvan Baconimport { vol } from 'memfs'; 2082815dcSEvan Bacon 3082815dcSEvan Baconimport { getConfigFilePaths, modifyConfigAsync } from '../Config'; 4082815dcSEvan Baconimport { getDynamicConfig, getStaticConfig } from '../getConfig'; 5082815dcSEvan Bacon 6082815dcSEvan Baconconst mockConfigContext = {} as any; 7082815dcSEvan Bacon 8082815dcSEvan Baconjest.mock('fs'); 9082815dcSEvan Bacon 10082815dcSEvan Bacondescribe(modifyConfigAsync, () => { 11082815dcSEvan Bacon beforeAll(async () => { 12082815dcSEvan Bacon vol.fromJSON( 13082815dcSEvan Bacon { 14082815dcSEvan Bacon 'package.json': JSON.stringify({}), 15082815dcSEvan Bacon }, 16082815dcSEvan Bacon 'no-config' 17082815dcSEvan Bacon ); 18082815dcSEvan Bacon vol.fromJSON( 19082815dcSEvan Bacon { 20082815dcSEvan Bacon 'package.json': JSON.stringify({}), 21082815dcSEvan Bacon 'app.config.js': 'export default {};', 22082815dcSEvan Bacon 'app.config.json': JSON.stringify({}), 23082815dcSEvan Bacon }, 24082815dcSEvan Bacon 'dynamic-and-static' 25082815dcSEvan Bacon ); 26082815dcSEvan Bacon vol.fromJSON( 27082815dcSEvan Bacon { 28082815dcSEvan Bacon 'app.config.json': JSON.stringify( 29082815dcSEvan Bacon { 30082815dcSEvan Bacon name: 'app-config-json', 31082815dcSEvan Bacon slug: 'app-config-json', 32082815dcSEvan Bacon version: '1.0.0', 33082815dcSEvan Bacon platforms: [], 34082815dcSEvan Bacon }, 35082815dcSEvan Bacon null, 36082815dcSEvan Bacon 2 37082815dcSEvan Bacon ), 38082815dcSEvan Bacon 'app.json': JSON.stringify( 39082815dcSEvan Bacon { 40082815dcSEvan Bacon name: 'app-json', 41082815dcSEvan Bacon }, 42082815dcSEvan Bacon null, 43082815dcSEvan Bacon 2 44082815dcSEvan Bacon ), 45082815dcSEvan Bacon 'package.json': JSON.stringify({}), 46082815dcSEvan Bacon }, 47082815dcSEvan Bacon 'static-override' 48082815dcSEvan Bacon ); 49082815dcSEvan Bacon }); 50082815dcSEvan Bacon 51082815dcSEvan Bacon afterAll(() => { 52082815dcSEvan Bacon vol.reset(); 53082815dcSEvan Bacon }); 54082815dcSEvan Bacon 55082815dcSEvan Bacon it(`can write to a static only config`, async () => { 56082815dcSEvan Bacon const { type, config } = await modifyConfigAsync( 57082815dcSEvan Bacon 'static-override', 58082815dcSEvan Bacon { foo: 'bar' } as any, 59082815dcSEvan Bacon { skipSDKVersionRequirement: true }, 60082815dcSEvan Bacon { dryRun: true } 61082815dcSEvan Bacon ); 62082815dcSEvan Bacon expect(type).toBe('success'); 63082815dcSEvan Bacon // @ts-ignore: foo property is not defined 64082815dcSEvan Bacon expect(config.foo).toBe('bar'); 65082815dcSEvan Bacon }); 66082815dcSEvan Bacon it(`cannot write to a dynamic config`, async () => { 67082815dcSEvan Bacon const { type, config } = await modifyConfigAsync( 68082815dcSEvan Bacon 'dynamic-and-static', 69082815dcSEvan Bacon {}, 70082815dcSEvan Bacon { skipSDKVersionRequirement: true }, 71082815dcSEvan Bacon { dryRun: true } 72082815dcSEvan Bacon ); 73082815dcSEvan Bacon expect(type).toBe('warn'); 74082815dcSEvan Bacon expect(config).toBe(null); 75082815dcSEvan Bacon }); 76082815dcSEvan Bacon it(`cannot write to a project without a config`, async () => { 77082815dcSEvan Bacon const { type, config } = await modifyConfigAsync( 78082815dcSEvan Bacon 'no-config', 79082815dcSEvan Bacon {}, 80082815dcSEvan Bacon { skipSDKVersionRequirement: true }, 81082815dcSEvan Bacon { dryRun: true } 82082815dcSEvan Bacon ); 83082815dcSEvan Bacon expect(type).toBe('fail'); 84082815dcSEvan Bacon expect(config).toBe(null); 85082815dcSEvan Bacon }); 86082815dcSEvan Bacon}); 87082815dcSEvan Bacon 88082815dcSEvan Baconconst invalidConfig = `/* eslint-disable */ 89082815dcSEvan Baconmodule.exports = { 90082815dcSEvan Bacon name: 'app', 91082815dcSEvan Bacon > 92082815dcSEvan Bacon slug: 'app', 93082815dcSEvan Bacon}`; 94082815dcSEvan Bacon 95082815dcSEvan Bacondescribe(getDynamicConfig, () => { 96082815dcSEvan Bacon beforeAll(async () => { 97082815dcSEvan Bacon vol.fromJSON( 98082815dcSEvan Bacon { 99082815dcSEvan Bacon 'exports-function.app.config.js': `export default function (config) { 100082815dcSEvan Bacon return { ...config }; 101082815dcSEvan Bacon }`, 102082815dcSEvan Bacon 'exports-object.app.config.js': `export default {};`, 103082815dcSEvan Bacon }, 104082815dcSEvan Bacon 'dynamic-export-types' 105082815dcSEvan Bacon ); 106082815dcSEvan Bacon vol.fromJSON( 107082815dcSEvan Bacon { 108082815dcSEvan Bacon // This file exists to test that an invalid app.config.ts 109082815dcSEvan Bacon // gets used instead of defaulting to a valid app.config.js 110082815dcSEvan Bacon 'app.config.js': `export default {};`, 111082815dcSEvan Bacon // This is a syntax error: 112082815dcSEvan Bacon 'app.config.ts': invalidConfig, 113082815dcSEvan Bacon }, 114082815dcSEvan Bacon 'syntax-error' 115082815dcSEvan Bacon ); 116082815dcSEvan Bacon vol.fromJSON( 117082815dcSEvan Bacon { 118082815dcSEvan Bacon // This is a missing import 119082815dcSEvan Bacon 'app.config.ts': [`import 'foobar'`, 'module.exports = {}'].join('\n'), 120082815dcSEvan Bacon }, 121082815dcSEvan Bacon 'missing-import-error' 122082815dcSEvan Bacon ); 123082815dcSEvan Bacon }); 124082815dcSEvan Bacon 125082815dcSEvan Bacon afterAll(() => { 126082815dcSEvan Bacon vol.reset(); 127082815dcSEvan Bacon }); 128082815dcSEvan Bacon 129082815dcSEvan Bacon it(`exports a function`, () => { 130082815dcSEvan Bacon expect( 131082815dcSEvan Bacon getDynamicConfig('dynamic-export-types/exports-function.app.config.js', mockConfigContext) 132082815dcSEvan Bacon .exportedObjectType 133082815dcSEvan Bacon ).toBe('function'); 134082815dcSEvan Bacon }); 135082815dcSEvan Bacon 136082815dcSEvan Bacon it(`exports an object`, () => { 137082815dcSEvan Bacon expect( 138082815dcSEvan Bacon getDynamicConfig('dynamic-export-types/exports-object.app.config.js', mockConfigContext) 139082815dcSEvan Bacon .exportedObjectType 140082815dcSEvan Bacon ).toBe('object'); 141082815dcSEvan Bacon }); 142082815dcSEvan Bacon 143082815dcSEvan Bacon // This tests error are thrown properly and ensures that a more specific 144082815dcSEvan Bacon // config is used instead of defaulting to a valid substitution. 145082815dcSEvan Bacon it(`throws a useful error for dynamic configs with a syntax error`, () => { 146082815dcSEvan Bacon const paths = getConfigFilePaths('syntax-error'); 147*97e1898cSEvan Bacon expect(() => getDynamicConfig(paths.dynamicConfigPath!, mockConfigContext)).toThrowError( 148082815dcSEvan Bacon /Error .* \(5:7\)/ 149082815dcSEvan Bacon ); 150082815dcSEvan Bacon }); 151082815dcSEvan Bacon // This tests error are thrown properly and ensures that a more specific 152082815dcSEvan Bacon // config is used instead of defaulting to a valid substitution. 153082815dcSEvan Bacon it(`throws a useful error for dynamic configs with a missing import`, () => { 154082815dcSEvan Bacon const paths = getConfigFilePaths('missing-import-error'); 155*97e1898cSEvan Bacon expect(() => getDynamicConfig(paths.dynamicConfigPath!, mockConfigContext)).toThrowError( 156082815dcSEvan Bacon /Require stack/ 157082815dcSEvan Bacon ); 158082815dcSEvan Bacon }); 159082815dcSEvan Bacon}); 160082815dcSEvan Bacon 161082815dcSEvan Bacondescribe(getStaticConfig, () => { 162082815dcSEvan Bacon beforeAll(async () => { 163082815dcSEvan Bacon vol.fromJSON( 164082815dcSEvan Bacon { 165082815dcSEvan Bacon 'package.json': JSON.stringify({}), 166082815dcSEvan Bacon 'app.json': JSON.stringify( 167082815dcSEvan Bacon { 168082815dcSEvan Bacon name: 'app-json', 169082815dcSEvan Bacon }, 170082815dcSEvan Bacon null, 171082815dcSEvan Bacon 2 172082815dcSEvan Bacon ), 173082815dcSEvan Bacon 'app.config.json': JSON.stringify( 174082815dcSEvan Bacon { 175082815dcSEvan Bacon name: 'app-config-json', 176082815dcSEvan Bacon slug: 'app-config-json', 177082815dcSEvan Bacon version: '1.0.0', 178082815dcSEvan Bacon platforms: [], 179082815dcSEvan Bacon }, 180082815dcSEvan Bacon null, 181082815dcSEvan Bacon 2 182082815dcSEvan Bacon ), 183082815dcSEvan Bacon }, 184082815dcSEvan Bacon 'static-override' 185082815dcSEvan Bacon ); 186082815dcSEvan Bacon }); 187082815dcSEvan Bacon 188082815dcSEvan Bacon afterAll(() => { 189082815dcSEvan Bacon vol.reset(); 190082815dcSEvan Bacon }); 191082815dcSEvan Bacon 192082815dcSEvan Bacon // This tests error are thrown properly and ensures that a more specific 193082815dcSEvan Bacon // config is used instead of defaulting to a valid substitution. 194082815dcSEvan Bacon it(`uses app.config.json instead of app.json if both exist`, () => { 195082815dcSEvan Bacon const paths = getConfigFilePaths('static-override'); 196082815dcSEvan Bacon expect(paths.staticConfigPath).toMatch(/app\.config\.json/); 197082815dcSEvan Bacon 198*97e1898cSEvan Bacon expect(getStaticConfig(paths.staticConfigPath!).name).toBe('app-config-json'); 199082815dcSEvan Bacon }); 200082815dcSEvan Bacon}); 201