Refactor to remove "Async" function name suffix
Remove convention where Async suffix is added to functions that returns a Promise. It was a habit from C#, but is not widely used in JavaScript / TypeScript world, also bloats the code. The code is more consistent with third party dependencies/frameworks without the suffix.
This commit is contained in:
@@ -3,7 +3,7 @@ import { expect } from 'chai';
|
||||
import { parseApplication } from '@/application/Parser/ApplicationParser';
|
||||
import { IApplication } from '@/domain/IApplication';
|
||||
import { IUrlStatus } from './StatusChecker/IUrlStatus';
|
||||
import { getUrlStatusesInParallelAsync, IBatchRequestOptions } from './StatusChecker/BatchStatusChecker';
|
||||
import { getUrlStatusesInParallel, IBatchRequestOptions } from './StatusChecker/BatchStatusChecker';
|
||||
|
||||
describe('collections', () => {
|
||||
// arrange
|
||||
@@ -25,7 +25,7 @@ describe('collections', () => {
|
||||
const testTimeoutInMs = urls.length * 60000 /* 1 minute */;
|
||||
it('have no dead urls', async () => {
|
||||
// act
|
||||
const results = await getUrlStatusesInParallelAsync(urls, options);
|
||||
const results = await getUrlStatusesInParallel(urls, options);
|
||||
// assert
|
||||
const deadUrls = results.filter((r) => r.code !== 200);
|
||||
expect(deadUrls).to.have.lengthOf(0, printUrls(deadUrls));
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { sleepAsync } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { sleep } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { IUrlStatus } from './IUrlStatus';
|
||||
import { getUrlStatusAsync, IRequestOptions } from './Requestor';
|
||||
import { getUrlStatus, IRequestOptions } from './Requestor';
|
||||
import { groupUrlsByDomain } from './UrlPerDomainGrouper';
|
||||
|
||||
export async function getUrlStatusesInParallelAsync(
|
||||
export async function getUrlStatusesInParallel(
|
||||
urls: string[],
|
||||
options?: IBatchRequestOptions): Promise<IUrlStatus[]> {
|
||||
// urls = [ 'https://privacy.sexy' ]; // Here to comment out when testing
|
||||
const uniqueUrls = Array.from(new Set(urls));
|
||||
options = { ...DefaultOptions, ...options };
|
||||
console.log('Options: ', options); // tslint:disable-line: no-console
|
||||
const results = await requestAsync(uniqueUrls, options);
|
||||
const results = await request(uniqueUrls, options);
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -35,19 +35,19 @@ const DefaultOptions: IBatchRequestOptions = {
|
||||
},
|
||||
};
|
||||
|
||||
function requestAsync(urls: string[], options: IBatchRequestOptions): Promise<IUrlStatus[]> {
|
||||
function request(urls: string[], options: IBatchRequestOptions): Promise<IUrlStatus[]> {
|
||||
if (!options.domainOptions.sameDomainParallelize) {
|
||||
return runOnEachDomainWithDelayAsync(
|
||||
return runOnEachDomainWithDelay(
|
||||
urls,
|
||||
(url) => getUrlStatusAsync(url, options.requestOptions),
|
||||
(url) => getUrlStatus(url, options.requestOptions),
|
||||
options.domainOptions.sameDomainDelayInMs);
|
||||
} else {
|
||||
return Promise.all(
|
||||
urls.map((url) => getUrlStatusAsync(url, options.requestOptions)));
|
||||
urls.map((url) => getUrlStatus(url, options.requestOptions)));
|
||||
}
|
||||
}
|
||||
|
||||
async function runOnEachDomainWithDelayAsync(
|
||||
async function runOnEachDomainWithDelay(
|
||||
urls: string[],
|
||||
action: (url: string) => Promise<IUrlStatus>,
|
||||
delayInMs: number): Promise<IUrlStatus[]> {
|
||||
@@ -58,7 +58,7 @@ async function runOnEachDomainWithDelayAsync(
|
||||
const status = await action(url);
|
||||
results.push(status);
|
||||
if (results.length !== group.length) {
|
||||
await sleepAsync(delayInMs);
|
||||
await sleep(delayInMs);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { sleepAsync } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { sleep } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { IUrlStatus } from './IUrlStatus';
|
||||
|
||||
const DefaultBaseRetryIntervalInMs = 5 /* sec */ * 1000;
|
||||
|
||||
export async function retryWithExponentialBackOffAsync(
|
||||
export async function retryWithExponentialBackOff(
|
||||
action: () => Promise<IUrlStatus>,
|
||||
baseRetryIntervalInMs: number = DefaultBaseRetryIntervalInMs,
|
||||
currentRetry = 1): Promise<IUrlStatus> {
|
||||
@@ -14,8 +14,8 @@ export async function retryWithExponentialBackOffAsync(
|
||||
const exponentialBackOffInMs = getRetryTimeoutInMs(currentRetry, baseRetryIntervalInMs);
|
||||
// tslint:disable-next-line: no-console
|
||||
console.log(`Retrying (${currentRetry}) in ${exponentialBackOffInMs / 1000} seconds`, status);
|
||||
await sleepAsync(exponentialBackOffInMs);
|
||||
return retryWithExponentialBackOffAsync(action, baseRetryIntervalInMs, currentRetry + 1);
|
||||
await sleep(exponentialBackOffInMs);
|
||||
return retryWithExponentialBackOff(action, baseRetryIntervalInMs, currentRetry + 1);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
|
||||
@@ -21,11 +21,11 @@ Coming soon 🚧
|
||||
|
||||
Programmatic usage is supported both on Node.js and browser.
|
||||
|
||||
### `getUrlStatusesInParallelAsync`
|
||||
### `getUrlStatusesInParallel`
|
||||
|
||||
```js
|
||||
// Simple example
|
||||
const statuses = await getUrlStatusesInParallelAsync([ 'https://privacy.sexy', /* ... */ ]);
|
||||
const statuses = await getUrlStatusesInParallel([ 'https://privacy.sexy', /* ... */ ]);
|
||||
if(statuses.all((r) => r.code === 200)) {
|
||||
console.log('All URLs are alive!');
|
||||
} else {
|
||||
@@ -33,7 +33,7 @@ if(statuses.all((r) => r.code === 200)) {
|
||||
}
|
||||
|
||||
// Fastest configuration
|
||||
const statuses = await getUrlStatusesInParallelAsync([ 'https://privacy.sexy', /* ... */ ], {
|
||||
const statuses = await getUrlStatusesInParallel([ 'https://privacy.sexy', /* ... */ ], {
|
||||
domainOptions: {
|
||||
sameDomainParallelize: false,
|
||||
}
|
||||
@@ -53,13 +53,13 @@ const statuses = await getUrlStatusesInParallelAsync([ 'https://privacy.sexy', /
|
||||
- Sets delay between requests to same host (domain) if same domain parallelization is disabled.
|
||||
- `requestOptions` (*object*): See [request options](#request-options).
|
||||
|
||||
### `getUrlStatusAsync`
|
||||
### `getUrlStatus`
|
||||
|
||||
Checks whether single URL is dead or alive.
|
||||
|
||||
```js
|
||||
// Simple example
|
||||
const status = await getUrlStatusAsync('https://privacy.sexy');
|
||||
const status = await getUrlStatus('https://privacy.sexy');
|
||||
console.log(`Status code: ${status.code}`);
|
||||
```
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { retryWithExponentialBackOffAsync } from './ExponentialBackOffRetryHandler';
|
||||
import { retryWithExponentialBackOff } from './ExponentialBackOffRetryHandler';
|
||||
import { IUrlStatus } from './IUrlStatus';
|
||||
import { fetchFollow, IFollowOptions } from './FetchFollow';
|
||||
|
||||
export async function getUrlStatusAsync(
|
||||
export async function getUrlStatus(
|
||||
url: string,
|
||||
options: IRequestOptions = DefaultOptions): Promise<IUrlStatus> {
|
||||
options = { ...DefaultOptions, ...options };
|
||||
const fetchOptions = getFetchOptions(url, options);
|
||||
return retryWithExponentialBackOffAsync(async () => {
|
||||
return retryWithExponentialBackOff(async () => {
|
||||
console.log('Requesting', url); // tslint:disable-line: no-console
|
||||
let result: IUrlStatus;
|
||||
try {
|
||||
|
||||
@@ -15,7 +15,7 @@ describe('ApplicationFactory', () => {
|
||||
expect(act).to.throw(expectedError);
|
||||
});
|
||||
});
|
||||
describe('getAppAsync', () => {
|
||||
describe('getApp', () => {
|
||||
it('returns result from the getter', async () => {
|
||||
// arrange
|
||||
const expected = new ApplicationStub();
|
||||
@@ -23,10 +23,10 @@ describe('ApplicationFactory', () => {
|
||||
const sut = new SystemUnderTest(getter);
|
||||
// act
|
||||
const actual = await Promise.all( [
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
]);
|
||||
// assert
|
||||
expect(actual.every((value) => value === expected));
|
||||
@@ -42,10 +42,10 @@ describe('ApplicationFactory', () => {
|
||||
const sut = new SystemUnderTest(getter);
|
||||
// act
|
||||
await Promise.all( [
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getAppAsync(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
sut.getApp(),
|
||||
]);
|
||||
// assert
|
||||
expect(totalExecution).to.equal(1);
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { ICategoryCollection } from '@/domain/ICategoryCollection';
|
||||
import { buildContextAsync } from '@/application/Context/ApplicationContextFactory';
|
||||
import { buildContext } from '@/application/Context/ApplicationContextFactory';
|
||||
import { IApplicationFactory } from '@/application/IApplicationFactory';
|
||||
import { IApplication } from '@/domain/IApplication';
|
||||
import { EnvironmentStub } from '@tests/unit/stubs/EnvironmentStub';
|
||||
@@ -10,7 +10,7 @@ import { ApplicationStub } from '@tests/unit/stubs/ApplicationStub';
|
||||
import { CategoryCollectionStub } from '@tests/unit/stubs/CategoryCollectionStub';
|
||||
|
||||
describe('ApplicationContextFactory', () => {
|
||||
describe('buildContextAsync', () => {
|
||||
describe('buildContext', () => {
|
||||
describe('factory', () => {
|
||||
it('sets application from factory', async () => {
|
||||
// arrange
|
||||
@@ -18,7 +18,7 @@ describe('ApplicationContextFactory', () => {
|
||||
new CategoryCollectionStub().withOs(OperatingSystem.macOS));
|
||||
const factoryMock = mockFactoryWithApp(expected);
|
||||
// act
|
||||
const context = await buildContextAsync(factoryMock);
|
||||
const context = await buildContext(factoryMock);
|
||||
// assert
|
||||
expect(expected).to.equal(context.app);
|
||||
});
|
||||
@@ -32,7 +32,7 @@ describe('ApplicationContextFactory', () => {
|
||||
const collection = new CategoryCollectionStub().withOs(expected);
|
||||
const factoryMock = mockFactoryWithCollection(collection);
|
||||
// act
|
||||
const context = await buildContextAsync(factoryMock, environment);
|
||||
const context = await buildContext(factoryMock, environment);
|
||||
// assert
|
||||
const actual = context.state.os;
|
||||
expect(expected).to.equal(actual);
|
||||
@@ -45,7 +45,7 @@ describe('ApplicationContextFactory', () => {
|
||||
const collection = new CategoryCollectionStub().withOs(expected);
|
||||
const factoryMock = mockFactoryWithCollection(collection);
|
||||
// act
|
||||
const context = await buildContextAsync(factoryMock, environment);
|
||||
const context = await buildContext(factoryMock, environment);
|
||||
// assert
|
||||
const actual = context.state.os;
|
||||
expect(expected).to.equal(actual);
|
||||
@@ -62,7 +62,7 @@ describe('ApplicationContextFactory', () => {
|
||||
const app = new ApplicationStub().withCollections(...allCollections);
|
||||
const factoryMock = mockFactoryWithApp(app);
|
||||
// act
|
||||
const context = await buildContextAsync(factoryMock, environment);
|
||||
const context = await buildContext(factoryMock, environment);
|
||||
// assert
|
||||
const actual = context.state.os;
|
||||
expect(expectedOs).to.equal(actual, `Expected: ${OperatingSystem[expectedOs]}, actual: ${OperatingSystem[actual]}`);
|
||||
@@ -78,6 +78,6 @@ function mockFactoryWithCollection(result: ICategoryCollection): IApplicationFac
|
||||
|
||||
function mockFactoryWithApp(app: IApplication): IApplicationFactory {
|
||||
return {
|
||||
getAppAsync: () => Promise.resolve(app),
|
||||
getApp: () => Promise.resolve(app),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import { CodeRunner } from '@/infrastructure/CodeRunner';
|
||||
|
||||
describe('CodeRunner', () => {
|
||||
describe('runCodeAsync', () => {
|
||||
describe('runCode', () => {
|
||||
it('creates temporary directory recursively', async () => {
|
||||
// arrange
|
||||
const expectedDir = 'expected-dir';
|
||||
@@ -17,7 +17,7 @@ describe('CodeRunner', () => {
|
||||
// act
|
||||
await context
|
||||
.withFolderName(folderName)
|
||||
.runCodeAsync();
|
||||
.runCode();
|
||||
|
||||
// assert
|
||||
expect(context.mocks.fs.mkdirHistory.length).to.equal(1);
|
||||
@@ -42,7 +42,7 @@ describe('CodeRunner', () => {
|
||||
.withCode(expectedCode)
|
||||
.withFolderName(folderName)
|
||||
.withExtension(extension)
|
||||
.runCodeAsync();
|
||||
.runCode();
|
||||
|
||||
// assert
|
||||
expect(context.mocks.fs.writeFileHistory.length).to.equal(1);
|
||||
@@ -66,7 +66,7 @@ describe('CodeRunner', () => {
|
||||
await context
|
||||
.withFolderName(folderName)
|
||||
.withExtension(extension)
|
||||
.runCodeAsync();
|
||||
.runCode();
|
||||
|
||||
// assert
|
||||
expect(context.mocks.fs.chmodCallHistory.length).to.equal(1);
|
||||
@@ -93,7 +93,7 @@ describe('CodeRunner', () => {
|
||||
// act
|
||||
await context
|
||||
.withOs(data.os)
|
||||
.runCodeAsync();
|
||||
.runCode();
|
||||
|
||||
// assert
|
||||
expect(context.mocks.child_process.executionHistory.length).to.equal(1);
|
||||
@@ -109,7 +109,7 @@ describe('CodeRunner', () => {
|
||||
context.mocks.path.setupJoinSequence('non-important-folder-name1', 'non-important-folder-name2');
|
||||
|
||||
// act
|
||||
await context.runCodeAsync();
|
||||
await context.runCode();
|
||||
|
||||
// assert
|
||||
const actualOrder = context.mocks.commandHistory.filter((command) => expectedOrder.includes(command));
|
||||
@@ -126,9 +126,9 @@ class TestContext {
|
||||
private fileExtension: string = 'fileExtension';
|
||||
private env = mockEnvironment(OperatingSystem.Windows);
|
||||
|
||||
public async runCodeAsync(): Promise<void> {
|
||||
public async runCode(): Promise<void> {
|
||||
const runner = new CodeRunner(this.mocks, this.env);
|
||||
await runner.runCodeAsync(this.code, this.folderName, this.fileExtension);
|
||||
await runner.runCode(this.code, this.folderName, this.fileExtension);
|
||||
}
|
||||
public withOs(os: OperatingSystem) {
|
||||
this.env = mockEnvironment(os);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { AsyncLazy } from '@/infrastructure/Threading/AsyncLazy';
|
||||
import { sleepAsync } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { sleep } from '@/infrastructure/Threading/AsyncSleep';
|
||||
|
||||
describe('AsyncLazy', () => {
|
||||
it('returns value from lambda', async () => {
|
||||
@@ -10,7 +10,7 @@ describe('AsyncLazy', () => {
|
||||
const lambda = () => Promise.resolve(expected);
|
||||
const sut = new AsyncLazy(lambda);
|
||||
// act
|
||||
const actual = await sut.getValueAsync();
|
||||
const actual = await sut.getValue();
|
||||
// assert
|
||||
expect(actual).to.equal(expected);
|
||||
});
|
||||
@@ -26,7 +26,7 @@ describe('AsyncLazy', () => {
|
||||
});
|
||||
const results = new Array<number>();
|
||||
for (let i = 0; i < 5; i++) {
|
||||
results.push(await sut.getValueAsync());
|
||||
results.push(await sut.getValue());
|
||||
}
|
||||
// assert
|
||||
expect(totalExecuted).to.equal(1);
|
||||
@@ -35,16 +35,16 @@ describe('AsyncLazy', () => {
|
||||
it('when running long-running task in parallel', async () => {
|
||||
// act
|
||||
const sut = new AsyncLazy(async () => {
|
||||
await sleepAsync(100);
|
||||
await sleep(100);
|
||||
totalExecuted++;
|
||||
return Promise.resolve(totalExecuted);
|
||||
});
|
||||
const results = await Promise.all([
|
||||
sut.getValueAsync(),
|
||||
sut.getValueAsync(),
|
||||
sut.getValueAsync(),
|
||||
sut.getValueAsync(),
|
||||
sut.getValueAsync()]);
|
||||
sut.getValue(),
|
||||
sut.getValue(),
|
||||
sut.getValue(),
|
||||
sut.getValue(),
|
||||
sut.getValue()]);
|
||||
// assert
|
||||
expect(totalExecuted).to.equal(1);
|
||||
expect(results).to.deep.equal([1, 1, 1, 1, 1]);
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
import 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import { sleepAsync, SchedulerType } from '@/infrastructure/Threading/AsyncSleep';
|
||||
import { sleep, SchedulerType } from '@/infrastructure/Threading/AsyncSleep';
|
||||
|
||||
describe('AsyncSleep', () => {
|
||||
it('fulfills after delay', async () => {
|
||||
// arrange
|
||||
const delayInMs = 10;
|
||||
const scheduler = new SchedulerMock();
|
||||
// act
|
||||
const sleep = sleepAsync(delayInMs, scheduler.mock);
|
||||
const promiseState = watchPromiseState(sleep);
|
||||
scheduler.tickNext(delayInMs);
|
||||
await flushPromiseResolutionQueue();
|
||||
// assert
|
||||
const actual = promiseState.isFulfilled();
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
it('pending before delay', async () => {
|
||||
// arrange
|
||||
const delayInMs = 10;
|
||||
const scheduler = new SchedulerMock();
|
||||
// act
|
||||
const sleep = sleepAsync(delayInMs, scheduler.mock);
|
||||
const promiseState = watchPromiseState(sleep);
|
||||
scheduler.tickNext(delayInMs / 5);
|
||||
await flushPromiseResolutionQueue();
|
||||
// assert
|
||||
const actual = promiseState.isPending();
|
||||
expect(actual).to.equal(true);
|
||||
describe('sleep', () => {
|
||||
it('fulfills after delay', async () => {
|
||||
// arrange
|
||||
const delayInMs = 10;
|
||||
const scheduler = new SchedulerMock();
|
||||
// act
|
||||
const promise = sleep(delayInMs, scheduler.mock);
|
||||
const promiseState = watchPromiseState(promise);
|
||||
scheduler.tickNext(delayInMs);
|
||||
await flushPromiseResolutionQueue();
|
||||
// assert
|
||||
const actual = promiseState.isFulfilled();
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
it('pending before delay', async () => {
|
||||
// arrange
|
||||
const delayInMs = 10;
|
||||
const scheduler = new SchedulerMock();
|
||||
// act
|
||||
const promise = sleep(delayInMs, scheduler.mock);
|
||||
const promiseState = watchPromiseState(promise);
|
||||
scheduler.tickNext(delayInMs / 5);
|
||||
await flushPromiseResolutionQueue();
|
||||
// assert
|
||||
const actual = promiseState.isPending();
|
||||
expect(actual).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user