<commit_before>const changelogHelper = require('./changelog');
const { getPrBody } = require('./pr-body');

module.exports = {
  ensurePr,
  checkAutoMerge,
};
// Ensures that PR exists with matching title/body
async function ensurePr(prConfig) {
  const config = { ...prConfig };

  logger.trace({ config }, 'ensurePr');
  // If there is a group, it will use the config of the first upgrade in the array
  const { branchName, prTitle, upgrades } = config;
  // Check if existing PR exists
  const existingPr = await platform.getBranchPr(branchName);
  if (existingPr) {
    logger.debug('Found existing PR');
  }
  config.upgrades = [];

  if (config.lockFileErrors && config.lockFileErrors.length) {
    logger.debug('Forcing PR because of lock file errors');
    config.forcePr = true;
  }

  let branchStatus;
  async function getBranchStatus() {
    if (!branchStatus) {
      branchStatus = await platform.getBranchStatus(
        branchName,
        config.requiredStatusChecks
      );
    }
    return branchStatus;
  }

  // Only create a PR if a branch automerge has failed
  if (
    config.automerge === true &&
    config.automergeType.startsWith('branch') &&
    !config.forcePr
  ) {
    logger.debug(
      `Branch is configured for branch automerge, branch status) is: ${await getBranchStatus()}`
    );
    if (
      (await getBranchStatus()) === 'pending' ||
      (await getBranchStatus()) === 'running'
    ) {
      logger.debug('Checking how long this branch has been pending');
      const lastCommitTime = await platform.getBranchLastCommitTime(branchName);
      const currentTime = new Date();
      const millisecondsPerHour = 1000 * 60 * 60;
      const elapsedHours = Math.round(
        (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour
      );
      if (elapsedHours >= config.prNotPendingHours) {
        logger.info('Branch exceeds prNotPending hours - forcing PR creation');
        config.forcePr = true;
      }
    }
    if (config.forcePr || (await getBranchStatus()) === 'failure') {
      logger.debug(`Branch tests failed, so will create PR`);
    } else {
      return null;
    }
  }
  if (config.prCreation === 'status-success') {
    logger.debug('Checking branch combined status');
    if ((await getBranchStatus()) !== 'success') {
      logger.debug(
        `Branch status is "${await getBranchStatus()}" - not creating PR`
      );
      return null;
    }
    logger.debug('Branch status success');
  } else if (
    config.prCreation === 'not-pending' &&
    !existingPr &&
    !config.forcePr
  ) {
    logger.debug('Checking branch combined status');
    if (
      (await getBranchStatus()) === 'pending' ||
      (await getBranchStatus()) === 'running'
    ) {
      logger.debug(
        `Branch status is "${await getBranchStatus()}" - checking timeout`
      );
      const lastCommitTime = await platform.getBranchLastCommitTime(branchName);
      const currentTime = new Date();
      const millisecondsPerHour = 1000 * 60 * 60;
      const elapsedHours = Math.round(
        (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour
      );
      if (elapsedHours < config.prNotPendingHours) {
        logger.debug(
          `Branch is ${elapsedHours} hours old - skipping PR creation`
        );
        return null;
      }
      logger.debug(
        `prNotPendingHours=${
          config.prNotPendingHours
        } threshold hit - creating PR`
      );
    }
    logger.debug('Branch status success');
  }

  const processedUpgrades = [];
  const commitRepos = [];

  // Get changelog and then generate template strings
  for (const upgrade of upgrades) {
    const upgradeKey = `${upgrade.depType}-${upgrade.depName}-${
      upgrade.manager
    }-${upgrade.fromVersion || upgrade.currentValue}-${upgrade.toVersion}`;
    if (processedUpgrades.includes(upgradeKey)) {
      continue; // eslint-disable-line no-continue
    }
    processedUpgrades.push(upgradeKey);
    upgrade.hasUrls = !!(upgrade.sourceUrl || upgrade.homepage);

    const logJSON = await changelogHelper.getChangeLogJSON({
      manager: upgrade.manager,
      versionScheme: upgrade.versionScheme,
      depType: upgrade.depType,
      depName: upgrade.depName,
      fromVersion: upgrade.fromVersion,
      toVersion: upgrade.toVersion,
      sourceUrl: upgrade.sourceUrl,
      releases: upgrade.releases,
    });

    if (logJSON) {
      upgrade.githubName = logJSON.project ? logJSON.project.github : undefined;
      upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;
      upgrade.releases = [];
      if (
        upgrade.hasReleaseNotes &&
        upgrade.githubName &&
        !commitRepos.includes(upgrade.githubName)
      ) {
        commitRepos.push(upgrade.githubName);
        logJSON.versions.forEach(version => {
          const release = { ...version };
          upgrade.releases.push(release);
        });
      }
    }
    config.upgrades.push(upgrade);
  }

  // Update the config object
  Object.assign(config, upgrades[0]);
  config.hasReleaseNotes = config.upgrades.some(upg => upg.hasReleaseNotes);

  const releaseNoteRepos = [];
  for (const upgrade of config.upgrades) {
    if (upgrade.hasReleaseNotes) {
      if (releaseNoteRepos.includes(upgrade.sourceUrl)) {
        logger.debug(
          { depName: upgrade.depName },
          'Removing duplicate release notes'
        );
        upgrade.hasReleaseNotes = false;
      } else {
        releaseNoteRepos.push(upgrade.sourceUrl);
      }
    }
  }

  const prBody = await getPrBody(config);

  try {
    if (existingPr) {
      logger.debug('Processing existing PR');
      // istanbul ignore if
      if (config.automerge && (await getBranchStatus()) === 'failure') {
        logger.debug(`Setting assignees and reviewers as status checks failed`);
        await addAssigneesReviewers(config, existingPr);
      }
      // Check if existing PR needs updating
      const reviewableIndex = existingPr.body.indexOf(
        '<!-- Reviewable:start -->'
      );
      let existingPrBody = existingPr.body;
      if (reviewableIndex > -1) {
        logger.debug('Stripping Reviewable content');
        existingPrBody = existingPrBody.slice(0, reviewableIndex);
      }
      existingPrBody = existingPrBody.trim();
      if (
        existingPr.title === prTitle &&
        noWhitespace(existingPrBody) === noWhitespace(prBody)
      ) {
        logger.debug(`${existingPr.displayNumber} does not need updating`);
        return existingPr;
      }
      // PR must need updating
      if (existingPr.title !== prTitle) {
        logger.info(
          {
            branchName,
            oldPrTitle: existingPr.title,
            newPrTitle: prTitle,
          },
          'PR title changed'
        );
      } else if (!config.committedFiles) {
        logger.debug(
          {
            prTitle,
            oldPrBody: existingPrBody,
            newPrBody: prBody,
          },
          'PR body changed'
        );
      }
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would update PR #' + existingPr.number);
      } else {
        await platform.updatePr(existingPr.number, prTitle, prBody);
        logger.info(
          { committedFiles: config.committedFiles, pr: existingPr.number },
          `PR updated`
        );
      }
      return existingPr;
    }
    logger.debug({ branch: branchName, prTitle }, `Creating PR`);
    // istanbul ignore if
    if (config.updateType === 'rollback') {
      logger.info('Creating Rollback PR');
    }
    let pr;
    try {
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would create PR: ' + prTitle);
        pr = { number: 0, displayNumber: 'Dry run PR' };
      } else {
        pr = await platform.createPr(
          branchName,
          prTitle,
          prBody,
          config.labels,
          false,
          config.statusCheckVerify
        );
        logger.info({ branch: branchName, pr: pr.number }, 'PR created');
      }
    } catch (err) {
      logger.warn({ err }, `Failed to create PR`);
      if (err.message === 'Validation Failed (422)') {
        logger.info({ branch: branchName }, 'Deleting invalid branch');
        // istanbul ignore if
        if (config.dryRun) {
          logger.info('DRY-RUN: Would delete branch: ' + config.branchName);
        } else {
          await platform.deleteBranch(branchName);
        }
      }
      // istanbul ignore if
      if (err.statusCode === 502) {
        logger.info(
          { branch: branchName },
          'Deleting branch due to server error'
        );
        // istanbul ignore if
        if (config.dryRun) {
          logger.info('DRY-RUN: Would delete branch: ' + config.branchName);
        } else {
          await platform.deleteBranch(branchName);
        }
      }
      return null;
    }
    if (
      config.branchAutomergeFailureMessage &&
      !config.suppressNotifications.includes('branchAutomergeFailure')
    ) {
      const subject = 'Branch automerge failure';
      let content =
        'This PR was configured for branch automerge, however this is not possible so it has been raised as a PR instead.';
      if (config.branchAutomergeFailureMessage === 'branch status error') {
        content += '\n___\n * Branch has one or more failed status checks';
      }
      logger.info('Adding branch automerge failure message to PR');
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('Would add comment to PR #' + pr.number);
      } else {
        await platform.ensureComment(pr.number, subject, content);
      }
    }
    // Skip assign and review if automerging PR
    if (config.automerge && (await getBranchStatus()) !== 'failure') {
      logger.debug(
        `Skipping assignees and reviewers as automerge=${config.automerge}`
      );
    } else {
      await addAssigneesReviewers(config, pr);
    }
    logger.info(`Created ${pr.displayNumber}`);
    return pr;
  } catch (err) {
    // istanbul ignore if
    if (
      err.message === 'rate-limit-exceeded' ||
      err.message === 'platform-failure' ||
      err.message === 'integration-unauthorized'
    ) {
      logger.debug('Passing error up');
      throw err;
    }
    logger.error({ err }, 'Failed to ensure PR:', err);
  }
  return null;
}

async function addAssigneesReviewers(config, pr) {
  if (config.assignees.length > 0) {
    try {
      const assignees = config.assignees.map(assignee =>
        assignee.length && assignee[0] === '@' ? assignee.slice(1) : assignee
      );
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would add assignees to PR #', pr.number);
      } else {
        await platform.addAssignees(pr.number, assignees);
        logger.info({ assignees: config.assignees }, 'Added assignees');
      }
    } catch (err) {
      logger.info(
        { assignees: config.assignees, err },
        'Failed to add assignees'
      );
    }
  }
  if (config.reviewers.length > 0) {
    try {
      const reviewers = config.reviewers.map(reviewer =>
        reviewer.length && reviewer[0] === '@' ? reviewer.slice(1) : reviewer
      );
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would add assignees to PR #', pr.number);
      } else {
        await platform.addReviewers(pr.number, reviewers);
        logger.info({ reviewers: config.reviewers }, 'Added reviewers');
      }
    } catch (err) {
      logger.info(
        { assignees: config.assignees, err },
        'Failed to add reviewers'
      );
    }
  }
}

async function checkAutoMerge(pr, config) {
  logger.trace({ config }, 'checkAutoMerge');
  const {
    branchName,
    automerge,
    automergeType,
    automergeComment,
    requiredStatusChecks,
  } = config;
  logger.debug(
    { automerge, automergeType, automergeComment },
    `Checking #${pr.number} for automerge`
  );
  if (automerge) {
    logger.debug('PR is configured for automerge');
    // Return if PR not ready for automerge
    if (pr.isConflicted) {
      logger.info('PR is conflicted');
      logger.debug({ pr });
      return false;
    }
    if (requiredStatusChecks && pr.canMerge !== true) {
      logger.info('PR is not ready for merge');
      return false;
    }
    // Check if it's been touched
    if (!pr.canRebase) {
      logger.info('PR is ready for automerge but has been modified');
      return false;
    }
    if (automergeType === 'pr-comment') {
      logger.info(`Applying automerge comment: ${automergeComment}`);
      // istanbul ignore if
      if (config.dryRun) {
        logger.info(
          'DRY-RUN: Would add PR automerge comment to PR #' + pr.number
        );
        return false;
      }
      return platform.ensureComment(pr.number, null, automergeComment);
    }
    // Let's merge this
    logger.debug(`Automerging #${pr.number}`);
    // istanbul ignore if
    if (config.dryRun) {
      logger.info('DRY-RUN: Would merge PR #' + pr.number);
      return false;
    }
    const res = await platform.mergePr(pr.number, branchName);
    if (res) {
      logger.info({ pr: pr.number }, 'PR automerged');
    }
    return res;
  }
  logger.debug('No automerge');
  return false;
}

function noWhitespace(input) {
  return input.replace(/\r?\n|\r|\s/g, '');
}
<commit_msg>fix(automerge): check branch status again before automerge<commit_after>const changelogHelper = require('./changelog');
const { getPrBody } = require('./pr-body');

module.exports = {
  ensurePr,
  checkAutoMerge,
};
// Ensures that PR exists with matching title/body
async function ensurePr(prConfig) {
  const config = { ...prConfig };

  logger.trace({ config }, 'ensurePr');
  // If there is a group, it will use the config of the first upgrade in the array
  const { branchName, prTitle, upgrades } = config;
  // Check if existing PR exists
  const existingPr = await platform.getBranchPr(branchName);
  if (existingPr) {
    logger.debug('Found existing PR');
  }
  config.upgrades = [];

  if (config.lockFileErrors && config.lockFileErrors.length) {
    logger.debug('Forcing PR because of lock file errors');
    config.forcePr = true;
  }

  let branchStatus;
  async function getBranchStatus() {
    if (!branchStatus) {
      branchStatus = await platform.getBranchStatus(
        branchName,
        config.requiredStatusChecks
      );
      logger.debug({ branchStatus, branchName }, 'getBranchStatus() result');
    }
    return branchStatus;
  }

  // Only create a PR if a branch automerge has failed
  if (
    config.automerge === true &&
    config.automergeType.startsWith('branch') &&
    !config.forcePr
  ) {
    logger.debug(
      `Branch is configured for branch automerge, branch status) is: ${await getBranchStatus()}`
    );
    if (
      (await getBranchStatus()) === 'pending' ||
      (await getBranchStatus()) === 'running'
    ) {
      logger.debug('Checking how long this branch has been pending');
      const lastCommitTime = await platform.getBranchLastCommitTime(branchName);
      const currentTime = new Date();
      const millisecondsPerHour = 1000 * 60 * 60;
      const elapsedHours = Math.round(
        (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour
      );
      if (elapsedHours >= config.prNotPendingHours) {
        logger.info('Branch exceeds prNotPending hours - forcing PR creation');
        config.forcePr = true;
      }
    }
    if (config.forcePr || (await getBranchStatus()) === 'failure') {
      logger.debug(`Branch tests failed, so will create PR`);
    } else {
      return null;
    }
  }
  if (config.prCreation === 'status-success') {
    logger.debug('Checking branch combined status');
    if ((await getBranchStatus()) !== 'success') {
      logger.debug(
        `Branch status is "${await getBranchStatus()}" - not creating PR`
      );
      return null;
    }
    logger.debug('Branch status success');
  } else if (
    config.prCreation === 'not-pending' &&
    !existingPr &&
    !config.forcePr
  ) {
    logger.debug('Checking branch combined status');
    if (
      (await getBranchStatus()) === 'pending' ||
      (await getBranchStatus()) === 'running'
    ) {
      logger.debug(
        `Branch status is "${await getBranchStatus()}" - checking timeout`
      );
      const lastCommitTime = await platform.getBranchLastCommitTime(branchName);
      const currentTime = new Date();
      const millisecondsPerHour = 1000 * 60 * 60;
      const elapsedHours = Math.round(
        (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour
      );
      if (elapsedHours < config.prNotPendingHours) {
        logger.debug(
          `Branch is ${elapsedHours} hours old - skipping PR creation`
        );
        return null;
      }
      logger.debug(
        `prNotPendingHours=${
          config.prNotPendingHours
        } threshold hit - creating PR`
      );
    }
    logger.debug('Branch status success');
  }

  const processedUpgrades = [];
  const commitRepos = [];

  // Get changelog and then generate template strings
  for (const upgrade of upgrades) {
    const upgradeKey = `${upgrade.depType}-${upgrade.depName}-${
      upgrade.manager
    }-${upgrade.fromVersion || upgrade.currentValue}-${upgrade.toVersion}`;
    if (processedUpgrades.includes(upgradeKey)) {
      continue; // eslint-disable-line no-continue
    }
    processedUpgrades.push(upgradeKey);
    upgrade.hasUrls = !!(upgrade.sourceUrl || upgrade.homepage);

    const logJSON = await changelogHelper.getChangeLogJSON({
      manager: upgrade.manager,
      versionScheme: upgrade.versionScheme,
      depType: upgrade.depType,
      depName: upgrade.depName,
      fromVersion: upgrade.fromVersion,
      toVersion: upgrade.toVersion,
      sourceUrl: upgrade.sourceUrl,
      releases: upgrade.releases,
    });

    if (logJSON) {
      upgrade.githubName = logJSON.project ? logJSON.project.github : undefined;
      upgrade.hasReleaseNotes = logJSON.hasReleaseNotes;
      upgrade.releases = [];
      if (
        upgrade.hasReleaseNotes &&
        upgrade.githubName &&
        !commitRepos.includes(upgrade.githubName)
      ) {
        commitRepos.push(upgrade.githubName);
        logJSON.versions.forEach(version => {
          const release = { ...version };
          upgrade.releases.push(release);
        });
      }
    }
    config.upgrades.push(upgrade);
  }

  // Update the config object
  Object.assign(config, upgrades[0]);
  config.hasReleaseNotes = config.upgrades.some(upg => upg.hasReleaseNotes);

  const releaseNoteRepos = [];
  for (const upgrade of config.upgrades) {
    if (upgrade.hasReleaseNotes) {
      if (releaseNoteRepos.includes(upgrade.sourceUrl)) {
        logger.debug(
          { depName: upgrade.depName },
          'Removing duplicate release notes'
        );
        upgrade.hasReleaseNotes = false;
      } else {
        releaseNoteRepos.push(upgrade.sourceUrl);
      }
    }
  }

  const prBody = await getPrBody(config);

  try {
    if (existingPr) {
      logger.debug('Processing existing PR');
      // istanbul ignore if
      if (config.automerge && (await getBranchStatus()) === 'failure') {
        logger.debug(`Setting assignees and reviewers as status checks failed`);
        await addAssigneesReviewers(config, existingPr);
      }
      // Check if existing PR needs updating
      const reviewableIndex = existingPr.body.indexOf(
        '<!-- Reviewable:start -->'
      );
      let existingPrBody = existingPr.body;
      if (reviewableIndex > -1) {
        logger.debug('Stripping Reviewable content');
        existingPrBody = existingPrBody.slice(0, reviewableIndex);
      }
      existingPrBody = existingPrBody.trim();
      if (
        existingPr.title === prTitle &&
        noWhitespace(existingPrBody) === noWhitespace(prBody)
      ) {
        logger.debug(`${existingPr.displayNumber} does not need updating`);
        return existingPr;
      }
      // PR must need updating
      if (existingPr.title !== prTitle) {
        logger.info(
          {
            branchName,
            oldPrTitle: existingPr.title,
            newPrTitle: prTitle,
          },
          'PR title changed'
        );
      } else if (!config.committedFiles) {
        logger.debug(
          {
            prTitle,
            oldPrBody: existingPrBody,
            newPrBody: prBody,
          },
          'PR body changed'
        );
      }
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would update PR #' + existingPr.number);
      } else {
        await platform.updatePr(existingPr.number, prTitle, prBody);
        logger.info(
          { committedFiles: config.committedFiles, pr: existingPr.number },
          `PR updated`
        );
      }
      return existingPr;
    }
    logger.debug({ branch: branchName, prTitle }, `Creating PR`);
    // istanbul ignore if
    if (config.updateType === 'rollback') {
      logger.info('Creating Rollback PR');
    }
    let pr;
    try {
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would create PR: ' + prTitle);
        pr = { number: 0, displayNumber: 'Dry run PR' };
      } else {
        pr = await platform.createPr(
          branchName,
          prTitle,
          prBody,
          config.labels,
          false,
          config.statusCheckVerify
        );
        logger.info({ branch: branchName, pr: pr.number }, 'PR created');
      }
    } catch (err) {
      logger.warn({ err }, `Failed to create PR`);
      if (err.message === 'Validation Failed (422)') {
        logger.info({ branch: branchName }, 'Deleting invalid branch');
        // istanbul ignore if
        if (config.dryRun) {
          logger.info('DRY-RUN: Would delete branch: ' + config.branchName);
        } else {
          await platform.deleteBranch(branchName);
        }
      }
      // istanbul ignore if
      if (err.statusCode === 502) {
        logger.info(
          { branch: branchName },
          'Deleting branch due to server error'
        );
        // istanbul ignore if
        if (config.dryRun) {
          logger.info('DRY-RUN: Would delete branch: ' + config.branchName);
        } else {
          await platform.deleteBranch(branchName);
        }
      }
      return null;
    }
    if (
      config.branchAutomergeFailureMessage &&
      !config.suppressNotifications.includes('branchAutomergeFailure')
    ) {
      const subject = 'Branch automerge failure';
      let content =
        'This PR was configured for branch automerge, however this is not possible so it has been raised as a PR instead.';
      if (config.branchAutomergeFailureMessage === 'branch status error') {
        content += '\n___\n * Branch has one or more failed status checks';
      }
      logger.info('Adding branch automerge failure message to PR');
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('Would add comment to PR #' + pr.number);
      } else {
        await platform.ensureComment(pr.number, subject, content);
      }
    }
    // Skip assign and review if automerging PR
    if (config.automerge && (await getBranchStatus()) !== 'failure') {
      logger.debug(
        `Skipping assignees and reviewers as automerge=${config.automerge}`
      );
    } else {
      await addAssigneesReviewers(config, pr);
    }
    logger.info(`Created ${pr.displayNumber}`);
    return pr;
  } catch (err) {
    // istanbul ignore if
    if (
      err.message === 'rate-limit-exceeded' ||
      err.message === 'platform-failure' ||
      err.message === 'integration-unauthorized'
    ) {
      logger.debug('Passing error up');
      throw err;
    }
    logger.error({ err }, 'Failed to ensure PR:', err);
  }
  return null;
}

async function addAssigneesReviewers(config, pr) {
  if (config.assignees.length > 0) {
    try {
      const assignees = config.assignees.map(assignee =>
        assignee.length && assignee[0] === '@' ? assignee.slice(1) : assignee
      );
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would add assignees to PR #', pr.number);
      } else {
        await platform.addAssignees(pr.number, assignees);
        logger.info({ assignees: config.assignees }, 'Added assignees');
      }
    } catch (err) {
      logger.info(
        { assignees: config.assignees, err },
        'Failed to add assignees'
      );
    }
  }
  if (config.reviewers.length > 0) {
    try {
      const reviewers = config.reviewers.map(reviewer =>
        reviewer.length && reviewer[0] === '@' ? reviewer.slice(1) : reviewer
      );
      // istanbul ignore if
      if (config.dryRun) {
        logger.info('DRY-RUN: Would add assignees to PR #', pr.number);
      } else {
        await platform.addReviewers(pr.number, reviewers);
        logger.info({ reviewers: config.reviewers }, 'Added reviewers');
      }
    } catch (err) {
      logger.info(
        { assignees: config.assignees, err },
        'Failed to add reviewers'
      );
    }
  }
}

async function checkAutoMerge(pr, config) {
  logger.trace({ config }, 'checkAutoMerge');
  const {
    branchName,
    automerge,
    automergeType,
    automergeComment,
    requiredStatusChecks,
  } = config;
  logger.debug(
    { automerge, automergeType, automergeComment },
    `Checking #${pr.number} for automerge`
  );
  if (automerge) {
    logger.debug('PR is configured for automerge');
    // Return if PR not ready for automerge
    if (pr.isConflicted) {
      logger.info('PR is conflicted');
      logger.debug({ pr });
      return false;
    }
    if (requiredStatusChecks && pr.canMerge !== true) {
      logger.info('PR is not ready for merge');
      return false;
    }
    const branchStatus = await platform.getBranchStatus(
      branchName,
      requiredStatusChecks
    );
    if (branchStatus !== 'success') {
      logger.info(
        `PR is not ready for merge (branch status is ${branchStatus})`
      );
      return false;
    }
    // Check if it's been touched
    if (!pr.canRebase) {
      logger.info('PR is ready for automerge but has been modified');
      return false;
    }
    if (automergeType === 'pr-comment') {
      logger.info(`Applying automerge comment: ${automergeComment}`);
      // istanbul ignore if
      if (config.dryRun) {
        logger.info(
          'DRY-RUN: Would add PR automerge comment to PR #' + pr.number
        );
        return false;
      }
      return platform.ensureComment(pr.number, null, automergeComment);
    }
    // Let's merge this
    logger.debug(`Automerging #${pr.number}`);
    // istanbul ignore if
    if (config.dryRun) {
      logger.info('DRY-RUN: Would merge PR #' + pr.number);
      return false;
    }
    const res = await platform.mergePr(pr.number, branchName);
    if (res) {
      logger.info({ pr: pr.number }, 'PR automerged');
    }
    return res;
  }
  logger.debug('No automerge');
  return false;
}

function noWhitespace(input) {
  return input.replace(/\r?\n|\r|\s/g, '');
}
<|endoftext|>


<commit_before>function getNicknames() {
    "use strict";

    var nicknames = {
                "27ninjabunnies": ["27nb", "nb", "ninja", "bunnies", "ninjabunnies"],
                "Alakaslam": ["slam"],
                "Artanis[Xp]": ["art", "artanis"],
                "batsnacks": ["bat", "bats"],
                "Beneather": ["ben"],
                "Bill Murray": ["bm", "bill", "murray"],
                "Blazinghand": ["bh", "blazing"],
                "boxerfred": ["bf", "boxer"],
                "Chezinu": ["che", "chez"],
                "Clarity_nl": ["clarity"],
                "Damdred": ["damd", "damdy"],
                "Dandel Ion": ["di", "dandel", "dandelion"],
                "EdgarAllanPoE": ["edgar", "allan", "poe", "edgarallenpoe"],
                "Fecalfeast": ["ff", "fecal"],
                "Fidei86": ["fidei"],
                "FirmTofu": ["ft", "firm", "tofu"],
                "GlowingBear": ["gb", "glowing", "bear"],
                "Half the Sky": ["hts", "sky"],
                "Hapahauli": ["hapa"],
                "Holyflare": ["hf"],
                "IAmRobik": ["robik"],
                "JudgeJudy": ["jj", "judge", "judy"],
                "justanothertownie": ["jat"],
                "Keirathi": ["kei", "keir"],
                "LightningStrike": ["ls", "lightning"],
                "Lord Tolkien": ["lt", "lord", "tolkien"],
                "marvellosity": ["marv", "marvy", "marvel", "marvelocity", "marshmallow"],
                "Oatsmaster": ["oat", "oats"],
                "ObiWanShinobi": ["ows", "obi", "obiwan", "shinobi"],
                "Onegu": ["o", "oneg"],
                "raynpelikoneet": ["ray", "rayn", "raypelikoneet"],
                "rsoultin": ["rs", "rsou", "rsoul"],
                "sandroba": ["sand", "roba"],
                "[UoN]Sentinel": ["sent", "sentinel"],
                "scott31337": ["scott"],
                "Stutters695": ["stutters"],
                "The Shining": ["shining"],
                "Tictock": ["ticktock"],
                "Tubesock": ["ts", "tube"],
                "VayneAuthority": ["va", "vayne"],
                "VisceraEyes": ["ve", "viscera"],
                "WaveofShadow": ["wos", "wave"],
                "Xatalos": ["xat", "xata"],
                "yamato77": ["yam", "yama", "yamato"]
            };

    return nicknames;
}<commit_msg>added more nicknames<commit_after>function getNicknames() {
    "use strict";

    var nicknames = {
                "27ninjabunnies": ["27nb", "nb", "ninja", "bunnies", "ninjabunnies"],
                "Alakaslam": ["slam"],
                "Artanis[Xp]": ["art", "artanis"],
                "batsnacks": ["bat", "bats"],
                "Beneather": ["ben"],
                "Bill Murray": ["bm", "bill", "murray"],
                "Blazinghand": ["bh", "blazing"],
                "boxerfred": ["bf", "boxer"],
                "Chezinu": ["che", "chez"],
                "Clarity_nl": ["clarity"],
                "CopCake": ["cc", "cop", "cake", "cupcake", "cop cake"],
                "Damdred": ["damd", "damdy"],
                "Dandel Ion": ["di", "dandel", "dandelion"],
                "deconduo": ["dc", "dec", "decon", "duo"],
                "EdgarAllanPoE": ["edgar", "allan", "poe", "edgarallenpoe"],
                "Fecalfeast": ["ff", "fecal"],
                "Fidei86": ["fidei, james"],
                "FirmTofu": ["ft", "firm", "tofu"],
                "GlowingBear": ["gb", "glowing", "bear"],
                "gobbledydook": ["gob", "gobb", "gobble", "dook", "gobbledy"],
                "Half the Sky": ["hts", "sky"],
                "Hapahauli": ["hapa"],
                "Holyflare": ["hf"],
                "IAmRobik": ["robik"],
                "JudgeJudy": ["jj", "judge", "judy"],
                "justanothertownie": ["jat"],
                "Keirathi": ["kei", "keir"],
                "LightningStrike": ["ls", "lightning"],
                "Lord Tolkien": ["lt", "lord", "tolkien"],
                "marvellosity": ["marv", "marvy", "marvel", "marvelocity", "marshmallow"],
                "MoosyDoosy": ["md", "moosy", "doosy", "moosy doosy"],
                "Oatsmaster": ["oat", "oats"],
                "ObiWanShinobi": ["ows", "obi", "obiwan", "shinobi"],
                "Onegu": ["o", "oneg"],
                "raynpelikoneet": ["ray", "rayn", "raypelikoneet"],
                "rsoultin": ["rs", "rsou", "rsoul"],
                "sandroba": ["sand", "roba"],
                "[UoN]Sentinel": ["sent", "sentinel"],
                "scott31337": ["scott"],
                "Stutters695": ["stutters"],
                "The Shining": ["shining"],
                "Tictock": ["ticktock"],
                "Tubesock": ["ts", "tube"],
                "VayneAuthority": ["va", "vayne"],
                "VisceraEyes": ["ve", "viscera"],
                "WaveofShadow": ["wos", "wave"],
                "Xatalos": ["xat", "xata"],
                "yamato77": ["yam", "yama", "yamato"]
            };

    return nicknames;
}<|endoftext|>


<commit_before>$(function() {
  var ref = new Firebase('https://poofytoo.firebaseio.com/infoloungelet');
  var lastColor = '';

  // Force Reset Page
  ref.child('refresh').on('value', function(s) {
    console.log(s.val());
    if (s.val() == 1) {
      ref.child('refresh').set(0);
      location.reload();
    }
  })

  var action = function() {
    currentTime();
    slideOverlay();
  }

  var randomColor = function() {
    var colors = ['green', 'purple', 'blue', 'pink', 'white', 'orange', 'orange', 'blue'];
    var color = colors[Math.floor(Math.random() * colors.length)];
    while (color == lastColor) {
      color = colors[Math.floor(Math.random() * colors.length)];
    }
    lastColor = color;
    return color;
  }

  var randomGreeting = function() {
    var greetings = ['HELLO!', 'HI!'];
    var r = Math.random();
    if (r < 0.4) {
      return currentTime();
    } else if (r < 0.8) {
      return currentDate();
    } else {
      return 'HELLO!';
    }
  }

  var currentTime = function() {
    var d = new Date();
    return d.getUTCHours() + ':' + d.getUTCMinutes();
  }

  var currentDate = function() {
    var m_names = new Array("JAN", "FEB", "MAR",
    "APR", "MAY", "JUNE", "JULY", "AUG", "SEPT",
    "OCT", "NOV", "DEC");

    var d = new Date();
    var curr_date = d.getUTCDate();
    var curr_month = d.getUTCMonth();
    return m_names[curr_month] + ' ' + curr_date
  }

  var slideOverlay = function() {
    var dir = Math.random() > 0.5 ? 'HOR' : 'VER';
    var fValue = dir == 'VER' ? $(document).height() : $(document).width();

    $('.a1').clone()
      .addClass('c1')
      .removeClass('a1')
      .addClass(randomColor())
      .css('f', 0)
      .css('clip', 'rect(0px, auto, auto, auto)')
      .appendTo('body')
      .show();

    $('.c1').find('h1').html(randomGreeting());
    $('.c1').animate({f: fValue},
    {
      step: function(now, fx) {
        if (dir == 'VER') {
          $(this).css('clip', 'rect(0px, auto, '+(now)+'px, 0px)')
        } else {
          $(this).css('clip', 'rect(0px, auto, auto, '+(fValue - now)+'px)')
        }
      },
      easing: 'easeInCubic',
      duration: 1000,
      complete: function() {
        $('.b1').remove();
        $(this)
          .removeClass('c1')
          .addClass('b1');
      }
    });

  }

  var INTERVAL = 10000;

  action();
  var timer = window.setInterval(action, INTERVAL);
});<commit_msg>back to local<commit_after>$(function() {
  var ref = new Firebase('https://poofytoo.firebaseio.com/infoloungelet');
  var lastColor = '';

  // Force Reset Page
  ref.child('refresh').on('value', function(s) {
    console.log(s.val());
    if (s.val() == 1) {
      ref.child('refresh').set(0);
      location.reload();
    }
  })

  var action = function() {
    currentTime();
    slideOverlay();
  }

  var randomColor = function() {
    var colors = ['green', 'purple', 'blue', 'pink', 'white', 'orange', 'orange', 'blue'];
    var color = colors[Math.floor(Math.random() * colors.length)];
    while (color == lastColor) {
      color = colors[Math.floor(Math.random() * colors.length)];
    }
    lastColor = color;
    return color;
  }

  var randomGreeting = function() {
    var greetings = ['HELLO!', 'HI!'];
    var r = Math.random();
    if (r < 0.4) {
      return currentTime();
    } else if (r < 0.8) {
      return currentDate();
    } else {
      return 'HELLO!';
    }
  }

  var currentTime = function() {
    var d = new Date();
    return d.getHours() + ':' + d.getMinutes();
  }

  var currentDate = function() {
    var m_names = new Array("JAN", "FEB", "MAR",
    "APR", "MAY", "JUNE", "JULY", "AUG", "SEPT",
    "OCT", "NOV", "DEC");

    var d = new Date();
    var curr_date = d.getDate();
    var curr_month = d.getMonth();
    return m_names[curr_month] + ' ' + curr_date
  }

  var slideOverlay = function() {
    var dir = Math.random() > 0.5 ? 'HOR' : 'VER';
    var fValue = dir == 'VER' ? $(document).height() : $(document).width();

    $('.a1').clone()
      .addClass('c1')
      .removeClass('a1')
      .addClass(randomColor())
      .css('f', 0)
      .css('clip', 'rect(0px, auto, auto, auto)')
      .appendTo('body')
      .show();

    $('.c1').find('h1').html(randomGreeting());
    $('.c1').animate({f: fValue},
    {
      step: function(now, fx) {
        if (dir == 'VER') {
          $(this).css('clip', 'rect(0px, auto, '+(now)+'px, 0px)')
        } else {
          $(this).css('clip', 'rect(0px, auto, auto, '+(fValue - now)+'px)')
        }
      },
      easing: 'easeInCubic',
      duration: 1000,
      complete: function() {
        $('.b1').remove();
        $(this)
          .removeClass('c1')
          .addClass('b1');
      }
    });

  }

  var INTERVAL = 10000;

  action();
  var timer = window.setInterval(action, INTERVAL);
});<|endoftext|>


<commit_before>import {TextBuffer} from 'atom';

export default class MultiFilePatch {
  constructor({buffer, layers, filePatches}) {
    this.buffer = buffer || null;

    this.patchLayer = layers && layers.patch;
    this.hunkLayer = layers && layers.hunk;
    this.unchangedLayer = layers && layers.unchanged;
    this.additionLayer = layers && layers.addition;
    this.deletionLayer = layers && layers.deletion;
    this.noNewlineLayer = layers && layers.noNewline;

    this.filePatches = filePatches || [];

    this.filePatchesByMarker = new Map();
    this.hunksByMarker = new Map();

    for (const filePatch of this.filePatches) {
      this.filePatchesByMarker.set(filePatch.getMarker(), filePatch);
      for (const hunk of filePatch.getHunks()) {
        this.hunksByMarker.set(hunk.getMarker(), hunk);
      }
    }
  }

  clone(opts = {}) {
    return new this.constructor({
      buffer: opts.buffer !== undefined ? opts.buffer : this.getBuffer(),
      layers: opts.layers !== undefined ? opts.layers : {
        patch: this.getPatchLayer(),
        hunk: this.getHunkLayer(),
        unchanged: this.getUnchangedLayer(),
        addition: this.getAdditionLayer(),
        deletion: this.getDeletionLayer(),
        noNewline: this.getNoNewlineLayer(),
      },
      filePatches: opts.filePatches !== undefined ? opts.filePatches : this.getFilePatches(),
    });
  }

  getBuffer() {
    return this.buffer;
  }

  getPatchLayer() {
    return this.patchLayer;
  }

  getHunkLayer() {
    return this.hunkLayer;
  }

  getUnchangedLayer() {
    return this.unchangedLayer;
  }

  getAdditionLayer() {
    return this.additionLayer;
  }

  getDeletionLayer() {
    return this.deletionLayer;
  }

  getNoNewlineLayer() {
    return this.noNewlineLayer;
  }

  getFilePatches() {
    return this.filePatches;
  }

  getPathSet() {
    return this.getFilePatches().reduce((pathSet, filePatch) => {
      for (const file of [filePatch.getOldFile(), filePatch.getNewFile()]) {
        if (file.isPresent()) {
          pathSet.add(file.getPath());
        }
      }
      return pathSet;
    }, new Set());
  }

  getFilePatchAt(bufferRow) {
    const [marker] = this.patchLayer.findMarkers({intersectsRow: bufferRow});
    return this.filePatchesByMarker.get(marker);
  }

  getHunkAt(bufferRow) {
    const [marker] = this.hunkLayer.findMarkers({intersectsRow: bufferRow});
    return this.hunksByMarker.get(marker);
  }

  getStagePatchForLines(selectedLineSet) {
    const nextLayeredBuffer = this.buildLayeredBuffer();
    const nextFilePatches = this.getFilePatchesContaining(selectedLineSet).map(fp => {
      return fp.buildStagePatchForLines(this.getBuffer(), nextLayeredBuffer, selectedLineSet);
    });

    return new MultiFilePatch(
      nextLayeredBuffer.buffer,
      nextLayeredBuffer.layers,
      nextFilePatches,
    );
  }

  getStagePatchForHunk(hunk) {
    return this.getStagePatchForLines(new Set(hunk.getBufferRows()));
  }

  getUnstagePatchForLines(selectedLineSet) {
    const nextLayeredBuffer = this.buildLayeredBuffer();
    const nextFilePatches = this.getFilePatchesContaining(selectedLineSet).map(fp => {
      return fp.buildUnstagePatchForLines(this.getBuffer(), nextLayeredBuffer, selectedLineSet);
    });

    return new MultiFilePatch(
      nextLayeredBuffer.buffer,
      nextLayeredBuffer.layers,
      nextFilePatches,
    );
  }

  getUnstagePatchForHunk(hunk) {
    return this.getUnstagePatchForLines(new Set(hunk.getBufferRows()));
  }

  getNextSelectionRange(lastMultiFilePatch, lastSelectedRows) {
    if (lastSelectedRows.size === 0) {
      const [firstPatch] = this.getFilePatches();
      if (!firstPatch) {
        return [[0, 0], [0, 0]];
      }

      return firstPatch.getFirstChangeRange();
    }

    const lastMax = Math.max(...lastSelectedRows);

    let lastSelectionIndex = 0;
    for (const lastFilePatch of lastMultiFilePatch.getFilePatches()) {
      for (const hunk of lastFilePatch.getHunks()) {
        let includesMax = false;
        let hunkSelectionOffset = 0;

        changeLoop: for (const change of hunk.getChanges()) {
          for (const {intersection, gap} of change.intersectRows(lastSelectedRows, true)) {
          // Only include a partial range if this intersection includes the last selected buffer row.
            includesMax = intersection.intersectsRow(lastMax);
            const delta = includesMax ? lastMax - intersection.start.row + 1 : intersection.getRowCount();

            if (gap) {
            // Range of unselected changes.
              hunkSelectionOffset += delta;
            }

            if (includesMax) {
              break changeLoop;
            }
          }
        }

        lastSelectionIndex += hunkSelectionOffset;

        if (includesMax) {
          break;
        }
      }
    }

    let newSelectionRow = 0;
    patchLoop: for (const filePatch of this.getFilePatches()) {
      for (const hunk of filePatch.getHunks()) {
        for (const change of hunk.getChanges()) {
          if (lastSelectionIndex < change.bufferRowCount()) {
            newSelectionRow = change.getStartBufferRow() + lastSelectionIndex;
            break patchLoop;
          } else {
            lastSelectionIndex -= change.bufferRowCount();
          }
        }
      }
    }

    return [[newSelectionRow, 0], [newSelectionRow, Infinity]];
  }

  adoptBufferFrom(lastMultiFilePatch) {
    lastMultiFilePatch.getPatchLayer().clear();
    lastMultiFilePatch.getHunkLayer().clear();
    lastMultiFilePatch.getUnchangedLayer().clear();
    lastMultiFilePatch.getAdditionLayer().clear();
    lastMultiFilePatch.getDeletionLayer().clear();
    lastMultiFilePatch.getNoNewlineLayer().clear();

    this.filePatchesByMarker.clear();
    this.hunksByMarker.clear();

    const nextBuffer = lastMultiFilePatch.getBuffer();
    nextBuffer.setText(this.getBuffer().getText());

    for (const filePatch of this.getFilePatches()) {
      filePatch.getPatch().reMarkOn(lastMultiFilePatch.getPatchLayer());
      this.filePatchesByMarker.set(filePatch.getMarker(), filePatch);

      for (const hunk of filePatch.getHunks()) {
        hunk.reMarkOn(lastMultiFilePatch.getHunkLayer());
        this.hunksByMarker.set(hunk.getMarker(), hunk);

        for (const region of hunk.getRegions()) {
          const target = region.when({
            unchanged: () => lastMultiFilePatch.getUnchangedLayer(),
            addition: () => lastMultiFilePatch.getAdditionLayer(),
            deletion: () => lastMultiFilePatch.getDeletionLayer(),
            nonewline: () => lastMultiFilePatch.getNoNewlineLayer(),
          });
          region.reMarkOn(target);
        }
      }
    }

    this.patchLayer = lastMultiFilePatch.getPatchLayer();
    this.hunkLayer = lastMultiFilePatch.getHunkLayer();
    this.unchangedLayer = lastMultiFilePatch.getUnchangedLayer();
    this.additionLayer = lastMultiFilePatch.getAdditionLayer();
    this.deletionLayer = lastMultiFilePatch.getDeletionLayer();
    this.noNewlineLayer = lastMultiFilePatch.getNoNewlineLayer();

    this.buffer = nextBuffer;
  }

  buildLayeredBuffer() {
    const buffer = new TextBuffer();
    buffer.retain();

    return {
      buffer,
      layers: {
        patch: buffer.addMarkerLayer(),
        hunk: buffer.addMarkerLayer(),
        unchanged: buffer.addMarkerLayer(),
        addition: buffer.addMarkerLayer(),
        deletion: buffer.addMarkerLayer(),
        noNewline: buffer.addMarkerLayer(),
      },
    };
  }

  /*
   * Efficiently locate the FilePatch instances that contain at least one row from a Set.
   */
  getFilePatchesContaining(rowSet) {
    const sortedRowSet = Array.from(rowSet);
    sortedRowSet.sort((a, b) => a - b);

    const filePatches = [];
    let lastFilePatch = null;
    for (const row of sortedRowSet) {
      // Because the rows are sorted, consecutive rows will almost certainly belong to the same patch, so we can save
      // many avoidable marker index lookups by comparing with the last.
      if (lastFilePatch && lastFilePatch.containsRow(row)) {
        continue;
      }

      lastFilePatch = this.getFilePatchAt(row);
      filePatches.push(lastFilePatch);
    }

    return filePatches;
  }

  anyPresent() {
    return this.buffer !== null && this.filePatches.some(fp => fp.isPresent());
  }

  didAnyChangeExecutableMode() {
    for (const filePatch of this.getFilePatches()) {
      if (filePatch.didChangeExecutableMode()) {
        return true;
      }
    }
    return false;
  }

  anyHaveTypechange() {
    return this.getFilePatches().some(fp => fp.hasTypechange());
  }

  getMaxLineNumberWidth() {
    return this.getFilePatches().reduce((maxWidth, filePatch) => {
      const width = filePatch.getMaxLineNumberWidth();
      return maxWidth >= width ? maxWidth : width;
    }, 0);
  }

  /*
   * Construct an apply-able patch String.
   */
  toString() {
    return this.filePatches.map(fp => fp.toStringIn(this.buffer)).join('');
  }
}
<commit_msg>Return real Ranges<commit_after>import {TextBuffer, Range} from 'atom';

export default class MultiFilePatch {
  constructor({buffer, layers, filePatches}) {
    this.buffer = buffer || null;

    this.patchLayer = layers && layers.patch;
    this.hunkLayer = layers && layers.hunk;
    this.unchangedLayer = layers && layers.unchanged;
    this.additionLayer = layers && layers.addition;
    this.deletionLayer = layers && layers.deletion;
    this.noNewlineLayer = layers && layers.noNewline;

    this.filePatches = filePatches || [];

    this.filePatchesByMarker = new Map();
    this.hunksByMarker = new Map();

    for (const filePatch of this.filePatches) {
      this.filePatchesByMarker.set(filePatch.getMarker(), filePatch);
      for (const hunk of filePatch.getHunks()) {
        this.hunksByMarker.set(hunk.getMarker(), hunk);
      }
    }
  }

  clone(opts = {}) {
    return new this.constructor({
      buffer: opts.buffer !== undefined ? opts.buffer : this.getBuffer(),
      layers: opts.layers !== undefined ? opts.layers : {
        patch: this.getPatchLayer(),
        hunk: this.getHunkLayer(),
        unchanged: this.getUnchangedLayer(),
        addition: this.getAdditionLayer(),
        deletion: this.getDeletionLayer(),
        noNewline: this.getNoNewlineLayer(),
      },
      filePatches: opts.filePatches !== undefined ? opts.filePatches : this.getFilePatches(),
    });
  }

  getBuffer() {
    return this.buffer;
  }

  getPatchLayer() {
    return this.patchLayer;
  }

  getHunkLayer() {
    return this.hunkLayer;
  }

  getUnchangedLayer() {
    return this.unchangedLayer;
  }

  getAdditionLayer() {
    return this.additionLayer;
  }

  getDeletionLayer() {
    return this.deletionLayer;
  }

  getNoNewlineLayer() {
    return this.noNewlineLayer;
  }

  getFilePatches() {
    return this.filePatches;
  }

  getPathSet() {
    return this.getFilePatches().reduce((pathSet, filePatch) => {
      for (const file of [filePatch.getOldFile(), filePatch.getNewFile()]) {
        if (file.isPresent()) {
          pathSet.add(file.getPath());
        }
      }
      return pathSet;
    }, new Set());
  }

  getFilePatchAt(bufferRow) {
    const [marker] = this.patchLayer.findMarkers({intersectsRow: bufferRow});
    return this.filePatchesByMarker.get(marker);
  }

  getHunkAt(bufferRow) {
    const [marker] = this.hunkLayer.findMarkers({intersectsRow: bufferRow});
    return this.hunksByMarker.get(marker);
  }

  getStagePatchForLines(selectedLineSet) {
    const nextLayeredBuffer = this.buildLayeredBuffer();
    const nextFilePatches = this.getFilePatchesContaining(selectedLineSet).map(fp => {
      return fp.buildStagePatchForLines(this.getBuffer(), nextLayeredBuffer, selectedLineSet);
    });

    return new MultiFilePatch(
      nextLayeredBuffer.buffer,
      nextLayeredBuffer.layers,
      nextFilePatches,
    );
  }

  getStagePatchForHunk(hunk) {
    return this.getStagePatchForLines(new Set(hunk.getBufferRows()));
  }

  getUnstagePatchForLines(selectedLineSet) {
    const nextLayeredBuffer = this.buildLayeredBuffer();
    const nextFilePatches = this.getFilePatchesContaining(selectedLineSet).map(fp => {
      return fp.buildUnstagePatchForLines(this.getBuffer(), nextLayeredBuffer, selectedLineSet);
    });

    return new MultiFilePatch(
      nextLayeredBuffer.buffer,
      nextLayeredBuffer.layers,
      nextFilePatches,
    );
  }

  getUnstagePatchForHunk(hunk) {
    return this.getUnstagePatchForLines(new Set(hunk.getBufferRows()));
  }

  getNextSelectionRange(lastMultiFilePatch, lastSelectedRows) {
    if (lastSelectedRows.size === 0) {
      const [firstPatch] = this.getFilePatches();
      if (!firstPatch) {
        return [[0, 0], [0, 0]];
      }

      return firstPatch.getFirstChangeRange();
    }

    const lastMax = Math.max(...lastSelectedRows);

    let lastSelectionIndex = 0;
    for (const lastFilePatch of lastMultiFilePatch.getFilePatches()) {
      for (const hunk of lastFilePatch.getHunks()) {
        let includesMax = false;
        let hunkSelectionOffset = 0;

        changeLoop: for (const change of hunk.getChanges()) {
          for (const {intersection, gap} of change.intersectRows(lastSelectedRows, true)) {
          // Only include a partial range if this intersection includes the last selected buffer row.
            includesMax = intersection.intersectsRow(lastMax);
            const delta = includesMax ? lastMax - intersection.start.row + 1 : intersection.getRowCount();

            if (gap) {
            // Range of unselected changes.
              hunkSelectionOffset += delta;
            }

            if (includesMax) {
              break changeLoop;
            }
          }
        }

        lastSelectionIndex += hunkSelectionOffset;

        if (includesMax) {
          break;
        }
      }
    }

    let newSelectionRow = 0;
    patchLoop: for (const filePatch of this.getFilePatches()) {
      for (const hunk of filePatch.getHunks()) {
        for (const change of hunk.getChanges()) {
          if (lastSelectionIndex < change.bufferRowCount()) {
            newSelectionRow = change.getStartBufferRow() + lastSelectionIndex;
            break patchLoop;
          } else {
            lastSelectionIndex -= change.bufferRowCount();
          }
        }
      }
    }

    return Range.fromObject([[newSelectionRow, 0], [newSelectionRow, Infinity]]);
  }

  adoptBufferFrom(lastMultiFilePatch) {
    lastMultiFilePatch.getPatchLayer().clear();
    lastMultiFilePatch.getHunkLayer().clear();
    lastMultiFilePatch.getUnchangedLayer().clear();
    lastMultiFilePatch.getAdditionLayer().clear();
    lastMultiFilePatch.getDeletionLayer().clear();
    lastMultiFilePatch.getNoNewlineLayer().clear();

    this.filePatchesByMarker.clear();
    this.hunksByMarker.clear();

    const nextBuffer = lastMultiFilePatch.getBuffer();
    nextBuffer.setText(this.getBuffer().getText());

    for (const filePatch of this.getFilePatches()) {
      filePatch.getPatch().reMarkOn(lastMultiFilePatch.getPatchLayer());
      this.filePatchesByMarker.set(filePatch.getMarker(), filePatch);

      for (const hunk of filePatch.getHunks()) {
        hunk.reMarkOn(lastMultiFilePatch.getHunkLayer());
        this.hunksByMarker.set(hunk.getMarker(), hunk);

        for (const region of hunk.getRegions()) {
          const target = region.when({
            unchanged: () => lastMultiFilePatch.getUnchangedLayer(),
            addition: () => lastMultiFilePatch.getAdditionLayer(),
            deletion: () => lastMultiFilePatch.getDeletionLayer(),
            nonewline: () => lastMultiFilePatch.getNoNewlineLayer(),
          });
          region.reMarkOn(target);
        }
      }
    }

    this.patchLayer = lastMultiFilePatch.getPatchLayer();
    this.hunkLayer = lastMultiFilePatch.getHunkLayer();
    this.unchangedLayer = lastMultiFilePatch.getUnchangedLayer();
    this.additionLayer = lastMultiFilePatch.getAdditionLayer();
    this.deletionLayer = lastMultiFilePatch.getDeletionLayer();
    this.noNewlineLayer = lastMultiFilePatch.getNoNewlineLayer();

    this.buffer = nextBuffer;
  }

  buildLayeredBuffer() {
    const buffer = new TextBuffer();
    buffer.retain();

    return {
      buffer,
      layers: {
        patch: buffer.addMarkerLayer(),
        hunk: buffer.addMarkerLayer(),
        unchanged: buffer.addMarkerLayer(),
        addition: buffer.addMarkerLayer(),
        deletion: buffer.addMarkerLayer(),
        noNewline: buffer.addMarkerLayer(),
      },
    };
  }

  /*
   * Efficiently locate the FilePatch instances that contain at least one row from a Set.
   */
  getFilePatchesContaining(rowSet) {
    const sortedRowSet = Array.from(rowSet);
    sortedRowSet.sort((a, b) => a - b);

    const filePatches = [];
    let lastFilePatch = null;
    for (const row of sortedRowSet) {
      // Because the rows are sorted, consecutive rows will almost certainly belong to the same patch, so we can save
      // many avoidable marker index lookups by comparing with the last.
      if (lastFilePatch && lastFilePatch.containsRow(row)) {
        continue;
      }

      lastFilePatch = this.getFilePatchAt(row);
      filePatches.push(lastFilePatch);
    }

    return filePatches;
  }

  anyPresent() {
    return this.buffer !== null && this.filePatches.some(fp => fp.isPresent());
  }

  didAnyChangeExecutableMode() {
    for (const filePatch of this.getFilePatches()) {
      if (filePatch.didChangeExecutableMode()) {
        return true;
      }
    }
    return false;
  }

  anyHaveTypechange() {
    return this.getFilePatches().some(fp => fp.hasTypechange());
  }

  getMaxLineNumberWidth() {
    return this.getFilePatches().reduce((maxWidth, filePatch) => {
      const width = filePatch.getMaxLineNumberWidth();
      return maxWidth >= width ? maxWidth : width;
    }, 0);
  }

  /*
   * Construct an apply-able patch String.
   */
  toString() {
    return this.filePatches.map(fp => fp.toStringIn(this.buffer)).join('');
  }
}
<|endoftext|>


<commit_before>/**
  Base object used for common functionality
**/
var BaseCommand = exports.BaseCommand = function() {
};

var id = 1;
BaseCommand.prototype.getRequestId = function() {
  if (!this.requestId) this.requestId = id++;
  return this.requestId;
};

BaseCommand.prototype.updateRequestId = function() {
  this.requestId = id++;
  return this.requestId;
};

// OpCodes
BaseCommand.OP_REPLY = 1;
BaseCommand.OP_MSG = 1000;
BaseCommand.OP_UPDATE = 2001;
BaseCommand.OP_INSERT =	2002;
BaseCommand.OP_GET_BY_OID = 2003;
BaseCommand.OP_QUERY = 2004;
BaseCommand.OP_GET_MORE = 2005;
BaseCommand.OP_DELETE =	2006;
BaseCommand.OP_KILL_CURSORS =	2007;<commit_msg>Added setReadPReference on BaseCommand<commit_after>/**
  Base object used for common functionality
**/
var BaseCommand = exports.BaseCommand = function BaseCommand() {
};

var id = 1;
BaseCommand.prototype.getRequestId = function getRequestId() {
  if (!this.requestId) this.requestId = id++;
  return this.requestId;
};

BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {}

BaseCommand.prototype.updateRequestId = function() {
  this.requestId = id++;
  return this.requestId;
};

// OpCodes
BaseCommand.OP_REPLY = 1;
BaseCommand.OP_MSG = 1000;
BaseCommand.OP_UPDATE = 2001;
BaseCommand.OP_INSERT =	2002;
BaseCommand.OP_GET_BY_OID = 2003;
BaseCommand.OP_QUERY = 2004;
BaseCommand.OP_GET_MORE = 2005;
BaseCommand.OP_DELETE =	2006;
BaseCommand.OP_KILL_CURSORS =	2007;<|endoftext|>


<commit_before>import vue from 'vue';
import './pager.css!';
import cls from './pager.css.map';

vue.component('kf-pager', {
  props: {
    initEntry: Number,
    pageEntries: {
      type: Array,
      default: function() {
        return [10, 20, 50, 100];
      }
    },
    totalEntries: {
      type: Number,
      default: 0
    },
    currentPage: {
      type: Number,
      default: 1
    },
    visiblePages: {
      type: Number,
      default: 5
    },
    onChange: {
      type: Function,
      default: () => {}
    }
  },
  data: function() {
    return {
      cls: cls,
      pageEntry: this.initEntry || this.pageEntries[0],
      current: this.currentPage - 1
    };
  },
  watch: {
    current: function(val) {
      this.currentPage = val + 1;
    }
  },
  computed: {
    pages: function() {
      return Math.ceil(this.totalEntries / this.pageEntry);
    },
    pageRange: function() {
      let pages = Math.ceil(this.totalEntries / this.pageEntry);
      let half = Math.floor(this.visiblePages/2);
      let start = this.current - half;
      if(start < 0) {
        start = 0;
      } else if(start + this.visiblePages >= pages) {
        start = pages - this.visiblePages;
      }

      let end = start + this.visiblePages;

      if(pages < this.visiblePages) {
        start = 0;
        end = pages;
      }

      return _.range(start, end);
    }
  },
  methods: {
    leftmost: function() {
      this.current = 0;
      this.onChange(this.current + 1, this.pageEntry);
    },
    rightmost: function() {
      this.current = this.pages - 1;
      this.onChange(this.current + 1, this.pageEntry);
    },
    prev: function() {
      let prev = this.current - 1;
      if(prev < 0) return;
      this.current = prev;
      this.onChange(this.current + 1, this.pageEntry);
    },
    next: function() {
      let next = this.current + 1;
      if(next == this.pages) return;
      this.current = next;
      this.onChange(this.current + 1, this.pageEntry);
    },
    go: function(n) {
      if(n >= this.pages || n < 0) return;
      this.current = n;
      this.onChange(this.current + 1, this.pageEntry);
    },
    onChangeEntry: function() {
      this.current = 0;
      this.onChange(1, this.pageEntry);
    }
  },
  template:
    '
' +
      '
' +
        '

' +
        '

' +
        '

' +
        '

' +
        '

' +
      '
' +
      '
' +
        '
每页' +
          '
' +
            '' +
            '' +
            '<select v-model="pageEntry" @change="onChangeEntry()">' +
              '<option v-for="opt in pageEntries" :value="opt" v-text="opt"></option>' +
            '</select>' +
          '
' +
        '项
' +
        '/' +
        '
' +
          '共页' +
        '
' +
        '
' +
          '项' +
        '
' +
        '
' +
          '
' +
            '
' +
              '<input type="pager" v-model="currentPage"/>' +
            '
' +
            '' +
          '
' +
        '
' +
      '
' +
    '
'
});
<commit_msg>pager通过enter跳转<commit_after>import vue from 'vue';
import './pager.css!';
import cls from './pager.css.map';

vue.component('kf-pager', {
  props: {
    initEntry: Number,
    pageEntries: {
      type: Array,
      default: function() {
        return [10, 20, 50, 100];
      }
    },
    totalEntries: {
      type: Number,
      default: 0
    },
    currentPage: {
      type: Number,
      default: 1
    },
    visiblePages: {
      type: Number,
      default: 5
    },
    onChange: {
      type: Function,
      default: () => {}
    }
  },
  data: function() {
    return {
      cls: cls,
      pageEntry: this.initEntry || this.pageEntries[0],
      current: this.currentPage - 1
    };
  },
  watch: {
    current: function(val) {
      this.currentPage = val + 1;
    }
  },
  computed: {
    pages: function() {
      return Math.ceil(this.totalEntries / this.pageEntry);
    },
    pageRange: function() {
      let pages = Math.ceil(this.totalEntries / this.pageEntry);
      let half = Math.floor(this.visiblePages/2);
      let start = this.current - half;
      if(start < 0) {
        start = 0;
      } else if(start + this.visiblePages >= pages) {
        start = pages - this.visiblePages;
      }

      let end = start + this.visiblePages;

      if(pages < this.visiblePages) {
        start = 0;
        end = pages;
      }

      return _.range(start, end);
    }
  },
  methods: {
    leftmost: function() {
      this.current = 0;
      this.onChange(this.current + 1, this.pageEntry);
    },
    rightmost: function() {
      this.current = this.pages - 1;
      this.onChange(this.current + 1, this.pageEntry);
    },
    prev: function() {
      let prev = this.current - 1;
      if(prev < 0) return;
      this.current = prev;
      this.onChange(this.current + 1, this.pageEntry);
    },
    next: function() {
      let next = this.current + 1;
      if(next == this.pages) return;
      this.current = next;
      this.onChange(this.current + 1, this.pageEntry);
    },
    go: function(n) {
      if(n >= this.pages || n < 0) return;
      this.current = n;
      this.onChange(this.current + 1, this.pageEntry);
    },
    onChangeEntry: function() {
      this.current = 0;
      this.onChange(1, this.pageEntry);
    }
  },
  template:
    '
' +
      '
' +
        '

' +
        '

' +
        '

' +
        '

' +
        '

' +
      '
' +
      '
' +
        '
每页' +
          '
' +
            '' +
            '' +
            '<select v-model="pageEntry" @change="onChangeEntry()">' +
              '<option v-for="opt in pageEntries" :value="opt" v-text="opt"></option>' +
            '</select>' +
          '
' +
        '项
' +
        '/' +
        '
' +
          '共页' +
        '
' +
        '
' +
          '项' +
        '
' +
        '
' +
          '
' +
            '
' +
              '<input type="pager" v-model="currentPage" @keyup.enter="go(currentPage - 1)"/>' +
            '
' +
            '' +
          '
' +
        '
' +
      '
' +
    '
'
});
<|endoftext|>


<commit_before>import {curry} from '../functional/curry';
import {reduced} from './reduced';
import {Base} from '../transducer/Base';
import {isTransducer} from '../type/isTransducer';

class Taker extends Base {
  constructor(n, xf){
    super();
    this.max = n;
    this.pos = 0;
    this.xf = xf;
  }
  '@@transducer/step'(result, input) {
    this.pos = this.pos + 1;
    return this.pos <= this.max ? this.xf['@@transducer/step'](result, input)
                               : reduced(result);
   }
}

 const _take =
   (n, arr) =>
     typeof arr === 'string' ? arr.substr(0, (n < 0 ? undefined : n))
                             : arr.slice(0, (n < 0 ? undefined : n));

export const take =
  curry(
    (n, xf) =>
      isTransducer(xf)     ? (new Taker(n, xf))
                           : _take(n, xf)
  );
<commit_msg>fix(take): get result from transducer<commit_after>import {curry} from '../functional/curry';
import {reduced} from './reduced';
import {Base} from '../transducer/Base';
import {isTransducer} from '../type/isTransducer';

class Taker extends Base {
  constructor(n, xf){
    super();
    this.max = n;
    this.pos = 0;
    this.xf = xf;
  }
  '@@transducer/step'(result, input) {
    this.pos = this.pos + 1;
    return this.pos <= this.max ? this.xf['@@transducer/step'](result, input)
                                : reduced(this.xf['@@transducer/result'](result));
   }
}

 const _take =
   (n, arr) =>
     typeof arr === 'string' ? arr.substr(0, (n < 0 ? undefined : n))
                             : arr.slice(0, (n < 0 ? undefined : n));

export const take =
  curry(
    (n, xf) =>
      isTransducer(xf)     ? (new Taker(n, xf))
                           : _take(n, xf)
  );
<|endoftext|>


<commit_before>// Console.Re API Tests

const testing = require('testing'),
  configs = require('./config'), // edit ./config.js and change console.re channel name
  disconnect = true;

if (process.env.CHANNEL) process.env.SERVER_CHANNEL = process.env.CHANNEL;
if (process.env.SERVER_CHANNEL === 'YOUR-CHANNEL-NAME') process.env.SERVER_CHANNEL = 'NodeTest';

const cl = require('./lib/connector.node.js').connect(process.env.SERVER_DOMAIN, process.env.SERVER_PORT, process.env.SERVER_CHANNEL, disconnect);

const string = 'Test',
  object = {
    key1: 1,
    key2: 2
  },
  array = [1, 2, 3, 4, 5],
  number = 43,
  bbcodes = [
    '[noparse][i]Italic[/i][/noparse]',
    '[noparse][b]Bold[/b][/noparse]',
    '[noparse][u]Underline[/u][/noparse]',
    '[noparse][<color>]red|green|blue|yellow|orange|lime|white|black[/<color>][/noparse]',
    '[noparse][size=<X>]1-20[/size][/noparse]'
  ];

function testConsoleClear(callback) {
  testing.assert(
    console.re.clear(),
    'testConsoleClear',
    callback
  );
  testing.success("console.re.clear(); passed", callback);
}

function testConsoleTime(callback) {
  testing.assert(
    console.re.time('run timer'),
    'testConsoleTime',
    callback
  );
  testing.success("console.re.time('run timer'); passed", callback);
}

function testConsoleLog(callback) {
  testing.assert(
    console.re.log('This is a %s', string),
    'testConsoleLog string',
    callback
  );
  testing.success("console.re.log('This is a %s', string); passed");

  testing.assert(
    console.re.log('This is an %s', object),
    'testConsoleLog object',
    callback
  );
  testing.success("console.re.log('This is an %s', object); passed");

  testing.assert(
    console.re.log('This is an %s', array),
    'testConsoleLog array',
    callback
  );
  testing.success("console.re.log('This is an %s', array); passed");

  testing.assert(
    console.re.log('This is a number %d', number),
    'testConsoleLog number',
    callback
  );
  testing.success("console.re.log('This is a number %d', number); passed");

  testing.assert(
    console.re.log('simple log output of [i]process.env[/i] %s', process.env),
    'testConsoleLog process.env',
    callback
  );
  testing.success("console.re.log('simple log output of [i]process.env[/i] %s', process.env); passed", callback);
}

function testConsoleInfo(callback) {
  testing.assert(
    console.re.info('using [[i]bbcodes[/i]] %s output can has in styles: [i]Italic[/i] [b]Bold[/b] [u]Underline[/u] and colors: [red]%s[/red] [green]%s[/green] [blue]%s[/blue] [yellow]%s[/yellow] [orange]%s[/orange] [lime]%s[/lime] [white]%s[/white] [black]%s[/black]', bbcodes, 'red', 'green', 'blue', 'yellow', 'orange', 'lime', 'white', 'black'),
    'testConsoleInfo',
    callback
  );
  testing.success("console.re.info('using [[i]bbcodes[/i]] %s output can has styles: [i]Italic[/i] [b]Bold[/b] [u]Underline[/u] and colors: [red]%s[/red] [green]%s[/green] [blue]%s[/blue] [yellow]%s[/yellow] [orange]%s[/orange] [lime]%s[/lime] [white]%s[/white] [black]%s[/black]', bbcodes, 'red', 'green', 'blue', 'yellow',  'orange', 'lime', 'white', 'black'); passed", callback);
}

function testConsoleCount(callback) {
  testing.assert(
    console.re.count('counter one %d'),
    'testConsoleCount',
    callback
  );
  testing.success("console.re.count('counter one %d'); passed", callback);
}

function testConsoleDebug(callback) {
  testing.assert(
    console.re.debug("debug output for %s and %s", {
      key1: 'one',
      key2: 'two',
      key3: 'three'
    }, [1, 2, 3, 'one', 'two', 'three']),
    'testConsoleDebug',
    callback
  );
  testing.success("console.re.debug('debug output for %s and %s', {key1:'one',key2:'two',key3:'three'}, [1,2,3,'one','two','three']); passed", callback);
}

function testConsoleWarn(callback) {
  testing.assert(
    console.re.warn('this is a warning level message'),
    'testConsoleWarn',
    callback
  );
  testing.success("console.re.warn('this is a warning level message'); passed", callback);
}

function testConsoleError(callback) {
  testing.assert(
    console.re.error('[red]output any error message using error level[/red]'),
    'testConsoleError',
    callback
  );
  testing.success("console.re.error('[red]output any error message using error level[/red]'); passed", callback);
}

function testConsoleTest(callback) {
  testing.assert(
    console.re.test("10 + 1", "[1,2,3,4,5,6]", "'text'", "1==1", "'ab'=='ba'"),
    'testConsoleTest',
    callback
  );
  testing.success('console.re.test("10 + 1","[1,2,3,4,5,6]","text","1==2","ab==ba"); passed', callback);
}

function testConsoleAssert(callback) {
  testing.assert(
    console.re.assert(1 !== 1, '1!==1 Assertion Failure'),
    'testConsoleAssert',
    callback
  );
  testing.success("console.re.assert(1!==1, 'Assertion 1!==1 has Failure'); passed", callback);
}

function testConsoleTrace(callback) {
  testing.assert(
    console.re.trace('Stack Trace output'),
    'testConsoleTrace',
    callback
  );
  testing.success("console.re.trace('Stack Trace output'); passed", callback);
}

function testConsoleTimeEnd(callback) {
  testing.assert(
    console.re.timeEnd('run timer'),
    'testConsoleTimeEnd',
    callback
  );
  testing.success("console.re.timeEnd('run timer'); passed", callback);
}

function testResults(error, result) {
  if (error) {
    testing.failure(`Console.Re API tests failed: ${error}`);
  } else {
    console.info('Console.Re API all tests passed');
  }
}

function consoleReTests() {
  console.re.info('Console.Re API Tests %s', 'started');

  testing.run([
    testConsoleClear,
    testConsoleTime,
    testConsoleLog,
    testConsoleInfo,
    testConsoleCount,
    testConsoleDebug,
    testConsoleWarn,
    testConsoleError,
    testConsoleTest,
    testConsoleAssert,
    testConsoleTrace,
    testConsoleTimeEnd
  ], testResults);

  console.re.info('Console.Re API Tests %s', 'end');
}

consoleReTests();
<commit_msg>Reposition test end log.<commit_after>// Console.Re API Tests

const testing = require('testing'),
  configs = require('./config'), // edit ./config.js and change console.re channel name
  disconnect = true;

if (process.env.CHANNEL) process.env.SERVER_CHANNEL = process.env.CHANNEL;
if (process.env.SERVER_CHANNEL === 'YOUR-CHANNEL-NAME') process.env.SERVER_CHANNEL = 'NodeTest';

const cl = require('./lib/connector.node.js').connect(process.env.SERVER_DOMAIN, process.env.SERVER_PORT, process.env.SERVER_CHANNEL, disconnect);

const string = 'Test',
  object = {
    key1: 1,
    key2: 2
  },
  array = [1, 2, 3, 4, 5],
  number = 43,
  bbcodes = [
    '[noparse][i]Italic[/i][/noparse]',
    '[noparse][b]Bold[/b][/noparse]',
    '[noparse][u]Underline[/u][/noparse]',
    '[noparse][<color>]red|green|blue|yellow|orange|lime|white|black[/<color>][/noparse]',
    '[noparse][size=<X>]1-20[/size][/noparse]'
  ];

function testConsoleClear(callback) {
  testing.assert(
    console.re.clear(),
    'testConsoleClear',
    callback
  );
  testing.success("console.re.clear(); passed", callback);
}

function testConsoleTime(callback) {
  testing.assert(
    console.re.time('run timer'),
    'testConsoleTime',
    callback
  );
  testing.success("console.re.time('run timer'); passed", callback);
}

function testConsoleLog(callback) {
  testing.assert(
    console.re.log('This is a %s', string),
    'testConsoleLog string',
    callback
  );
  testing.success("console.re.log('This is a %s', string); passed");

  testing.assert(
    console.re.log('This is an %s', object),
    'testConsoleLog object',
    callback
  );
  testing.success("console.re.log('This is an %s', object); passed");

  testing.assert(
    console.re.log('This is an %s', array),
    'testConsoleLog array',
    callback
  );
  testing.success("console.re.log('This is an %s', array); passed");

  testing.assert(
    console.re.log('This is a number %d', number),
    'testConsoleLog number',
    callback
  );
  testing.success("console.re.log('This is a number %d', number); passed");

  testing.assert(
    console.re.log('simple log output of [i]process.env[/i] %s', process.env),
    'testConsoleLog process.env',
    callback
  );
  testing.success("console.re.log('simple log output of [i]process.env[/i] %s', process.env); passed", callback);
}

function testConsoleInfo(callback) {
  testing.assert(
    console.re.info('using [[i]bbcodes[/i]] %s output can has in styles: [i]Italic[/i] [b]Bold[/b] [u]Underline[/u] and colors: [red]%s[/red] [green]%s[/green] [blue]%s[/blue] [yellow]%s[/yellow] [orange]%s[/orange] [lime]%s[/lime] [white]%s[/white] [black]%s[/black]', bbcodes, 'red', 'green', 'blue', 'yellow', 'orange', 'lime', 'white', 'black'),
    'testConsoleInfo',
    callback
  );
  testing.success("console.re.info('using [[i]bbcodes[/i]] %s output can has styles: [i]Italic[/i] [b]Bold[/b] [u]Underline[/u] and colors: [red]%s[/red] [green]%s[/green] [blue]%s[/blue] [yellow]%s[/yellow] [orange]%s[/orange] [lime]%s[/lime] [white]%s[/white] [black]%s[/black]', bbcodes, 'red', 'green', 'blue', 'yellow',  'orange', 'lime', 'white', 'black'); passed", callback);
}

function testConsoleCount(callback) {
  testing.assert(
    console.re.count('counter one %d'),
    'testConsoleCount',
    callback
  );
  testing.success("console.re.count('counter one %d'); passed", callback);
}

function testConsoleDebug(callback) {
  testing.assert(
    console.re.debug("debug output for %s and %s", {
      key1: 'one',
      key2: 'two',
      key3: 'three'
    }, [1, 2, 3, 'one', 'two', 'three']),
    'testConsoleDebug',
    callback
  );
  testing.success("console.re.debug('debug output for %s and %s', {key1:'one',key2:'two',key3:'three'}, [1,2,3,'one','two','three']); passed", callback);
}

function testConsoleWarn(callback) {
  testing.assert(
    console.re.warn('this is a warning level message'),
    'testConsoleWarn',
    callback
  );
  testing.success("console.re.warn('this is a warning level message'); passed", callback);
}

function testConsoleError(callback) {
  testing.assert(
    console.re.error('[red]output any error message using error level[/red]'),
    'testConsoleError',
    callback
  );
  testing.success("console.re.error('[red]output any error message using error level[/red]'); passed", callback);
}

function testConsoleTest(callback) {
  testing.assert(
    console.re.test("10 + 1", "[1,2,3,4,5,6]", "'text'", "1==1", "'ab'=='ba'"),
    'testConsoleTest',
    callback
  );
  testing.success('console.re.test("10 + 1","[1,2,3,4,5,6]","text","1==2","ab==ba"); passed', callback);
}

function testConsoleAssert(callback) {
  testing.assert(
    console.re.assert(1 !== 1, '1!==1 Assertion Failure'),
    'testConsoleAssert',
    callback
  );
  testing.success("console.re.assert(1!==1, 'Assertion 1!==1 has Failure'); passed", callback);
}

function testConsoleTrace(callback) {
  testing.assert(
    console.re.trace('Stack Trace output'),
    'testConsoleTrace',
    callback
  );
  testing.success("console.re.trace('Stack Trace output'); passed", callback);
}

function testConsoleTimeEnd(callback) {
  testing.assert(
    console.re.timeEnd('run timer'),
    'testConsoleTimeEnd',
    callback
  );
  testing.success("console.re.timeEnd('run timer'); passed", callback);
}

function testResults(error, result) {
  console.re.info('Console.Re API Tests %s', 'end');

  if (error) {
    testing.failure(`Console.Re API tests failed: ${error}`);
  } else {
    console.info('Console.Re API all tests passed');
  }
}

function consoleReTests() {
  console.re.info('Console.Re API Tests %s', 'started');

  testing.run([
    testConsoleClear,
    testConsoleTime,
    testConsoleLog,
    testConsoleInfo,
    testConsoleCount,
    testConsoleDebug,
    testConsoleWarn,
    testConsoleError,
    testConsoleTest,
    testConsoleAssert,
    testConsoleTrace,
    testConsoleTimeEnd
  ], testResults);
}

consoleReTests();
<|endoftext|>


<commit_before>var sightengine = require('./sightengine')('1234','test');
var assert = require('assert');
var fs = require('fs');
var path = require('path');

describe('test feedback', function() {
  it('should return success', function(done) {
    sightengine.feedback('nudity', 'safe', 'https://sightengine.com/assets/img/examples/example5.jpg').then((result) => {
      done(assert.equal('success', result.status))
    })
  });

  it('should return error', function(done) {
    sightengine.feedback('nudity', 'safe', 'https://sightengine.com/assets/img/examples/example99999.jpg').then((result) => {
      done(assert.equal('failure', result.status))
    })
  });
});

describe('test image moderation', function() {
  it('should return success', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_url('https://sightengine.com/assets/img/examples/example5.jpg').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['nudity']).set_url('https://sightengine.com/assets/img/examples/example5.jpg').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_file(path.resolve(__dirname, 'assets', 'image.jpg')).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['celebrities']).set_file(path.resolve(__dirname, 'assets', 'image.jpg')).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    var binaryImage = fs.createReadStream(path.resolve(__dirname, 'assets', 'image.jpg'));

    sightengine.check(['nudity']).set_bytes(binaryImage).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    var binaryImage = fs.createReadStream(path.resolve(__dirname, 'assets', 'image.jpg'));

    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_bytes(binaryImage).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return error', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face']).set_url('https://sightengine.com/assets/img/examples/example99999.jpg').then(function(result) {
      done(assert.equal('failure', result.status))
    })
  });
});

describe('test video moderation', function() {
  it('should return success', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face']).video('http://www.quirksmode.org/html5/videos/big_buck_bunny.webm', 'http://requestb.in/1d097l71').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });
});

<commit_msg>change timeout<commit_after>var sightengine = require('./sightengine')('1234','test');
var assert = require('assert');
var fs = require('fs');
var path = require('path');

describe('test feedback', function() {
  it('should return success', function(done) {
    sightengine.feedback('nudity', 'safe', 'https://sightengine.com/assets/img/examples/example5.jpg').then((result) => {
      done(assert.equal('success', result.status))
    })
  });

  it('should return error', function(done) {
    sightengine.feedback('nudity', 'safe', 'https://sightengine.com/assets/img/examples/example99999.jpg').then((result) => {
      done(assert.equal('failure', result.status))
    })
  });
});

describe('test image moderation', function() {
  it('should return success', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_url('https://sightengine.com/assets/img/examples/example5.jpg').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['nudity']).set_url('https://sightengine.com/assets/img/examples/example5.jpg').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_file(path.resolve(__dirname, 'assets', 'image.jpg')).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    sightengine.check(['celebrities']).set_file(path.resolve(__dirname, 'assets', 'image.jpg')).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    var binaryImage = fs.createReadStream(path.resolve(__dirname, 'assets', 'image.jpg'));

    sightengine.check(['nudity']).set_bytes(binaryImage).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return success', function(done) {
    var binaryImage = fs.createReadStream(path.resolve(__dirname, 'assets', 'image.jpg'));

    sightengine.check(['nudity', 'type', 'properties','wad','face', 'celebrities']).set_bytes(binaryImage).then(function(result) {
      done(assert.equal('success', result.status))
    })
  });

  it('should return error', function(done) {
    sightengine.check(['nudity', 'type', 'properties','wad','face']).set_url('https://sightengine.com/assets/img/examples/example99999.jpg').then(function(result) {
      done(assert.equal('failure', result.status))
    })
  });
});

describe('test video moderation', function() {
  it('should return success', function(done) {
    this.timeout(7000);
    sightengine.check(['nudity', 'type', 'properties','wad','face']).video('http://www.quirksmode.org/html5/videos/big_buck_bunny.webm', 'http://requestb.in/1d097l71').then(function(result) {
      done(assert.equal('success', result.status))
    })
  });
});

<|endoftext|>