#!/bin/bash # # create-tests.sh - Interactive test case generator for skills # # Usage: ./create-tests.sh # # This script interactively generates evals/evals.json with 3 template test cases. # set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Parse arguments SKILL_DIR="" usage() { echo "Usage: $0 " echo "" echo "Examples:" echo " $0 ~/.config/opencode/skills/my-skill" echo " $0 ./my-skill" exit 1 } # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -h|--help) usage ;; -*) echo -e "${RED}Error: Unknown option $1${NC}" usage ;; *) if [[ -z "$SKILL_DIR" ]]; then SKILL_DIR="$1" else echo -e "${RED}Error: Multiple skill directories provided${NC}" usage fi shift ;; esac done # Validate skill directory if [[ -z "$SKILL_DIR" ]]; then echo -e "${RED}Error: Skill directory is required${NC}" usage fi # Resolve path SKILL_DIR="$(cd "$SKILL_DIR" 2>/dev/null && pwd)" || { echo -e "${RED}Error: Cannot access directory: $SKILL_DIR${NC}" exit 1 } # Get skill name from directory SKILL_NAME="$(basename "$SKILL_DIR")" # Verify SKILL.md exists if [[ ! -f "$SKILL_DIR/SKILL.md" ]]; then echo -e "${RED}Error: SKILL.md not found in $SKILL_DIR${NC}" echo "This does not appear to be a valid skill directory." exit 1 fi echo "========================================" echo "Creating Test Cases for: $SKILL_NAME" echo "========================================" echo "" # Create evals directory mkdir -p "$SKILL_DIR/evals" echo -e "${GREEN}✓ Created evals/ directory${NC}" echo "" # Check if evals.json already exists if [[ -f "$SKILL_DIR/evals/evals.json" ]]; then echo -e "${YELLOW}⚠ evals.json already exists${NC}" read -p "Overwrite? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Aborted." exit 0 fi fi # Get skill purpose from user echo "Let's create 3 test cases for your skill." echo "" echo "First, tell me about your skill's purpose:" echo " (e.g., 'Helps users convert CSV files to JSON format')" read -r SKILL_PURPOSE if [[ -z "$SKILL_PURPOSE" ]]; then SKILL_PURPOSE="[Describe what your skill does]" fi echo "" echo "Now I'll generate 3 test case templates." echo "You can edit evals/evals.json later to customize them." echo "" # Generate evals.json cat > "$SKILL_DIR/evals/evals.json" << EVALSJSON { "skill_name": "$SKILL_NAME", "description": "$SKILL_PURPOSE", "evals": [ { "id": 1, "name": "common-case", "type": "common", "prompt": "[REPLACE WITH REALISTIC USER REQUEST]\n\nExample: Convert the CSV file at ./data/sales.csv to JSON format and save it as ./output/sales.json. Make sure dates are in ISO 8601 format.", "expected_output": "[DESCRIBE EXPECTED RESULT]\n\nExample: A JSON file at ./output/sales.json containing the sales data from the CSV, with all dates converted to ISO 8601 format.", "assertions": [ "Output file exists at the specified location", "File is valid JSON", "Dates are in ISO 8601 format" ], "notes": "This tests the typical, straightforward use case." }, { "id": 2, "name": "edge-case", "type": "edge", "prompt": "[REPLACE WITH EDGE CASE SCENARIO]\n\nExample: Convert a CSV file with 100,000 rows, some containing special characters (emojis, Unicode) and empty values in certain columns. The file is at ./data/large_export.csv.", "expected_output": "[DESCRIBE EXPECTED BEHAVIOR]\n\nExample: JSON file is created successfully, handling all special characters correctly and preserving empty values as null or empty strings.", "assertions": [ "Large file is processed without errors", "Special characters are preserved correctly", "Empty values are handled appropriately" ], "notes": "This tests edge cases like large files, special characters, or missing data." }, { "id": 3, "name": "varied-phrasing", "type": "variation", "prompt": "[REPLACE WITH SAME INTENT, DIFFERENT WORDS]\n\nExample: Hey, I've got this spreadsheet in data/sales.csv. Can you turn it into JSON for me? And make sure the dates look right - you know, standard format?", "expected_output": "[SAME AS COMMON CASE]", "assertions": [ "Skill triggers correctly with casual language", "Output matches common case results", "Implicit requirements (date formatting) are handled" ], "notes": "This tests that the skill works with different phrasings and casual language." } ] } EVALSJSON echo -e "${GREEN}✓ Created evals/evals.json${NC}" echo "" echo "========================================" echo "Next Steps:" echo "========================================" echo "" echo "1. Edit evals/evals.json" echo " Replace the [PLACEHOLDER] text with realistic test cases" echo "" echo "2. Tips for writing good test prompts:" echo " - Include file paths (e.g., ./data/file.csv)" echo " - Add personal context (e.g., 'my boss sent me')" echo " - Use specific values and column names" echo " - Mix formal and casual language" echo "" echo "3. Run tests when ready:" echo " ~/.config/opencode/skills/skill-builder/scripts/run-tests.sh $SKILL_DIR" echo "" echo -e "${GREEN}Done!${NC}"