Skip to content

Commit

Permalink
Fixing extendClass function and adding more extensive tests (#896)
Browse files Browse the repository at this point in the history
* Fixing `extendClass` function to properly handle custom configuration passed to constructor
  • Loading branch information
jdalrymple authored Jun 16, 2020
1 parent 51e22d9 commit 8f6ca53
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 4 deletions.
6 changes: 4 additions & 2 deletions packages/gitbeaker-requester-utils/src/RequesterUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ export interface Constructable {
function extendClass<T extends Constructable>(Base: T, customConfig: object): T {
return class extends Base {
constructor(...options: any[]) {
super({ ...options, ...customConfig });
const [config, ...opts] = options;

super({ ...customConfig, ...config }, ...opts);
}
};
}

export function modifyServices<T extends { [name: string]: Constructable }>(
services: T,
customConfig: object,
customConfig: object = {},
) {
const updated: { [name: string]: Constructable } = {};

Expand Down
102 changes: 100 additions & 2 deletions packages/gitbeaker-requester-utils/test/unit/RequesterUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-classes-per-file */
import * as FormData from 'form-data';
import { createInstance, defaultRequest, modifyServices } from '../../src/RequesterUtils';

Expand All @@ -11,6 +12,12 @@ describe('defaultRequest', () => {
requestTimeout: 50,
};

it('should not use default request options if not passed', async () => {
const options = defaultRequest(service);

expect(options.method).toBe('get');
});

it('should stringify body if it isnt of type FormData', async () => {
const testBody = { test: 6 };
const { body, headers } = defaultRequest(service, {
Expand Down Expand Up @@ -55,11 +62,26 @@ describe('defaultRequest', () => {
it('should default searchParams to an empty string if undefined', async () => {
const { searchParams } = defaultRequest(service, {
query: undefined,
method: 'get',
});

expect(searchParams).toBe('');
});

it('should format searchParams to an stringified object', async () => {
const { searchParams } = defaultRequest(service, {
query: { a: 5 },
});

expect(searchParams).toBe('a=5');
});

it('should format searchParams to an stringified object and decamelize properties', async () => {
const { searchParams } = defaultRequest(service, {
query: { thisSearchTerm: 5 },
});

expect(searchParams).toBe('this_search_term=5');
});
});

describe('createInstance', () => {
Expand Down Expand Up @@ -99,8 +121,12 @@ describe('createInstance', () => {
});

describe('modifyServices', () => {
it('should modify class with default properties', async () => {
it('should preset class with extended properties', async () => {
class A {
x?: number;

y?: number;

constructor({ x, y }: { x?: number; y?: number } = {}) {
this.x = x;
this.y = y;
Expand All @@ -112,4 +138,76 @@ describe('modifyServices', () => {

expect(b.x).toBe(3);
});

it('should preset class with default properties', async () => {
class A {
x: number;

y?: number;

constructor({ x = 8, y }: { x?: number; y?: number } = {}) {
this.x = x;
this.y = y;
}
}

const { A: B } = modifyServices({ A });
const b = new B();

expect(b.x).toBe(8);
});

it('should overwrite default properties with extended properties', async () => {
class A {
x: number;

y?: number;

constructor({ x = 8, y }: { x?: number; y?: number } = {}) {
this.x = x;
this.y = y;
}
}

const { A: B } = modifyServices({ A }, { x: 3 });
const b = new B();

expect(b.x).toBe(3);
});

it('should overwrite default properties with custom properties', async () => {
class A {
x: number;

y?: number;

constructor({ x = 8, y }: { x?: number; y?: number } = {}) {
this.x = x;
this.y = y;
}
}

const { A: B } = modifyServices({ A });
const b = new B({ x: 5 });

expect(b.x).toBe(5);
});

it('should overwrite default and extended properties with custom properties', async () => {
class A {
x: number;

y?: number;

constructor({ x = 8, y }: { x?: number; y?: number } = {}) {
this.x = x;
this.y = y;
}
}

const { A: B } = modifyServices({ A }, { x: 2 });
const b = new B({ x: 5 });

expect(b.x).toBe(5);
});
});

0 comments on commit 8f6ca53

Please sign in to comment.