Skip to content

Commit

Permalink
Feature/400/fetch images from url (#401)
Browse files Browse the repository at this point in the history
* (#400) Implement fetchFromUrl + tests

* (#400) Re-export fetchFromUrl as part of the public API

* (#400) Added docstring for fetchFromUrl
  • Loading branch information
s1hofmann authored May 6, 2022
1 parent 4183d97 commit b410d7f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const loadImage = providerRegistry.getImageReader().load;
const saveImage = providerRegistry.getImageWriter().store;

const imageResource = (fileName: string) => loadImageResource(providerRegistry, screen.config.resourceDirectory, fileName);
export {fetchFromUrl} from "./lib/imageResources.function";

export {
clipboard,
Expand Down
45 changes: 44 additions & 1 deletion lib/imageResources.function.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {loadImageResource} from "./imageResources.function";
import {fetchFromUrl, loadImageResource} from "./imageResources.function";
import {mockPartial} from "sneer";
import {ProviderRegistry} from "./provider/provider-registry.class";
import {ImageReader} from "./provider";
import {join} from "path";
import {ColorMode} from "./colormode.enum";

const loadMock = jest.fn();
const providerRegistryMock = mockPartial<ProviderRegistry>({
Expand All @@ -25,4 +26,46 @@ describe('imageResources', () => {
// THEN
expect(loadMock).toBeCalledWith(join(resourceDirectoryPath, imageFileName));
});
});

describe('fetchFromUrl', () => {
it('should throw on malformed URLs', async () => {
// GIVEN
const malformedUrl = "foo";

// WHEN
const SUT = () => fetchFromUrl(malformedUrl);

// THEN
await expect(SUT).rejects.toThrowError("Invalid URL");
});

it('should throw on non-image URLs', async () => {
// GIVEN
const nonImageUrl = 'https://www.npmjs.com/package/jimp';

// WHEN
const SUT = () => fetchFromUrl(nonImageUrl);

// THEN
await expect(SUT).rejects.toThrowError('Could not find MIME for Buffer');
});

it('should return an RGB image from a valid URL', async () => {
// GIVEN
const validImageUrl = 'https://github.com/nut-tree/nut.js/raw/master/.gfx/nut.png';
const expectedDimensions = {
width: 502,
height: 411
};
const expectedColorMode = ColorMode.RGB;

// WHEN
const rgbImage = await fetchFromUrl(validImageUrl);

// THEN
expect(rgbImage.colorMode).toBe(expectedColorMode);
expect(rgbImage.width).toBe(expectedDimensions.width);
expect(rgbImage.height).toBe(expectedDimensions.height);
});
});
36 changes: 36 additions & 0 deletions lib/imageResources.function.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
import {join, normalize} from "path";
import {ProviderRegistry} from "./provider/provider-registry.class";
import {URL} from "url";
import {Image} from "./image.class";
import Jimp from "jimp";
import {ColorMode} from "./colormode.enum";

export function loadImageResource(providerRegistry: ProviderRegistry, resourceDirectory: string, fileName: string) {
const fullPath = normalize(join(resourceDirectory, fileName));
return providerRegistry.getImageReader().load(fullPath);
}

/**
* fetchFromUrl loads remote image content at runtime to provide it for further use in on-screen image search
* @param url The remote URl to fetch an image from as string or {@link URL}
* @throws On malformed URL input or in case of non-image remote content
*/
export async function fetchFromUrl(url: string | URL): Promise<Image> {
let imageUrl: URL;
if (url instanceof URL) {
imageUrl = url;
} else {
try {
imageUrl = new URL(url);
} catch (e) {
throw e;
}
}
return Jimp.read(imageUrl.href)
.then((image) => {
return new Image(
image.bitmap.width,
image.bitmap.height,
image.bitmap.data,
4,
imageUrl.href,
ColorMode.RGB
);
})
.catch(err => {
throw err;
});
}

0 comments on commit b410d7f

Please sign in to comment.