@digigov/text-search 1.2.0-85c27c19 → 1.2.0-daaf7bdf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/search/lang/gr/encoder/index.js +7 -4
- package/cjs/search/lang/gr/encoder.js.map +2 -2
- package/index.js +1 -1
- package/package.json +1 -1
- package/search/lang/gr/encoder/index.js +7 -4
- package/search/lang/gr/encoder.js.map +2 -2
- package/src/hook.spec.ts +43 -76
- package/src/search/lang/gr/encoder.ts +8 -4
|
@@ -21,15 +21,18 @@ __export(encoder_exports, {
|
|
|
21
21
|
encodeGreek: () => encodeGreek
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(encoder_exports);
|
|
24
|
-
var import_normalization_map = require("
|
|
25
|
-
const whitespaceRegex =
|
|
26
|
-
const diacriticsRegex =
|
|
24
|
+
var import_normalization_map = require("@digigov/text-search/search/lang/gr/normalization-map");
|
|
25
|
+
const whitespaceRegex = new RegExp("[p{Z}p{S}p{P}p{C}]+", "u");
|
|
26
|
+
const diacriticsRegex = new RegExp("[\u0300-\u036F]", "g");
|
|
27
27
|
const greekCharsRegex = new RegExp(
|
|
28
28
|
Object.keys(import_normalization_map.greekToGreeklishMap).join("|"),
|
|
29
29
|
"igu"
|
|
30
30
|
);
|
|
31
31
|
function encodeGreek(str) {
|
|
32
|
-
return ("" + str).toLowerCase().normalize("NFD").replace(diacriticsRegex, "").replace(
|
|
32
|
+
return ("" + str).toLowerCase().normalize("NFD").replace(diacriticsRegex, "").replace(
|
|
33
|
+
greekCharsRegex,
|
|
34
|
+
(match) => match in import_normalization_map.greekToGreeklishMap ? import_normalization_map.greekToGreeklishMap[match] : match
|
|
35
|
+
).split(whitespaceRegex);
|
|
33
36
|
}
|
|
34
37
|
// Annotate the CommonJS export names for ESM import in node:
|
|
35
38
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/search/lang/gr/encoder.ts"],
|
|
4
|
-
"sourcesContent": ["import { greekToGreeklishMap } from '
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAAoC;AAEpC,MAAM,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { greekToGreeklishMap } from '@digigov/text-search/search/lang/gr/normalization-map';\n\nconst whitespaceRegex = new RegExp('[p{Z}p{S}p{P}p{C}]+', 'u');\nconst diacriticsRegex = new RegExp('[\\u0300-\\u036f]', 'g');\nconst greekCharsRegex = new RegExp(\n Object.keys(greekToGreeklishMap).join('|'),\n 'igu'\n);\n\n/**\n * Encode a string containing greek characters to greeklish\n *\n * This function is used to encode and tokenize a string containing greek characters.\n * It replaces greek characters with their latin counterparts, while also removing\n * any diacritics.\n *\n * @param str - The string to encode\n * @returns An array of encoded words\n */\nexport function encodeGreek(str: string) {\n return ('' + str)\n .toLowerCase()\n .normalize('NFD')\n .replace(diacriticsRegex, '')\n .replace(greekCharsRegex, (match) =>\n match in greekToGreeklishMap\n ? greekToGreeklishMap[match as keyof typeof greekToGreeklishMap]\n : match\n )\n .split(whitespaceRegex);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAAoC;AAEpC,MAAM,kBAAkB,IAAI,OAAO,uBAAuB,GAAG;AAC7D,MAAM,kBAAkB,IAAI,OAAO,mBAAmB,GAAG;AACzD,MAAM,kBAAkB,IAAI;AAAA,EAC1B,OAAO,KAAK,4CAAmB,EAAE,KAAK,GAAG;AAAA,EACzC;AACF;AAYO,SAAS,YAAY,KAAa;AACvC,UAAQ,KAAK,KACV,YAAY,EACZ,UAAU,KAAK,EACf,QAAQ,iBAAiB,EAAE,EAC3B;AAAA,IAAQ;AAAA,IAAiB,CAAC,UACzB,SAAS,+CACL,6CAAoB,KAAyC,IAC7D;AAAA,EACN,EACC,MAAM,eAAe;AAC1B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { greekToGreeklishMap } from "
|
|
2
|
-
const whitespaceRegex =
|
|
3
|
-
const diacriticsRegex =
|
|
1
|
+
import { greekToGreeklishMap } from "@digigov/text-search/search/lang/gr/normalization-map";
|
|
2
|
+
const whitespaceRegex = new RegExp("[p{Z}p{S}p{P}p{C}]+", "u");
|
|
3
|
+
const diacriticsRegex = new RegExp("[\u0300-\u036F]", "g");
|
|
4
4
|
const greekCharsRegex = new RegExp(
|
|
5
5
|
Object.keys(greekToGreeklishMap).join("|"),
|
|
6
6
|
"igu"
|
|
7
7
|
);
|
|
8
8
|
function encodeGreek(str) {
|
|
9
|
-
return ("" + str).toLowerCase().normalize("NFD").replace(diacriticsRegex, "").replace(
|
|
9
|
+
return ("" + str).toLowerCase().normalize("NFD").replace(diacriticsRegex, "").replace(
|
|
10
|
+
greekCharsRegex,
|
|
11
|
+
(match) => match in greekToGreeklishMap ? greekToGreeklishMap[match] : match
|
|
12
|
+
).split(whitespaceRegex);
|
|
10
13
|
}
|
|
11
14
|
export {
|
|
12
15
|
encodeGreek
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/search/lang/gr/encoder.ts"],
|
|
4
|
-
"sourcesContent": ["import { greekToGreeklishMap } from '
|
|
5
|
-
"mappings": "AAAA,SAAS,2BAA2B;AAEpC,MAAM,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { greekToGreeklishMap } from '@digigov/text-search/search/lang/gr/normalization-map';\n\nconst whitespaceRegex = new RegExp('[p{Z}p{S}p{P}p{C}]+', 'u');\nconst diacriticsRegex = new RegExp('[\\u0300-\\u036f]', 'g');\nconst greekCharsRegex = new RegExp(\n Object.keys(greekToGreeklishMap).join('|'),\n 'igu'\n);\n\n/**\n * Encode a string containing greek characters to greeklish\n *\n * This function is used to encode and tokenize a string containing greek characters.\n * It replaces greek characters with their latin counterparts, while also removing\n * any diacritics.\n *\n * @param str - The string to encode\n * @returns An array of encoded words\n */\nexport function encodeGreek(str: string) {\n return ('' + str)\n .toLowerCase()\n .normalize('NFD')\n .replace(diacriticsRegex, '')\n .replace(greekCharsRegex, (match) =>\n match in greekToGreeklishMap\n ? greekToGreeklishMap[match as keyof typeof greekToGreeklishMap]\n : match\n )\n .split(whitespaceRegex);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,2BAA2B;AAEpC,MAAM,kBAAkB,IAAI,OAAO,uBAAuB,GAAG;AAC7D,MAAM,kBAAkB,IAAI,OAAO,mBAAmB,GAAG;AACzD,MAAM,kBAAkB,IAAI;AAAA,EAC1B,OAAO,KAAK,mBAAmB,EAAE,KAAK,GAAG;AAAA,EACzC;AACF;AAYO,SAAS,YAAY,KAAa;AACvC,UAAQ,KAAK,KACV,YAAY,EACZ,UAAU,KAAK,EACf,QAAQ,iBAAiB,EAAE,EAC3B;AAAA,IAAQ;AAAA,IAAiB,CAAC,UACzB,SAAS,sBACL,oBAAoB,KAAyC,IAC7D;AAAA,EACN,EACC,MAAM,eAAe;AAC1B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/hook.spec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { act, renderHook } from '@testing-library/react
|
|
2
|
-
import useSearch from '
|
|
3
|
-
import documents from '
|
|
1
|
+
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
2
|
+
import useSearch from '@digigov/text-search/hook';
|
|
3
|
+
import documents from '@digigov/text-search/test-utils/data.json';
|
|
4
4
|
|
|
5
5
|
describe('loading', () => {
|
|
6
6
|
it('should start when searching', async () => {
|
|
@@ -10,33 +10,27 @@ describe('loading', () => {
|
|
|
10
10
|
expect(result.current.loading).toBe(true);
|
|
11
11
|
});
|
|
12
12
|
it('should stop after search is completed', async () => {
|
|
13
|
-
const { result
|
|
14
|
-
useSearch(documents, 'Anastasia')
|
|
15
|
-
);
|
|
13
|
+
const { result } = renderHook(() => useSearch(documents, 'Anastasia'));
|
|
16
14
|
expect(result.current.loading).toBe(false);
|
|
17
15
|
act(() => result.current.search());
|
|
18
16
|
expect(result.current.loading).toBe(true);
|
|
19
|
-
await
|
|
20
|
-
expect(result.current.loading).toBe(false);
|
|
17
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
21
18
|
});
|
|
22
19
|
});
|
|
23
20
|
|
|
24
21
|
describe('reset', () => {
|
|
25
22
|
it('should change the returned result back to the initial data', async () => {
|
|
26
|
-
const { result
|
|
27
|
-
useSearch(documents, 'Anastasia')
|
|
28
|
-
);
|
|
23
|
+
const { result } = renderHook(() => useSearch(documents, 'Anastasia'));
|
|
29
24
|
expect(result.current.loading).toBe(false);
|
|
30
25
|
act(() => result.current.search());
|
|
31
26
|
expect(result.current.loading).toBe(true);
|
|
32
27
|
expect(result.current.data).toEqual(documents);
|
|
33
|
-
await
|
|
34
|
-
expect(result.current.loading).toBe(false);
|
|
28
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
35
29
|
expect(result.current.data.length).toBe(1);
|
|
36
30
|
|
|
37
31
|
act(() => result.current.reset());
|
|
38
32
|
expect(result.current.data).toEqual(documents);
|
|
39
|
-
expect(result.current.loading).toBe(false);
|
|
33
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
40
34
|
});
|
|
41
35
|
});
|
|
42
36
|
|
|
@@ -45,23 +39,20 @@ describe('search', () => {
|
|
|
45
39
|
const { result } = renderHook(() => useSearch(documents));
|
|
46
40
|
expect(result.current.loading).toBe(false);
|
|
47
41
|
act(() => result.current.search());
|
|
48
|
-
expect(result.current.loading).toBe(false);
|
|
42
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
49
43
|
expect(result.current.data).toEqual(documents);
|
|
50
44
|
});
|
|
51
45
|
it('should return an empty array when there are no relevant items', async () => {
|
|
52
|
-
const { result
|
|
53
|
-
useSearch(documents, 'fajsgsdgsdgsd')
|
|
54
|
-
);
|
|
46
|
+
const { result } = renderHook(() => useSearch(documents, 'fajsgsdgsdgsd'));
|
|
55
47
|
expect(result.current.loading).toBe(false);
|
|
56
48
|
act(() => result.current.search());
|
|
57
49
|
expect(result.current.loading).toBe(true);
|
|
58
50
|
expect(result.current.data).toEqual(documents);
|
|
59
|
-
await
|
|
60
|
-
expect(result.current.loading).toBe(false);
|
|
51
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
61
52
|
expect(result.current.data).toEqual([]);
|
|
62
53
|
});
|
|
63
54
|
it('should return an empty array when relevant field is not indexed', async () => {
|
|
64
|
-
const { result
|
|
55
|
+
const { result } = renderHook(() =>
|
|
65
56
|
useSearch(documents, 'Anastasia', {
|
|
66
57
|
indexing: {
|
|
67
58
|
fields: ['lastName'], // missing 'firstName'
|
|
@@ -72,38 +63,31 @@ describe('search', () => {
|
|
|
72
63
|
act(() => result.current.search());
|
|
73
64
|
expect(result.current.loading).toBe(true);
|
|
74
65
|
expect(result.current.data).toEqual(documents);
|
|
75
|
-
await
|
|
76
|
-
expect(result.current.loading).toBe(false);
|
|
66
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
77
67
|
expect(result.current.data).toEqual([]);
|
|
78
68
|
});
|
|
79
69
|
it('should return a single result when there is only one relevant item', async () => {
|
|
80
|
-
const { result
|
|
81
|
-
useSearch(documents, 'Anastasia')
|
|
82
|
-
);
|
|
70
|
+
const { result } = renderHook(() => useSearch(documents, 'Anastasia'));
|
|
83
71
|
expect(result.current.loading).toBe(false);
|
|
84
72
|
act(() => result.current.search());
|
|
85
73
|
expect(result.current.loading).toBe(true);
|
|
86
74
|
expect(result.current.data).toEqual(documents);
|
|
87
|
-
await
|
|
88
|
-
expect(result.current.loading).toBe(false);
|
|
75
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
89
76
|
expect(result.current.data.length).toBe(1);
|
|
90
77
|
|
|
91
78
|
const firstResult = result.current.data[0] as NonNullable<
|
|
92
|
-
typeof result.current.data[0]
|
|
79
|
+
(typeof result.current.data)[0]
|
|
93
80
|
>;
|
|
94
81
|
expect(firstResult).toBeDefined();
|
|
95
82
|
expect(Object.values(firstResult).values()).toContain('Anastasia');
|
|
96
83
|
});
|
|
97
84
|
it('should return multiple results when there are multiple relevant items', async () => {
|
|
98
|
-
const { result
|
|
99
|
-
useSearch(documents, 'Kari')
|
|
100
|
-
);
|
|
85
|
+
const { result } = renderHook(() => useSearch(documents, 'Kari'));
|
|
101
86
|
expect(result.current.loading).toBe(false);
|
|
102
87
|
act(() => result.current.search());
|
|
103
88
|
expect(result.current.loading).toBe(true);
|
|
104
89
|
expect(result.current.data).toEqual(documents);
|
|
105
|
-
await
|
|
106
|
-
expect(result.current.loading).toBe(false);
|
|
90
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
107
91
|
expect(result.current.data.length).toBeGreaterThanOrEqual(2);
|
|
108
92
|
|
|
109
93
|
result.current.data.forEach((item) => {
|
|
@@ -112,43 +96,37 @@ describe('search', () => {
|
|
|
112
96
|
});
|
|
113
97
|
});
|
|
114
98
|
it('should work with a partial query', async () => {
|
|
115
|
-
const { result
|
|
116
|
-
useSearch(documents, 'anast')
|
|
117
|
-
);
|
|
99
|
+
const { result } = renderHook(() => useSearch(documents, 'anast'));
|
|
118
100
|
expect(result.current.loading).toBe(false);
|
|
119
101
|
act(() => result.current.search());
|
|
120
102
|
expect(result.current.loading).toBe(true);
|
|
121
103
|
expect(result.current.data).toEqual(documents);
|
|
122
|
-
await
|
|
123
|
-
expect(result.current.loading).toBe(false);
|
|
104
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
124
105
|
expect(result.current.data.length).toBe(1);
|
|
125
106
|
|
|
126
107
|
const firstResult = result.current.data[0] as NonNullable<
|
|
127
|
-
typeof result.current.data[0]
|
|
108
|
+
(typeof result.current.data)[0]
|
|
128
109
|
>;
|
|
129
110
|
expect(firstResult).toBeDefined();
|
|
130
111
|
expect(Object.values(firstResult).values()).toContain('Anastasia');
|
|
131
112
|
});
|
|
132
113
|
it('should work with nested field if not explicitly stated', async () => {
|
|
133
|
-
const { result
|
|
134
|
-
useSearch(documents, 'Titanic')
|
|
135
|
-
);
|
|
114
|
+
const { result } = renderHook(() => useSearch(documents, 'Titanic'));
|
|
136
115
|
expect(result.current.loading).toBe(false);
|
|
137
116
|
act(() => result.current.search());
|
|
138
117
|
expect(result.current.loading).toBe(true);
|
|
139
118
|
expect(result.current.data).toEqual(documents);
|
|
140
|
-
await
|
|
141
|
-
expect(result.current.loading).toBe(false);
|
|
119
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
142
120
|
expect(result.current.data.length).toBe(1);
|
|
143
121
|
|
|
144
122
|
const firstResult = result.current.data[0] as NonNullable<
|
|
145
|
-
typeof result.current.data[0]
|
|
123
|
+
(typeof result.current.data)[0]
|
|
146
124
|
>;
|
|
147
125
|
expect(firstResult).toBeDefined();
|
|
148
126
|
expect(Object.values(firstResult.address).values()).toContain('Titanic');
|
|
149
127
|
});
|
|
150
128
|
it('should work with nested field if explicitly stated', async () => {
|
|
151
|
-
const { result
|
|
129
|
+
const { result } = renderHook(() =>
|
|
152
130
|
useSearch(documents, 'Titanic', {
|
|
153
131
|
indexing: {
|
|
154
132
|
fields: ['address.city'],
|
|
@@ -159,18 +137,17 @@ describe('search', () => {
|
|
|
159
137
|
act(() => result.current.search());
|
|
160
138
|
expect(result.current.loading).toBe(true);
|
|
161
139
|
expect(result.current.data).toEqual(documents);
|
|
162
|
-
await
|
|
163
|
-
expect(result.current.loading).toBe(false);
|
|
140
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
164
141
|
expect(result.current.data.length).toBe(1);
|
|
165
142
|
|
|
166
143
|
const firstResult = result.current.data[0] as NonNullable<
|
|
167
|
-
typeof result.current.data[0]
|
|
144
|
+
(typeof result.current.data)[0]
|
|
168
145
|
>;
|
|
169
146
|
expect(firstResult).toBeDefined();
|
|
170
147
|
expect(Object.values(firstResult.address).values()).toContain('Titanic');
|
|
171
148
|
});
|
|
172
149
|
it('should work with nested ID', async () => {
|
|
173
|
-
const { result
|
|
150
|
+
const { result } = renderHook(() =>
|
|
174
151
|
useSearch(documents, 'Titanic', {
|
|
175
152
|
indexing: {
|
|
176
153
|
idKey: 'address.street',
|
|
@@ -181,55 +158,48 @@ describe('search', () => {
|
|
|
181
158
|
act(() => result.current.search());
|
|
182
159
|
expect(result.current.loading).toBe(true);
|
|
183
160
|
expect(result.current.data).toEqual(documents);
|
|
184
|
-
await
|
|
185
|
-
expect(result.current.loading).toBe(false);
|
|
161
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
186
162
|
expect(result.current.data.length).toBe(1);
|
|
187
163
|
|
|
188
164
|
const firstResult = result.current.data[0] as NonNullable<
|
|
189
|
-
typeof result.current.data[0]
|
|
165
|
+
(typeof result.current.data)[0]
|
|
190
166
|
>;
|
|
191
167
|
expect(firstResult).toBeDefined();
|
|
192
168
|
expect(Object.values(firstResult.address).values()).toContain('Titanic');
|
|
193
169
|
});
|
|
194
170
|
it('should work with indexed Greek characters and Latin query', async () => {
|
|
195
|
-
const { result
|
|
196
|
-
useSearch(documents, 'Markos')
|
|
197
|
-
);
|
|
171
|
+
const { result } = renderHook(() => useSearch(documents, 'Markos'));
|
|
198
172
|
expect(result.current.loading).toBe(false);
|
|
199
173
|
act(() => result.current.search());
|
|
200
174
|
expect(result.current.loading).toBe(true);
|
|
201
175
|
expect(result.current.data).toEqual(documents);
|
|
202
|
-
await
|
|
203
|
-
expect(result.current.loading).toBe(false);
|
|
176
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
204
177
|
expect(result.current.data.length).toBe(1);
|
|
205
178
|
|
|
206
179
|
const firstResult = result.current.data[0] as NonNullable<
|
|
207
|
-
typeof result.current.data[0]
|
|
180
|
+
(typeof result.current.data)[0]
|
|
208
181
|
>;
|
|
209
182
|
expect(firstResult).toBeDefined();
|
|
210
183
|
expect(Object.values(firstResult).values()).toContain('Μάρκος');
|
|
211
184
|
});
|
|
212
185
|
it('should work with indexed Greek characters and Greek query', async () => {
|
|
213
|
-
const { result
|
|
214
|
-
useSearch(documents, 'Μάρκος')
|
|
215
|
-
);
|
|
186
|
+
const { result } = renderHook(() => useSearch(documents, 'Μάρκος'));
|
|
216
187
|
expect(result.current.loading).toBe(false);
|
|
217
188
|
act(() => result.current.search());
|
|
218
189
|
expect(result.current.loading).toBe(true);
|
|
219
190
|
expect(result.current.data).toEqual(documents);
|
|
220
|
-
await
|
|
221
|
-
expect(result.current.loading).toBe(false);
|
|
191
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
222
192
|
expect(result.current.data.length).toBe(1);
|
|
223
193
|
|
|
224
194
|
const firstResult = result.current.data[0] as NonNullable<
|
|
225
|
-
typeof result.current.data[0]
|
|
195
|
+
(typeof result.current.data)[0]
|
|
226
196
|
>;
|
|
227
197
|
expect(firstResult).toBeDefined();
|
|
228
198
|
expect(Object.values(firstResult).values()).toContain('Μάρκος');
|
|
229
199
|
});
|
|
230
200
|
it('should react to changes in the documents list', async () => {
|
|
231
201
|
const emptyDocuments: typeof documents = [];
|
|
232
|
-
const { result, rerender
|
|
202
|
+
const { result, rerender } = renderHook(
|
|
233
203
|
({ documents }) => useSearch(documents, 'Anastasia'),
|
|
234
204
|
{
|
|
235
205
|
initialProps: { documents: emptyDocuments },
|
|
@@ -238,8 +208,7 @@ describe('search', () => {
|
|
|
238
208
|
expect(result.current.loading).toBe(false);
|
|
239
209
|
act(() => result.current.search());
|
|
240
210
|
expect(result.current.loading).toBe(true);
|
|
241
|
-
await
|
|
242
|
-
expect(result.current.loading).toBe(false);
|
|
211
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
243
212
|
expect(result.current.data).toEqual([]);
|
|
244
213
|
|
|
245
214
|
rerender({ documents });
|
|
@@ -249,18 +218,17 @@ describe('search', () => {
|
|
|
249
218
|
act(() => result.current.search());
|
|
250
219
|
expect(result.current.loading).toBe(true);
|
|
251
220
|
expect(result.current.data).toEqual([]);
|
|
252
|
-
await
|
|
253
|
-
expect(result.current.loading).toBe(false);
|
|
221
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
254
222
|
expect(result.current.data.length).toBe(1);
|
|
255
223
|
|
|
256
224
|
const firstResult = result.current.data[0] as NonNullable<
|
|
257
|
-
typeof result.current.data[0]
|
|
225
|
+
(typeof result.current.data)[0]
|
|
258
226
|
>;
|
|
259
227
|
expect(firstResult).toBeDefined();
|
|
260
228
|
expect(Object.values(firstResult).values()).toContain('Anastasia');
|
|
261
229
|
});
|
|
262
230
|
it('should react to changes in the search query', async () => {
|
|
263
|
-
const { result, rerender
|
|
231
|
+
const { result, rerender } = renderHook(
|
|
264
232
|
({ query }) => useSearch(documents, query),
|
|
265
233
|
{
|
|
266
234
|
initialProps: { query: '' },
|
|
@@ -276,12 +244,11 @@ describe('search', () => {
|
|
|
276
244
|
act(() => result.current.search());
|
|
277
245
|
expect(result.current.loading).toBe(true);
|
|
278
246
|
expect(result.current.data).toEqual(documents);
|
|
279
|
-
await
|
|
280
|
-
expect(result.current.loading).toBe(false);
|
|
247
|
+
await waitFor(() => expect(result.current.loading).toBe(false));
|
|
281
248
|
expect(result.current.data.length).toBe(1);
|
|
282
249
|
|
|
283
250
|
const firstResult = result.current.data[0] as NonNullable<
|
|
284
|
-
typeof result.current.data[0]
|
|
251
|
+
(typeof result.current.data)[0]
|
|
285
252
|
>;
|
|
286
253
|
expect(firstResult).toBeDefined();
|
|
287
254
|
expect(Object.values(firstResult).values()).toContain('Anastasia');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { greekToGreeklishMap } from '
|
|
1
|
+
import { greekToGreeklishMap } from '@digigov/text-search/search/lang/gr/normalization-map';
|
|
2
2
|
|
|
3
|
-
const whitespaceRegex =
|
|
4
|
-
const diacriticsRegex =
|
|
3
|
+
const whitespaceRegex = new RegExp('[p{Z}p{S}p{P}p{C}]+', 'u');
|
|
4
|
+
const diacriticsRegex = new RegExp('[\u0300-\u036f]', 'g');
|
|
5
5
|
const greekCharsRegex = new RegExp(
|
|
6
6
|
Object.keys(greekToGreeklishMap).join('|'),
|
|
7
7
|
'igu'
|
|
@@ -22,6 +22,10 @@ export function encodeGreek(str: string) {
|
|
|
22
22
|
.toLowerCase()
|
|
23
23
|
.normalize('NFD')
|
|
24
24
|
.replace(diacriticsRegex, '')
|
|
25
|
-
.replace(greekCharsRegex, (match) =>
|
|
25
|
+
.replace(greekCharsRegex, (match) =>
|
|
26
|
+
match in greekToGreeklishMap
|
|
27
|
+
? greekToGreeklishMap[match as keyof typeof greekToGreeklishMap]
|
|
28
|
+
: match
|
|
29
|
+
)
|
|
26
30
|
.split(whitespaceRegex);
|
|
27
31
|
}
|