|
| 1 | +#!/usr/bin/env bash |
| 2 | +# tests/skills/test-project-setup-onboarding-step.sh |
| 3 | +# Tests that plugins/dso/skills/project-setup/SKILL.md contains an onboarding |
| 4 | +# integration step (Step 7) that offers /dso:dev-onboarding and /dso:design-onboarding |
| 5 | +# with correct structure, prompts, and artifact detection. |
| 6 | +# |
| 7 | +# Validates (8 named assertions): |
| 8 | +# SC1: Step 7 heading present after Step 6 in SKILL.md |
| 9 | +# SC2: Option descriptions include brief summaries of what each skill produces |
| 10 | +# SC3: AskUserQuestion with 4 options when both skills available |
| 11 | +# SC4: yes/no variant when only one skill available |
| 12 | +# SC5: dev-onboarding invoked before design-onboarding in the sequence |
| 13 | +# SC6: skip option ends setup with no additional steps |
| 14 | +# SC8a: references DESIGN_NOTES.md and ARCH_ENFORCEMENT.md for artifact detection |
| 15 | +# SC8b: both artifacts present → prompt skipped entirely |
| 16 | +# |
| 17 | +# Usage: bash tests/skills/test-project-setup-onboarding-step.sh |
| 18 | +# Returns: exit 0 if all tests pass, exit 1 if any fail |
| 19 | + |
| 20 | +set -uo pipefail |
| 21 | + |
| 22 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 23 | +PLUGIN_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" |
| 24 | +DSO_PLUGIN_DIR="$PLUGIN_ROOT/plugins/dso" |
| 25 | +SKILL_MD="$DSO_PLUGIN_DIR/skills/project-setup/SKILL.md" |
| 26 | + |
| 27 | +source "$PLUGIN_ROOT/tests/lib/assert.sh" |
| 28 | + |
| 29 | +echo "=== test-project-setup-onboarding-step.sh ===" |
| 30 | + |
| 31 | +# test_step7_exists (SC1): Step 7 heading must be present in SKILL.md after Step 6 |
| 32 | +test_step7_exists() { |
| 33 | + _snapshot_fail |
| 34 | + local step7_exists="missing" |
| 35 | + if grep -q "^## Step 7" "$SKILL_MD" 2>/dev/null; then |
| 36 | + local step6_line step7_line |
| 37 | + step6_line=$(grep -n "^## Step 6" "$SKILL_MD" 2>/dev/null | head -1 | cut -d: -f1) |
| 38 | + step7_line=$(grep -n "^## Step 7" "$SKILL_MD" 2>/dev/null | head -1 | cut -d: -f1) |
| 39 | + if [[ -n "$step6_line" && -n "$step7_line" && "$step7_line" -gt "$step6_line" ]]; then |
| 40 | + step7_exists="found" |
| 41 | + fi |
| 42 | + fi |
| 43 | + assert_eq "test_step7_exists" "found" "$step7_exists" |
| 44 | + assert_pass_if_clean "test_step7_exists" |
| 45 | +} |
| 46 | + |
| 47 | +# test_descriptive_labels (SC2): option descriptions must include brief summaries of |
| 48 | +# what each skill produces (e.g. what dev-onboarding and design-onboarding generate) |
| 49 | +test_descriptive_labels() { |
| 50 | + _snapshot_fail |
| 51 | + local step7_content has_skill_names has_descriptions has_descriptive_labels |
| 52 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 53 | + if echo "$step7_content" | grep -qiE "dev-onboarding|design-onboarding"; then |
| 54 | + has_skill_names="yes" |
| 55 | + else |
| 56 | + has_skill_names="no" |
| 57 | + fi |
| 58 | + if echo "$step7_content" | grep -qiE "produces|generates|creates|sets up|ARCH_ENFORCEMENT|DESIGN_NOTES|codebase guide|architecture"; then |
| 59 | + has_descriptions="yes" |
| 60 | + else |
| 61 | + has_descriptions="no" |
| 62 | + fi |
| 63 | + if [[ "$has_skill_names" == "yes" && "$has_descriptions" == "yes" ]]; then |
| 64 | + has_descriptive_labels="found" |
| 65 | + else |
| 66 | + has_descriptive_labels="missing" |
| 67 | + fi |
| 68 | + assert_eq "test_descriptive_labels" "found" "$has_descriptive_labels" |
| 69 | + assert_pass_if_clean "test_descriptive_labels" |
| 70 | +} |
| 71 | + |
| 72 | +# test_four_option_prompt (SC3): Step 7 must include an AskUserQuestion with 4 options |
| 73 | +# when both skills are available (dev-onboarding and design-onboarding) |
| 74 | +test_four_option_prompt() { |
| 75 | + _snapshot_fail |
| 76 | + local step7_content four_option_found |
| 77 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 78 | + four_option_found="missing" |
| 79 | + if echo "$step7_content" | grep -qiE "AskUserQuestion"; then |
| 80 | + if echo "$step7_content" | grep -qiE "both.*onboarding|run both|both skills|option.*both|4\)"; then |
| 81 | + four_option_found="found" |
| 82 | + fi |
| 83 | + fi |
| 84 | + assert_eq "test_four_option_prompt" "found" "$four_option_found" |
| 85 | + assert_pass_if_clean "test_four_option_prompt" |
| 86 | +} |
| 87 | + |
| 88 | +# test_single_option_prompt (SC4): Step 7 must include a yes/no variant for when |
| 89 | +# only one onboarding skill is available |
| 90 | +test_single_option_prompt() { |
| 91 | + _snapshot_fail |
| 92 | + local step7_content single_option_found |
| 93 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 94 | + single_option_found="missing" |
| 95 | + if echo "$step7_content" | grep -qiE "only one|one.*available|yes.*no|yes/no|if only"; then |
| 96 | + single_option_found="found" |
| 97 | + fi |
| 98 | + assert_eq "test_single_option_prompt" "found" "$single_option_found" |
| 99 | + assert_pass_if_clean "test_single_option_prompt" |
| 100 | +} |
| 101 | + |
| 102 | +# test_invocation_order (SC5): dev-onboarding must be invoked before design-onboarding |
| 103 | +# when running in sequence (dev-onboarding appears at a lower line number) |
| 104 | +test_invocation_order() { |
| 105 | + _snapshot_fail |
| 106 | + local step7_content dev_line design_line invocation_order_ok |
| 107 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 108 | + invocation_order_ok="missing" |
| 109 | + dev_line=$(echo "$step7_content" | grep -n "dev-onboarding" | head -1 | cut -d: -f1) |
| 110 | + design_line=$(echo "$step7_content" | grep -n "design-onboarding" | head -1 | cut -d: -f1) |
| 111 | + if [[ -n "$dev_line" && -n "$design_line" && "$dev_line" -lt "$design_line" ]]; then |
| 112 | + invocation_order_ok="found" |
| 113 | + fi |
| 114 | + assert_eq "test_invocation_order" "found" "$invocation_order_ok" |
| 115 | + assert_pass_if_clean "test_invocation_order" |
| 116 | +} |
| 117 | + |
| 118 | +# test_skip_ends_setup (SC6): skip option must end setup with no additional steps |
| 119 | +test_skip_ends_setup() { |
| 120 | + _snapshot_fail |
| 121 | + local step7_content skip_ends_setup |
| 122 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 123 | + skip_ends_setup="missing" |
| 124 | + if echo "$step7_content" | grep -qiE "skip.*setup.*complete|skip.*no.*additional|skip.*end|skip.*nothing|skip.*done|setup is complete|no additional steps"; then |
| 125 | + skip_ends_setup="found" |
| 126 | + fi |
| 127 | + assert_eq "test_skip_ends_setup" "found" "$skip_ends_setup" |
| 128 | + assert_pass_if_clean "test_skip_ends_setup" |
| 129 | +} |
| 130 | + |
| 131 | +# test_artifact_detection (SC8): Step 7 must reference DESIGN_NOTES.md and |
| 132 | +# ARCH_ENFORCEMENT.md as the artifacts used to detect whether onboarding already ran |
| 133 | +test_artifact_detection() { |
| 134 | + _snapshot_fail |
| 135 | + local step7_content has_design_notes has_arch_enforcement artifact_detection |
| 136 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 137 | + has_design_notes="no" |
| 138 | + has_arch_enforcement="no" |
| 139 | + if echo "$step7_content" | grep -q "DESIGN_NOTES.md"; then |
| 140 | + has_design_notes="yes" |
| 141 | + fi |
| 142 | + if echo "$step7_content" | grep -q "ARCH_ENFORCEMENT.md"; then |
| 143 | + has_arch_enforcement="yes" |
| 144 | + fi |
| 145 | + if [[ "$has_design_notes" == "yes" && "$has_arch_enforcement" == "yes" ]]; then |
| 146 | + artifact_detection="found" |
| 147 | + else |
| 148 | + artifact_detection="missing" |
| 149 | + fi |
| 150 | + assert_eq "test_artifact_detection" "found" "$artifact_detection" |
| 151 | + assert_pass_if_clean "test_artifact_detection" |
| 152 | +} |
| 153 | + |
| 154 | +# test_both_artifacts_skip_entirely (SC8): when both DESIGN_NOTES.md and |
| 155 | +# ARCH_ENFORCEMENT.md are present, the prompt must be skipped entirely |
| 156 | +test_both_artifacts_skip_entirely() { |
| 157 | + _snapshot_fail |
| 158 | + local step7_content both_artifacts_skip |
| 159 | + step7_content=$(awk '/^## Step 7/,/^## Step [89]|^## Error/' "$SKILL_MD" 2>/dev/null) |
| 160 | + both_artifacts_skip="missing" |
| 161 | + if echo "$step7_content" | grep -qiE "both.*present.*skip|skip.*both.*present|both.*artifact.*skip|already.*both.*skip|both.*exist.*skip|skip.*entirely|skip.*prompt|skip this step"; then |
| 162 | + both_artifacts_skip="found" |
| 163 | + fi |
| 164 | + assert_eq "test_both_artifacts_skip_entirely" "found" "$both_artifacts_skip" |
| 165 | + assert_pass_if_clean "test_both_artifacts_skip_entirely" |
| 166 | +} |
| 167 | + |
| 168 | +# Run all 8 assertion functions |
| 169 | +test_step7_exists |
| 170 | +test_descriptive_labels |
| 171 | +test_four_option_prompt |
| 172 | +test_single_option_prompt |
| 173 | +test_invocation_order |
| 174 | +test_skip_ends_setup |
| 175 | +test_artifact_detection |
| 176 | +test_both_artifacts_skip_entirely |
| 177 | + |
| 178 | +print_summary |
0 commit comments