'use strict' const chai = require('chai') chai.use(require('chai-as-promised')) const { expect } = chai const path = require('path') const fsp = require('fs').promises const fse = require('fs-extra') const overrideArgv = require('process-utils/override-argv') const overrideEnv = require('process-utils/override-env') const requireUncached = require('ncjsm/require-uncached') const resolveServerlessConfigPath = require('../../../../lib/cli/resolve-configuration-path') const resolveInput = require('../../../../lib/cli/resolve-input') describe('test/unit/lib/cli/resolve-configuration-path.test.js', () => { let configurationPath afterEach(async () => { if (!configurationPath) return try { await fsp.unlink(configurationPath) } catch { // Ignore any error } }) it('should not resolve a path in not a service context', async () => { expect(await resolveServerlessConfigPath()).to.equal(null) }) it('should recognize "serverless.yml"', async () => { configurationPath = path.resolve('serverless.yml') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.yaml"', async () => { configurationPath = path.resolve('serverless.yaml') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.json"', async () => { configurationPath = path.resolve('serverless.json') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.js"', async () => { configurationPath = path.resolve('serverless.js') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.ts"', async () => { configurationPath = path.resolve('serverless.ts') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.cjs"', async () => { configurationPath = path.resolve('serverless.cjs') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) it('should recognize "serverless.mjs"', async () => { configurationPath = path.resolve('serverless.mjs') await fse.ensureFile(configurationPath) expect(await resolveServerlessConfigPath()).to.equal(configurationPath) }) describe('"--config" param support', () => { before(async () => Promise.all([ fse.ensureFile(path.resolve('custom.yml')), fse.ensureFile(path.resolve('nested/custom.yml')), fse.ensureFile(path.resolve('custom.foo')), fse.ensureDir(path.resolve('custom-dir.yml')), ]), ) beforeEach(() => { resolveInput.clear() }) it('should accept absolute path, pointing configuration in current working directory', async () => { await overrideArgv( { args: ['serverless', '--config', path.resolve('custom.yml')], }, async () => expect(await resolveServerlessConfigPath()).to.equal( path.resolve('custom.yml'), ), ) }) it('should temporarily support nested path', async () => { await overrideEnv(async () => { process.env.SLS_DEPRECATION_NOTIFICATION_MODE = 'warn' const uncached = requireUncached(() => ({ resolveServerlessConfigPath: require('../../../../lib/cli/resolve-configuration-path'), })) await overrideArgv( { args: ['serverless', '--config', 'nested/custom.yml'], }, async () => { await expect( uncached.resolveServerlessConfigPath(), ).to.eventually.be.rejected.and.have.property( 'code', 'NESTED_CUSTOM_CONFIGURATION_PATH', ) }, ) }) }) it('should reject unsupported extension', async () => { await overrideArgv( { args: ['serverless', '--config', 'custom.foo'], }, () => expect( resolveServerlessConfigPath(), ).to.eventually.be.rejected.and.have.property( 'code', 'INVALID_SERVICE_CONFIG_PATH', ), ) }) it('should reject not existing file', async () => { await overrideArgv( { args: ['serverless', '--config', 'not-existing.yml'], }, () => expect( resolveServerlessConfigPath(), ).to.eventually.be.rejected.and.have.property( 'code', 'INVALID_SERVICE_CONFIG_PATH', ), ) }) it('should reject directory', async () => { await overrideArgv( { args: ['serverless', '--config', 'custom-dir.yml'], }, () => expect( resolveServerlessConfigPath(), ).to.eventually.be.rejected.and.have.property( 'code', 'INVALID_SERVICE_CONFIG_PATH', ), ) }) it('should recognize top level file with supported extension', async () => { await overrideArgv( { args: ['serverless', '--config', 'custom.yml'], }, async () => expect(await resolveServerlessConfigPath()).to.equal( path.resolve('custom.yml'), ), ) }) it('should recognize "param=value" format', async () => { await overrideArgv( { args: ['serverless', '--config=custom.yml'], }, async () => expect(await resolveServerlessConfigPath()).to.equal( path.resolve('custom.yml'), ), ) }) }) describe('options support', () => { before(async () => Promise.all([ fse.ensureFile(path.resolve('custom/custom.yml')), fse.ensureFile(path.resolve('normal/serverless.yml')), ]), ) beforeEach(() => { resolveInput.clear() }) it('should support custom cwd', async () => { expect(await resolveServerlessConfigPath({ cwd: 'normal' })).to.equal( path.resolve('normal/serverless.yml'), ) }) it('should support custom cli options', async () => { expect( await resolveServerlessConfigPath({ cwd: 'custom', options: { config: 'custom.yml' }, }), ).to.equal(path.resolve('custom/custom.yml')) }) }) })