<|start_filename|>test/db/migrate-json.test.js<|end_filename|>
const expect    = require('expect.js');
const Support   = require(__dirname + '/../support');
const helpers   = require(__dirname + '/../support/helpers');
const gulp      = require('gulp');
const fs        = require('fs');
const _         = require('lodash');

[
  'db:migrate',
  'db:migrate --migrations-path migrations',
  '--migrations-path migrations db:migrate',
  'db:migrate --migrations-path ./migrations',
  'db:migrate --migrations-path ./migrations/',
  'db:migrate --config ../../support/tmp/config/config.json',
  'db:migrate --config ' + Support.resolveSupportPath('tmp', 'config', 'config.json'),
  'db:migrate --config ../../support/tmp/config/config.js'
].forEach(flag => {
  const prepare = function (callback, options) {
    options = _.assign({ config: {} }, options || {});

    let configPath    = 'config/';
    let migrationFile = options.migrationFile || 'createPerson';
    const config        = _.assign({
      migrationStorage: 'json'
    }, helpers.getTestConfig(), options.config);
    let configContent = JSON.stringify(config);

    migrationFile = migrationFile + '.js';

    if (flag.match(/config\.js$/)) {
      configPath    = configPath + 'config.js';
      configContent = 'module.exports = ' + configContent;
    } else {
      configPath = configPath + 'config.json';
    }

    gulp
      .src(Support.resolveSupportPath('tmp'))
      .pipe(helpers.clearDirectory())
      .pipe(helpers.runCli('init'))
      .pipe(helpers.removeFile('config/config.json'))
      .pipe(helpers.copyMigration(migrationFile))
      .pipe(helpers.overwriteFile(configContent, configPath))
      .pipe(helpers.runCli(flag, { pipeStdout: true }))
      .pipe(helpers.teardown(callback));
  };

  describe(Support.getTestDialectTeaser(flag) + ' (JSON)', () => {
    describe('the migration storage file', () => {
      it('should be written to the default location', done => {
        const storageFile = Support.resolveSupportPath('tmp', 'sequelize-meta.json');

        prepare(() => {
          expect(fs.statSync(storageFile).isFile()).to.be(true);
          expect(fs.readFileSync(storageFile).toString())
            .to.match(/^\[\n  "\d{14}-createPerson\.(js)"\n\]$/);
          done();
        });
      });

      it('should be written to the specified location', done => {
        const storageFile = Support.resolveSupportPath('tmp', 'custom-meta.json');

        prepare(() => {
          expect(fs.statSync(storageFile).isFile()).to.be(true);
          expect(fs.readFileSync(storageFile).toString())
            .to.match(/^\[\n  "\d{14}-createPerson\.(js)"\n\]$/);
          done();
        }, { config: { migrationStoragePath: storageFile } });
      });
    });

    it('creates the respective table', function (done) {
      const self = this;

      prepare(() => {
        helpers.readTables(self.sequelize, tables => {
          expect(tables).to.have.length(1);
          expect(tables).to.contain('Person');
          done();
        });
      });
    });

    describe('the logging option', () => {
      it('does not print sql queries by default', done => {
        prepare((__, stdout) => {
          expect(stdout).to.not.contain('Executing');
          done();
        });
      });

      it('interprets a custom option', done => {
        prepare((__, stdout) => {
          expect(stdout).to.contain('Executing');
          done();
        }, { config: { logging: true } });
      });
    });

    describe('promise based migrations', () => {
      it('correctly creates two tables', function (done) {
        const self = this;

        prepare(() => {
          helpers.readTables(self.sequelize, tables => {
            expect(tables.sort()).to.eql([
              'Person',
              'Task'
            ]);
            done();
          });
        }, {
          migrationFile: 'new/*createPerson',
          config:        { promisifyMigrations: false }
        });
      });
    });
  });
});


<|start_filename|>test/db/seed/undo/all.test.js<|end_filename|>
const expect  = require('expect.js');
const Support = require(__dirname + '/../../../support');
const helpers = require(__dirname + '/../../../support/helpers');
const gulp    = require('gulp');
const _       = require('lodash');

[
  'db:seed:undo:all'
].forEach(flag => {
  const prepare = function (callback, options) {
    const _flag  = options.flag || flag;
    const config = _.assign({}, helpers.getTestConfig(), options.config || {});

    const pipeline = gulp
      .src(Support.resolveSupportPath('tmp'))
      .pipe(helpers.clearDirectory())
      .pipe(helpers.runCli('init'))
      .pipe(helpers.copyMigration('createPerson.js'));

    if ( options.copySeeds ) {
      pipeline.pipe(helpers.copySeeder('seedPerson.js'))
        .pipe(helpers.copySeeder('seedPerson2.js'));
    }

    pipeline.pipe(helpers.overwriteFile(JSON.stringify(config),
      'config/config.json'))
      .pipe(helpers.runCli('db:migrate'))
      .pipe(helpers.runCli(_flag, { pipeStdout: true }))
      .pipe(helpers.teardown(callback));
  };

  describe(Support.getTestDialectTeaser(flag), () => {
    it('stops execution if no seeders have been found', done => {
      prepare((err, output) => {
        expect(err).to.equal(null);
        expect(output).to.contain('No seeders found.');
        done();
      }, {copySeeds: false});
    });

    it('is correctly undoing all seeders if they have been done already', function (done) {
      const self = this;

      prepare(() => {
        helpers.countTable(self.sequelize, 'Person', res => {
          expect(res).to.have.length(1);
          expect(res[0].count).to.eql(2);

          gulp
            .src(Support.resolveSupportPath('tmp'))
            .pipe(helpers.runCli(flag, { pipeStdout: true }))
            .pipe(helpers.teardown(() => {
              helpers.countTable(self.sequelize, 'Person', res => {
                expect(res).to.have.length(1);
                expect(res[0].count).to.eql(0);
                done();
              });
            }));
        });
      }, {flag: 'db:seed:all', copySeeds: true});
    });

    it('is correctly undoing all seeders when storage is none', function (done) {
      const self = this;

      prepare(() => {
        helpers.countTable(self.sequelize, 'Person', res => {
          expect(res).to.have.length(1);
          expect(res[0].count).to.eql(2);

          gulp
            .src(Support.resolveSupportPath('tmp'))
            .pipe(helpers.runCli(flag, { pipeStdout: true }))
            .pipe(helpers.teardown(() => {
              helpers.countTable(self.sequelize, 'Person', res => {
                expect(res).to.have.length(1);
                expect(res[0].count).to.eql(0);
                done();
              });
            }));
        });
      }, {
        flag: 'db:seed:all',
        copySeeds: true,
        config: { seederStorage: 'none' }
      });
    });
  });
});


<|start_filename|>test/db/migrate/schema/add_timestamps.test.js<|end_filename|>


const expect    = require('expect.js');
const Support   = require(__dirname + '/../../../support');
const helpers   = require(__dirname + '/../../../support/helpers');
const gulp      = require('gulp');

[
  'db:migrate:schema:timestamps:add'
].forEach(flag => {
  const prepare = function (config, callback) {
    config = helpers.getTestConfig(config);

    gulp
      .src(Support.resolveSupportPath('tmp'))
      .pipe(helpers.clearDirectory())
      .pipe(helpers.runCli('init'))
      .pipe(helpers.copyMigration('createPerson.js'))
      .pipe(helpers.copyMigration('renamePersonToUser.js'))
      .pipe(helpers.overwriteFile(JSON.stringify(config), 'config/config.json'))
      .pipe(helpers.runCli('db:migrate'))
      .pipe(helpers.teardown(callback));
  };

  describe(Support.getTestDialectTeaser(flag), () => {
    beforeEach(function (done) {
      prepare.call(this, null, () => {
        return gulp
          .src(Support.resolveSupportPath('tmp'))
          .pipe(helpers.runCli(flag))
          .pipe(helpers.teardown(done));
      });
    });

    it('renames the original table', function (done) {
      const self = this;

      helpers.readTables(self.sequelize, tables => {
        expect(tables).to.have.length(3);
        expect(tables.indexOf('SequelizeMeta')).to.be.above(-1);
        expect(tables.indexOf('SequelizeMetaBackup')).to.be.above(-1);
        done();
      });
    });

    it('keeps the data in the original table', function (done) {
      helpers.execQuery(
        this.sequelize,
        this.sequelize.getQueryInterface().QueryGenerator.selectQuery('SequelizeMetaBackup'),
        { raw: true }
      ).then(items => {
        expect(items.length).to.equal(2);
        done();
      });
    });

    it('keeps the structure of the original table', function (done) {
      const self = this;

      helpers.readTables(self.sequelize, () => {
        return self
          .sequelize
          .getQueryInterface()
          .describeTable('SequelizeMetaBackup')
          .then(fields => {
            expect(Object.keys(fields).sort()).to.eql(['name']);
            done();
            return null;
          });
      });
    });

    it('creates a new SequelizeMeta table with the new structure', function (done) {
      this.sequelize.getQueryInterface().describeTable('SequelizeMeta').then(fields => {
        expect(Object.keys(fields).sort()).to.eql(['createdAt', 'name', 'updatedAt']);
        done();
      });
    });

    it('copies the entries into the new table', function (done) {
      helpers.execQuery(
        this.sequelize,
        this.sequelize.getQueryInterface().QueryGenerator.selectQuery('SequelizeMeta'),
        { raw: true, type: 'SELECT' }
      ).then(items => {
        expect(items[0].name).to.eql('20111117063700-createPerson.js');
        expect(items[1].name).to.eql('20111205064000-renamePersonToUser.js');
        done();
      });
    });

    it('is possible to undo one of the already executed migrations', function (done) {
      const self = this;

      gulp
        .src(Support.resolveSupportPath('tmp'))
        .pipe(helpers.runCli('db:migrate:undo'))
        .pipe(helpers.teardown(() => {
          helpers.execQuery(
            self.sequelize,
            self.sequelize.getQueryInterface().QueryGenerator.selectQuery('SequelizeMeta'),
            { raw: true, type: 'SELECT' }
          ).then(items => {
            expect(items[0].name).to.eql('20111117063700-createPerson.js');
            done();
          });
        }));
    });
  });
});


<|start_filename|>src/helpers/template-helper.js<|end_filename|>
import _ from 'lodash';
import beautify from 'js-beautify';
import helpers from './index';

module.exports = {
  render (path, locals, options) {
    options = _.assign({
      beautify: true,
      indent_size: 2,
      preserve_newlines: false
    }, options || {});

    const template = helpers.asset.read(path);
    let content  = _.template(template)(locals || {});

    if (options.beautify) {
      content = beautify(content, options);
    }

    return content;
  }
};


<|start_filename|>test/db/migrate/status.test.js<|end_filename|>


const Support = require(__dirname + '/../../support');
const helpers = require(__dirname + '/../../support/helpers');
const gulp    = require('gulp');

[
  'db:migrate:status'
].forEach(flag => {
  describe(Support.getTestDialectTeaser(flag), () => {
    it('is correctly reports a down and an up migration', done => {
      gulp
        .src(Support.resolveSupportPath('tmp'))
        .pipe(helpers.clearDirectory())
        .pipe(helpers.runCli('init'))
        .pipe(helpers.copyMigration('createPerson.js'))
        .pipe(helpers.overwriteFile(JSON.stringify(helpers.getTestConfig()), 'config/config.json'))
        .pipe(helpers.runCli('db:migrate', { pipeStdout: false }))
        .pipe(helpers.copyMigration('renamePersonToUser.js'))
        .pipe(helpers.runCli(flag, { pipeStdout: true }))
        .pipe(helpers.ensureContent('up 20111117063700-createPerson.js'))
        .pipe(helpers.ensureContent('down 20111205064000-renamePersonToUser.js'))
        .pipe(helpers.teardown(done));
    });
  });
});


<|start_filename|>src/helpers/asset-helper.js<|end_filename|>
import fs from 'fs-extra';
import path from 'path';

const assets = {
  copy: (from, to) => {
    fs.copySync(path.resolve(__dirname, '..', 'assets', from), to);
  },

  read: assetPath => {
    return fs.readFileSync(path.resolve(__dirname, '..', 'assets', assetPath)).toString();
  },

  write: (targetPath, content) => {
    fs.writeFileSync(targetPath, content);
  },

  inject: (filePath, token, content) => {
    const fileContent = fs.readFileSync(filePath).toString();
    fs.writeFileSync(filePath, fileContent.replace(token, content));
  },

  injectConfigFilePath: (filePath, configPath) => {
    this.inject(filePath, '__CONFIG_FILE__', configPath);
  },

  mkdirp: pathToCreate => {
    fs.mkdirpSync(pathToCreate);
  }
};

module.exports = assets;
module.exports.default = assets;

<|start_filename|>src/helpers/generic-helper.js<|end_filename|>
import path from 'path';

const resolve = require('resolve').sync;
import getYArgs from '../core/yargs';

const args = getYArgs().argv;

const generic = {
  getEnvironment: () => {
    return args.env || process.env.NODE_ENV || 'development';
  },

  getSequelize: file => {
    const resolvePath = file ? path.join('sequelize', file) : 'sequelize';
    const resolveOptions = { basedir: process.cwd() };

    let sequelizePath;

    try {
      sequelizePath = require.resolve(resolvePath, resolveOptions);
    } catch (e) {
    }

    try {
      sequelizePath = sequelizePath || resolve(resolvePath, resolveOptions);
    } catch (e) {
      console.error('Unable to resolve sequelize package in ' + process.cwd());
      process.exit(1);
    }

    return require(sequelizePath);
  },

  execQuery: (sequelize, sql, options) => {
    if (sequelize.query.length === 2) {
      return sequelize.query(sql, options);
    } else {
      return sequelize.query(sql, null, options);
    }
  }
};

module.exports = generic;
module.exports.default = generic;
