Ismo Vuorinen c5334da82f fix(ci): ensure parser is built before testing in GitHub workflows
- Add explicit parser build step before sample code testing
- Remove --scope parameter that requires parser to be compiled first
- Fix tree-sitter CLI v0.25.0 compatibility issue in CI environment

The issue was that tree-sitter CLI v0.25.0 requires the parser to be
compiled before it can recognize custom language scopes. This fix
ensures the parser is always built before attempting to parse test files,
resolving the 'Unknown scope' error in GitHub Actions.
2026-01-04 15:32:40 +02:00
2025-09-11 22:41:39 +03:00
2026-01-04 15:32:39 +02:00
2025-09-11 22:41:39 +03:00
2025-09-11 22:41:39 +03:00

tree-sitter-shellspec

Test Status Grammar Coverage Tree-sitter

A comprehensive Tree-sitter grammar for ShellSpec - a BDD (Behavior Driven Development) testing framework for POSIX shell scripts.

Overview

This grammar extends the tree-sitter-bash grammar to provide complete parsing support for ShellSpec's BDD constructs.

It enables syntax highlighting, code navigation, and tooling integration for ShellSpec test files.

Features

  • Complete ShellSpec syntax support - All block types, hooks, and utility constructs
  • Real-world compatibility - Tested against official ShellSpec examples
  • Bash integration - Seamlessly handles mixed ShellSpec/bash code
  • Production ready - 100% test coverage with 59 comprehensive test cases
  • Editor support - Works with any Tree-sitter compatible editor

Installation

Using npm

npm install @ivuorinen/tree-sitter-shellspec

Manual Installation

git clone https://github.com/ivuorinen/tree-sitter-shellspec.git
cd tree-sitter-shellspec
npm install
npm run build

Grammar Support

Block Types

Describe Blocks (Example Groups)

Describe 'Calculator functions'
  # Test cases go here
End

# Variants: Describe, fDescribe (focused), xDescribe (skipped)

Context Blocks (Sub-groups)

Context 'when input is valid'
  # Specific test scenarios
End

# Variants: Context, ExampleGroup, fContext, xContext

Example Blocks (Test Cases)

It 'should calculate sum correctly'
  When call add 2 3
  The output should eq 5
End

# Variants: It, Example, Specify, fIt, fExample, fSpecify, xIt, xExample, xSpecify

Hook Types

Block-Style Hooks

BeforeEach 'setup test environment'
  # Setup code here
End

AfterEach 'cleanup after test'
  # Cleanup code here
End

# Available: BeforeEach, AfterEach, BeforeAll, AfterAll, BeforeCall, AfterCall, BeforeRun, AfterRun

Statement-Style Hooks

Before 'setup_function'
Before 'setup1' 'setup2'  # Multiple functions
After 'cleanup_function'
Before 'variable=value'    # Inline code

Utility Blocks

Data Blocks

Data 'test input data'
  item1 value1
  item2 value2
End

Parameters

Parameters
  'param1'
  'param2'
End

Test Control

Skip 'not implemented yet'
  # Skipped test code
End

Pending 'work in progress'
  # Code that should fail for now
End

Todo 'implement feature X'  # Note without block

Directives

Include External Scripts

Include ./helper_functions.sh
Include ./custom_matchers.sh

Conditional Skip

Skip if "platform not supported" [ "$PLATFORM" != "linux" ]
Skip if "command not available" ! command -v docker

Usage Examples

Basic Test Structure

#!/usr/bin/env shellspec

Describe 'My Application'
  Include ./lib/my_app.sh

  Before 'setup_test_env'
  After 'cleanup_test_env'

  Context 'when user provides valid input'
    It 'processes input correctly'
      When call process_input "valid data"
      The status should be success
      The output should include "Processing complete"
    End

    It 'returns expected format'
      When call format_output "test"
      The output should match pattern "^Result: .*"
    End
  End

  Context 'when user provides invalid input'
    Skip if "validation not implemented" ! grep -q "validate" lib/my_app.sh

    It 'handles errors gracefully'
      When call process_input ""
      The status should be failure
      The stderr should include "Error: Invalid input"
    End
  End
End

Top-Level Examples (No Describe Required)

It 'can run without describe block'
  When call echo "hello"
  The output should eq "hello"
End

Complex Hook Chains

Describe 'Complex setup scenario'
  Before 'init_database' 'load_fixtures' 'start_services'
  After 'stop_services' 'cleanup_database'

  BeforeEach 'reset test state'
    test_counter=0
    temp_dir=$(mktemp -d)
  End

  AfterEach 'verify cleanup'
    [ "$test_counter" -gt 0 ]
    rm -rf "$temp_dir"
  End

  It 'runs with full setup chain'
    When call complex_operation
    The status should be success
  End
End

Development

Prerequisites

  • Node.js (v22 or later)
  • Tree-sitter CLI (provided via devDependency) — use npx tree-sitter <cmd>

Setup

git clone https://github.com/ivuorinen/tree-sitter-shellspec.git
cd tree-sitter-shellspec
npm install

Available Scripts

# Generate parser from grammar
npm run generate

# Run test suite (59 comprehensive tests)
npm test

# Build the parser
npm run build

# Development workflow
npm run dev          # Generate + test
npm run dev:watch    # Watch mode for development

# Linting and formatting
npm run lint         # Check code style
npm run lint:fix     # Auto-fix style issues
npm run format       # Format code

# Utilities
npm run clean        # Clean generated files
npm run rebuild      # Clean + generate + build

Testing

The grammar includes comprehensive test coverage:

  • Comprehensive test cases covering all ShellSpec constructs
  • Real-world patterns from official ShellSpec repository
  • Edge cases and complex nesting scenarios
  • Mixed content (ShellSpec + bash code)
# Run all tests
npm test

# Test specific patterns
tree-sitter test --filter "describe_blocks"
tree-sitter test --filter "real_world_patterns"

Grammar Structure

The grammar extends tree-sitter-bash with these main rules:

  • shellspec_describe_block - Describe/fDescribe/xDescribe blocks
  • shellspec_context_block - Context/ExampleGroup blocks
  • shellspec_it_block - It/Example/Specify blocks
  • shellspec_hook_block - BeforeEach/AfterEach/etc. blocks
  • shellspec_utility_block - Data/Parameters/Skip/Pending/Todo blocks
  • shellspec_hook_statement - Before/After statements
  • shellspec_directive_statement - Include and conditional Skip

Editor Integration

Neovim (with nvim-treesitter)

Add to your Tree-sitter config:

require'nvim-treesitter.configs'.setup {
  ensure_installed = { "bash", "shellspec" },
  highlight = {
    enable = true,
  },
}

VS Code

Install a Tree-sitter extension that supports custom grammars, then add this grammar to your configuration.

Emacs (with tree-sitter-mode)

Add to your configuration:

(add-to-list 'tree-sitter-major-mode-language-alist '(sh-mode . shellspec))

Contributing

Contributions are welcome! Please see our contributing guidelines for details.

Areas for Contribution

  • Enhanced Data block support - Advanced syntax (:raw, :expand, | filters)
  • Assertion parsing - When/The statement structures
  • Performance optimization - Reduce parser conflicts
  • Editor plugins - Syntax highlighting themes
  • Documentation - Usage examples and tutorials

Reporting Issues

Please report issues with:

  • ShellSpec code that doesn't parse correctly
  • Missing syntax highlighting
  • Performance problems
  • Documentation improvements

License

MIT License - see LICENSE file for details.

Acknowledgments


Star this project if you find it useful for your ShellSpec development workflow!

Description
No description provided
Readme 1.9 MiB