import { TempDir } from './util' ; import { cosmiconfig , cosmiconfigSync } from '../src' ; const temp = new TempDir ( ) ; beforeEach ( ( ) => { temp . clean ( ) ; } ) ; afterAll ( ( ) => { temp . deleteTempDir ( ) ; } ) ; describe ( 'loads defined JSON config path' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.json' , '{ "foo": true }' ) ; } ) ; const file = temp . absolutePath ( 'foo.json' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads defined YAML config path' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.yaml' , 'foo: true' ) ; } ) ; const file = temp . absolutePath ( 'foo.yaml' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads defined JS config path' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.js' , 'module.exports = { foo: true };' ) ; } ) ; const file = temp . absolutePath ( 'foo.js' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads modularized JS config path' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.js' , 'module.exports = { foo: true };' ) ; temp . createFile ( 'foo-module.js' , 'module.exports = require("./foo");' ) ; } ) ; const file = temp . absolutePath ( 'foo-module.js' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads yaml-like JS config path' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo-yaml-like.js' , 'module.exports = { foo: true };' ) ; } ) ; const file = temp . absolutePath ( 'foo-yaml-like.js' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads package prop when configPath is package.json' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'package.json' , `{
      "foo": {
        "bar": "baz"
      },
      "otherPackage": {
        "please": "no"
      }
    }` ) ; } ) ; const configPath = temp . absolutePath ( 'package.json' ) ; const checkResult = ( result , expectedConfig ) => { expect ( result . config ) . toEqual ( expectedConfig ) ; expect ( result . filepath ) . toBe ( configPath ) ; } ; describe ( 'default package prop' , ( ) => { const expectedConfig = { bar : 'baz' } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; } ) ; describe ( 'specified packageProp' , ( ) => { const expectedConfig = { please : 'no' } ; const explorerOptions = { packageProp : 'otherPackage' } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , explorerOptions ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' , explorerOptions ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; } ) ; describe ( 'nested packageProp' , ( ) => { const expectedConfig = 'baz' ; const explorerOptions = { packageProp : 'foo.bar' } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , explorerOptions ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' , explorerOptions ) . load ( configPath ) ; checkResult ( result , expectedConfig ) ; } ) ; } ) ; describe ( 'inaccurate packageProp returns undefined, does not error' , ( ) => { const options = { packageProp : 'otherrrPackage' } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , options ) . load ( configPath ) ; expect ( result ) . toBeNull ( ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' , options ) . load ( configPath ) ; expect ( result ) . toBeNull ( ) ; } ) ; } ) ; describe ( 'inaccurate nested packageProp returns undefined, does not error' , ( ) => { const options = { packageProp : 'foo.baz' } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , options ) . load ( configPath ) ; expect ( result ) . toBeNull ( ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' , options ) . load ( configPath ) ; expect ( result ) . toBeNull ( ) ; } ) ; } ) ; } ) ; describe ( 'runs transform' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.json' , '{ "foo": true }' ) ; } ) ; const configPath = temp . absolutePath ( 'foo.json' ) ; const transform = ( result ) => { result . config . foo = [ result . config . foo ] ; return result ; } ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { foo : [ true ] } ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' , { transform , } ) . load ( configPath ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' , { transform , } ) . load ( configPath ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'does not swallow transform errors' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.json' , '{ "foo": true }' ) ; } ) ; const configPath = temp . absolutePath ( 'foo.json' ) ; const expectedError = new Error ( 'These pretzels are making me thirsty!' ) ; const transform = ( ) => { throw expectedError ; } ; test ( 'async' , async ( ) => { await expect ( cosmiconfig ( 'successful-files-tests' , { transform } ) . load ( configPath ) ) . rejects . toThrow ( expectedError ) ; } ) ; test ( 'sync' , ( ) => { expect ( ( ) => cosmiconfigSync ( 'successful-files-tests' , { transform } ) . load ( configPath ) ) . toThrow ( expectedError ) ; } ) ; } ) ; describe ( 'loads defined JSON file with no extension' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo-valid-json' , '{ "json": true }' ) ; } ) ; const file = temp . absolutePath ( 'foo-valid-json' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { json : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'loads defined YAML file with no extension' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo-valid-yaml' , 'yaml: true' ) ; } ) ; const file = temp . absolutePath ( 'foo-valid-yaml' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { yaml : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'custom loaders can be async' , ( ) => { let loadThingsSync ; let loadThingsAsync ; beforeEach ( ( ) => { temp . createFile ( '.foorc.things' , 'one\ntwo\nthree\t\t\n  four\n' ) ; loadThingsSync = jest . fn ( ( ) => ( { things : true } ) ) ; loadThingsAsync = jest . fn ( async ( ) => ( { things : true } ) ) ; } ) ; const file = temp . absolutePath ( '.foorc.things' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { things : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const explorerOptions = { loaders : { '.things' : loadThingsAsync , } , } ; const result = await cosmiconfig ( 'foo' , explorerOptions ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const explorerOptions = { loaders : { '.things' : loadThingsSync , } , } ; const result = cosmiconfigSync ( 'foo' , explorerOptions ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'a custom loader entry can include just an async loader' , ( ) => { beforeEach ( ( ) => { temp . createFile ( '.foorc.things' , 'one\ntwo\nthree\t\t\n  four\n' ) ; } ) ; const loadThingsAsync = async ( ) => ( { things : true } ) ; const explorerOptions = { loaders : { '.things' : loadThingsAsync , } , } ; const file = temp . absolutePath ( '.foorc.things' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { things : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , explorerOptions ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'a custom loader entry can include only a sync loader and work for both sync and async functions' , ( ) => { beforeEach ( ( ) => { temp . createFile ( '.foorc.things' , 'one\ntwo\nthree\t\t\n  four\n' ) ; } ) ; const loadThingsSync = ( ) => { return { things : true } ; } ; const explorerOptions = { loaders : { '.things' : loadThingsSync , } , } ; const file = temp . absolutePath ( '.foorc.things' ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { things : true } ) ; expect ( result . filepath ) . toBe ( file ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'foo' , explorerOptions ) . load ( file ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'foo' , explorerOptions ) . load ( file ) ; checkResult ( result ) ; } ) ; } ) ; describe ( 'works fine if sync loader returns a Promise from a JS file' , ( ) => { beforeEach ( ( ) => { temp . createFile ( 'foo.config.js' , 'module.exports = Promise.resolve({ a: 1 });' ) ; } ) ; const file = temp . absolutePath ( 'foo.config.js' ) ; const explorerOptions = { stopDir : temp . absolutePath ( '.' ) , searchPlaces : [ 'foo.config.js' ] , } ; test ( 'sync' , async ( ) => { const result = cosmiconfigSync ( 'foo' , explorerOptions ) . load ( file ) ; expect ( result ) . toEqual ( { filepath : file , config : expect . any ( Promise ) , } ) ; if ( result === null ) { throw new Error ( 'test is broken' ) ; } const resolvedConfig = await result . config ; expect ( resolvedConfig ) . toEqual ( { a : 1 } ) ; } ) ; } ) ; describe ( 'loads defined JS config relative path' , ( ) => { const currentDir = process . cwd ( ) ; beforeEach ( ( ) => { temp . createFile ( 'config/bar.js' , 'module.exports = { bar: true };' ) ; process . chdir ( temp . dir ) ; } ) ; afterEach ( ( ) => { process . chdir ( currentDir ) ; } ) ; const relativeFile = './config/bar.js' ; const absoluteFile = temp . absolutePath ( relativeFile ) ; const checkResult = ( result ) => { expect ( result . config ) . toEqual ( { bar : true } ) ; expect ( result . filepath ) . toBe ( absoluteFile ) ; } ; test ( 'async' , async ( ) => { const result = await cosmiconfig ( 'successful-files-tests' ) . load ( relativeFile ) ; checkResult ( result ) ; } ) ; test ( 'sync' , ( ) => { const result = cosmiconfigSync ( 'successful-files-tests' ) . load ( relativeFile ) ; checkResult ( result ) ; } ) ; } ) ;