Skip to content

Commit

Permalink
feat(image): add image via.placeholder provider (#1186)
Browse files Browse the repository at this point in the history
  • Loading branch information
Devdre1909 committed Aug 8, 2022
1 parent 7372e9a commit 00d4741
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/modules/image/index.ts
Expand Up @@ -2,6 +2,7 @@ import type { Faker } from '../..';
import type { MethodsOf } from '../../utils/types';
import { LoremPicsum } from './providers/lorempicsum';
import { Lorempixel } from './providers/lorempixel';
import { Placeholder } from './providers/placeholder';
import { Unsplash } from './providers/unsplash';

/**
Expand All @@ -13,6 +14,7 @@ export class Image {
readonly lorempixel: Lorempixel;
readonly unsplash: Unsplash;
readonly lorempicsum: LoremPicsum;
readonly placeholder: Placeholder;

constructor(private readonly faker: Faker) {
// Bind `this` so namespaced is working correctly
Expand All @@ -26,6 +28,7 @@ export class Image {
this.lorempixel = new Lorempixel(this.faker);
this.unsplash = new Unsplash(this.faker);
this.lorempicsum = new LoremPicsum(this.faker);
this.placeholder = new Placeholder(this.faker);
}

/**
Expand Down
101 changes: 101 additions & 0 deletions src/modules/image/providers/placeholder.ts
@@ -0,0 +1,101 @@
import type { Faker } from '../../..';

/**
* Module to generate links to images on `https://via.placeholder.com/`.
*/
export class Placeholder {
constructor(private readonly faker: Faker) {
// Bind `this` so namespaced is working correctly
for (const name of Object.getOwnPropertyNames(Placeholder.prototype)) {
if (name === 'constructor' || typeof this[name] !== 'function') {
continue;
}
this[name] = this[name].bind(this);
}
}

/**
* Generates a new placeholder image url.
*
* @param width The width of the image (in pixels). Defaults to `640`.
* @param height The height of the image (in pixels). Defaults to `width`.
* @param text The text of the image.
* @param format The file format of the image. Supports `png`, `jpeg`, `png`, `gif`, `webp`.
* @param backgroundColor The background color of the placeholder. Supports HEX CODE format.
* @param textColor The text color of the placeholder. Requires `backgroundColor`. Supports HEX CODE format.
*
* @example
* faker.image.placeholder.imageUrl() // https://via.placeholder.com/640x640
* faker.image.placeholder.imageUrl(200) // https://via.placeholder.com/200x200
* faker.image.placeholder.imageUrl(200, 100) // https://via.placeholder.com/200x100
* faker.image.placeholder.imageUrl(200, 100, 'Fish') // https://via.placeholder.com/200x100?text=Fish
* faker.image.placeholder.imageUrl(200, 100, 'Fish', 'webp') // https://via.placeholder.com/200x100.webp?text=Fish
* faker.image.placeholder.imageUrl(200, 100, 'Fish', 'webp') // https://via.placeholder.com/200x100.webp?text=Fish
* faker.image.placeholder.imageUrl(200, 100, 'Fish', 'webp', '000000', 'ffffff) // https://via.placeholder.com/200x100/000000/FFFFFF.webp?text=Fish
*
*/
imageUrl(
width?: number,
height?: number,
text?: string,
format?: 'png' | 'jpeg' | 'jpg' | 'gif' | 'webp',
backgroundColor?: string,
textColor?: string
): string {
width = width || 640;
height = height || width;

let url = 'https://via.placeholder.com';
url += `/${width}x${height}`;

if (backgroundColor != null) {
url += `/${backgroundColor.replace('#', '').toUpperCase()}`;

if (textColor != null) {
url += `/${textColor.replace('#', '').toUpperCase()}`;
}
}

if (format != null) {
url += `.${format}`;
}

if (text != null) {
const urlParam = new URLSearchParams({ text });
url += `?${urlParam.toString()}`;
}

return url;
}

/**
* Generate a new placeholder image with random colors and text.
*
* @param width The width of the image (in pixels). Defaults to `640`.
* @param height The height of the image (in pixels). Defaults to `width`.
* @param format The file format of the image. Supports `png` `jpeg` `png` `gif` `webp`.
*
* @example
* faker.image.placeholder.randomUrl() // https://via.placeholder.com/640x640/000000/ffffff?text=lorum
* faker.image.placeholder.randomUrl(150) // https://via.placeholder.com/150x150/000000/ffffff?text=lorum
* faker.image.placeholder.randomUrl(150, 200) // https://via.placeholder.com/150x200/000000/ffffff?text=lorum
* faker.image.placeholder.randomUrl(150, 200, 'png') // https://via.placeholder.com/150x200/000000/ffffff.png?text=lorum
*/
randomUrl(
width?: number,
height?: number,
format?: 'png' | 'jpeg' | 'jpg' | 'gif' | 'webp'
): string {
return this.imageUrl(
width,
height,
this.faker.lorem.word(),
format,
this.faker.color.rgb({
casing: 'upper',
prefix: '',
}),
this.faker.color.rgb({ casing: 'upper', prefix: '' })
);
}
}
116 changes: 116 additions & 0 deletions test/image.spec.ts
Expand Up @@ -237,6 +237,122 @@ describe('image', () => {
}
});

describe('placeholder', () => {
describe('imageUrl()', () => {
it('should return a random image url from placeholder', () => {
const imageUrl = faker.image.placeholder.imageUrl();

expect(imageUrl).toBe('https://via.placeholder.com/640x640');
});

it('should return a square random image url from placeholder with width and height', () => {
const imageUrl = faker.image.placeholder.imageUrl(100);

expect(imageUrl).toBe('https://via.placeholder.com/100x100');
});

it('should return a random image url with a gif format', () => {
const imageUrl = faker.image.placeholder.imageUrl(
100,
100,
undefined,
'gif'
);

expect(imageUrl).toBe('https://via.placeholder.com/100x100.gif');
});

it('should return a random image url with correct text for a specified format', () => {
const imageUrl = faker.image.placeholder.imageUrl(
100,
100,
'I love food',
'png'
);

expect(imageUrl).toBe(
'https://via.placeholder.com/100x100.png?text=I+love+food'
);
});

it('should return a random image url with specified background color and text color', () => {
const imageUrl = faker.image.placeholder.imageUrl(
100,
100,
undefined,
undefined,
'000000',
'ffffff'
);

expect(imageUrl).toBe(
'https://via.placeholder.com/100x100/000000/FFFFFF'
);
});

it('should return a random image url with specified background color and color without the #', () => {
const imageUrl = faker.image.placeholder.imageUrl(
100,
100,
undefined,
undefined,
'#000000',
'#ffffff'
);

expect(imageUrl).toBe(
'https://via.placeholder.com/100x100/000000/FFFFFF'
);
});

it('should return a random image url given all parameter', () => {
const imageUrl = faker.image.placeholder.imageUrl(
100,
200,
'I love food',
'jpg',
'000000',
'ffffff'
);

expect(imageUrl).toBe(
'https://via.placeholder.com/100x200/000000/FFFFFF.jpg?text=I+love+food'
);
});
});

describe('randomUrl()', () => {
it('should return a random url with specified width and height', () => {
const imageUrl = faker.image.placeholder.randomUrl(200, 150);

// https://via.placeholder.com/150/000000/FFFFFF/
const urlSpilt = imageUrl.split('/');

console.log(imageUrl);

expect(urlSpilt[0]).toBe('https:');
expect(urlSpilt[2]).toBe('via.placeholder.com');
expect(urlSpilt[3]).toBe('200x150');
expect(urlSpilt[4]).toHaveLength(6);
expect(urlSpilt[5].split('?')[0]).toHaveLength(6);
expect(urlSpilt[5].split('?')[1]).toContain('text=');
});
it('should return a random url with specified width and height and format', () => {
const imageUrl = faker.image.placeholder.randomUrl(200, 150, 'png');

const urlSpilt = imageUrl.split('/');

expect(urlSpilt[0]).toBe('https:');
expect(urlSpilt[2]).toBe('via.placeholder.com');
expect(urlSpilt[3]).toBe('200x150');
expect(urlSpilt[4]).toHaveLength(6);
expect(urlSpilt[5].split('?')[0]).toHaveLength(10);
expect(urlSpilt[5].split('?')[0]).toContain('.png');
expect(urlSpilt[5].split('?')[1]).toContain('text=');
});
});
});

describe('dataUri', () => {
it('should return a blank data', () => {
const dataUri = faker.image.dataUri(200, 300);
Expand Down

0 comments on commit 00d4741

Please sign in to comment.