diff --git a/CI/tests/jest.yml b/CI/tests/jest.yml new file mode 100644 index 0000000..3332838 --- /dev/null +++ b/CI/tests/jest.yml @@ -0,0 +1,49 @@ +jest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Cache node_modules + uses: actions/cache@v4 + with: + path: node_modules + key: node-${{ hashFiles('package-lock.json') }} + restore-keys: node- + + - name: Install dependencies + run: npm ci + + - name: Run Jest + run: | + set -euo pipefail + + CONFIG_FOUND=0 + + if [ -f "package.json" ]; then + if grep -q '"jest"' package.json; then + CONFIG_FOUND=1 + fi + for config in "jest.config.js" "jest.config.ts" "jest.config.mjs" "jest.config.cjs"; do + if [ -f "$config" ]; then + CONFIG_FOUND=1 + break + fi + done + fi + + if [ $CONFIG_FOUND -eq 0 ]; then + echo "::error::No Jest configuration found" + exit 1 + fi + + if npx jest --ci --runInBand --passWithNoTests; then + echo "✅ Jest tests passed" + else + echo "❌ Jest tests failed" + exit 1 + fi diff --git a/README.md b/README.md index dc435cf..4332c87 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ that projects compose into their own workflows. | mermaid-cli | build | [CI/build/mermaid.yml](https://github.com/prog-time/workflows/blob/main/CI/build/mermaid.yml) | | BATS | tests | [CI/tests/bats.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/bats.yml) | | go test | tests | [CI/tests/go_test.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/go_test.yml) | +| Jest | tests | [CI/tests/jest.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/jest.yml) | | Laravel | tests | [CI/tests/laravel_tests.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/laravel_tests.yml) | | pytest | tests | [CI/tests/pytest.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/pytest.yml) | | RSpec | tests | [CI/tests/rspec.yml](https://github.com/prog-time/workflows/blob/main/CI/tests/rspec.yml) | @@ -96,6 +97,7 @@ Workflows/ │ │ └── tests/ │ │ ├── bats.yml │ │ ├── go_test.yml +│ │ ├── jest.yml │ │ ├── laravel_tests.yml │ │ ├── pytest.yml │ │ └── rspec.yml @@ -116,10 +118,12 @@ Workflows/ │ │ ├── stylelint.sh │ │ ├── swiftlint.sh │ │ └── yamllint.sh -│ └── security/ -│ ├── gitleaks.sh -│ ├── semgrep.sh -│ └── trivy.sh +│ ├── security/ +│ │ ├── gitleaks.sh +│ │ ├── semgrep.sh +│ │ └── trivy.sh +│ └── tests/ +│ └── jest.sh │ ├── CI/ # assembled output (ready to use) │ ├── linters/ @@ -142,6 +146,8 @@ Workflows/ │ │ ├── gitleaks.bats │ │ ├── semgrep.bats │ │ └── trivy.bats +│ ├── tests/ +│ │ └── jest.bats │ └── helpers/ │ └── common.bash # shared test utilities (mocks, temp dirs) │ @@ -252,6 +258,7 @@ shellcheck: |---------|--------------| | `CI/tests/bats.yml` | BATS tests (`tests/` directory) | | `CI/tests/go_test.yml` | Go test suite (`go test ./...`) | +| `CI/tests/jest.yml` | JavaScript/TypeScript test suite (Jest) | | `CI/tests/laravel_tests.yml` | Laravel test suite (PHP 8.2, SQLite, parallel) | | `CI/tests/pytest.yml` | Python test suite (pytest) | | `CI/tests/rspec.yml` | Ruby test suite (RSpec via Bundler) | diff --git a/scripts/CI/tests/jest.yml b/scripts/CI/tests/jest.yml new file mode 100644 index 0000000..48ebc21 --- /dev/null +++ b/scripts/CI/tests/jest.yml @@ -0,0 +1,22 @@ +jest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Cache node_modules + uses: actions/cache@v4 + with: + path: node_modules + key: node-${{ hashFiles('package-lock.json') }} + restore-keys: node- + + - name: Install dependencies + run: npm ci + + - name: Run Jest + run: bash scripts/shell/tests/jest.sh diff --git a/scripts/shell/tests/jest.sh b/scripts/shell/tests/jest.sh new file mode 100644 index 0000000..8e7048b --- /dev/null +++ b/scripts/shell/tests/jest.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +CONFIG_FOUND=0 + +if [ -f "package.json" ]; then + if grep -q '"jest"' package.json; then + CONFIG_FOUND=1 + fi + for config in "jest.config.js" "jest.config.ts" "jest.config.mjs" "jest.config.cjs"; do + if [ -f "$config" ]; then + CONFIG_FOUND=1 + break + fi + done +fi + +if [ $CONFIG_FOUND -eq 0 ]; then + echo "::error::No Jest configuration found" + exit 1 +fi + +if npx jest --ci --runInBand --passWithNoTests; then + echo "✅ Jest tests passed" +else + echo "❌ Jest tests failed" + exit 1 +fi diff --git a/tests/tests/jest.bats b/tests/tests/jest.bats new file mode 100644 index 0000000..795ffbe --- /dev/null +++ b/tests/tests/jest.bats @@ -0,0 +1,59 @@ +#!/usr/bin/env bats + +load "../helpers/common" + +SCRIPT="$BATS_TEST_DIRNAME/../../scripts/shell/tests/jest.sh" + +setup() { + setup_test_dir + mkdir -p "$TEST_DIR/bin" + export PATH="$TEST_DIR/bin:$PATH" +} + +teardown() { + teardown_test_dir +} + +# Helper: create a stub for "npx jest ..." that always exits with +make_npx_stub() { + local exit_code="$1" + cat > "$TEST_DIR/bin/npx" < package.json <<'EOF' +{ + "devDependencies": { + "jest": "^29.0.0" + } +} +EOF + run bash "$SCRIPT" + [ "$status" -eq 0 ] + [[ "$output" == *"✅ Jest tests passed"* ]] +} + +@test "jest.config.js present (no jest in devDependencies), tests fail: exits 1 with failure message" { + make_npx_stub 1 + cat > package.json <<'EOF' +{ + "devDependencies": {} +} +EOF + touch jest.config.js + run bash "$SCRIPT" + [ "$status" -eq 1 ] + [[ "$output" == *"❌ Jest tests failed"* ]] +}