<commit_before>/**
 * @copyright Copyright 2021 <NAME> <<EMAIL>>
 * @license MIT
 */

'use strict';

const assert = require('assert');
const sinon = require('sinon');
const timers = require('timers');
const { promisify } = require('util');

const retryAsync = require('../../lib/retry-async.js');

// TODO [engine:node@>=15]: import { setImmediate } from 'timers/promises';
const setImmediateP = promisify(timers.setImmediate);

const clock = sinon.useFakeTimers({
  target: { Date },
});
const timeOptions = {
  now: clock.Date.now,
  setTimeout: promisify(clock.setTimeout),
};

function neverCalled() {
  throw new Error('should not be called');
}

describe('retryAsync', () => {
  beforeEach(() => clock.reset());

  it('calls operation immediately with given args once if truthy', async () => {
    const stubResult = {};
    const stub = sinon.stub().resolves(stubResult);
    const args = [1, {}, false];
    const result = retryAsync(
      stub,
      { setTimeout: neverCalled },
      ...args,
    );
    stub.calledOnceWithExactly(...args);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly(...args);
  });

  it('calls operation with given number of args', async () => {
    const stubResult = {};
    const stub = sinon.stub().resolves(stubResult);
    const args = [undefined, undefined];
    const result = retryAsync(
      stub,
      { setTimeout: neverCalled },
      ...args,
    );
    stub.calledOnceWithExactly(...args);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly(...args);
  });

  it('returns immediately for !shouldRetry', async () => {
    const stubResult = null;
    const stub = sinon.stub().resolves(stubResult);
    const shouldRetry = sinon.stub().returns(false);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry,
      },
    );
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);
  });

  it('handles non-Promise return values', async () => {
    const stubResult = undefined;
    const stub = sinon.stub().returns(stubResult);
    const shouldRetry = sinon.stub().returns(false);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry,
      },
    );
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);<commit_msg>Test retry-async for operation throw/reject<commit_after>/**
 * @copyright Copyright 2021 <NAME> <<EMAIL>>
 * @license MIT
 */

'use strict';

const assert = require('assert');
const sinon = require('sinon');
const timers = require('timers');
const { promisify } = require('util');

const retryAsync = require('../../lib/retry-async.js');

// TODO [engine:node@>=15]: import { setImmediate } from 'timers/promises';
const setImmediateP = promisify(timers.setImmediate);

const clock = sinon.useFakeTimers({
  target: { Date },
});
const timeOptions = {
  now: clock.Date.now,
  setTimeout: promisify(clock.setTimeout),
};

function neverCalled() {
  throw new Error('should not be called');
}

describe('retryAsync', () => {
  beforeEach(() => clock.reset());

  it('calls operation immediately with given args once if truthy', async () => {
    const stubResult = {};
    const stub = sinon.stub().resolves(stubResult);
    const args = [1, {}, false];
    const result = retryAsync(
      stub,
      { setTimeout: neverCalled },
      ...args,
    );
    stub.calledOnceWithExactly(...args);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly(...args);
  });

  it('calls operation with given number of args', async () => {
    const stubResult = {};
    const stub = sinon.stub().resolves(stubResult);
    const args = [undefined, undefined];
    const result = retryAsync(
      stub,
      { setTimeout: neverCalled },
      ...args,
    );
    stub.calledOnceWithExactly(...args);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly(...args);
  });

  it('returns immediately for !shouldRetry', async () => {
    const stubResult = null;
    const stub = sinon.stub().resolves(stubResult);
    const shouldRetry = sinon.stub().returns(false);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry,
      },
    );
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);
    assert.strictEqual(await result, stubResult);
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);
  });

  it('returns immediately with rejection', async () => {
    const stubCause = new Error('test');
    const stub = sinon.stub().rejects(stubCause);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry: neverCalled,
      },
    );
    stub.calledOnceWithExactly();
    await assert.rejects(
      () => result,
      (cause) => {
        assert.strictEqual(cause, stubCause);
        return true;
      },
    );
    stub.calledOnceWithExactly();
  });

  it('returns immediately with exception', async () => {
    const stubCause = new Error('test');
    const stub = sinon.stub().throws(stubCause);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry: neverCalled,
      },
    );
    stub.calledOnceWithExactly();
    await assert.rejects(
      () => result,
      (cause) => {
        assert.strictEqual(cause, stubCause);
        return true;
      },
    );
    stub.calledOnceWithExactly();
  });

  it('handles non-Promise return values', async () => {
    const stubResult = undefined;
    const stub = sinon.stub().returns(stubResult);
    const shouldRetry = sinon.stub().returns(false);
    const result = retryAsync(
      stub,
      {
        setTimeout: neverCalled,
        shouldRetry,
      },
    );
    stub.calledOnceWithExactly();
    shouldRetry.calledOnceWithExactly(stubResult);
{'fraction_non_alphanumeric': 0.1438187489738959, 'fraction_numerical': 0.0022984731571170577, 'mean_word_length': 3.130169491525424, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4192270', 'n_tokens_mistral': 1795, 'n_tokens_neox': 1857, 'n_words': 397}