|
3 | 3 | # Tests that plugins/dso/skills/onboarding/SKILL.md has the correct structure |
4 | 4 | # for the /dso:onboarding Socratic dialogue skill. |
5 | 5 | # |
6 | | -# Validates (33 named assertions): |
| 6 | +# Validates (41 named assertions): |
7 | 7 | # test_skill_file_exists: SKILL.md exists at the expected path |
8 | 8 | # test_frontmatter_valid: frontmatter has name=onboarding and user-invocable=true |
9 | 9 | # test_sub_agent_guard_present: Orchestrator Signal SUB-AGENT-GUARD block present |
@@ -835,4 +835,210 @@ test_jekyll_git_clone_path() { |
835 | 835 |
|
836 | 836 | test_jekyll_git_clone_path |
837 | 837 |
|
| 838 | +# ── RED CI config key / workflow tests (7330-bf69) ─────────────────────────── |
| 839 | + |
| 840 | +# test_ci_config_key_coverage: SKILL.md must reference all 4 CI config keys: |
| 841 | +# ci.fast_gate_job, ci.fast_fail_job, ci.test_ceil_job, ci.integration_workflow |
| 842 | +test_ci_config_key_coverage() { |
| 843 | + _snapshot_fail |
| 844 | + local keys_found keys_missing key |
| 845 | + keys_found=0 |
| 846 | + keys_missing="" |
| 847 | + local required_keys=("ci.fast_gate_job" "ci.fast_fail_job" "ci.test_ceil_job" "ci.integration_workflow") |
| 848 | + for key in "${required_keys[@]}"; do |
| 849 | + if grep -qF "$key" "$SKILL_MD" 2>/dev/null; then |
| 850 | + (( keys_found++ )) |
| 851 | + else |
| 852 | + keys_missing="$keys_missing $key" |
| 853 | + fi |
| 854 | + done |
| 855 | + if [[ "$keys_found" -eq 4 ]]; then |
| 856 | + assert_eq "test_ci_config_key_coverage" "found" "found" |
| 857 | + else |
| 858 | + assert_eq "test_ci_config_key_coverage" "all 4 CI config keys" "$keys_found keys found (missing:$keys_missing)" |
| 859 | + fi |
| 860 | + assert_pass_if_clean "test_ci_config_key_coverage" |
| 861 | +} |
| 862 | + |
| 863 | +# test_ci_workflow_confidence_gating: SKILL.md must reference ci_workflow_confidence-gated logic — |
| 864 | +# must reference ci_workflow_confidence AND contain numbered selection for low-confidence/multiple workflows |
| 865 | +test_ci_workflow_confidence_gating() { |
| 866 | + _snapshot_fail |
| 867 | + local has_confidence has_selection result |
| 868 | + has_confidence="no" |
| 869 | + has_selection="no" |
| 870 | + if grep -q "ci_workflow_confidence" "$SKILL_MD" 2>/dev/null; then |
| 871 | + has_confidence="yes" |
| 872 | + fi |
| 873 | + if grep -qiE "numbered selection|multiple.*workflow|low.*confidence|confidence.*low" "$SKILL_MD" 2>/dev/null; then |
| 874 | + has_selection="yes" |
| 875 | + fi |
| 876 | + if [[ "$has_confidence" == "yes" && "$has_selection" == "yes" ]]; then |
| 877 | + result="found" |
| 878 | + else |
| 879 | + result="missing" |
| 880 | + fi |
| 881 | + assert_eq "test_ci_workflow_confidence_gating" "found" "$result" |
| 882 | + assert_pass_if_clean "test_ci_workflow_confidence_gating" |
| 883 | +} |
| 884 | + |
| 885 | +test_ci_config_key_coverage |
| 886 | +test_ci_workflow_confidence_gating |
| 887 | + |
| 888 | +# ── RED merge.ci_workflow_name auto-migration tests (e9a7-39cd) ────────────── |
| 889 | + |
| 890 | +# test_ci_workflow_name_deprecation_migration: SKILL.md must contain auto-migration logic from |
| 891 | +# merge.ci_workflow_name to ci.workflow_name, with a conditional skip when ci.workflow_name exists |
| 892 | +test_ci_workflow_name_deprecation_migration() { |
| 893 | + _snapshot_fail |
| 894 | + local has_old_key has_new_key has_skip result |
| 895 | + has_old_key="no" |
| 896 | + has_new_key="no" |
| 897 | + has_skip="no" |
| 898 | + if grep -q "merge.ci_workflow_name" "$SKILL_MD" 2>/dev/null; then |
| 899 | + has_old_key="yes" |
| 900 | + fi |
| 901 | + if grep -q "ci.workflow_name" "$SKILL_MD" 2>/dev/null; then |
| 902 | + has_new_key="yes" |
| 903 | + fi |
| 904 | + if grep -qiE "skip.*if.*ci\.workflow_name|ci\.workflow_name.*already|already.*exists" "$SKILL_MD" 2>/dev/null; then |
| 905 | + has_skip="yes" |
| 906 | + fi |
| 907 | + if [[ "$has_old_key" == "yes" && "$has_new_key" == "yes" && "$has_skip" == "yes" ]]; then |
| 908 | + result="found" |
| 909 | + else |
| 910 | + result="missing" |
| 911 | + fi |
| 912 | + assert_eq "test_ci_workflow_name_deprecation_migration" "found" "$result" |
| 913 | + assert_pass_if_clean "test_ci_workflow_name_deprecation_migration" |
| 914 | +} |
| 915 | + |
| 916 | +test_ci_workflow_name_deprecation_migration |
| 917 | + |
| 918 | +# ── RED key name mismatch tests (89aa-3b1f) ────────────────────────────────── |
| 919 | + |
| 920 | +# test_key_name_jira_project: SKILL.md must reference "jira.project" but NOT "jira.project_key" |
| 921 | +test_key_name_jira_project() { |
| 922 | + _snapshot_fail |
| 923 | + local has_correct has_incorrect result |
| 924 | + has_correct="no" |
| 925 | + has_incorrect="no" |
| 926 | + if grep -q "jira.project" "$SKILL_MD" 2>/dev/null; then |
| 927 | + has_correct="yes" |
| 928 | + fi |
| 929 | + if grep -q "jira.project_key" "$SKILL_MD" 2>/dev/null; then |
| 930 | + has_incorrect="yes" |
| 931 | + fi |
| 932 | + if [[ "$has_correct" == "yes" && "$has_incorrect" == "no" ]]; then |
| 933 | + result="found" |
| 934 | + else |
| 935 | + result="missing" |
| 936 | + fi |
| 937 | + assert_eq "test_key_name_jira_project" "found" "$result" |
| 938 | + assert_pass_if_clean "test_key_name_jira_project" |
| 939 | +} |
| 940 | + |
| 941 | +# test_key_name_design_system_name: SKILL.md must reference "design.system_name" but NOT |
| 942 | +# bare "design.system" without the _name suffix |
| 943 | +test_key_name_design_system_name() { |
| 944 | + _snapshot_fail |
| 945 | + local has_correct has_incorrect result |
| 946 | + has_correct="no" |
| 947 | + has_incorrect="no" |
| 948 | + if grep -q "design.system_name" "$SKILL_MD" 2>/dev/null; then |
| 949 | + has_correct="yes" |
| 950 | + fi |
| 951 | + if grep "design\.system" "$SKILL_MD" 2>/dev/null | grep -v "design\.system_name" | grep -q "design\.system"; then |
| 952 | + has_incorrect="yes" |
| 953 | + fi |
| 954 | + if [[ "$has_correct" == "yes" && "$has_incorrect" == "no" ]]; then |
| 955 | + result="found" |
| 956 | + else |
| 957 | + result="missing" |
| 958 | + fi |
| 959 | + assert_eq "test_key_name_design_system_name" "found" "$result" |
| 960 | + assert_pass_if_clean "test_key_name_design_system_name" |
| 961 | +} |
| 962 | + |
| 963 | +# test_design_tokens_path_audit: design.tokens_path must either exist in validate-config.sh KNOWN_KEYS |
| 964 | +# OR must NOT be referenced in SKILL.md config table |
| 965 | +test_design_tokens_path_audit() { |
| 966 | + _snapshot_fail |
| 967 | + local validate_config_sh tokens_in_known_keys tokens_in_skill result |
| 968 | + validate_config_sh="$PLUGIN_ROOT/plugins/dso/scripts/validate-config.sh" |
| 969 | + tokens_in_known_keys="no" |
| 970 | + tokens_in_skill="no" |
| 971 | + if grep -q "design.tokens_path" "$validate_config_sh" 2>/dev/null; then |
| 972 | + tokens_in_known_keys="yes" |
| 973 | + fi |
| 974 | + if grep -q "design.tokens_path" "$SKILL_MD" 2>/dev/null; then |
| 975 | + tokens_in_skill="yes" |
| 976 | + fi |
| 977 | + # Pass if: tokens_path is in KNOWN_KEYS (legitimate) OR not referenced in SKILL.md (no mismatch) |
| 978 | + if [[ "$tokens_in_known_keys" == "yes" || "$tokens_in_skill" == "no" ]]; then |
| 979 | + result="found" |
| 980 | + else |
| 981 | + result="missing" |
| 982 | + fi |
| 983 | + assert_eq "test_design_tokens_path_audit" "found" "$result" |
| 984 | + assert_pass_if_clean "test_design_tokens_path_audit" |
| 985 | +} |
| 986 | + |
| 987 | +test_key_name_jira_project |
| 988 | +test_key_name_design_system_name |
| 989 | +test_design_tokens_path_audit |
| 990 | + |
| 991 | +# ── RED version.file_path and stack config tests (2e7c-d060) ───────────────── |
| 992 | + |
| 993 | +# test_version_file_path_config: SKILL.md must reference version.file_path AND version_files |
| 994 | +# (the project-detect.sh output key), with numbered selection when multiple version files exist |
| 995 | +test_version_file_path_config() { |
| 996 | + _snapshot_fail |
| 997 | + local has_config_key has_detect_key has_selection result |
| 998 | + has_config_key="no" |
| 999 | + has_detect_key="no" |
| 1000 | + has_selection="no" |
| 1001 | + if grep -q "version.file_path" "$SKILL_MD" 2>/dev/null; then |
| 1002 | + has_config_key="yes" |
| 1003 | + fi |
| 1004 | + if grep -q "version_files" "$SKILL_MD" 2>/dev/null; then |
| 1005 | + has_detect_key="yes" |
| 1006 | + fi |
| 1007 | + if grep -qiE "numbered selection|multiple.*version|version.*multiple|select.*version" "$SKILL_MD" 2>/dev/null; then |
| 1008 | + has_selection="yes" |
| 1009 | + fi |
| 1010 | + if [[ "$has_config_key" == "yes" && "$has_detect_key" == "yes" && "$has_selection" == "yes" ]]; then |
| 1011 | + result="found" |
| 1012 | + else |
| 1013 | + result="missing" |
| 1014 | + fi |
| 1015 | + assert_eq "test_version_file_path_config" "found" "$result" |
| 1016 | + assert_pass_if_clean "test_version_file_path_config" |
| 1017 | +} |
| 1018 | + |
| 1019 | +# test_stack_config_key: SKILL.md must reference "stack" as a config key populated |
| 1020 | +# from detect-stack.sh output |
| 1021 | +test_stack_config_key() { |
| 1022 | + _snapshot_fail |
| 1023 | + local has_stack_key has_detect_stack result |
| 1024 | + has_stack_key="no" |
| 1025 | + has_detect_stack="no" |
| 1026 | + if grep -qE "\bstack\b" "$SKILL_MD" 2>/dev/null; then |
| 1027 | + has_stack_key="yes" |
| 1028 | + fi |
| 1029 | + if grep -q "detect-stack.sh" "$SKILL_MD" 2>/dev/null; then |
| 1030 | + has_detect_stack="yes" |
| 1031 | + fi |
| 1032 | + if [[ "$has_stack_key" == "yes" && "$has_detect_stack" == "yes" ]]; then |
| 1033 | + result="found" |
| 1034 | + else |
| 1035 | + result="missing" |
| 1036 | + fi |
| 1037 | + assert_eq "test_stack_config_key" "found" "$result" |
| 1038 | + assert_pass_if_clean "test_stack_config_key" |
| 1039 | +} |
| 1040 | + |
| 1041 | +test_version_file_path_config |
| 1042 | +test_stack_config_key |
| 1043 | + |
838 | 1044 | print_summary |
0 commit comments