import sinon from 'sinon';

import './logger';
import { assert } from '~/test/utils';

let consoleLog;
let consoleInfo;
let consoleWarn;
let consoleError;
let consoleGroup;
let consoleGroupEnd;
let consoleTable;

describe('Logger util test', () => {
  beforeEach(function () {
    consoleLog = sinon.stub(console, 'log').callsFake(() => null);
    consoleError = sinon.stub(console, 'error').callsFake(() => null);
    consoleGroup = sinon.stub(console, 'group').callsFake(() => null);
    consoleGroupEnd = sinon.stub(console, 'groupEnd').callsFake(() => null);
    consoleInfo = sinon.stub(console, 'info').callsFake(() => null);
    consoleTable = sinon.stub(console, 'table').callsFake(() => null);
    consoleWarn = sinon.stub(console, 'warn').callsFake(() => null);
  });

  afterEach(function () {
    consoleLog.restore();
    consoleError.restore();
    consoleGroup.restore();
    consoleGroupEnd.restore();
    consoleInfo.restore();
    consoleTable.restore();
    consoleWarn.restore();
  });

  it('logger object exists', function () {
    expect(logger).toBeDefined();
    expect(Object.keys(logger).length).toBeGreaterThan(0);
  });

  it('can log a message', function () {
    const log = 'log--1';

    logger.log(log);

    assert.calledOnceWithExactly(consoleLog, log, null);
    expect(consoleLog.args[0][1]).toBeNull();
  });

  it('can log an error message', function () {
    const error = 'error--1';

    logger.error(error);

    assert.notCalled(consoleError);
    assert.calledOnceWithExactly(consoleLog, error, null);
  });

  it('can log a grooup message', function () {
    const group = 'info--1';

    logger.group(group);

    assert.calledOnceWithExactly(consoleGroup, group, null);
  });

  it('can log a group end', function () {
    logger.groupEnd();

    assert.calledOnceWithExactly(consoleGroupEnd);
  });

  it('can log an info message', function () {
    const info = 'info--1';

    logger.info(info);

    assert.calledOnceWithExactly(consoleInfo, info, null);
  });

  it('can log a table message', function () {
    const table = ['table--1', 'table--2'];

    logger.table(table);

    assert.calledOnceWithExactly(consoleTable, table, null);
  });

  it('can log a warning message', function () {
    const warn = 'warn--1';

    logger.warn(warn);

    assert.notCalled(consoleWarn);
    assert.calledOnceWithExactly(consoleLog, warn, null);
  });

  it('can log to termial console without styles', function () {
    const log = 'log--2';

    logger.log(log);

    assert.calledOnceWithExactly(consoleLog, log, null);
  });

  it('can log to browser console with styles', function () {
    const log = 'log--3';

    // eslint-disable-next-line no-global-assign
    window = {};
    logger.log(log);

    assert.calledOnceWithExactly(consoleLog, `%c ${log}`, 'color: #03A9F4; font-weight: normal');
  });
});
