Skip to content

Commit 1d78e2e

Browse files
committed
(#455) Refactor handling of finder implementations, add tests
1 parent eba13ba commit 1d78e2e

5 files changed

+328
-86
lines changed

lib/match-request.class.spec.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Image } from "./image.class";
2+
import {
3+
createMatchRequest,
4+
isImageMatchRequest,
5+
isTextMatchRequest,
6+
} from "./match-request.class";
7+
import { mockPartial } from "sneer";
8+
import { ProviderRegistry } from "./provider/provider-registry.class";
9+
import { LogProviderInterface } from "./provider";
10+
import { NoopLogProvider } from "./provider/log/noop-log-provider.class";
11+
import { Region } from "./region.class";
12+
import { TextQuery } from "./query.class";
13+
14+
beforeEach(() => {
15+
jest.clearAllMocks();
16+
});
17+
18+
const providerRegistryMock = mockPartial<ProviderRegistry>({
19+
getLogProvider(): LogProviderInterface {
20+
return new NoopLogProvider();
21+
},
22+
});
23+
24+
const screenImage = new Image(0, 0, Buffer.of(0), 3, "dummy", 0, 0);
25+
const dummyRegion = new Region(0, 0, 0, 0);
26+
27+
describe("MatchRequest", () => {
28+
it("should create an image match request for images", () => {
29+
// GIVEN
30+
const needle = new Image(0, 0, Buffer.of(0), 3, "dummy", 0, 0);
31+
32+
// WHEN
33+
const matchRequest = createMatchRequest(
34+
providerRegistryMock,
35+
needle,
36+
dummyRegion,
37+
0,
38+
screenImage
39+
);
40+
41+
// THEN
42+
expect(isImageMatchRequest(matchRequest)).toBeTruthy();
43+
});
44+
45+
it.each<TextQuery>([
46+
{
47+
id: "dummy",
48+
type: "text",
49+
by: {
50+
word: "dummy-query",
51+
},
52+
},
53+
{
54+
id: "dummy",
55+
type: "text",
56+
by: {
57+
line: "dummy-query",
58+
},
59+
},
60+
])(
61+
"should create a text match request for text queries",
62+
(needle: TextQuery) => {
63+
// GIVEN
64+
65+
// WHEN
66+
const matchRequest = createMatchRequest(
67+
providerRegistryMock,
68+
needle,
69+
dummyRegion,
70+
0,
71+
screenImage
72+
);
73+
74+
// THEN
75+
expect(isTextMatchRequest(matchRequest)).toBeTruthy();
76+
}
77+
);
78+
});

lib/match-request.class.ts

+10-36
Original file line numberDiff line numberDiff line change
@@ -26,59 +26,33 @@ export function isTextMatchRequest<PROVIDER_DATA_TYPE>(
2626
return isTextQuery(matchRequest.needle);
2727
}
2828

29-
export function createTextMatchRequest<PROVIDER_DATA_TYPE>(
29+
export function createMatchRequest<PROVIDER_DATA_TYPE>(
3030
providerRegistry: ProviderRegistry,
3131
needle: TextQuery | Promise<TextQuery>,
3232
searchRegion: Region,
3333
minMatch: number,
3434
screenImage: Image,
3535
params?: OptionalSearchParameters<PROVIDER_DATA_TYPE>
36-
): MatchRequest<TextQuery, PROVIDER_DATA_TYPE> {
37-
return createMatchRequest<PROVIDER_DATA_TYPE>(
38-
providerRegistry,
39-
needle,
40-
searchRegion,
41-
minMatch,
42-
screenImage,
43-
params
44-
);
45-
}
46-
47-
export function createImageMatchRequest<PROVIDER_DATA_TYPE>(
36+
): MatchRequest<TextQuery, PROVIDER_DATA_TYPE>;
37+
export function createMatchRequest<PROVIDER_DATA_TYPE>(
4838
providerRegistry: ProviderRegistry,
4939
needle: Image | Promise<Image>,
5040
searchRegion: Region,
5141
minMatch: number,
5242
screenImage: Image,
5343
params?: OptionalSearchParameters<PROVIDER_DATA_TYPE>
54-
): MatchRequest<Image, PROVIDER_DATA_TYPE> {
55-
return createMatchRequest<PROVIDER_DATA_TYPE>(
56-
providerRegistry,
57-
needle,
58-
searchRegion,
59-
minMatch,
60-
screenImage,
61-
params
62-
);
63-
}
64-
65-
function createMatchRequest<PROVIDER_DATA_TYPE>(
66-
providerRegistry: ProviderRegistry,
67-
needle: TextQuery | Promise<TextQuery>,
68-
searchRegion: Region,
69-
minMatch: number,
70-
screenImage: Image,
71-
params?: OptionalSearchParameters<PROVIDER_DATA_TYPE>
72-
): MatchRequest<TextQuery, PROVIDER_DATA_TYPE>;
73-
function createMatchRequest<PROVIDER_DATA_TYPE>(
44+
): MatchRequest<Image, PROVIDER_DATA_TYPE>;
45+
export function createMatchRequest<PROVIDER_DATA_TYPE>(
7446
providerRegistry: ProviderRegistry,
75-
needle: Image | Promise<Image>,
47+
needle: RegionResultFindInput | Promise<RegionResultFindInput>,
7648
searchRegion: Region,
7749
minMatch: number,
7850
screenImage: Image,
7951
params?: OptionalSearchParameters<PROVIDER_DATA_TYPE>
80-
): MatchRequest<Image, PROVIDER_DATA_TYPE>;
81-
function createMatchRequest<PROVIDER_DATA_TYPE>(
52+
):
53+
| MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
54+
| MatchRequest<Image, PROVIDER_DATA_TYPE>;
55+
export function createMatchRequest<PROVIDER_DATA_TYPE>(
8256
providerRegistry: ProviderRegistry,
8357
needle: RegionResultFindInput | Promise<RegionResultFindInput>,
8458
searchRegion: Region,

lib/match-result.class.spec.ts

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { createMatchRequest } from "./match-request.class";
2+
import { Image } from "./image.class";
3+
import { Region } from "./region.class";
4+
import { mockPartial } from "sneer";
5+
import { ProviderRegistry } from "./provider/provider-registry.class";
6+
import { ImageFinderInterface, LogProviderInterface } from "./provider";
7+
import { NoopLogProvider } from "./provider/log/noop-log-provider.class";
8+
import { TextFinderInterface } from "./provider/text-finder.interface";
9+
import { getMatchResult, getMatchResults } from "./match-result.class";
10+
import { TextQuery } from "./query.class";
11+
12+
const dummyImage = new Image(0, 0, Buffer.of(0), 3, "dummy-needle", 0, 0);
13+
const screenImage = new Image(
14+
0,
15+
0,
16+
Buffer.of(0),
17+
3,
18+
"dummy-screen-image",
19+
0,
20+
0
21+
);
22+
const dummyRegion = new Region(0, 0, 0, 0);
23+
24+
beforeEach(() => {
25+
jest.clearAllMocks();
26+
});
27+
28+
const imageFinderMock: ImageFinderInterface = {
29+
findMatch: jest.fn(),
30+
findMatches: jest.fn(),
31+
};
32+
const textFinderMock: TextFinderInterface = {
33+
findMatch: jest.fn(),
34+
findMatches: jest.fn(),
35+
};
36+
37+
const providerRegistryMock = mockPartial<ProviderRegistry>({
38+
getLogProvider(): LogProviderInterface {
39+
return new NoopLogProvider();
40+
},
41+
getImageFinder(): ImageFinderInterface {
42+
return imageFinderMock as unknown as ImageFinderInterface;
43+
},
44+
getTextFinder(): TextFinderInterface {
45+
return textFinderMock as unknown as TextFinderInterface;
46+
},
47+
});
48+
49+
describe("matchResults", () => {
50+
describe("getMatchResult", () => {
51+
it("should call the correct finder implementation for a given image match request", async () => {
52+
// GIVEN
53+
const imageMatchRequest = createMatchRequest(
54+
providerRegistryMock,
55+
dummyImage,
56+
dummyRegion,
57+
0,
58+
screenImage
59+
);
60+
61+
// WHEN
62+
await getMatchResult(providerRegistryMock, imageMatchRequest);
63+
64+
// THEN
65+
expect(imageFinderMock.findMatch).toBeCalledTimes(1);
66+
});
67+
68+
it.each<TextQuery>([
69+
{
70+
id: "dummy",
71+
type: "text",
72+
by: {
73+
word: "dummy-query",
74+
},
75+
},
76+
{
77+
id: "dummy",
78+
type: "text",
79+
by: {
80+
line: "dummy-query",
81+
},
82+
},
83+
])(
84+
"should all the correct finder implementation for a given text query",
85+
async (needle: TextQuery) => {
86+
// GIVEN
87+
const matchRequest = createMatchRequest(
88+
providerRegistryMock,
89+
needle,
90+
dummyRegion,
91+
0,
92+
screenImage
93+
);
94+
95+
// WHEN
96+
await getMatchResult(providerRegistryMock, matchRequest);
97+
98+
// THEN
99+
expect(textFinderMock.findMatch).toBeCalledTimes(1);
100+
}
101+
);
102+
});
103+
104+
describe("getMatchResults", () => {
105+
it("should call the correct finder implementation for a given image match request", async () => {
106+
// GIVEN
107+
const imageMatchRequest = createMatchRequest(
108+
providerRegistryMock,
109+
dummyImage,
110+
dummyRegion,
111+
0,
112+
screenImage
113+
);
114+
115+
// WHEN
116+
await getMatchResults(providerRegistryMock, imageMatchRequest);
117+
118+
// THEN
119+
expect(imageFinderMock.findMatches).toBeCalledTimes(1);
120+
});
121+
122+
it.each<TextQuery>([
123+
{
124+
id: "dummy",
125+
type: "text",
126+
by: {
127+
word: "dummy-query",
128+
},
129+
},
130+
{
131+
id: "dummy",
132+
type: "text",
133+
by: {
134+
line: "dummy-query",
135+
},
136+
},
137+
])(
138+
"should all the correct finder implementation for a given text query",
139+
async (needle: TextQuery) => {
140+
// GIVEN
141+
const matchRequest = createMatchRequest(
142+
providerRegistryMock,
143+
needle,
144+
dummyRegion,
145+
0,
146+
screenImage
147+
);
148+
149+
// WHEN
150+
await getMatchResults(providerRegistryMock, matchRequest);
151+
152+
// THEN
153+
expect(textFinderMock.findMatches).toBeCalledTimes(1);
154+
}
155+
);
156+
});
157+
});

lib/match-result.class.ts

+54
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { Region } from "./region.class";
2+
import { isImageMatchRequest, MatchRequest } from "./match-request.class";
3+
import { ProviderRegistry } from "./provider/provider-registry.class";
4+
import { Image } from "./image.class";
5+
import { TextQuery } from "./query.class";
26

37
export class MatchResult {
48
constructor(
@@ -7,3 +11,53 @@ export class MatchResult {
711
public readonly error?: Error
812
) {}
913
}
14+
15+
export async function getMatchResults<PROVIDER_DATA_TYPE>(
16+
providerRegistry: ProviderRegistry,
17+
matchRequest: MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
18+
): Promise<MatchResult[]>;
19+
export async function getMatchResults<PROVIDER_DATA_TYPE>(
20+
providerRegistry: ProviderRegistry,
21+
matchRequest: MatchRequest<Image, PROVIDER_DATA_TYPE>
22+
): Promise<MatchResult[]>;
23+
export async function getMatchResults<PROVIDER_DATA_TYPE>(
24+
providerRegistry: ProviderRegistry,
25+
matchRequest:
26+
| MatchRequest<Image, PROVIDER_DATA_TYPE>
27+
| MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
28+
): Promise<MatchResult[]>;
29+
export async function getMatchResults<PROVIDER_DATA_TYPE>(
30+
providerRegistry: ProviderRegistry,
31+
matchRequest:
32+
| MatchRequest<Image, PROVIDER_DATA_TYPE>
33+
| MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
34+
): Promise<MatchResult[]> {
35+
return isImageMatchRequest(matchRequest)
36+
? providerRegistry.getImageFinder().findMatches(matchRequest)
37+
: providerRegistry.getTextFinder().findMatches(matchRequest);
38+
}
39+
40+
export async function getMatchResult<PROVIDER_DATA_TYPE>(
41+
providerRegistry: ProviderRegistry,
42+
matchRequest: MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
43+
): Promise<MatchResult>;
44+
export async function getMatchResult<PROVIDER_DATA_TYPE>(
45+
providerRegistry: ProviderRegistry,
46+
matchRequest: MatchRequest<Image, PROVIDER_DATA_TYPE>
47+
): Promise<MatchResult>;
48+
export async function getMatchResult<PROVIDER_DATA_TYPE>(
49+
providerRegistry: ProviderRegistry,
50+
matchRequest:
51+
| MatchRequest<Image, PROVIDER_DATA_TYPE>
52+
| MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
53+
): Promise<MatchResult>;
54+
export async function getMatchResult<PROVIDER_DATA_TYPE>(
55+
providerRegistry: ProviderRegistry,
56+
matchRequest:
57+
| MatchRequest<Image, PROVIDER_DATA_TYPE>
58+
| MatchRequest<TextQuery, PROVIDER_DATA_TYPE>
59+
): Promise<MatchResult> {
60+
return isImageMatchRequest(matchRequest)
61+
? providerRegistry.getImageFinder().findMatch(matchRequest)
62+
: providerRegistry.getTextFinder().findMatch(matchRequest);
63+
}

0 commit comments

Comments
 (0)