prquicktest 1.0.0 → 1.1.0

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.
@@ -86,6 +86,18 @@ function getHeaderLevel(line) {
86
86
  return match ? match[1].length : null;
87
87
  }
88
88
 
89
+ /**
90
+ * Check if a line starts a condition (case-insensitive)
91
+ * Matches: "condition:", "check:", "check for:"
92
+ */
93
+ function parseCondition(line) {
94
+ const match = line.match(/^(condition|check\s*for|check)\s*:\s*(.+)/i);
95
+ if (match) {
96
+ return match[2].trim();
97
+ }
98
+ return null;
99
+ }
100
+
89
101
  function parseMarkdown(content) {
90
102
  const blocks = [];
91
103
  const lines = content.split('\n');
@@ -138,10 +150,18 @@ function parseMarkdown(content) {
138
150
  } else {
139
151
  // Skip non-code content outside testing sections
140
152
  if (inTestingSection) {
153
+ // Check if this line is a condition
154
+ const condition = parseCondition(line);
155
+ if (condition) {
156
+ blocks.push({ type: 'condition', content: condition });
157
+ i++;
158
+ continue;
159
+ }
160
+
141
161
  const textLines = [line];
142
162
  i++;
143
163
 
144
- while (i < lines.length && !lines[i].match(/^```/) && !lines[i].match(/^#{1,6}\s+/)) {
164
+ while (i < lines.length && !lines[i].match(/^```/) && !lines[i].match(/^#{1,6}\s+/) && !parseCondition(lines[i])) {
145
165
  textLines.push(lines[i]);
146
166
  i++;
147
167
  }
@@ -202,6 +222,35 @@ function runCode(lang, code) {
202
222
  });
203
223
  }
204
224
 
225
+ function printConditionSummary(conditionResults) {
226
+ if (conditionResults.length === 0) return;
227
+
228
+ console.log(`${colors.cyan}═══════════════════════════════════${colors.reset}`);
229
+ console.log(`${colors.cyan} Condition Summary${colors.reset}`);
230
+ console.log(`${colors.cyan}═══════════════════════════════════${colors.reset}\n`);
231
+
232
+ const passed = conditionResults.filter(c => c.passed).length;
233
+ const failed = conditionResults.filter(c => c.passed === false).length;
234
+ const skipped = conditionResults.filter(c => c.passed === null).length;
235
+
236
+ for (const result of conditionResults) {
237
+ let status;
238
+ if (result.passed === true) {
239
+ status = `${colors.green}✓ PASS${colors.reset}`;
240
+ } else if (result.passed === false) {
241
+ status = `${colors.red}✗ FAIL${colors.reset}`;
242
+ } else {
243
+ status = `${colors.yellow}○ SKIP${colors.reset}`;
244
+ }
245
+ console.log(` ${status} ${result.condition}`);
246
+ }
247
+
248
+ console.log();
249
+ console.log(`${colors.cyan}───────────────────────────────────${colors.reset}`);
250
+ console.log(` ${colors.green}Passed: ${passed}${colors.reset} ${colors.red}Failed: ${failed}${colors.reset} ${colors.yellow}Skipped: ${skipped}${colors.reset}`);
251
+ console.log();
252
+ }
253
+
205
254
  async function run(content, skipConfirm = false) {
206
255
  const blocks = parseMarkdown(content);
207
256
 
@@ -222,14 +271,39 @@ async function run(content, skipConfirm = false) {
222
271
  console.log(`${colors.cyan}─────────────────────────────────${colors.reset}\n`);
223
272
 
224
273
  let codeBlockIndex = 0;
274
+ let lastCodeBlockRan = false;
275
+ const conditionResults = [];
225
276
 
226
277
  for (const block of blocks) {
227
278
  if (block.type === 'text') {
228
279
  // Echo non-code content
229
280
  console.log(block.content);
230
281
  console.log();
282
+ } else if (block.type === 'condition') {
283
+ // Show the condition and ask if it passed
284
+ console.log(`${colors.yellow}┌─ Condition ─────────────────────${colors.reset}`);
285
+ console.log(`${colors.yellow}│${colors.reset} ${block.content}`);
286
+ console.log(`${colors.yellow}└─────────────────────────────────${colors.reset}`);
287
+
288
+ if (!lastCodeBlockRan) {
289
+ console.log(`${colors.dim}(Code block was skipped, marking condition as skipped)${colors.reset}\n`);
290
+ conditionResults.push({ condition: block.content, passed: null });
291
+ continue;
292
+ }
293
+
294
+ const answer = await prompt(`${colors.yellow}Was this condition met? [y/N] ${colors.reset}`);
295
+ const passed = answer === 'y' || answer === 'yes';
296
+
297
+ if (passed) {
298
+ console.log(`${colors.green}✓ Condition passed${colors.reset}\n`);
299
+ } else {
300
+ console.log(`${colors.red}✗ Condition failed${colors.reset}\n`);
301
+ }
302
+
303
+ conditionResults.push({ condition: block.content, passed });
231
304
  } else if (block.type === 'code') {
232
305
  codeBlockIndex++;
306
+ lastCodeBlockRan = false;
233
307
 
234
308
  // Show the code block
235
309
  console.log(`${colors.cyan}┌─ [${codeBlockIndex}/${codeBlocks.length}] ${block.lang || 'code'} ─────────────────────${colors.reset}`);
@@ -242,6 +316,7 @@ async function run(content, skipConfirm = false) {
242
316
 
243
317
  if (answer === 'q' || answer === 'quit') {
244
318
  console.log('Aborted.');
319
+ printConditionSummary(conditionResults);
245
320
  return;
246
321
  }
247
322
 
@@ -254,6 +329,7 @@ async function run(content, skipConfirm = false) {
254
329
  // Execute the block
255
330
  console.log(`${colors.cyan}├─ output ─────────────────────${colors.reset}`);
256
331
  const result = await runCode(block.lang, block.content);
332
+ lastCodeBlockRan = true;
257
333
 
258
334
  if (!result.skipped) {
259
335
  if (result.success) {
@@ -266,6 +342,7 @@ async function run(content, skipConfirm = false) {
266
342
  }
267
343
  }
268
344
 
345
+ printConditionSummary(conditionResults);
269
346
  console.log(`${colors.green}Done!${colors.reset}`);
270
347
  }
271
348
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prquicktest",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Run code blocks from GitHub PR descriptions",
5
5
  "type": "module",
6
6
  "scripts": {