@kakarot-ci/core 0.6.6 → 0.7.1

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/dist/index.cjs CHANGED
@@ -87,6 +87,7 @@ var KakarotConfigSchema = import_zod.z.object({
87
87
  enableAutoCommit: import_zod.z.boolean().default(true),
88
88
  commitStrategy: import_zod.z.enum(["direct", "branch-pr"]).default("direct"),
89
89
  enablePRComments: import_zod.z.boolean().default(true),
90
+ enableCoverage: import_zod.z.boolean().default(false),
90
91
  debug: import_zod.z.boolean().default(false)
91
92
  });
92
93
 
@@ -160,24 +161,11 @@ async function findProjectRoot(startPath) {
160
161
  async function loadConfig() {
161
162
  const explorer = (0, import_cosmiconfig.cosmiconfig)("kakarot", {
162
163
  searchPlaces: [
163
- "kakarot.config.ts",
164
164
  "kakarot.config.js",
165
- ".kakarot-ci.config.ts",
166
165
  ".kakarot-ci.config.js",
167
166
  ".kakarot-ci.config.json",
168
167
  "package.json"
169
- ],
170
- loaders: {
171
- ".ts": async (filepath) => {
172
- try {
173
- const configModule = await import(filepath);
174
- return configModule.default || configModule.config || null;
175
- } catch (err) {
176
- error(`Failed to load TypeScript config: ${err instanceof Error ? err.message : String(err)}`);
177
- return null;
178
- }
179
- }
180
- }
168
+ ]
181
169
  });
182
170
  try {
183
171
  const result = await explorer.search();
@@ -214,7 +202,7 @@ async function loadConfig() {
214
202
  } catch (err) {
215
203
  if (err instanceof Error && err.message.includes("apiKey")) {
216
204
  error(
217
- "Missing required apiKey. Provide it via:\n - Config file (kakarot.config.ts, .kakarot-ci.config.js/json, or package.json)\n - Environment variable: KAKAROT_API_KEY"
205
+ "Missing required apiKey. Provide it via:\n - Config file (kakarot.config.js, .kakarot-ci.config.js/json, or package.json)\n - Environment variable: KAKAROT_API_KEY"
218
206
  );
219
207
  }
220
208
  throw err;
@@ -437,6 +425,7 @@ var GitHubClient = class {
437
425
  async fileExists(ref, path) {
438
426
  const originalError = console.error;
439
427
  const originalWarn = console.warn;
428
+ const originalLog = console.log;
440
429
  const suppress404 = (...args) => {
441
430
  const message = String(args[0] || "");
442
431
  if (message.includes("404") || message.includes("Not Found")) {
@@ -451,9 +440,17 @@ var GitHubClient = class {
451
440
  }
452
441
  originalWarn(...args);
453
442
  };
443
+ const suppress404Log = (...args) => {
444
+ const message = String(args[0] || "");
445
+ if (message.includes("404") || message.includes("Not Found")) {
446
+ return;
447
+ }
448
+ originalLog(...args);
449
+ };
454
450
  try {
455
451
  console.error = suppress404;
456
452
  console.warn = suppress404Warn;
453
+ console.log = suppress404Log;
457
454
  await this.octokit.rest.repos.getContent({
458
455
  owner: this.owner,
459
456
  repo: this.repo,
@@ -476,6 +473,7 @@ var GitHubClient = class {
476
473
  } finally {
477
474
  console.error = originalError;
478
475
  console.warn = originalWarn;
476
+ console.log = originalLog;
479
477
  }
480
478
  }
481
479
  /**
@@ -1147,15 +1145,49 @@ function buildSystemPrompt(framework) {
1147
1145
  const importStatement = framework === "jest" ? "import { describe, it, expect } from 'jest';" : "import { describe, it, expect } from 'vitest';";
1148
1146
  return `You are an expert ${frameworkName} test writer. Your task is to generate comprehensive unit tests for TypeScript/JavaScript functions.
1149
1147
 
1148
+ CRITICAL: Test the ACTUAL behavior of the code, not assumed behavior.
1149
+
1150
1150
  Requirements:
1151
1151
  1. Generate complete, runnable ${frameworkName} test code
1152
1152
  2. Use ${frameworkName} syntax and best practices
1153
- 3. Test edge cases, error conditions, and normal operation
1154
- 4. Use descriptive test names that explain what is being tested
1155
- 5. Include proper setup/teardown if needed
1156
- 6. Mock external dependencies appropriately
1157
- 7. Test both success and failure scenarios
1158
- 8. Follow the existing test file structure if one exists
1153
+ 3. Analyze the function code to determine its ACTUAL runtime behavior before writing tests
1154
+ 4. Test edge cases and normal operation based on what the code actually does
1155
+ 5. Only test for errors/exceptions if the code actually throws them (check for try/catch, throw statements, or validation logic)
1156
+ 6. Match JavaScript/TypeScript runtime semantics:
1157
+ - Arithmetic operations (+, -, *, /, %, **) do NOT throw errors for invalid inputs; they return NaN or Infinity
1158
+ - Division by zero returns Infinity (not an error)
1159
+ - Modulo by zero returns NaN (not an error)
1160
+ - Bitwise operations convert values to 32-bit integers
1161
+ - Operations with null/undefined may coerce to numbers or return NaN
1162
+ - TypeScript types are compile-time only; runtime behavior follows JavaScript rules
1163
+ 7. For async functions:
1164
+ - Use async/await or .then()/.catch() appropriately
1165
+ - Test both resolved and rejected promises
1166
+ - Use resolves and rejects matchers when appropriate
1167
+ - Await async function calls in tests
1168
+ 8. For functions with side effects or external dependencies:
1169
+ - Mock external dependencies (APIs, file system, databases, etc.)
1170
+ - Mock imported modules using ${framework === "jest" ? "jest.mock()" : "vi.mock()"}
1171
+ - Reset mocks between tests to ensure test isolation
1172
+ - Verify mock calls if the function's behavior depends on them
1173
+ 9. For functions that modify state:
1174
+ - Test state before and after function calls
1175
+ - Reset state between tests if needed
1176
+ - Test state mutations, not just return values
1177
+ 10. For error testing:
1178
+ - Only test for errors if the function actually throws them
1179
+ - Match actual error types and messages (use toThrow() with specific error types/messages)
1180
+ - For async errors, use rejects matcher
1181
+ 11. Import handling:
1182
+ - Use the same import paths as the source file
1183
+ - Import types correctly (type imports for TypeScript types)
1184
+ - Mock dependencies at the module level, not the function level
1185
+ 12. Test isolation:
1186
+ - Each test should be independent and not rely on other tests
1187
+ - Use beforeEach/afterEach for setup/teardown when needed
1188
+ - Don't share mutable state between tests
1189
+ 13. Use descriptive test names that explain what is being tested
1190
+ 14. Follow the existing test file structure if one exists
1159
1191
 
1160
1192
  Output format:
1161
1193
  - Return ONLY the test code, no explanations or markdown code blocks
@@ -1225,18 +1257,38 @@ ${existingTestFile}
1225
1257
 
1226
1258
  `;
1227
1259
  }
1228
- prompt += `Generate comprehensive unit tests for ${target.functionName}. Include:
1260
+ prompt += `Generate comprehensive unit tests for ${target.functionName}. IMPORTANT: Analyze the function code above to determine its ACTUAL behavior before writing tests.
1261
+
1262
+ `;
1263
+ prompt += `Include:
1229
1264
  `;
1230
1265
  prompt += `- Tests for normal operation with various inputs
1231
1266
  `;
1232
- prompt += `- Tests for edge cases (null, undefined, empty arrays, etc.)
1267
+ prompt += `- Tests for edge cases based on what the code actually does (null, undefined, empty arrays, etc.)
1233
1268
  `;
1234
- prompt += `- Tests for error conditions if applicable
1269
+ prompt += `- Tests for error conditions ONLY if the code actually throws errors (check for throw statements, validation, or error handling)
1235
1270
  `;
1236
1271
  prompt += `- Tests for boundary conditions
1237
1272
  `;
1238
1273
  prompt += `- Proper mocking of dependencies if needed
1239
1274
 
1275
+ `;
1276
+ prompt += `Key considerations:
1277
+ `;
1278
+ prompt += `- If the function is async, use async/await in tests and test both success and error cases
1279
+ `;
1280
+ prompt += `- If the function uses external dependencies (imports), mock them appropriately
1281
+ `;
1282
+ prompt += `- If the function modifies state, test the state changes
1283
+ `;
1284
+ prompt += `- Match actual return types and values, not assumed types
1285
+ `;
1286
+ prompt += `- TypeScript types are compile-time only; test runtime behavior
1287
+ `;
1288
+ prompt += `- JavaScript/TypeScript arithmetic and bitwise operations do NOT throw errors for invalid inputs. They return NaN, Infinity, or perform type coercion. Only test for errors if the function code explicitly throws them.
1289
+ `;
1290
+ prompt += `- Use the same import paths as the source file for consistency
1291
+
1240
1292
  `;
1241
1293
  prompt += `Return ONLY the test code, no explanations or markdown formatting.`;
1242
1294
  return prompt;
@@ -1261,13 +1313,34 @@ Context:
1261
1313
  - The test code failed to run or produced incorrect results
1262
1314
  - You need to analyze the error and fix the test code
1263
1315
 
1316
+ CRITICAL: Tests must match the ACTUAL behavior of the code being tested, not assumed behavior.
1317
+
1264
1318
  Requirements:
1265
- 1. Fix the test code to make it pass
1266
- 2. Maintain the original test intent
1267
- 3. Use proper ${frameworkName} syntax
1268
- 4. Ensure all imports and dependencies are correct
1269
- 5. Fix any syntax errors, type errors, or logical errors
1270
- 6. If the original code being tested has issues, note that but focus on fixing the test
1319
+ 1. Analyze the original function code to understand its ACTUAL runtime behavior
1320
+ 2. Fix the test code to match what the function actually does, not what it "should" do
1321
+ 3. Only expect errors/exceptions if the function code actually throws them
1322
+ 4. Match JavaScript/TypeScript runtime semantics:
1323
+ - Arithmetic operations do NOT throw errors; they return NaN or Infinity
1324
+ - Division by zero returns Infinity (not an error)
1325
+ - Modulo by zero returns NaN (not an error)
1326
+ - Bitwise operations convert values to 32-bit integers
1327
+ - TypeScript types are compile-time only; runtime behavior follows JavaScript rules
1328
+ 5. For async functions:
1329
+ - Ensure tests properly await async calls
1330
+ - Use resolves/rejects matchers appropriately
1331
+ - Test both success and error cases for async functions
1332
+ 6. For functions with dependencies:
1333
+ - Ensure mocks are properly set up
1334
+ - Verify import paths match the source file
1335
+ - Reset mocks if needed for test isolation
1336
+ 7. For error testing:
1337
+ - Only expect errors if the function actually throws them
1338
+ - Match actual error types and messages
1339
+ - Use appropriate matchers (toThrow, rejects, etc.)
1340
+ 8. Maintain the original test intent where possible, but prioritize correctness
1341
+ 9. Use proper ${frameworkName} syntax
1342
+ 10. Ensure all imports and dependencies are correct
1343
+ 11. Fix any syntax errors, type errors, or logical errors
1271
1344
 
1272
1345
  Output format:
1273
1346
  - Return ONLY the fixed test code, no explanations or markdown code blocks
@@ -2000,7 +2073,7 @@ async function runPullRequest(context) {
2000
2073
  })),
2001
2074
  errors
2002
2075
  };
2003
- if (testFiles.size > 0) {
2076
+ if (config.enableCoverage && testFiles.size > 0) {
2004
2077
  const testRunner = createTestRunner(framework);
2005
2078
  const writtenPaths = Array.from(testFiles.keys());
2006
2079
  try {
@@ -2018,12 +2091,12 @@ async function runPullRequest(context) {
2018
2091
  summary.coverageReport = coverageReport;
2019
2092
  summary.testResults = finalTestResults;
2020
2093
  } else {
2021
- debug("Could not read coverage report (coverage package may be missing)");
2094
+ warn("Could not read coverage report (coverage package may be missing)");
2022
2095
  }
2023
2096
  } catch (err) {
2024
2097
  const errorMessage = err instanceof Error ? err.message : String(err);
2025
2098
  if (errorMessage.includes("coverage") || errorMessage.includes("MISSING DEPENDENCY")) {
2026
- debug(`Coverage collection skipped (missing coverage package): ${errorMessage.split("\n")[0]}`);
2099
+ warn(`Coverage collection failed (coverage package may be missing): ${errorMessage.split("\n")[0]}`);
2027
2100
  } else {
2028
2101
  throw err;
2029
2102
  }
@@ -2120,7 +2193,8 @@ async function commitTests(githubClient, pr, testFiles, config, summary) {
2120
2193
  info(`Committing ${testFiles.length} test file(s)`);
2121
2194
  try {
2122
2195
  if (config.commitStrategy === "branch-pr") {
2123
- const branchName = `kakarot-ci/tests-pr-${pr.number}`;
2196
+ const timestamp = Date.now();
2197
+ const branchName = `kakarot-ci/tests-pr-${pr.number}-${timestamp}`;
2124
2198
  const baseSha = await githubClient.createBranch(branchName, pr.head.ref);
2125
2199
  await githubClient.commitFiles({
2126
2200
  files: testFiles.map((file) => ({