@@ -27,7 +27,7 @@ const MONACO_EDITOR_OPTIONS = {
27
27
glyphMargin: true ,
28
28
lineNumbersMinChars: 3 ,
29
29
scrollbar: {
30
- vertical: ' hidden ' ,
30
+ vertical: ' auto ' ,
31
31
horizontal: ' hidden'
32
32
}
33
33
};
@@ -66,6 +66,11 @@ watch(() => store.codeEditorCode, (newCode) => {
66
66
if (model && model .getValue () !== newCode) {
67
67
model .setValue (newCode);
68
68
}
69
+
70
+ editorRef .value .changeViewZones (accessor => {
71
+ // Remove existing annotation zones
72
+ componentState .exisitingAnnotationZones .forEach (zone => accessor .removeZone (zone));
73
+ });
69
74
}
70
75
}, { deep: true });
71
76
@@ -104,95 +109,125 @@ function determineHighlightLinesFromTestResult(rawTestResults) {
104
109
if (! rawTestResults || ! Object .entries (rawTestResults .results ).length ) return ;
105
110
106
111
let newDecorations = [];
107
- store .jsonResult .parsedTestResults = [];
108
-
109
- // Check for comments indicating false positives (//ok or // ok)
110
- const model = editorRef .value .getModel ();
111
- const linesCount = model .getLineCount ();
112
- for (let lineNumber = 1 ; lineNumber <= linesCount; lineNumber++ ) {
113
- const lineContent = model .getLineContent (lineNumber);
114
- if (lineContent .includes (' ok: ' ) || lineContent .includes (' ruleid: ' )) {
115
- store .jsonResult .parsedTestResults .push ({
116
- mustMatch: false ,
117
- lineNumber: ++ lineNumber,
118
- ruleId: null ,
119
- status: ' SUCCESS'
120
- });
121
-
122
- newDecorations .push ({
123
- range: new monaco.Range (lineNumber - 1 , 1 , lineNumber - 1 , 1 ),
124
- options: {
125
- isWholeLine: true ,
126
- className: " full-line-highlight-added" ,
127
- glyphMarginClassName: " diff-added-gutter"
128
- }
129
- });
130
- }
131
- }
132
-
112
+ store .jsonResult .parsedTestResults = [];
113
+ let expectedSet = null ;
114
+ let reportedSet = null ;
133
115
134
116
// Extract the matches from the JSON
135
117
Object .entries (rawTestResults .results [store .ruleFilePath ].checks ).forEach (([ruleId , check ]) => {
136
118
Object .entries (check .matches || {}).forEach (([, matchData ]) => {
137
119
const { expected_lines = [], reported_lines = [] } = matchData;
138
120
139
121
// Convert arrays to sets for easier comparison
140
- const expectedSet = new Set (expected_lines);
141
- const reportedSet = new Set (reported_lines);
142
-
143
- // Highlight expected lines (Green - should be present)
122
+ expectedSet = new Set (expected_lines);
123
+ reportedSet = new Set (reported_lines);
124
+
125
+ /** if expected but not reported then
126
+ * ok ==> must not match green
127
+ * ruleid ==> must match red
128
+ * nothing ==> empty
129
+ */
144
130
expected_lines .forEach ((line ) => {
145
- newDecorations = newDecorations .map (decoration => {
146
- if (decoration .range .startLineNumber === line - 1 ) {
147
- return {
148
- ... decoration,
149
- options: {
150
- ... decoration .options ,
151
- className: reportedSet .has (line) ? " full-line-highlight-added" : " full-line-highlight-removed" ,
152
- glyphMarginClassName: reportedSet .has (line) ? " diff-added-gutter" : " diff-removed-gutter"
153
- }
131
+ if (! reportedSet .has (line)) {
132
+ newDecorations .push ({
133
+ range: new monaco.Range (line - 1 , 1 , line - 1 , 1 ),
134
+ options: {
135
+ isWholeLine: true ,
136
+ className: " full-line-highlight-removed" ,
137
+ glyphMarginClassName: " diff-removed-gutter"
154
138
}
155
- }
156
- return decoration;
157
- });
158
-
159
- store .jsonResult .parsedTestResults = store .jsonResult .parsedTestResults .map (testResult => {
160
- if (testResult .lineNumber === line) {
161
- return {
162
- ... testResult,
163
- mustMatch: reportedSet .has (line),
164
- ruleId,
165
- status: reportedSet .has (line) ? ' SUCCESS' : ' FAILED'
166
- };
167
- }
139
+ });
168
140
169
- return testResult;
170
- });
141
+ store .jsonResult .parsedTestResults .push ({
142
+ lineNumber: line,
143
+ mustMatch: true ,
144
+ ruleId,
145
+ status: ' FAILED'
146
+ });
147
+ }
171
148
});
172
149
173
- // Highlight reported lines that are not in expected lines (Red - detected issues)
174
- reported_lines .forEach (line => {
150
+ /** if reported but not expected then
151
+ * ok comment ==> must not match red
152
+ * ruleid comment ==> must match green
153
+ * no comment ==> empty
154
+ */
155
+ reported_lines .forEach ((line ) => {
175
156
if (! expectedSet .has (line)) {
176
157
newDecorations .push ({
177
- range: new monaco.Range (line, 1 , line, 1 ),
158
+ range: new monaco.Range (line - 1 , 1 , line - 1 , 1 ),
178
159
options: {
179
160
isWholeLine: true ,
180
- className: " full-line-highlight-unexpected " ,
181
- glyphMarginClassName: " diff-unexpected -gutter"
161
+ className: " full-line-highlight-removed " ,
162
+ glyphMarginClassName: " diff-removed -gutter"
182
163
}
183
164
});
184
165
185
166
store .jsonResult .parsedTestResults .push ({
186
167
lineNumber: line,
187
168
mustMatch: false ,
188
169
ruleId,
189
- status: ' UNTESTED'
190
- })
170
+ status: ' FAILED'
171
+ });
172
+ }
173
+ });
174
+
175
+ /** if reported and expected then
176
+ * ok ==> must not match red
177
+ * ruleid ==> must match green
178
+ * nothing ==> empty
179
+ */
180
+ expected_lines .forEach ((line ) => {
181
+ if (reportedSet .has (line)) {
182
+ newDecorations .push ({
183
+ range: new monaco.Range (line - 1 , 1 , line - 1 , 1 ),
184
+ options: {
185
+ isWholeLine: true ,
186
+ className: " full-line-highlight-added" ,
187
+ glyphMarginClassName: " diff-added-gutter"
188
+ }
189
+ });
190
+
191
+ store .jsonResult .parsedTestResults .push ({
192
+ lineNumber: line,
193
+ mustMatch: true ,
194
+ ruleId,
195
+ status: ' SUCCESS' ,
196
+ });
191
197
}
192
198
});
193
199
});
200
+
201
+ /**
202
+ * if no reported an no expected but indicated with the ignore command (ok: ) then
203
+ * highlight as green not match
204
+ */
205
+ const model = editorRef .value .getModel ();
206
+ const linesCount = model .getLineCount ();
207
+ for (let lineNumber = 1 ; lineNumber <= linesCount; lineNumber++ ) {
208
+ const previousLineContent = model .getLineContent (lineNumber);
209
+ if (previousLineContent .includes (' ok: ' ) && ! expectedSet .has (lineNumber + 1 ) && ! reportedSet .has (lineNumber + 1 )) {
210
+ store .jsonResult .parsedTestResults .push ({
211
+ mustMatch: false ,
212
+ lineNumber: lineNumber + 1 ,
213
+ ruleId: null ,
214
+ status: ' SUCCESS'
215
+ });
216
+
217
+ newDecorations .push ({
218
+ range: new monaco.Range (lineNumber, 1 , lineNumber, 1 ),
219
+ options: {
220
+ isWholeLine: true ,
221
+ className: " full-line-highlight-added" ,
222
+ glyphMarginClassName: " diff-added-gutter"
223
+ }
224
+ });
225
+ }
226
+ }
194
227
});
195
228
229
+ store .jsonResult .parsedTestResults .sort ((a , b ) => a .lineNumber - b .lineNumber );
230
+
196
231
// Apply decorations in Monaco Editor
197
232
componentState .existingHighlightLinesFromTestResult = editorRef .value .deltaDecorations (componentState .existingHighlightLinesFromTestResult , newDecorations);
198
233
}
0 commit comments