@intentsolutionsio/mutation-test-runner 1.0.0 → 1.0.5

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.
@@ -1,6 +1,35 @@
1
1
  ---
2
2
  name: mutation-tester
3
3
  description: Validate test quality through mutation testing
4
+ tools:
5
+ - Read
6
+ - Write
7
+ - Edit
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ - WebFetch
12
+ - WebSearch
13
+ - Task
14
+ - TodoWrite
15
+ model: sonnet
16
+ color: orange
17
+ version: 1.0.0
18
+ author: Jeremy Longshore <jeremy@intentsolutions.io>
19
+ tags:
20
+ - testing
21
+ - mutation
22
+ - tester
23
+ disallowedTools: []
24
+ skills: []
25
+ background: false
26
+ # ── upgrade levers — uncomment + set when tuning this agent ──
27
+ # effort: high # reasoning depth: low/medium/high/xhigh/max (omit = inherit session)
28
+ # maxTurns: 50 # cap the agentic loop (omit = engine default)
29
+ # memory: project # persistent scope: user/project/local (omit = ephemeral)
30
+ # isolation: worktree # run in an isolated git worktree
31
+ # initialPrompt: "…" # seed the agent's first turn
32
+ # hooks / mcpServers / permissionMode → set at the PLUGIN level, not on a plugin agent
4
33
  ---
5
34
  # Mutation Test Runner Agent
6
35
 
@@ -9,6 +38,7 @@ Validate test suite quality by introducing code mutations and verifying tests ca
9
38
  ## Mutation Testing Concept
10
39
 
11
40
  Mutation testing modifies ("mutates") code to check if tests detect the changes:
41
+
12
42
  - **Mutant killed** - Test failed (good, caught the bug)
13
43
  - **Mutant survived** - Test passed (bad, missed the bug)
14
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentsolutionsio/mutation-test-runner",
3
- "version": "1.0.0",
3
+ "version": "1.0.5",
4
4
  "description": "Mutation testing to validate test quality by introducing code changes and verifying tests catch them",
5
5
  "keywords": [
6
6
  "testing",
@@ -1,16 +1,21 @@
1
1
  ---
2
2
  name: running-mutation-tests
3
- description: |
4
- Execute mutation testing to evaluate test suite effectiveness.
3
+ description: 'Execute mutation testing to evaluate test suite effectiveness.
4
+
5
5
  Use when performing specialized testing.
6
- Trigger with phrases like "run mutation tests", "test the tests", or "validate test effectiveness".
7
6
 
7
+ Trigger with phrases like "run mutation tests", "test the tests", or "validate test
8
+ effectiveness".
9
+
10
+ '
8
11
  allowed-tools: Read, Write, Edit, Grep, Glob, Bash(test:mutation-*)
9
12
  version: 1.0.0
10
13
  author: Jeremy Longshore <jeremy@intentsolutions.io>
11
14
  license: MIT
12
- compatible-with: claude-code, codex, openclaw
13
- tags: [testing, mutation-tests]
15
+ tags:
16
+ - testing
17
+ - mutation-tests
18
+ compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
14
19
  ---
15
20
  # Mutation Test Runner
16
21
 
@@ -75,6 +80,7 @@ Execute mutation testing to evaluate the effectiveness of a test suite by system
75
80
  ## Examples
76
81
 
77
82
  **Stryker configuration for TypeScript project:**
83
+
78
84
  ```javascript
79
85
  // stryker.config.mjs
80
86
  export default {
@@ -89,6 +95,7 @@ export default {
89
95
  ```
90
96
 
91
97
  **Example surviving mutant and fix:**
98
+
92
99
  ```
93
100
  Mutant: src/utils/discount.ts:15 -- ConditionalExpression
94
101
  Original: if (total > 100)
@@ -105,6 +112,7 @@ it('applies discount above 100', () => {
105
112
  ```
106
113
 
107
114
  **mutmut for Python:**
115
+
108
116
  ```bash
109
117
  # Run mutation testing
110
118
  mutmut run --paths-to-mutate=src/ --tests-dir=tests/
@@ -122,4 +130,4 @@ mutmut show 42
122
130
  - mutmut (Python): https://github.com/boxed/mutmut
123
131
  - PITest (Java): https://pitest.org/
124
132
  - go-mutesting: https://github.com/zimmski/go-mutesting
125
- - Mutation testing theory: https://en.wikipedia.org/wiki/Mutation_testing
133
+ - Mutation testing theory: https://en.wikipedia.org/wiki/Mutation_testing
@@ -143,12 +143,12 @@ def is_valid_email(email):
143
143
 
144
144
  **Example Recommendations:**
145
145
 
146
- * **Increase Test Coverage:** Focus on adding tests to cover the areas identified by the surviving mutants and no coverage mutants.
147
- * **Strengthen Assertions:** Review existing test assertions to ensure they are robust enough to detect subtle changes in behavior.
148
- * **Test Edge Cases:** Pay particular attention to testing edge cases and boundary conditions.
149
- * **Refactor Code:** In some cases, the surviving mutants may indicate areas of code that are overly complex or difficult to test. Consider refactoring these areas to improve testability.
150
- * **Improve Test Data:** Ensure the test data used is diverse and representative of real-world scenarios.
146
+ * **Increase Test Coverage:** Focus on adding tests to cover the areas identified by the surviving mutants and no coverage mutants.
147
+ * **Strengthen Assertions:** Review existing test assertions to ensure they are robust enough to detect subtle changes in behavior.
148
+ * **Test Edge Cases:** Pay particular attention to testing edge cases and boundary conditions.
149
+ * **Refactor Code:** In some cases, the surviving mutants may indicate areas of code that are overly complex or difficult to test. Consider refactoring these areas to improve testability.
150
+ * **Improve Test Data:** Ensure the test data used is diverse and representative of real-world scenarios.
151
151
 
152
152
  ## Conclusion
153
153
 
154
- `[Summarize the key findings and recommendations. Reiterate the importance of mutation testing as a tool for improving test suite effectiveness and ensuring code quality. State the next steps for addressing the identified issues.]`
154
+ `[Summarize the key findings and recommendations. Reiterate the importance of mutation testing as a tool for improving test suite effectiveness and ensuring code quality. State the next steps for addressing the identified issues.]`
@@ -1,4 +1,3 @@
1
1
  # References
2
2
 
3
3
  Bundled resources for mutation-test-runner skill
4
-
@@ -6,6 +6,6 @@ Bundled resources for mutation-test-runner skill
6
6
  - [x] mutation_analyzer.py: Analyzes the mutation test results to identify weak coverage areas and suggest improvements.
7
7
  - [x] test_selector.py: Selects the most relevant tests to run based on the mutations introduced, optimizing testing time.
8
8
 
9
-
10
9
  ## Auto-Generated
10
+
11
11
  Scripts generated on 2025-12-10 03:48:17
@@ -5,31 +5,25 @@ Analyzes the mutation test results to identify weak coverage areas and suggest i
5
5
  Generated: 2025-12-10 03:48:17
6
6
  """
7
7
 
8
- import os
9
8
  import json
10
9
  import argparse
11
10
  from pathlib import Path
12
- from typing import Dict, List
11
+ from typing import Dict
13
12
  from datetime import datetime
14
13
 
14
+
15
15
  class Analyzer:
16
16
  def __init__(self, target_path: str):
17
17
  self.target_path = Path(target_path)
18
- self.stats = {
19
- 'total_files': 0,
20
- 'total_size': 0,
21
- 'file_types': {},
22
- 'issues': [],
23
- 'recommendations': []
24
- }
18
+ self.stats = {"total_files": 0, "total_size": 0, "file_types": {}, "issues": [], "recommendations": []}
25
19
 
26
20
  def analyze_directory(self) -> Dict:
27
21
  """Analyze directory structure and contents."""
28
22
  if not self.target_path.exists():
29
- self.stats['issues'].append(f"Path does not exist: {self.target_path}")
23
+ self.stats["issues"].append(f"Path does not exist: {self.target_path}")
30
24
  return self.stats
31
25
 
32
- for file_path in self.target_path.rglob('*'):
26
+ for file_path in self.target_path.rglob("*"):
33
27
  if file_path.is_file():
34
28
  self.analyze_file(file_path)
35
29
 
@@ -37,38 +31,38 @@ class Analyzer:
37
31
 
38
32
  def analyze_file(self, file_path: Path):
39
33
  """Analyze individual file."""
40
- self.stats['total_files'] += 1
41
- self.stats['total_size'] += file_path.stat().st_size
34
+ self.stats["total_files"] += 1
35
+ self.stats["total_size"] += file_path.stat().st_size
42
36
 
43
37
  # Track file types
44
38
  ext = file_path.suffix.lower()
45
39
  if ext:
46
- self.stats['file_types'][ext] = self.stats['file_types'].get(ext, 0) + 1
40
+ self.stats["file_types"][ext] = self.stats["file_types"].get(ext, 0) + 1
47
41
 
48
42
  # Check for potential issues
49
43
  if file_path.stat().st_size > 100 * 1024 * 1024: # 100MB
50
- self.stats['issues'].append(f"Large file: {file_path} ({file_path.stat().st_size // 1024 // 1024}MB)")
44
+ self.stats["issues"].append(f"Large file: {file_path} ({file_path.stat().st_size // 1024 // 1024}MB)")
51
45
 
52
46
  if file_path.stat().st_size == 0:
53
- self.stats['issues'].append(f"Empty file: {file_path}")
47
+ self.stats["issues"].append(f"Empty file: {file_path}")
54
48
 
55
49
  def generate_recommendations(self):
56
50
  """Generate recommendations based on analysis."""
57
- if self.stats['total_files'] == 0:
58
- self.stats['recommendations'].append("No files found - check target path")
51
+ if self.stats["total_files"] == 0:
52
+ self.stats["recommendations"].append("No files found - check target path")
59
53
 
60
- if len(self.stats['file_types']) > 20:
61
- self.stats['recommendations'].append("Many file types detected - consider organizing")
54
+ if len(self.stats["file_types"]) > 20:
55
+ self.stats["recommendations"].append("Many file types detected - consider organizing")
62
56
 
63
- if self.stats['total_size'] > 1024 * 1024 * 1024: # 1GB
64
- self.stats['recommendations'].append("Large total size - consider archiving old data")
57
+ if self.stats["total_size"] > 1024 * 1024 * 1024: # 1GB
58
+ self.stats["recommendations"].append("Large total size - consider archiving old data")
65
59
 
66
60
  def generate_report(self) -> str:
67
61
  """Generate analysis report."""
68
62
  report = []
69
- report.append("\n" + "="*60)
70
- report.append(f"ANALYSIS REPORT - mutation-test-runner")
71
- report.append("="*60)
63
+ report.append("\n" + "=" * 60)
64
+ report.append("ANALYSIS REPORT - mutation-test-runner")
65
+ report.append("=" * 60)
72
66
  report.append(f"Target: {self.target_path}")
73
67
  report.append(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
74
68
  report.append("")
@@ -80,34 +74,37 @@ class Analyzer:
80
74
  report.append(f" File Types: {len(self.stats['file_types'])}")
81
75
 
82
76
  # Top file types
83
- if self.stats['file_types']:
77
+ if self.stats["file_types"]:
84
78
  report.append("\n📁 TOP FILE TYPES")
85
- sorted_types = sorted(self.stats['file_types'].items(), key=lambda x: x[1], reverse=True)[:5]
79
+ sorted_types = sorted(self.stats["file_types"].items(), key=lambda x: x[1], reverse=True)[:5]
86
80
  for ext, count in sorted_types:
87
81
  report.append(f" {ext or 'no extension'}: {count} files")
88
82
 
89
83
  # Issues
90
- if self.stats['issues']:
84
+ if self.stats["issues"]:
91
85
  report.append(f"\n⚠️ ISSUES ({len(self.stats['issues'])})")
92
- for issue in self.stats['issues'][:10]:
86
+ for issue in self.stats["issues"][:10]:
93
87
  report.append(f" - {issue}")
94
- if len(self.stats['issues']) > 10:
88
+ if len(self.stats["issues"]) > 10:
95
89
  report.append(f" ... and {len(self.stats['issues']) - 10} more")
96
90
 
97
91
  # Recommendations
98
- if self.stats['recommendations']:
92
+ if self.stats["recommendations"]:
99
93
  report.append("\n💡 RECOMMENDATIONS")
100
- for rec in self.stats['recommendations']:
94
+ for rec in self.stats["recommendations"]:
101
95
  report.append(f" - {rec}")
102
96
 
103
97
  report.append("")
104
98
  return "\n".join(report)
105
99
 
100
+
106
101
  def main():
107
- parser = argparse.ArgumentParser(description="Analyzes the mutation test results to identify weak coverage areas and suggest improvements.")
108
- parser.add_argument('target', help='Target directory to analyze')
109
- parser.add_argument('--output', '-o', help='Output report file')
110
- parser.add_argument('--json', action='store_true', help='Output as JSON')
102
+ parser = argparse.ArgumentParser(
103
+ description="Analyzes the mutation test results to identify weak coverage areas and suggest improvements."
104
+ )
105
+ parser.add_argument("target", help="Target directory to analyze")
106
+ parser.add_argument("--output", "-o", help="Output report file")
107
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
111
108
 
112
109
  args = parser.parse_args()
113
110
 
@@ -127,8 +124,10 @@ def main():
127
124
  else:
128
125
  print(output)
129
126
 
130
- return 0 if len(stats['issues']) == 0 else 1
127
+ return 0 if len(stats["issues"]) == 0 else 1
128
+
131
129
 
132
130
  if __name__ == "__main__":
133
131
  import sys
132
+
134
133
  sys.exit(main())