mirror of
https://github.com/creyD/prettier_action.git
synced 2026-04-12 19:30:30 +02:00
Add comprehensive testing infrastructure
This commit adds a complete testing setup for the prettier_action: - Adds BATS (Bash Automated Testing System) testing framework - Creates unit tests for _git_setup() and _git_changed() functions - Creates plugin validation tests to ensure proper prettier plugin format - Creates integration tests for end-to-end workflows - Adds automated test runner script (tests/run_tests.sh) - Adds GitHub Actions workflow for CI/CD testing - Includes ShellCheck linting for bash scripts - Updates README with comprehensive testing documentation - Updates .gitignore to exclude test artifacts Test coverage includes: - Git configuration with different identity modes - File change detection - Plugin name validation (official, community, and scoped formats) - Working directory handling - node_modules cleanup - package-lock.json restoration - only_changed file filtering - Dry run behavior The test suite can be run locally with ./tests/run_tests.sh and runs automatically on all pushes and pull requests.
This commit is contained in:
81
.github/workflows/test.yml
vendored
Normal file
81
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: Run Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master, dev, 'claude/**' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master, dev ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Run BATS Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Git
|
||||||
|
run: |
|
||||||
|
git config --global user.name "GitHub Actions"
|
||||||
|
git config --global user.email "actions@github.com"
|
||||||
|
|
||||||
|
- name: Install BATS
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
./run_tests.sh --install-only
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
./bats/bin/bats unit_tests.bats
|
||||||
|
|
||||||
|
- name: Run plugin validation tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
./bats/bin/bats plugin_validation_tests.bats
|
||||||
|
|
||||||
|
- name: Run integration tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
./bats/bin/bats integration_tests.bats
|
||||||
|
|
||||||
|
- name: Run all tests with runner script
|
||||||
|
run: |
|
||||||
|
./tests/run_tests.sh
|
||||||
|
|
||||||
|
test-action:
|
||||||
|
name: Test Action End-to-End
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Create test files
|
||||||
|
run: |
|
||||||
|
echo "const x=1;const y=2;" > test.js
|
||||||
|
echo "function foo(){return 'bar';}" > test2.js
|
||||||
|
|
||||||
|
- name: Run prettier action in dry mode
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dry: true
|
||||||
|
prettier_options: "--write --check test*.js"
|
||||||
|
no_commit: true
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
shellcheck:
|
||||||
|
name: Shellcheck
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Run ShellCheck
|
||||||
|
uses: ludeeus/action-shellcheck@master
|
||||||
|
with:
|
||||||
|
scandir: '.'
|
||||||
|
severity: warning
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
# NPM
|
# NPM
|
||||||
node_modules/
|
node_modules/
|
||||||
|
# Testing
|
||||||
|
tests/bats/
|
||||||
|
tests/test_temp_*/
|
||||||
|
|||||||
67
README.md
67
README.md
@@ -158,6 +158,73 @@ jobs:
|
|||||||
|
|
||||||
More documentation for writing a workflow can be found [here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions).
|
More documentation for writing a workflow can be found [here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
This project includes comprehensive test coverage using [BATS (Bash Automated Testing System)](https://github.com/bats-core/bats-core).
|
||||||
|
|
||||||
|
### Running Tests Locally
|
||||||
|
|
||||||
|
To run the tests locally, execute the test runner script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tests/run_tests.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This script will automatically:
|
||||||
|
1. Install BATS and required dependencies if not already present
|
||||||
|
2. Run all unit tests
|
||||||
|
3. Run plugin validation tests
|
||||||
|
4. Run integration tests
|
||||||
|
|
||||||
|
### Test Structure
|
||||||
|
|
||||||
|
The test suite is organized into three main categories:
|
||||||
|
|
||||||
|
- **`tests/unit_tests.bats`** - Unit tests for bash functions in `entrypoint.sh`
|
||||||
|
- Tests for `_git_setup()` function with different identity configurations
|
||||||
|
- Tests for `_git_changed()` function for detecting file changes
|
||||||
|
|
||||||
|
- **`tests/plugin_validation_tests.bats`** - Tests for Prettier plugin validation logic
|
||||||
|
- Validates official `@prettier/plugin-*` format
|
||||||
|
- Validates community `prettier-plugin-*` format
|
||||||
|
- Validates scoped `@scope/prettier-plugin-*` format
|
||||||
|
- Ensures invalid plugin names are rejected
|
||||||
|
|
||||||
|
- **`tests/integration_tests.bats`** - Integration tests for end-to-end workflows
|
||||||
|
- Tests working directory handling
|
||||||
|
- Tests node_modules cleanup
|
||||||
|
- Tests package-lock.json restoration
|
||||||
|
- Tests file filtering for `only_changed` mode
|
||||||
|
- Tests dry run behavior
|
||||||
|
|
||||||
|
### Manual BATS Installation
|
||||||
|
|
||||||
|
If you prefer to install BATS manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
./run_tests.sh --install-only
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run individual test files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tests/bats/bin/bats tests/unit_tests.bats
|
||||||
|
./tests/bats/bin/bats tests/plugin_validation_tests.bats
|
||||||
|
./tests/bats/bin/bats tests/integration_tests.bats
|
||||||
|
```
|
||||||
|
|
||||||
|
### Continuous Integration
|
||||||
|
|
||||||
|
Tests are automatically run on every push and pull request via GitHub Actions. See [`.github/workflows/test.yml`](.github/workflows/test.yml) for the CI configuration.
|
||||||
|
|
||||||
|
The CI workflow includes:
|
||||||
|
- Unit tests
|
||||||
|
- Plugin validation tests
|
||||||
|
- Integration tests
|
||||||
|
- End-to-end action testing in dry mode
|
||||||
|
- ShellCheck linting for bash scripts
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
Please report all bugs and feature request using the [GitHub issues function](https://github.com/creyD/prettier_action/issues/new). Thanks!
|
Please report all bugs and feature request using the [GitHub issues function](https://github.com/creyD/prettier_action/issues/new). Thanks!
|
||||||
|
|||||||
195
tests/integration_tests.bats
Normal file
195
tests/integration_tests.bats
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
# Integration tests for prettier_action
|
||||||
|
# These tests verify the overall behavior of the action
|
||||||
|
|
||||||
|
load 'test_helper'
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
setup_test_repo
|
||||||
|
mock_github_env
|
||||||
|
set_default_inputs
|
||||||
|
export SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_DIRNAME}")" && pwd)"
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
teardown_test_repo
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Action sets correct working directory when not specified" {
|
||||||
|
export INPUT_WORKING_DIRECTORY=""
|
||||||
|
export GITHUB_ACTION_PATH="/test/path"
|
||||||
|
|
||||||
|
# We'll test that the directory change logic works correctly
|
||||||
|
# by verifying the default assignment
|
||||||
|
result=$(bash -c '
|
||||||
|
INPUT_WORKING_DIRECTORY=""
|
||||||
|
GITHUB_ACTION_PATH="/test/path"
|
||||||
|
if [ -z "$INPUT_WORKING_DIRECTORY" ]; then
|
||||||
|
INPUT_WORKING_DIRECTORY=$GITHUB_ACTION_PATH
|
||||||
|
fi
|
||||||
|
echo "$INPUT_WORKING_DIRECTORY"
|
||||||
|
')
|
||||||
|
|
||||||
|
[ "$result" = "/test/path" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Action preserves working directory when specified" {
|
||||||
|
export INPUT_WORKING_DIRECTORY="/custom/path"
|
||||||
|
|
||||||
|
result=$(bash -c '
|
||||||
|
INPUT_WORKING_DIRECTORY="/custom/path"
|
||||||
|
GITHUB_ACTION_PATH="/test/path"
|
||||||
|
if [ -z "$INPUT_WORKING_DIRECTORY" ]; then
|
||||||
|
INPUT_WORKING_DIRECTORY=$GITHUB_ACTION_PATH
|
||||||
|
fi
|
||||||
|
echo "$INPUT_WORKING_DIRECTORY"
|
||||||
|
')
|
||||||
|
|
||||||
|
[ "$result" = "/custom/path" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Clean node folder removes node_modules when it exists" {
|
||||||
|
# Create node_modules directory
|
||||||
|
mkdir -p node_modules
|
||||||
|
echo "test" > node_modules/test.txt
|
||||||
|
|
||||||
|
# Simulate the clean logic
|
||||||
|
INPUT_CLEAN_NODE_FOLDER=true
|
||||||
|
if $INPUT_CLEAN_NODE_FOLDER; then
|
||||||
|
if [ -d 'node_modules' ]; then
|
||||||
|
rm -r node_modules/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify node_modules was removed
|
||||||
|
[ ! -d "node_modules" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Clean node folder handles missing node_modules gracefully" {
|
||||||
|
# Ensure no node_modules exists
|
||||||
|
[ ! -d "node_modules" ]
|
||||||
|
|
||||||
|
# Simulate the clean logic
|
||||||
|
INPUT_CLEAN_NODE_FOLDER=true
|
||||||
|
run bash -c '
|
||||||
|
if $INPUT_CLEAN_NODE_FOLDER; then
|
||||||
|
if [ -d "node_modules" ]; then
|
||||||
|
rm -r node_modules/
|
||||||
|
echo "Deleted"
|
||||||
|
else
|
||||||
|
echo "No node_modules/ folder."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" =~ "No node_modules/ folder." ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Package-lock.json is restored when it exists" {
|
||||||
|
# Create a package-lock.json and commit it
|
||||||
|
echo '{"name": "test"}' > package-lock.json
|
||||||
|
git add package-lock.json
|
||||||
|
git commit -m "Add package-lock.json"
|
||||||
|
|
||||||
|
# Modify it
|
||||||
|
echo '{"name": "modified"}' > package-lock.json
|
||||||
|
|
||||||
|
# Restore it using git checkout
|
||||||
|
git checkout -- package-lock.json
|
||||||
|
|
||||||
|
# Verify it was restored
|
||||||
|
content=$(cat package-lock.json)
|
||||||
|
[[ "$content" =~ '"name": "test"' ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Package-lock.json restore handles missing file gracefully" {
|
||||||
|
# Ensure no package-lock.json exists
|
||||||
|
[ ! -f "package-lock.json" ]
|
||||||
|
|
||||||
|
# Try to restore (should not fail)
|
||||||
|
run bash -c '
|
||||||
|
if [ -f "package-lock.json" ]; then
|
||||||
|
git checkout -- package-lock.json || echo "No package-lock.json file tracked by git."
|
||||||
|
else
|
||||||
|
echo "No package-lock.json file."
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[[ "$output" =~ "No package-lock.json file." ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "File pattern logic for only_changed mode filters correctly" {
|
||||||
|
# Create initial commit
|
||||||
|
echo "file1" > file1.txt
|
||||||
|
echo "file2" > file2.txt
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial commit"
|
||||||
|
|
||||||
|
# Modify only file1
|
||||||
|
echo "modified" > file1.txt
|
||||||
|
git add file1.txt
|
||||||
|
git commit -m "Modify file1"
|
||||||
|
|
||||||
|
# Modify both files
|
||||||
|
echo "changed1" > file1.txt
|
||||||
|
echo "changed2" > file2.txt
|
||||||
|
|
||||||
|
# Get files changed in previous commit
|
||||||
|
git diff --name-only HEAD HEAD~1 > /tmp/prev.txt
|
||||||
|
|
||||||
|
# Get files with current changes
|
||||||
|
git diff --name-only HEAD > /tmp/cur.txt
|
||||||
|
|
||||||
|
# Verify file1.txt is in prev.txt (it was changed in last commit)
|
||||||
|
run grep "file1.txt" /tmp/prev.txt
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# Verify both files are in cur.txt (both have current changes)
|
||||||
|
run grep "file1.txt" /tmp/cur.txt
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
run grep "file2.txt" /tmp/cur.txt
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# Files in cur.txt but not in prev.txt should be reset
|
||||||
|
# In this case, file2.txt should be reset
|
||||||
|
for file in $(comm -1 -3 /tmp/prev.txt /tmp/cur.txt); do
|
||||||
|
[ "$file" = "file2.txt" ]
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Dry run mode detects unpretty files" {
|
||||||
|
# This tests the logic flow for dry run
|
||||||
|
# We simulate detecting changes
|
||||||
|
|
||||||
|
# Create a test file
|
||||||
|
echo "test" > test.txt
|
||||||
|
|
||||||
|
# Simulate git detecting changes
|
||||||
|
run bash -c '
|
||||||
|
source tests/test_helper.bash
|
||||||
|
setup_test_repo
|
||||||
|
echo "test" > test.txt
|
||||||
|
_git_changed
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "No changes scenario is handled correctly" {
|
||||||
|
# Create and commit a file
|
||||||
|
echo "test" > test.txt
|
||||||
|
git add test.txt
|
||||||
|
git commit -m "Add test file"
|
||||||
|
|
||||||
|
# Verify no changes
|
||||||
|
run bash -c '
|
||||||
|
source tests/test_helper.bash
|
||||||
|
load_script_functions entrypoint.sh
|
||||||
|
_git_changed
|
||||||
|
'
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
99
tests/plugin_validation_tests.bats
Normal file
99
tests/plugin_validation_tests.bats
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
# Integration tests for prettier plugin validation
|
||||||
|
|
||||||
|
load 'test_helper'
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
setup_test_repo
|
||||||
|
mock_github_env
|
||||||
|
set_default_inputs
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
teardown_test_repo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test valid prettier plugin patterns
|
||||||
|
@test "Valid @prettier/plugin-* format should pass validation" {
|
||||||
|
# Test the regex pattern used in entrypoint.sh
|
||||||
|
plugin="@prettier/plugin-php"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Valid prettier-plugin-* format should pass validation" {
|
||||||
|
plugin="prettier-plugin-java"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Valid @scope/prettier-plugin-* format should pass validation" {
|
||||||
|
plugin="@company/prettier-plugin-custom"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Invalid plugin name should fail validation" {
|
||||||
|
plugin="some-random-package"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Invalid plugin with wrong prefix should fail validation" {
|
||||||
|
plugin="@other/plugin-something"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Multiple valid plugins should all pass validation" {
|
||||||
|
plugins="@prettier/plugin-php prettier-plugin-java @scope/prettier-plugin-custom"
|
||||||
|
|
||||||
|
for plugin in $plugins; do
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Plugin name with uppercase should fail validation" {
|
||||||
|
plugin="@prettier/plugin-PHP"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Plugin name with numbers or underscores should fail validation" {
|
||||||
|
plugin1="@prettier/plugin-test123"
|
||||||
|
plugin2="prettier-plugin-test_name"
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin1' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
|
||||||
|
run bash -c "echo '$plugin2' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Official prettier plugins should be recognized" {
|
||||||
|
# List of known official prettier plugins
|
||||||
|
plugins=(
|
||||||
|
"@prettier/plugin-php"
|
||||||
|
"@prettier/plugin-ruby"
|
||||||
|
"@prettier/plugin-xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
for plugin in "${plugins[@]}"; do
|
||||||
|
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
done
|
||||||
|
}
|
||||||
115
tests/run_tests.sh
Executable file
115
tests/run_tests.sh
Executable file
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Test runner script for prettier_action
|
||||||
|
# This script installs BATS and runs all tests
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
BATS_VERSION="v1.11.0"
|
||||||
|
BATS_INSTALL_DIR="$SCRIPT_DIR/bats"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo "========================================="
|
||||||
|
echo "Prettier Action Test Runner"
|
||||||
|
echo "========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Function to install BATS
|
||||||
|
install_bats() {
|
||||||
|
echo -e "${YELLOW}Installing BATS (Bash Automated Testing System)...${NC}"
|
||||||
|
|
||||||
|
if [ -d "$BATS_INSTALL_DIR" ]; then
|
||||||
|
echo "BATS already installed at $BATS_INSTALL_DIR"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clone BATS
|
||||||
|
git clone --depth 1 --branch "$BATS_VERSION" https://github.com/bats-core/bats-core.git "$BATS_INSTALL_DIR"
|
||||||
|
|
||||||
|
# Clone support libraries
|
||||||
|
mkdir -p "$BATS_INSTALL_DIR/test_helper"
|
||||||
|
git clone --depth 1 https://github.com/bats-core/bats-support.git "$BATS_INSTALL_DIR/test_helper/bats-support"
|
||||||
|
git clone --depth 1 https://github.com/bats-core/bats-assert.git "$BATS_INSTALL_DIR/test_helper/bats-assert"
|
||||||
|
|
||||||
|
echo -e "${GREEN}BATS installed successfully!${NC}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if BATS is available
|
||||||
|
check_bats() {
|
||||||
|
if [ -x "$BATS_INSTALL_DIR/bin/bats" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Check if BATS is installed, if not install it
|
||||||
|
if ! check_bats; then
|
||||||
|
install_bats
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Running tests...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run all test files
|
||||||
|
TEST_FILES=(
|
||||||
|
"$SCRIPT_DIR/unit_tests.bats"
|
||||||
|
"$SCRIPT_DIR/plugin_validation_tests.bats"
|
||||||
|
"$SCRIPT_DIR/integration_tests.bats"
|
||||||
|
)
|
||||||
|
|
||||||
|
FAILED=0
|
||||||
|
|
||||||
|
for test_file in "${TEST_FILES[@]}"; do
|
||||||
|
if [ -f "$test_file" ]; then
|
||||||
|
echo "Running $(basename "$test_file")..."
|
||||||
|
if "$BATS_INSTALL_DIR/bin/bats" "$test_file"; then
|
||||||
|
echo -e "${GREEN}✓ $(basename "$test_file") passed${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ $(basename "$test_file") failed${NC}"
|
||||||
|
FAILED=1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "========================================="
|
||||||
|
if [ $FAILED -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}All tests passed!${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}Some tests failed!${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command line arguments
|
||||||
|
case "${1:-}" in
|
||||||
|
--install-only)
|
||||||
|
install_bats
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--help)
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " --install-only Only install BATS without running tests"
|
||||||
|
echo " --help Show this help message"
|
||||||
|
echo ""
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
main
|
||||||
|
;;
|
||||||
|
esac
|
||||||
78
tests/test_helper.bash
Normal file
78
tests/test_helper.bash
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Test helper functions for prettier_action tests
|
||||||
|
|
||||||
|
# Set up a temporary test directory
|
||||||
|
setup_test_repo() {
|
||||||
|
export TEST_TEMP_DIR="$(mktemp -d)"
|
||||||
|
cd "$TEST_TEMP_DIR" || exit 1
|
||||||
|
git init
|
||||||
|
git config user.name "Test User"
|
||||||
|
git config user.email "test@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean up temporary test directory
|
||||||
|
teardown_test_repo() {
|
||||||
|
if [ -n "$TEST_TEMP_DIR" ] && [ -d "$TEST_TEMP_DIR" ]; then
|
||||||
|
rm -rf "$TEST_TEMP_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a sample file for testing
|
||||||
|
create_sample_file() {
|
||||||
|
local filename="${1:-test.js}"
|
||||||
|
local content="${2:-const x=1;const y=2;}"
|
||||||
|
echo "$content" > "$filename"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a sample package.json
|
||||||
|
create_package_json() {
|
||||||
|
cat > package.json << 'EOF'
|
||||||
|
{
|
||||||
|
"name": "test-project",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Test project"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mock git environment variables for GitHub Actions
|
||||||
|
mock_github_env() {
|
||||||
|
export GITHUB_ACTOR="${GITHUB_ACTOR:-test-actor}"
|
||||||
|
export GITHUB_ACTOR_ID="${GITHUB_ACTOR_ID:-12345}"
|
||||||
|
export GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH:-/app}"
|
||||||
|
export GITHUB_BASE_REF="${GITHUB_BASE_REF:-main}"
|
||||||
|
export GITHUB_STEP_SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/null}"
|
||||||
|
export INPUT_GITHUB_TOKEN="${INPUT_GITHUB_TOKEN:-test-token}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set default input environment variables
|
||||||
|
set_default_inputs() {
|
||||||
|
export INPUT_WORKING_DIRECTORY="${INPUT_WORKING_DIRECTORY:-}"
|
||||||
|
export INPUT_PRETTIER_VERSION="${INPUT_PRETTIER_VERSION:-latest}"
|
||||||
|
export INPUT_PRETTIER_OPTIONS="${INPUT_PRETTIER_OPTIONS:---write **/*.js}"
|
||||||
|
export INPUT_PRETTIER_PLUGINS="${INPUT_PRETTIER_PLUGINS:-}"
|
||||||
|
export INPUT_ALLOW_OTHER_PLUGINS="${INPUT_ALLOW_OTHER_PLUGINS:-false}"
|
||||||
|
export INPUT_CLEAN_NODE_FOLDER="${INPUT_CLEAN_NODE_FOLDER:-true}"
|
||||||
|
export INPUT_ONLY_CHANGED="${INPUT_ONLY_CHANGED:-false}"
|
||||||
|
export INPUT_ONLY_CHANGED_PR="${INPUT_ONLY_CHANGED_PR:-false}"
|
||||||
|
export INPUT_FILE_PATTERN="${INPUT_FILE_PATTERN:-*}"
|
||||||
|
export INPUT_DRY="${INPUT_DRY:-false}"
|
||||||
|
export INPUT_NO_COMMIT="${INPUT_NO_COMMIT:-false}"
|
||||||
|
export INPUT_SAME_COMMIT="${INPUT_SAME_COMMIT:-false}"
|
||||||
|
export INPUT_COMMIT_MESSAGE="${INPUT_COMMIT_MESSAGE:-Automated formatting}"
|
||||||
|
export INPUT_COMMIT_DESCRIPTION="${INPUT_COMMIT_DESCRIPTION:-}"
|
||||||
|
export INPUT_COMMIT_OPTIONS="${INPUT_COMMIT_OPTIONS:-}"
|
||||||
|
export INPUT_PUSH_OPTIONS="${INPUT_PUSH_OPTIONS:-}"
|
||||||
|
export INPUT_GIT_IDENTITY="${INPUT_GIT_IDENTITY:-actions}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load a bash script without executing it (for testing functions)
|
||||||
|
load_script_functions() {
|
||||||
|
local script_path="$1"
|
||||||
|
# Source only the function definitions, not the main program
|
||||||
|
# We extract functions by finding lines between function definitions and the main program block
|
||||||
|
sed -n '/^_git_setup/,/^}/p' "$script_path" > "$TEST_TEMP_DIR/functions.sh"
|
||||||
|
sed -n '/^_git_changed/,/^}/p' "$script_path" >> "$TEST_TEMP_DIR/functions.sh"
|
||||||
|
source "$TEST_TEMP_DIR/functions.sh"
|
||||||
|
}
|
||||||
124
tests/unit_tests.bats
Normal file
124
tests/unit_tests.bats
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
# Unit tests for prettier_action entrypoint.sh functions
|
||||||
|
|
||||||
|
load 'test_helper'
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
setup_test_repo
|
||||||
|
mock_github_env
|
||||||
|
set_default_inputs
|
||||||
|
|
||||||
|
# Load the functions from entrypoint.sh
|
||||||
|
export SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_DIRNAME}")" && pwd)"
|
||||||
|
load_script_functions "$SCRIPT_DIR/entrypoint.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
teardown_test_repo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test _git_setup function with 'actions' identity
|
||||||
|
@test "_git_setup creates .netrc file with correct permissions" {
|
||||||
|
export INPUT_GIT_IDENTITY="actions"
|
||||||
|
|
||||||
|
run _git_setup
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ -f "$HOME/.netrc" ]
|
||||||
|
|
||||||
|
# Check file permissions (should be 600)
|
||||||
|
local perms=$(stat -c "%a" "$HOME/.netrc")
|
||||||
|
[ "$perms" = "600" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_setup configures git with 'actions' identity" {
|
||||||
|
export INPUT_GIT_IDENTITY="actions"
|
||||||
|
|
||||||
|
run _git_setup
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# Check git config
|
||||||
|
local git_name=$(git config --global user.name)
|
||||||
|
local git_email=$(git config --global user.email)
|
||||||
|
|
||||||
|
[ "$git_name" = "GitHub Action" ]
|
||||||
|
[ "$git_email" = "actions@github.com" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_setup configures git with 'author' identity" {
|
||||||
|
export INPUT_GIT_IDENTITY="author"
|
||||||
|
export GITHUB_ACTOR="test-user"
|
||||||
|
export GITHUB_ACTOR_ID="54321"
|
||||||
|
|
||||||
|
run _git_setup
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# Check git config
|
||||||
|
local git_name=$(git config --global user.name)
|
||||||
|
local git_email=$(git config --global user.email)
|
||||||
|
|
||||||
|
[ "$git_name" = "test-user" ]
|
||||||
|
[ "$git_email" = "54321+test-user@users.noreply.github.com" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_setup fails with invalid identity" {
|
||||||
|
export INPUT_GIT_IDENTITY="invalid"
|
||||||
|
|
||||||
|
run _git_setup
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
[[ "$output" =~ "GIT_IDENTITY must be either 'author' or 'actions'" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_changed returns true when files are modified" {
|
||||||
|
# Create and commit a file
|
||||||
|
echo "test" > test.txt
|
||||||
|
git add test.txt
|
||||||
|
git commit -m "Initial commit"
|
||||||
|
|
||||||
|
# Modify the file
|
||||||
|
echo "modified" > test.txt
|
||||||
|
|
||||||
|
run _git_changed
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_changed returns false when no files are modified" {
|
||||||
|
# Create and commit a file
|
||||||
|
echo "test" > test.txt
|
||||||
|
git add test.txt
|
||||||
|
git commit -m "Initial commit"
|
||||||
|
|
||||||
|
# No modifications
|
||||||
|
run _git_changed
|
||||||
|
|
||||||
|
[ "$status" -eq 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_changed returns true for untracked files" {
|
||||||
|
# Create a file without committing
|
||||||
|
echo "test" > untracked.txt
|
||||||
|
|
||||||
|
run _git_changed
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "_git_changed returns true for staged files" {
|
||||||
|
# Create and commit a file
|
||||||
|
echo "test" > test.txt
|
||||||
|
git add test.txt
|
||||||
|
git commit -m "Initial commit"
|
||||||
|
|
||||||
|
# Add a new file and stage it
|
||||||
|
echo "new file" > new.txt
|
||||||
|
git add new.txt
|
||||||
|
|
||||||
|
run _git_changed
|
||||||
|
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user