'use strict';

const BbPromise = require('bluebird');
const _ = require('lodash');
const chai = require('chai');
const sinon = require('sinon');
const mockery = require('mockery');
const Serverless = require('serverless');
const makeWebpackMock = require('./webpack.mock');

chai.use(require('chai-as-promised'));
chai.use(require('sinon-chai'));

const expect = chai.expect;

describe('compile', () => {
  let sandbox;
  let webpackMock;
  let baseModule;
  let serverless;
  let module;

  before(() => {
    sandbox = sinon.sandbox.create();
    sandbox.usingPromise(BbPromise);

    webpackMock = makeWebpackMock(sandbox);

    mockery.enable({ warnOnUnregistered: false });
    mockery.registerMock('webpack', webpackMock);
    baseModule = require('../lib/compile');
    Object.freeze(baseModule);
  });

  after(() => {
    mockery.disable();
    mockery.deregisterAll();
  });

  beforeEach(() => {
    serverless = new Serverless();
    serverless.cli = {
      log: sandbox.stub(),
      consoleLog: sandbox.stub()
    };

    module = _.assign({
      serverless,
      options: {},
    }, baseModule);
  });

  afterEach(() => {
    // This will reset the webpackMock too
    sandbox.restore();
  });

  it('should expose a `compile` method', () => {
    expect(module.compile).to.be.a('function');
  });

  it('should compile with webpack from a context configuration', () => {
    const testWebpackConfig = 'testconfig';
    module.webpackConfig = testWebpackConfig;
    return expect(module.compile()).to.be.fulfilled
    .then(() => {
      expect(webpackMock).to.have.been.calledWith(testWebpackConfig);
      expect(webpackMock.compilerMock.run).to.have.been.calledOnce;
      return null;
    });
  });

  it('should fail if there are compilation errors', () => {
    module.webpackConfig = 'testconfig';
    // We stub errors here. It will be reset again in afterEach()
    sandbox.stub(webpackMock.statsMock.compilation, 'errors').value(['error']);
    return expect(module.compile()).to.be.rejectedWith(/compilation error/);
  });

  it('should work with multi compile', () => {
    const testWebpackConfig = 'testconfig';
    const multiStats = [{
      compilation: {
        errors: [],
        compiler: {
          outputPath: 'statsMock-outputPath',
        },
      },
      toString: sandbox.stub().returns('testStats'),
    }];
    module.webpackConfig = testWebpackConfig;
    module.multiCompile = true;
    webpackMock.compilerMock.run.reset();
    webpackMock.compilerMock.run.yields(null, multiStats);
    return expect(module.compile()).to.be.fulfilled
    .then(() => {
      expect(webpackMock).to.have.been.calledWith(testWebpackConfig);
      expect(webpackMock.compilerMock.run).to.have.been.calledOnce;
      return null;
    });
  });

  it('should use correct stats option', () => {
    const testWebpackConfig = {
      stats: 'minimal'
    };
    let mockStats = {
      compilation: {
        errors: [],
        compiler: {
          outputPath: 'statsMock-outputPath'
        }
      },
      toString: sandbox.stub().returns('testStats')
    };

    module.webpackConfig = testWebpackConfig;
    webpackMock.compilerMock.run.reset();
    webpackMock.compilerMock.run.yields(null, mockStats);
    return (expect(module.compile()).to.be.fulfilled)
    .then(() => {
      module.webpackConfig = [testWebpackConfig];
      return (expect(module.compile()).to.be.fulfilled);
    })
    .then(() => {
      expect(mockStats.toString.args).to.eql([[testWebpackConfig.stats], [testWebpackConfig.stats]]);
    });
  });
});

@@ -2887,18 +2887,20 @@
  %7D;%0A    
-le
+cons
 t mockSt
@@ -3306,24 +3306,177 @@
 hen(() =%3E %7B%0A
+      expect(webpackMock).to.have.been.calledWith(testWebpackConfig);%0A      expect(mockStats.toString.firstCall.args).to.eql(%5BtestWebpackConfig.stats%5D);%0A
       module
@@ -3587,32 +3587,104 @@
   .then(() =%3E %7B%0A
+      expect(webpackMock).to.have.been.calledWith(%5BtestWebpackConfig%5D);%0A
       expect(moc

fix compile.test.js