Home Reference Source Test

src/lib/core/seeder-generator.test.js

import test from 'ava';
import sinon from 'sinon';
import path from 'path';

import SeederGenerator, {
  __RewireAPI__ as moduleRewireAPI,
} from './seeder-generator';

const helperData = {
  name: 'some-name',
  seederName: 'SomeName',
  seederFileName: 'some-name.seeder.js',
  seederFilePath: 'some/path/some-name.seeder.js',
  seederFileRelativePath: 'some/relative-path/some-name.seeder.js',
  seederTemplate: 'some template',
  userSeedersFolderPath: 'some/path/for/seeders',
  userSeedersFolderName: 'some-folder-name',
};

test('should create a new instance of SeederGenerator', t => {
  const createStubs = () => {
    sinon.stub(SeederGenerator.prototype, '_initOptions');
    sinon.stub(SeederGenerator.prototype, '_initMemFs');
    sinon.stub(SeederGenerator.prototype, '_initName');
  };
  const restoreStubs = () => {
    SeederGenerator.prototype._initOptions.restore();
    SeederGenerator.prototype._initMemFs.restore();
    SeederGenerator.prototype._initName.restore();
  };

  createStubs();

  const { name, seederTemplate, userSeedersFolderPath } = helperData;

  const generator = new SeederGenerator({
    name,
    seederTemplate,
    userSeedersFolderPath,
  });

  t.true(
    generator._initOptions.calledWith({
      seederTemplate,
      userSeedersFolderPath,
    })
  );
  t.true(generator._initMemFs.called);
  t.true(generator._initName.calledWith(name));

  restoreStubs();
});

test('should generate Seeder', async t => {
  const { seederFileRelativePath } = helperData;

  const context = {
    seederFileRelativePath,
    _validateSeederFileNotExists: sinon.stub(),
    _copySeederTemplate: sinon.stub(),
    _commitMemFsChanges: sinon.stub().resolves(),
  };

  const result = await SeederGenerator.prototype.generate.call(context);

  t.true(context._validateSeederFileNotExists.called);
  t.true(context._copySeederTemplate.called);
  t.true(context._commitMemFsChanges.called);

  t.is(result, context.seederFileRelativePath);
});

test('should init options', t => {
  const createStubs = ({ getFolderNameFromPath }) => {
    moduleRewireAPI.__Rewire__('getFolderNameFromPath', getFolderNameFromPath);
  };
  const restoreStubs = () => {
    moduleRewireAPI.__ResetDependency__('getFolderNameFromPath');
  };

  const {
    seederTemplate,
    userSeedersFolderPath,
    userSeedersFolderName,
  } = helperData;

  const getFolderNameFromPath = sinon
    .stub()
    .withArgs(userSeedersFolderPath)
    .returns(userSeedersFolderName);

  createStubs({ getFolderNameFromPath });

  const context = {};

  SeederGenerator.prototype._initOptions.call(context, {
    seederTemplate,
    userSeedersFolderPath,
  });

  t.true(getFolderNameFromPath.calledWith(userSeedersFolderPath));
  t.deepEqual(context, {
    options: {
      seederTemplate,
      userSeedersFolderName,
      userSeedersFolderPath,
    },
  });

  restoreStubs();
});

test('should init memFs', t => {
  const createStubs = ({ memFs, editor }) => {
    moduleRewireAPI.__Rewire__('memFs', memFs);
    moduleRewireAPI.__Rewire__('editor', editor);
  };
  const restoreStubs = () => {
    moduleRewireAPI.__ResetDependency__('memFs');
    moduleRewireAPI.__ResetDependency__('editor');
  };

  const store = 'some store';
  const fs = 'some fs';

  const memFs = { create: sinon.stub().returns(store) };
  const editor = {
    create: sinon
      .stub()
      .withArgs(store)
      .returns(fs),
  };

  createStubs({ memFs, editor });

  const context = {};

  SeederGenerator.prototype._initMemFs.call(context);

  t.true(memFs.create.called);
  t.true(editor.create.calledWith(store));
  t.deepEqual(context, { fs });

  restoreStubs();
});

test('should init name', t => {
  const {
    name,
    seederName,
    seederFileName,
    userSeedersFolderPath,
    userSeedersFolderName,
  } = helperData;

  const seederFilePath = path.join(userSeedersFolderPath, seederFileName);
  const seederFileRelativePath = path.join(
    userSeedersFolderName,
    seederFileName
  );

  const context = { options: { userSeedersFolderPath, userSeedersFolderName } };
  const expectedContext = Object.assign({}, context, {
    name,
    seederName,
    seederFileName,
    seederFilePath,
    seederFileRelativePath,
  });

  SeederGenerator.prototype._initName.call(context, name);

  t.deepEqual(context, expectedContext);
});

test('_validateSeederFileNotExists should throw error when seeder file are already exists', t => {
  const { seederFilePath, seederFileRelativePath } = helperData;

  const fs = { exists: () => true };
  const context = { fs, seederFilePath, seederFileRelativePath };

  t.throws(
    () => SeederGenerator.prototype._validateSeederFileNotExists.call(context),
    Error
  );
});

test('_validateSeederFileNotExists should not throw error when seeder file are not exists', t => {
  const { seederFilePath, seederFileRelativePath } = helperData;

  const fs = { exists: () => false };
  const context = { fs, seederFilePath, seederFileRelativePath };

  t.notThrows(() =>
    SeederGenerator.prototype._validateSeederFileNotExists.call(context)
  );
});

test('should commit memFs changes', async t => {
  const fs = { commit: sinon.stub().callsArg(0) };

  const context = { fs };

  await SeederGenerator.prototype._commitMemFsChanges.call(context);

  t.true(fs.commit.called);
});

test('should copy seeder template', async t => {
  const { seederName, seederTemplate, seederFilePath } = helperData;

  const fs = { copyTpl: sinon.spy() };
  const context = {
    fs,
    seederName,
    seederFilePath,
    options: { seederTemplate },
  };

  SeederGenerator.prototype._copySeederTemplate.call(context);

  t.true(fs.copyTpl.calledWith(seederTemplate, seederFilePath, { seederName }));
});