180 lines
5.5 KiB
Bash
Executable File
180 lines
5.5 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# create-tests.sh - Interactive test case generator for skills
|
|
#
|
|
# Usage: ./create-tests.sh <path/to/skill-directory>
|
|
#
|
|
# 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 <path/to/skill-directory>"
|
|
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}"
|