Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

[WIP] Mock data source refactor and example #71

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 117 additions & 21 deletions packages/core/src/repository/data-source/mock.data-source.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,131 @@
import {DeleteDataSource, GetDataSource, PutDataSource} from './data-source';
import {Query} from '..';
import {DeviceConsoleLogger, Logger} from '../../helpers';
import { IdQuery, Query } from "../query/query";
import { SingleDataSourceRepository } from "../single-data-source.repository";
import { DeleteDataSource, GetDataSource, PutDataSource } from "./data-source";

export class MockDataSource<T> implements GetDataSource<T>, PutDataSource<T>, DeleteDataSource {
constructor(
private readonly one: T,
private readonly many: T[],
private readonly logger: Logger = new DeviceConsoleLogger(),
) {}
export class MockDataSource<T>
implements
GetDataSource<T>,
PutDataSource<T>,
DeleteDataSource {
constructor(
protected readonly itemsFactory: MockItemDataSourceFactory<T>,
joselufo marked this conversation as resolved.
Show resolved Hide resolved
protected readonly delay = 0,
) {}

async get(query: Query): Promise<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, can you add explicit visibility to these methods?

Suggested change
async get(query: Query): Promise<T> {
public async get(query: Query): Promise<T> {

await this.sourceDelay();
return this.itemsFactory.getGetItem(query);
}

async getAll(query: Query): Promise<T[]> {
await this.sourceDelay();
return this.itemsFactory.getGetAllItems(query);
}

async put(
value: T,
query: Query,
): Promise<T> {
await this.sourceDelay();
return this.itemsFactory.getPutItem(value, query);
}

async putAll(
values: T[],
query: Query,
): Promise<T[]> {
await this.sourceDelay();
return this.itemsFactory.getPutAllItems(values, query);
}

async delete(query: Query): Promise<void> {
await this.sourceDelay();
return Promise.resolve();
}

private sourceDelay(): Promise<void> {
return new Promise(resolve => setTimeout(resolve, this.delay));
}
}

export interface MockItemDataSourceFactory<T> {
getGetItem(query?: Query): T;
getGetAllItems(query?: Query): T[];
getPutItem(value?: T, query?: Query): T;
getPutAllItems(values?: T[], query?: Query): T[];
}

export abstract class DefaultMockItemDataSourceFactory<T> implements MockItemDataSourceFactory<T> {

protected get randId() {
return Math.floor(Math.random() * 10000);
}

protected get randUid() {
return Math.random().toString(36).substr(2, 9);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

public async get(query: Query): Promise<T> {
return this.one;
public abstract getGetItem(query?: Query): T;

public abstract getGetAllItems(query?: Query): T[];

public getPutItem(value?: T, query?: Query): T {
if (!!value && value.hasOwnProperty('id') && value['id'] === undefined) {
// Setting an id for object creation simulation
if (typeof value['id'] === 'string') {
value['id'] = this.randUid;
} else if (typeof value['id'] === 'number') {
value['id'] = this.randId;
Comment on lines +76 to +78
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first this fooled me and I thought you had a bug & that you were setting the methods to value['id'], then I realised that both randId & randUid where using get keyword… maybe is clearer to just have the methods and to remove get?

Suggested change
value['id'] = this.randUid;
} else if (typeof value['id'] === 'number') {
value['id'] = this.randId;
value['id'] = this.randUid();
} else if (typeof value['id'] === 'number') {
value['id'] = this.randId();

}
}
return value;
}

public async getAll(query: Query): Promise<T[]> {
return this.many;
public getPutAllItems(values?: T[], query?: Query): T[] {
return values;
}
}

public async put(value: T, query: Query): Promise<T> {
return this.one;
// ---> App scope

Comment on lines +89 to +90
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part could be extracted to the reference… not sure where though.

export class MockUserDataSourceFactory extends DefaultMockItemDataSourceFactory<UserModel> {

private createUser(query?: Query): UserModel {
const randId = query instanceof IdQuery ? query.id : Math.floor(Math.random() * 1000);
return new UserModel (
randId,
`User_${randId}`,
);
Comment on lines +94 to +98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes more sense to call this id:

Suggested change
const randId = query instanceof IdQuery ? query.id : Math.floor(Math.random() * 1000);
return new UserModel (
randId,
`User_${randId}`,
);
const id = (query instanceof IdQuery) ? query.id : Math.floor(Math.random() * 1000);
return new UserModel(id, `User_${id}`);

}

public async putAll(values: T[], query: Query): Promise<T[]> {
return this.many;
public getGetItem(query?: Query): UserModel {
return this.createUser(query);
}

public async delete(query: Query): Promise<void> {
return;
public getGetAllItems(query?: Query): UserModel[] {
return [
this.createUser(query),
this.createUser(query),
this.createUser(query),
this.createUser(query),
this.createUser(query),
];
}
}

public async deleteAll(query: Query): Promise<void> {
this.logger.warning('[DEPRECATION] `deleteAll` will be deprecated. Use `delete` instead.');
export class UserModel {
constructor(
public readonly id: number,
public readonly name: string,
) {
}
}

export function getLandingPageRepository(
): SingleDataSourceRepository<UserModel> {
const dataSource = new MockDataSource(
new MockUserDataSourceFactory(),
1500,
);
return new SingleDataSourceRepository(dataSource, dataSource, dataSource);
}