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:
undergroundwires
2021-10-30 12:35:20 +01:00
parent 799fb091b8
commit 82c43ba2e3
35 changed files with 189 additions and 187 deletions

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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}`);
```

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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),
};
}

View File

@@ -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);

View File

@@ -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]);

View File

@@ -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);
});
});
});