Skip to content

Commit

Permalink
[#110] Added init script to make onboarding easier (#132)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Skrypnyk <alex@drevops.com>
  • Loading branch information
tannguyen04 and AlexSkrypnyk authored May 1, 2024
1 parent 0333c85 commit 679ed14
Show file tree
Hide file tree
Showing 13 changed files with 801 additions and 88 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/test-scaffold.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,37 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2

- name: Check coding standards
uses: luizm/action-sh-checker@v0.8.0
env:
SHFMT_OPTS: -i 2 -ci -s -d

- name: Setup Node.js
uses: actions/setup-node@v4

- name: Setup kcov
run: wget https://github.com/SimonKagstrom/kcov/releases/download/v42/kcov-amd64.tar.gz && tar -xf kcov-amd64.tar.gz && sudo mv ./usr/local/bin/kcov /usr/local/bin/kcov && kcov --version

- name: Install dependencies
run: npm ci
working-directory: .scaffold/tests

- name: Run tests
run: kcov --include-pattern=.sh,.bash --bash-parse-files-in-dir=. --exclude-pattern=vendor,node_modules,.scaffold-coverage-html "$(pwd)"/.scaffold-coverage-html .scaffold/tests/node_modules/.bin/bats .scaffold/tests/bats

- name: Upload coverage report as an artifact
uses: actions/upload-artifact@v4
with:
name: ${{github.job}}-code-coverage-report
path: ./.scaffold-coverage-html
if-no-files-found: error

# - name: Upload coverage report to Codecov
# uses: codecov/codecov-action@v4
# with:
# directory: ./.scaffold-coverage-html
# fail_ci_if_error: true
# token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions .scaffold/tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/coverage
136 changes: 136 additions & 0 deletions .scaffold/tests/bats/_assert_init.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
#
# Scaffold template assertions.
#

# This file structure should exist in every project type.
assert_files_present_common() {
local dir="${1:-$(pwd)}"

pushd "${dir}" >/dev/null || exit 1

# Assert that some files must be exist.
assert_file_exists "force_crystal.info.yml"
assert_file_exists "phpcs.xml"
assert_file_exists "phpmd.xml"
assert_file_exists "phpstan.neon"
assert_file_exists ".editorconfig"
assert_file_exists ".gitattributes"
assert_file_exists ".gitignore"
assert_file_exists "README.md"
assert_file_exists "logo.png"

# Assert that some files must not be exist.
assert_file_not_exists "README.dist.md"
assert_file_not_exists "logo.tmp.png"
assert_file_not_exists "LICENSE"
assert_file_not_exists ".github/workflows/test-scaffold.yml"

# Assert some dirs/files must not be exist.
assert_dir_not_exists ".scaffold"

# Assert that .gitignore were processed correctly.
assert_file_contains ".gitignore" "composer.lock"
assert_file_contains ".gitignore" "build"
assert_file_not_contains ".gitignore" "/coverage"

# Assert that documentation was processed correctly.
assert_file_not_contains README.md "META"

# Assert that .gitattributes were processed correctly.
assert_file_contains ".gitattributes" ".editorconfig"
assert_file_not_contains ".gitattributes" "# .editorconfig"
assert_file_contains ".gitattributes" ".gitattributes"
assert_file_not_contains ".gitattributes" "# .gitattributes"
assert_file_contains ".gitattributes" ".github"
assert_file_not_contains ".gitattributes" "# .github"
assert_file_contains ".gitattributes" ".gitignore"
assert_file_not_contains ".gitattributes" "# .gitignore"
assert_file_not_contains ".gitattributes" "# Uncomment the lines below in your project."
assert_file_contains ".gitattributes" "tests"
assert_file_contains ".gitattributes" "phpcs.xml"
assert_file_contains ".gitattributes" "phpmd.xml"
assert_file_contains ".gitattributes" "phpstan.neon"
assert_file_not_contains ".gitattributes" "# tests"
assert_file_not_contains ".gitattributes" "# phpcs.xml"
assert_file_not_contains ".gitattributes" "# phpmd.xml"
assert_file_not_contains ".gitattributes" "# phpstan.neon"

# Assert that composer.json were processed correctly.
assert_file_contains "composer.json" '"name": "drupal/force_crystal"'
assert_file_contains "composer.json" '"description": "Provides force_crystal functionality."'
assert_file_contains "composer.json" '"homepage": "https://drupal.org/project/force_crystal"'
assert_file_contains "composer.json" '"issues": "https://drupal.org/project/issues/force_crystal"'
assert_file_contains "composer.json" '"source": "https://git.drupalcode.org/project/force_crystal"'

# Assert that extension info file were processed correctly.
assert_file_contains "force_crystal.info.yml" 'name: Force Crystal'

# Assert other things.
assert_dir_not_contains_string "${dir}" "your_extension"
assert_dir_contains_string "${dir}" "YodasHut"

popd >/dev/null || exit 1
}

assert_files_present_extension_type_module() {
local dir="${1:-$(pwd)}"

pushd "${dir}" >/dev/null || exit 1

# Assert that extension info file were processed correctly.
assert_file_contains "force_crystal.info.yml" 'type: module'
assert_file_not_contains "force_crystal.info.yml" 'type: theme'
assert_file_not_contains "force_crystal.info.yml" 'base theme: false'

# Assert that composer.json file were processed correctly.
assert_file_contains "composer.json" '"type": "drupal-module"'

# Assert some dirs/files must be exist.
assert_dir_exists "tests/src/Unit"
assert_dir_exists "tests/src/Functional"

popd >/dev/null || exit 1
}

assert_files_present_extension_type_theme() {
local dir="${1:-$(pwd)}"

pushd "${dir}" >/dev/null || exit 1

# Assert that extension info file were processed correctly.
assert_file_contains "force_crystal.info.yml" 'type: theme'
assert_file_contains "force_crystal.info.yml" 'base theme: false'
assert_file_not_contains "force_crystal.info.yml" 'type: module'

# Assert that composer.json file were processed correctly.
assert_file_contains "composer.json" '"type": "drupal-theme"'

# Assert some dirs/files must not be exist.
assert_dir_not_exists "tests/src/Unit"
assert_dir_not_exists "tests/src/Functional"

popd >/dev/null || exit 1
}

assert_workflow() {
local dir="${1:-$(pwd)}"

pushd "${dir}" >/dev/null || exit 1

./.devtools/build-codebase.sh

# Lint.
pushd "build" >/dev/null || exit 1
vendor/bin/phpcs
vendor/bin/phpstan
vendor/bin/rector --clear-cache --dry-run
vendor/bin/phpmd . text phpmd.xml
vendor/bin/twigcs
popd >/dev/null || exit 1

# Change mode to make bats have enough permission to clean tmp test directory.
chmod -R 777 "build/web/sites/default"

popd >/dev/null || exit 1
}
61 changes: 61 additions & 0 deletions .scaffold/tests/bats/_helper.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
#
# Helpers related to common testing functionality.
#
# Run with "--verbose-run" to see debug output.
#

################################################################################
# BATS HOOK IMPLEMENTATIONS #
################################################################################

setup() {
[ ! -d ".git" ] && echo "Tests must be run from the repository root directory." && exit 1

# For a list of available variables see:
# @see https://bats-core.readthedocs.io/en/stable/writing-tests.html#special-variables

# Register a path to libraries.
export BATS_LIB_PATH="${BATS_TEST_DIRNAME}/../node_modules"

# Load 'bats-helpers' library.
bats_load_library bats-helpers

# Setup command mocking.
setup_mock

# Current directory where the test is run from.
# shellcheck disable=SC2155
export CUR_DIR="$(pwd)"

# Project directory root (where .git is located).
export ROOT_DIR="${CUR_DIR}"

# Directory where the shell command script will be running in.
export BUILD_DIR="${BUILD_DIR:-"${BATS_TEST_TMPDIR//\/\//\/}/scaffold-$(date +%s)"}"
fixture_prepare_dir "${BUILD_DIR}"

# Copy codebase at the last commit into the BUILD_DIR.
# Tests requiring to work with the copy of the codebase should opt-in using
# BATS_FIXTURE_EXPORT_CODEBASE_ENABLED=1.
# Note that during development of tests the local changes need to be
# committed.
fixture_export_codebase "${BUILD_DIR}" "${ROOT_DIR}"

# Print debug information if "--verbose-run" is passed.
# LCOV_EXCL_START
if [ "${BATS_VERBOSE_RUN-}" = "1" ]; then
echo "BUILD_DIR: ${BUILD_DIR}" >&3
fi
# LCOV_EXCL_END

# Change directory to the current project directory for each test. Tests
# requiring to operate outside of BUILD_DIR should change directory explicitly
# within their tests.
pushd "${BUILD_DIR}" >/dev/null || exit 1
}

teardown() {
# Move back to the original directory.
popd >/dev/null || cd "${CUR_DIR}" || exit 1
}
117 changes: 117 additions & 0 deletions .scaffold/tests/bats/functional.init.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env bats
#
# Functional tests for init.sh.
#
# Example usage:
# ./.scaffold/tests/node_modules/.bin/bats --no-tempdir-cleanup --formatter tap --filter-tags smoke .scaffold/tests
#
# shellcheck disable=SC2030,SC2031,SC2129

load _helper
load _assert_init

export BATS_FIXTURE_EXPORT_CODEBASE_ENABLED=1
export SCRIPT_FILE="init.sh"

# bats test_tags=smoke
@test "Init, defaults - extension module, workflow" {
answers=(
"YodasHut" # namespace
"Force Crystal" # name
"force_crystal" # machine_name
"module" # type
"GitHub Actions" # ci_provider
"nothing" # remove init script
"nothing" # proceed with init
)
tui_run "${answers[@]}"

assert_output_contains "Please follow the prompts to adjust your extension configuration"
assert_files_present_common "${BUILD_DIR}"
assert_files_present_extension_type_module "${BUILD_DIR}"
assert_file_not_exists ".circleci/config.yml"
assert_output_contains "Initialization complete."

assert_workflow "${BUILD_DIR}"
}

# bats test_tags=smoke
@test "Init, extension theme, workflow" {
answers=(
"YodasHut" # namespace
"Force Crystal" # name
"force_crystal" # machine_name
"theme" # type
"GitHub Actions" # ci_provider
"nothing" # remove init script
"nothing" # proceed with init
)
tui_run "${answers[@]}"

assert_output_contains "Please follow the prompts to adjust your extension configuration"
assert_files_present_common "${BUILD_DIR}"
assert_files_present_extension_type_theme "${BUILD_DIR}"
assert_file_not_exists ".circleci/config.yml"
assert_output_contains "Initialization complete."

assert_workflow "${BUILD_DIR}"
}

# bats test_tags=smoke
@test "Init, CircleCI" {
answers=(
"YodasHut" # namespace
"Force Crystal" # name
"force_crystal" # machine_name
"module" # type
"CircleCI" # ci_provider
"nothing" # remove init script
"nothing" # proceed with init
)
tui_run "${answers[@]}"

assert_output_contains "Please follow the prompts to adjust your extension configuration"
assert_files_present_common "${BUILD_DIR}"
assert_files_present_extension_type_module "${BUILD_DIR}"
assert_file_exists ".circleci/config.yml"
assert_dir_not_exists ".github/workflows"
assert_output_contains "Initialization complete."
}

@test "Init, do not remove script" {
answers=(
"YodasHut" # namespace
"Force Crystal" # name
"force_crystal" # machine_name
"module" # type
"CircleCI" # ci_provider
"n" # remove init script
"nothing" # proceed with init
)
tui_run "${answers[@]}"

assert_output_contains "Please follow the prompts to adjust your extension configuration"
assert_files_present_common "${BUILD_DIR}"
assert_files_present_extension_type_module "${BUILD_DIR}"
assert_file_exists "init.sh"
assert_output_contains "Initialization complete."
}

@test "Init, remove script" {
answers=(
"YodasHut" # namespace
"Force Crystal" # name
"force_crystal" # machine_name
"module" # type
"CircleCI" # ci_provider
"y" # remove init script
"nothing" # proceed with init
)
tui_run "${answers[@]}"

assert_output_contains "Please follow the prompts to adjust your extension configuration"
assert_files_present_common "${BUILD_DIR}"
assert_files_present_extension_type_module "${BUILD_DIR}"
assert_file_not_exists "init.sh"
assert_output_contains "Initialization complete."
}
13 changes: 13 additions & 0 deletions .scaffold/tests/bats/smoke.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bats
#
# Smoke tests.
#
# shellcheck disable=SC2030,SC2031,SC2129

load _helper

# ./tests/scaffold/node_modules/.bin/bats --no-tempdir-cleanup --formatter tap --filter-tags smoke tests/scaffold
# bats test_tags=smoke
@test "Smoke" {
assert_contains "scaffold" "${BUILD_DIR}"
}
19 changes: 19 additions & 0 deletions .scaffold/tests/bats/unit.init.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bats
#
# Unit tests for init.sh.
#
# shellcheck disable=SC2034

load _helper
load "../../../init.sh"

@test "Test all conversions" {
input="I am a_string-With spaces 13"

TEST_CASES=(
"$input" "file_name" "i_am_a_string-with_spaces_13"
"$input" "route_path" "i_am_a_string-with_spaces_13"
)

dataprovider_run "convert_string" 3
}
Loading

1 comment on commit 679ed14

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.