| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #!/bin/bash
- # Functional tests for data-processing skill
- # Tests jq and yq CLI tools
- set -euo pipefail
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- FIXTURES="$SCRIPT_DIR/../fixtures"
- # Colors
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- NC='\033[0m'
- PASSED=0
- FAILED=0
- SKIPPED=0
- pass() { ((PASSED++)); echo -e "${GREEN}✓${NC} $1"; }
- fail() { ((FAILED++)); echo -e "${RED}✗${NC} $1: $2"; }
- skip() { ((SKIPPED++)); echo -e "${YELLOW}○${NC} $1 (skipped: $2)"; }
- # Check prerequisites
- HAS_JQ=false
- HAS_YQ=false
- check_prereqs() {
- local missing=()
- if command -v jq >/dev/null 2>&1; then
- HAS_JQ=true
- else
- missing+=("jq")
- fi
- if command -v yq >/dev/null 2>&1; then
- HAS_YQ=true
- else
- missing+=("yq")
- fi
- if [[ ${#missing[@]} -gt 0 ]]; then
- echo -e "${YELLOW}Missing tools: ${missing[*]}${NC}"
- echo "Install with: brew install ${missing[*]}"
- echo "Some tests will be skipped."
- echo ""
- fi
- }
- # Test helper
- assert_eq() {
- local name="$1"
- local expected="$2"
- local actual="$3"
- if [[ "$expected" == "$actual" ]]; then
- pass "$name"
- else
- fail "$name" "expected '$expected', got '$actual'"
- fi
- }
- assert_contains() {
- local name="$1"
- local needle="$2"
- local haystack="$3"
- if [[ "$haystack" == *"$needle"* ]]; then
- pass "$name"
- else
- fail "$name" "output does not contain '$needle'"
- fi
- }
- # === jq Tests ===
- test_jq_extract_field() {
- if [[ $HAS_JQ != true ]]; then
- skip "jq: extract single field" "jq not installed"
- return
- fi
- local result
- result=$(echo '{"name": "test-app"}' | jq -r '.name')
- assert_eq "jq: extract single field" "test-app" "$result"
- }
- test_jq_nested_field() {
- [[ $HAS_JQ != true ]] && { skip "jq: extract nested field" "jq not installed"; return; }
- local result
- result=$(echo '{"scripts": {"build": "tsc"}}' | jq -r '.scripts.build')
- assert_eq "jq: extract nested field" "tsc" "$result"
- }
- test_jq_array_filter() {
- [[ $HAS_JQ != true ]] && { skip "jq: filter array by condition" "jq not installed"; return; }
- local result
- result=$(echo '{"users": [{"name": "Alice", "active": true}, {"name": "Bob", "active": false}]}' | jq -r '.users[] | select(.active == true) | .name')
- assert_eq "jq: filter array by condition" "Alice" "$result"
- }
- test_jq_array_length() {
- [[ $HAS_JQ != true ]] && { skip "jq: count array length" "jq not installed"; return; }
- local result
- result=$(echo '{"items": [1, 2, 3, 4, 5]}' | jq '.items | length')
- assert_eq "jq: count array length" "5" "$result"
- }
- test_jq_raw_output() {
- [[ $HAS_JQ != true ]] && { skip "jq: raw string output" "jq not installed"; return; }
- local quoted unquoted
- quoted=$(echo '{"name": "myapp"}' | jq '.name')
- unquoted=$(echo '{"name": "myapp"}' | jq -r '.name')
- if [[ "$quoted" == '"myapp"' && "$unquoted" == "myapp" ]]; then
- pass "jq: raw string output (-r flag)"
- else
- fail "jq: raw string output" "quoted='$quoted', unquoted='$unquoted'"
- fi
- }
- test_jq_map_transform() {
- [[ $HAS_JQ != true ]] && { skip "jq: map transformation" "jq not installed"; return; }
- local result
- result=$(echo '{"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}' | jq '[.users[] | {id, name}] | length')
- assert_eq "jq: map transformation" "2" "$result"
- }
- test_jq_package_json() {
- [[ $HAS_JQ != true ]] && { skip "jq: parse package.json" "jq not installed"; return; }
- if [[ -f "$FIXTURES/package.json" ]]; then
- local name version
- name=$(jq -r '.name' "$FIXTURES/package.json")
- version=$(jq -r '.version' "$FIXTURES/package.json")
- if [[ -n "$name" && -n "$version" ]]; then
- pass "jq: parse package.json fixture"
- else
- fail "jq: parse package.json" "name='$name', version='$version'"
- fi
- else
- skip "jq: parse package.json fixture" "fixture not found"
- fi
- }
- # === yq Tests ===
- test_yq_extract_field() {
- [[ $HAS_YQ != true ]] && { skip "yq: extract YAML field" "yq not installed"; return; }
- local result
- result=$(echo -e "name: myapp\nversion: 2.0.0" | yq -r '.name')
- assert_eq "yq: extract YAML field" "myapp" "$result"
- }
- test_yq_list_keys() {
- [[ $HAS_YQ != true ]] && { skip "yq: list keys count" "yq not installed"; return; }
- local result
- result=$(echo -e "database:\n host: localhost\n port: 5432" | yq '.database | keys | length')
- assert_eq "yq: list keys count" "2" "$result"
- }
- test_yq_docker_compose() {
- [[ $HAS_YQ != true ]] && { skip "yq: Docker Compose services" "yq not installed"; return; }
- local result
- result=$(echo -e "services:\n web:\n image: nginx\n db:\n image: postgres" | yq '.services | keys | length')
- assert_eq "yq: Docker Compose services" "2" "$result"
- }
- test_yq_toml_parsing() {
- [[ $HAS_YQ != true ]] && { skip "yq: TOML parsing" "yq not installed"; return; }
- local result
- result=$(echo -e '[package]\nname = "myapp"' | yq -p toml -r '.package.name')
- assert_eq "yq: TOML parsing" "myapp" "$result"
- }
- test_yq_config_fixture() {
- [[ $HAS_YQ != true ]] && { skip "yq: parse config.yaml" "yq not installed"; return; }
- if [[ -f "$FIXTURES/config.yaml" ]]; then
- local result
- result=$(yq -r '.name' "$FIXTURES/config.yaml")
- if [[ -n "$result" && "$result" != "null" ]]; then
- pass "yq: parse config.yaml fixture"
- else
- fail "yq: parse config.yaml" "got '$result'"
- fi
- else
- skip "yq: parse config.yaml fixture" "fixture not found"
- fi
- }
- # === Run Tests ===
- main() {
- echo "=== data-processing functional tests ==="
- echo ""
- check_prereqs
- echo "--- jq tests ---"
- test_jq_extract_field
- test_jq_nested_field
- test_jq_array_filter
- test_jq_array_length
- test_jq_raw_output
- test_jq_map_transform
- test_jq_package_json
- echo ""
- echo "--- yq tests ---"
- test_yq_extract_field
- test_yq_list_keys
- test_yq_docker_compose
- test_yq_toml_parsing
- test_yq_config_fixture
- echo ""
- echo "=== Results ==="
- echo -e "Passed: ${GREEN}$PASSED${NC}"
- echo -e "Failed: ${RED}$FAILED${NC}"
- echo -e "Skipped: ${YELLOW}$SKIPPED${NC}"
- [[ $FAILED -eq 0 ]]
- }
- main "$@"
|