#!/usr/bin/env bash # Unit tests for lib/parse.sh TESTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(dirname "$TESTS_DIR")" FIXTURES="$TESTS_DIR/fixtures" source "$TESTS_DIR/framework.sh" source "$ROOT_DIR/lib/colors.sh" source "$ROOT_DIR/lib/parse.sh" # --------------------------------------------------------------------------- suite "parse: basic variable" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/basic.env.example" assert_eq "1" "${#ENV_VARS[@]}" "finds exactly one variable" assert_eq "BASIC_VAR" "${ENV_VARS[0]}" "correct variable name" assert_eq "default" "$ENV_DEFAULT_BASIC_VAR" "correct default value" assert_eq "true" "$ENV_REQUIRED_BASIC_VAR" "required flag set" assert_eq "Description" "$ENV_DESC_BASIC_VAR" "description captured" assert_eq "string" "$ENV_TYPE_BASIC_VAR" "type defaults to string" # --------------------------------------------------------------------------- suite "parse: all type annotations" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/all_types.env.example" assert_eq "string" "$ENV_TYPE_STR_VAR" "explicit string type" assert_eq "number" "$ENV_TYPE_NUM_VAR" "number type" assert_eq "bool" "$ENV_TYPE_BOOL_VAR" "bool type" assert_eq "secret" "$ENV_TYPE_SECRET_VAR" "secret type" assert_eq "url" "$ENV_TYPE_URL_VAR" "url type" assert_eq "email" "$ENV_TYPE_EMAIL_VAR" "email type" assert_eq "enum:a,b,c" "$ENV_TYPE_ENUM_VAR" "enum type with options" assert_eq "true" "$ENV_REQUIRED_SECRET_VAR" "required annotation on secret" assert_eq "false" "$ENV_REQUIRED_STR_VAR" "non-required defaults to false" assert_eq "42" "$ENV_DEFAULT_NUM_VAR" "numeric default" assert_eq "https://example.com" "$ENV_DEFAULT_URL_VAR" "URL default" assert_empty "$ENV_DEFAULT_SECRET_VAR" "empty default preserved" # --------------------------------------------------------------------------- suite "parse: variable order preserved" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/all_types.env.example" assert_eq "7" "${#ENV_VARS[@]}" "all seven variables found" assert_eq "STR_VAR" "${ENV_VARS[0]}" "first variable" assert_eq "NUM_VAR" "${ENV_VARS[1]}" "second variable" assert_eq "BOOL_VAR" "${ENV_VARS[2]}" "third variable" assert_eq "SECRET_VAR" "${ENV_VARS[3]}" "fourth variable" assert_eq "URL_VAR" "${ENV_VARS[4]}" "fifth variable" assert_eq "EMAIL_VAR" "${ENV_VARS[5]}" "sixth variable" assert_eq "ENUM_VAR" "${ENV_VARS[6]}" "seventh variable" # --------------------------------------------------------------------------- suite "parse: variable with no annotations" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/no_annotations.env.example" assert_eq "2" "${#ENV_VARS[@]}" "finds two variables" assert_eq "string" "$ENV_TYPE_PLAIN_VAR" "type defaults to string" assert_eq "false" "$ENV_REQUIRED_PLAIN_VAR" "required defaults to false" assert_empty "$ENV_DESC_PLAIN_VAR" "no description" assert_eq "value" "$ENV_DEFAULT_PLAIN_VAR" "correct default" assert_empty "$ENV_DEFAULT_ANOTHER_VAR" "empty default preserved" # --------------------------------------------------------------------------- suite "parse: multi-line description" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/multiline_desc.env.example" assert_contains "First line" "$ENV_DESC_MULTI_VAR" "first description line included" assert_contains "Second line" "$ENV_DESC_MULTI_VAR" "second description line appended" # --------------------------------------------------------------------------- suite "parse: orphaned comment block (no variable follows)" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/orphaned_comments.env.example" assert_eq "1" "${#ENV_VARS[@]}" "only one real variable found" assert_eq "REAL_VAR" "${ENV_VARS[0]}" "correct variable captured" assert_eq "value" "$ENV_DEFAULT_REAL_VAR" "correct default" # --------------------------------------------------------------------------- suite "parse: empty file" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/empty.env.example" assert_eq "0" "${#ENV_VARS[@]}" "no variables in empty file" # --------------------------------------------------------------------------- suite "parse: value containing equals signs" # --------------------------------------------------------------------------- parse_env_example "$FIXTURES/value_with_equals.env.example" assert_eq "1" "${#ENV_VARS[@]}" "one variable" assert_contains "sslmode=require" "$ENV_DEFAULT_DB_URL" "first query param preserved" assert_contains "connect_timeout=10" "$ENV_DEFAULT_DB_URL" "second query param preserved" assert_eq "url" "$ENV_TYPE_DB_URL" "type annotation on same var" # --------------------------------------------------------------------------- suite "parse: missing file returns error" # --------------------------------------------------------------------------- assert_failure "non-existent file returns non-zero" \ parse_env_example "/nonexistent/path.env.example" # --------------------------------------------------------------------------- suite "parse: real-world example.env.example" # --------------------------------------------------------------------------- parse_env_example "$ROOT_DIR/example.env.example" assert_eq "7" "${#ENV_VARS[@]}" "all 7 variables" assert_eq "APP_NAME" "${ENV_VARS[0]}" "first var is APP_NAME" assert_eq "APP_ENV" "${ENV_VARS[1]}" "second var is APP_ENV" assert_eq "true" "$ENV_REQUIRED_APP_NAME" "APP_NAME required" assert_eq "true" "$ENV_REQUIRED_APP_ENV" "APP_ENV required" assert_eq "false" "$ENV_REQUIRED_PORT" "PORT optional" assert_eq "number" "$ENV_TYPE_PORT" "PORT is number type" assert_eq "bool" "$ENV_TYPE_DEBUG" "DEBUG is bool type" assert_eq "secret" "$ENV_TYPE_JWT_SECRET" "JWT_SECRET is secret type" assert_eq "url" "$ENV_TYPE_DATABASE_URL" "DATABASE_URL is url type" assert_eq "email" "$ENV_TYPE_ADMIN_EMAIL" "ADMIN_EMAIL is email type" assert_eq "enum:development,staging,production" "$ENV_TYPE_APP_ENV" "APP_ENV enum options" print_summary