1+
2+ <!doctype html>
3+ < html lang ="en ">
4+
5+ < head >
6+ < title > Code coverage report for OmniPoly/filterHelper.js</ title >
7+ < meta charset ="utf-8 " />
8+ < link rel ="stylesheet " href ="../prettify.css " />
9+ < link rel ="stylesheet " href ="../base.css " />
10+ < link rel ="shortcut icon " type ="image/x-icon " href ="../favicon.png " />
11+ < meta name ="viewport " content ="width=device-width, initial-scale=1 " />
12+ < style type ='text/css '>
13+ .coverage-summary .sorter {
14+ background-image : url(../ sor t-arrow-sprite.png);
15+ }
16+ </ style >
17+ </ head >
18+
19+ < body >
20+ < div class ='wrapper '>
21+ < div class ='pad1 '>
22+ < h1 > < a href ="../index.html "> All files</ a > / < a href ="index.html "> OmniPoly</ a > filterHelper.js</ h1 >
23+ < div class ='clearfix '>
24+
25+ < div class ='fl pad1y space-right2 '>
26+ < span class ="strong "> 92.3% </ span >
27+ < span class ="quiet "> Statements</ span >
28+ < span class ='fraction '> 12/13</ span >
29+ </ div >
30+
31+
32+ < div class ='fl pad1y space-right2 '>
33+ < span class ="strong "> 88.23% </ span >
34+ < span class ="quiet "> Branches</ span >
35+ < span class ='fraction '> 15/17</ span >
36+ </ div >
37+
38+
39+ < div class ='fl pad1y space-right2 '>
40+ < span class ="strong "> 100% </ span >
41+ < span class ="quiet "> Functions</ span >
42+ < span class ='fraction '> 3/3</ span >
43+ </ div >
44+
45+
46+ < div class ='fl pad1y space-right2 '>
47+ < span class ="strong "> 92.3% </ span >
48+ < span class ="quiet "> Lines</ span >
49+ < span class ='fraction '> 12/13</ span >
50+ </ div >
51+
52+
53+ </ div >
54+ < p class ="quiet ">
55+ Press < em > n</ em > or < em > j</ em > to go to the next uncovered block, < em > b</ em > , < em > p</ em > or < em > k</ em > for the previous block.
56+ </ p >
57+ < template id ="filterTemplate ">
58+ < div class ="quiet ">
59+ Filter:
60+ < input type ="search " id ="fileSearch ">
61+ </ div >
62+ </ template >
63+ </ div >
64+ < div class ='status-line high '> </ div >
65+ < pre > < table class ="coverage ">
66+ < tr > < td class ="line-count quiet "> < a name ='L1 '> </ a > < a href ='#L1 '> 1</ a >
67+ < a name ='L2 '> </ a > < a href ='#L2 '> 2</ a >
68+ < a name ='L3 '> </ a > < a href ='#L3 '> 3</ a >
69+ < a name ='L4 '> </ a > < a href ='#L4 '> 4</ a >
70+ < a name ='L5 '> </ a > < a href ='#L5 '> 5</ a >
71+ < a name ='L6 '> </ a > < a href ='#L6 '> 6</ a >
72+ < a name ='L7 '> </ a > < a href ='#L7 '> 7</ a >
73+ < a name ='L8 '> </ a > < a href ='#L8 '> 8</ a >
74+ < a name ='L9 '> </ a > < a href ='#L9 '> 9</ a >
75+ < a name ='L10 '> </ a > < a href ='#L10 '> 10</ a >
76+ < a name ='L11 '> </ a > < a href ='#L11 '> 11</ a >
77+ < a name ='L12 '> </ a > < a href ='#L12 '> 12</ a >
78+ < a name ='L13 '> </ a > < a href ='#L13 '> 13</ a >
79+ < a name ='L14 '> </ a > < a href ='#L14 '> 14</ a >
80+ < a name ='L15 '> </ a > < a href ='#L15 '> 15</ a >
81+ < a name ='L16 '> </ a > < a href ='#L16 '> 16</ a >
82+ < a name ='L17 '> </ a > < a href ='#L17 '> 17</ a >
83+ < a name ='L18 '> </ a > < a href ='#L18 '> 18</ a >
84+ < a name ='L19 '> </ a > < a href ='#L19 '> 19</ a >
85+ < a name ='L20 '> </ a > < a href ='#L20 '> 20</ a >
86+ < a name ='L21 '> </ a > < a href ='#L21 '> 21</ a >
87+ < a name ='L22 '> </ a > < a href ='#L22 '> 22</ a >
88+ < a name ='L23 '> </ a > < a href ='#L23 '> 23</ a >
89+ < a name ='L24 '> </ a > < a href ='#L24 '> 24</ a >
90+ < a name ='L25 '> </ a > < a href ='#L25 '> 25</ a >
91+ < a name ='L26 '> </ a > < a href ='#L26 '> 26</ a >
92+ < a name ='L27 '> </ a > < a href ='#L27 '> 27</ a >
93+ < a name ='L28 '> </ a > < a href ='#L28 '> 28</ a >
94+ < a name ='L29 '> </ a > < a href ='#L29 '> 29</ a >
95+ < a name ='L30 '> </ a > < a href ='#L30 '> 30</ a >
96+ < a name ='L31 '> </ a > < a href ='#L31 '> 31</ a >
97+ < a name ='L32 '> </ a > < a href ='#L32 '> 32</ a >
98+ < a name ='L33 '> </ a > < a href ='#L33 '> 33</ a >
99+ < a name ='L34 '> </ a > < a href ='#L34 '> 34</ a >
100+ < a name ='L35 '> </ a > < a href ='#L35 '> 35</ a >
101+ < a name ='L36 '> </ a > < a href ='#L36 '> 36</ a >
102+ < a name ='L37 '> </ a > < a href ='#L37 '> 37</ a >
103+ < a name ='L38 '> </ a > < a href ='#L38 '> 38</ a >
104+ < a name ='L39 '> </ a > < a href ='#L39 '> 39</ a >
105+ < a name ='L40 '> </ a > < a href ='#L40 '> 40</ a >
106+ < a name ='L41 '> </ a > < a href ='#L41 '> 41</ a >
107+ < a name ='L42 '> </ a > < a href ='#L42 '> 42</ a >
108+ < a name ='L43 '> </ a > < a href ='#L43 '> 43</ a >
109+ < a name ='L44 '> </ a > < a href ='#L44 '> 44</ a > </ td > < td class ="line-coverage quiet "> < span class ="cline-any cline-neutral "> </ span >
110+ < span class ="cline-any cline-neutral "> </ span >
111+ < span class ="cline-any cline-neutral "> </ span >
112+ < span class ="cline-any cline-neutral "> </ span >
113+ < span class ="cline-any cline-neutral "> </ span >
114+ < span class ="cline-any cline-neutral "> </ span >
115+ < span class ="cline-any cline-neutral "> </ span >
116+ < span class ="cline-any cline-neutral "> </ span >
117+ < span class ="cline-any cline-neutral "> </ span >
118+ < span class ="cline-any cline-neutral "> </ span >
119+ < span class ="cline-any cline-neutral "> </ span >
120+ < span class ="cline-any cline-neutral "> </ span >
121+ < span class ="cline-any cline-neutral "> </ span >
122+ < span class ="cline-any cline-neutral "> </ span >
123+ < span class ="cline-any cline-yes "> 1x</ span >
124+ < span class ="cline-any cline-neutral "> </ span >
125+ < span class ="cline-any cline-yes "> 4x</ span >
126+ < span class ="cline-any cline-neutral "> </ span >
127+ < span class ="cline-any cline-neutral "> </ span >
128+ < span class ="cline-any cline-yes "> 4x</ span >
129+ < span class ="cline-any cline-neutral "> </ span >
130+ < span class ="cline-any cline-neutral "> </ span >
131+ < span class ="cline-any cline-yes "> 4x</ span >
132+ < span class ="cline-any cline-neutral "> </ span >
133+ < span class ="cline-any cline-neutral "> </ span >
134+ < span class ="cline-any cline-yes "> 3x</ span >
135+ < span class ="cline-any cline-neutral "> </ span >
136+ < span class ="cline-any cline-yes "> 2x</ span >
137+ < span class ="cline-any cline-no "> </ span >
138+ < span class ="cline-any cline-neutral "> </ span >
139+ < span class ="cline-any cline-yes "> 2x</ span >
140+ < span class ="cline-any cline-neutral "> </ span >
141+ < span class ="cline-any cline-neutral "> </ span >
142+ < span class ="cline-any cline-neutral "> </ span >
143+ < span class ="cline-any cline-yes "> 2x</ span >
144+ < span class ="cline-any cline-neutral "> </ span >
145+ < span class ="cline-any cline-neutral "> </ span >
146+ < span class ="cline-any cline-yes "> 1x</ span >
147+ < span class ="cline-any cline-neutral "> </ span >
148+ < span class ="cline-any cline-yes "> 3x</ span >
149+ < span class ="cline-any cline-neutral "> </ span >
150+ < span class ="cline-any cline-yes "> 4x</ span >
151+ < span class ="cline-any cline-yes "> 4x</ span >
152+ < span class ="cline-any cline-neutral "> </ span > </ td > < td class ="text "> < pre class ="prettyprint lang-js "> import { lookupWord } from "./server/words.js";
153+
154+ /**
155+ * Filters a LanguageTool API response.
156+ *
157+ * - Preserves all top‑level fields of the original result.
158+ * - For each match:
159+ * • If the rule category is "TYPOS" and dictionary filtering is enabled, remove the match when the word exists in the custom dictionary.
160+ * • Otherwise keep the match unchanged.
161+ *
162+ * @param {object} result The raw response from LanguageTool.
163+ * @param {boolean} enableDictionaryFilter Whether to enable dictionary-based filtering (default: true).
164+ * @returns {object} A new object with the same top‑level properties and a filtered `matches` array.
165+ */
166+ export const filterResult = (result, enableDictionaryFilter = true) => {
167+ // Log for debugging purposes
168+ console.log("[FILTER] total matches received:", result.matches?.length ?? 0);
169+
170+ // Clone the entire result to keep all other fields intact
171+ const filtered = { ...result };
172+
173+ // Safely process the `matches` array if it exists
174+ filtered.matches = (result.matches || [])
175+ .map((match) => {
176+ // If dictionary filtering is enabled and this is a typo rule, check the custom dictionary
177+ if (enableDictionaryFilter && match.rule?.category?.id === "TYPOS") {
178+ // Validate context exists before extracting text
179+ < span class ="missing-if-branch " title ="if path not taken " > I</ span > if (!match.context || !match.context.text) {
180+ < span class ="cstat-no " title ="statement not covered " > return match;</ span >
181+ }
182+ const exists = lookupWord(
183+ match.context.text.substr(match.context.offset, match.context.length)
184+ );
185+ // Remove the match when the word is present in the dictionary
186+ return exists ? false : match;
187+ }
188+ // Keep all other matches unchanged (or when dictionary filtering is disabled)
189+ return match;
190+ })
191+ .filter((elem) => elem); // Drop any `false` entries
192+
193+ console.log("[FILTER] matches after dictionary filter:", filtered.matches?.length ?? < span class ="branch-1 cbranch-no " title ="branch not covered " > 0)</ span > ;
194+ return filtered;
195+ };</ pre > </ td > </ tr > </ table > </ pre >
196+
197+ < div class ='push '> </ div > <!-- for sticky footer -->
198+ </ div > <!-- /wrapper -->
199+ < div class ='footer quiet pad2 space-top1 center small '>
200+ Code coverage generated by
201+ < a href ="https://istanbul.js.org/ " target ="_blank " rel ="noopener noreferrer "> istanbul</ a >
202+ at 2026-02-07T21:03:50.361Z
203+ </ div >
204+ < script src ="../prettify.js "> </ script >
205+ < script >
206+ window . onload = function ( ) {
207+ prettyPrint ( ) ;
208+ } ;
209+ </ script >
210+ < script src ="../sorter.js "> </ script >
211+ < script src ="../block-navigation.js "> </ script >
212+ </ body >
213+ </ html >
214+
0 commit comments