Skip to content

Feature/400/fetch images from url #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
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
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;
});
}