Skip to content

⚠️ DOCUMENTATION UNDER CONSTRUCTION ⚠️

This documentation is being written from scratch. What you see here is essentially placeholder content and should not be trusted as accurate. Expect significant changes and updates.

Component Model C++ Tests ​

This directory contains the test suite for the component-model-cpp library.

Test Components ​

1. Component Model ABI Tests (main.cpp, scratchpad.cpp) ​

Core tests for the WebAssembly Component Model canonical ABI implementation:

  • Type marshaling (lift/lower operations)
  • String encoding conversions
  • List handling
  • Record and variant types
  • Resource management
  • Async primitives (futures, streams, tasks)
  • Error contexts

Running:

bash
cmake --build build
cd build && ctest -R component-model-test
# Or directly:
./build/test/component-model-test

2. WIT Grammar Tests (test_grammar.cpp) ​

Validates the ANTLR4-based WIT parser against official test files from the wit-bindgen project.

📖 Detailed grammar testing instructions are included in this section.

Requirements ​

  • Java Runtime Environment (for ANTLR)
  • CMake flag: -DWIT_CODEGEN=ON

Quick Start ​

Linux/macOS:

bash
# 1. Configure CMake with grammar support
cmake -B build -DWIT_CODEGEN=ON

# 2. Build the grammar and test executable
cmake --build build --target test-wit-grammar

# 3. Run the tests
cd build && ctest -R wit-grammar-test --verbose

Windows:

bash
# 1. Configure CMake with grammar support
cmake -B build -DWIT_CODEGEN=ON

# 2. Build the grammar and test executable (specify configuration)
cmake --build build --target test-wit-grammar --config Release

# 3. Run the tests (must specify -C configuration on Windows)
cd build && ctest -C Release -R wit-grammar-test --verbose

3. WIT Stub Generation ​

Generate C++ host function stubs from all WIT test files. Useful for testing the code generator and creating reference implementations.

📖 Stub generation and validation guidance appears throughout this section.

Quick Start ​

bash
# Prerequisites: build wit-codegen tool
cmake --build build --target wit-codegen

# Generate stubs for all test files (Python - recommended)
cd test && ./generate_test_stubs.py

# Or use the bash script
cd test && ./generate_test_stubs.sh

# Verbose output (see what files are generated)
./generate_test_stubs.py -v

# Filter specific files
./generate_test_stubs.py -f "streams"

# Skip CMakeLists.txt generation (if you don't need them)
./generate_test_stubs.py --no-cmake

Individual Stub Compilation ​

Each generated stub includes its own CMakeLists.txt in a dedicated subdirectory for standalone compilation testing:

bash
# Generate stubs with CMakeLists.txt (default, parallelized)
cmake --build build --target generate-test-stubs

# Navigate to a specific stub directory
cd build/test/generated_stubs/simple-functions

# Build the individual stub
cmake -S . -B build
cmake --build build

Performance: Generation is parallelized using all available CPU cores by default. For 199 WIT files:

  • Sequential: ~20 seconds
  • Parallel (32 cores): ~4 seconds (5x faster)

Control parallelization:

bash
python test/generate_test_stubs.py -j 8        # Use 8 parallel jobs
python test/generate_test_stubs.py -j 1        # Sequential (for debugging)
python test/generate_test_stubs.py --no-cmake  # Skip CMakeLists.txt generation

Structure: Each stub gets its own directory with all files:

generated_stubs/
├── simple-functions/
│   ├── CMakeLists.txt
│   ├── simple-functions.hpp
│   ├── simple-functions_wamr.hpp
│   └── simple-functions_wamr.cpp
├── integers/
│   ├── CMakeLists.txt
│   ├── integers.hpp
│   ├── integers_wamr.hpp
│   └── integers_wamr.cpp
...

Note: Stubs with _wamr.cpp files require WAMR (WebAssembly Micro Runtime) headers. The generated CMakeLists.txt includes helpful comments about dependencies and will automatically find the local cmcpp headers.

Code Generation Validation ​

The framework also validates generated code by attempting to compile it:

bash
# Generate AND compile stubs (validation test)
cmake --build build --target test-stubs-full

⚠️ IMPORTANT: Compilation failures are expected and useful! They indicate bugs in wit-codegen that need fixing. Detailed validation notes are included in the following section.

Generated Files ​

For each .wit file in the test suite:

  • <name>.hpp - Host/guest function declarations
  • <name>_wamr.hpp - WAMR host wrappers with automatic marshaling
  • <name>_wamr.cpp - WAMR native symbol registration

Example output:

generated_stubs/
├── floats.hpp
├── floats_wamr.hpp
├── floats_wamr.cpp
├── streams.hpp
├── streams_wamr.hpp
└── streams_wamr.cpp

Use Cases ​

  • Testing: Verify the full toolchain (grammar → parser → codegen) works end-to-end
  • Reference: See how WIT features map to C++ types and WAMR integration
  • Development: Quick starting point for implementing Component Model features

What Gets Tested ​

The test suite validates the grammar against 95+ official WIT test files including:

Basic Types

  • ✅ Integers (u8, u16, u32, u64, s8, s16, s32, s64)
  • ✅ Floats (f32, f64)
  • ✅ Strings and characters
  • ✅ Booleans

Complex Types

  • ✅ Records (structs with named fields)
  • ✅ Variants (tagged unions)
  • ✅ Enums (variants without payloads)
  • ✅ Flags (bitsets)
  • ✅ Tuples
  • ✅ Lists (including fixed-length lists)
  • ✅ Options and Results

Async Features (Recently Added)

  • ✅ Async functions (async func)
  • ✅ Futures (future<T> and future)
  • ✅ Streams (stream<T> and stream)

Resources

  • ✅ Resource declarations
  • ✅ Resource methods
  • ✅ Static resource functions
  • ✅ Constructors (infallible and fallible)
  • ✅ Owned handles (resource-name)
  • ✅ Borrowed handles (borrow<resource-name>)

Package & Interface Features

  • ✅ Package declarations with versions
  • ✅ Nested namespaces and packages
  • ✅ Interface definitions
  • ✅ World definitions
  • ✅ Import and export statements
  • ✅ Use statements (local and cross-package)
  • ✅ Include statements with renaming

Feature Gates

  • ✅ @unstable(feature = name) gates
  • ✅ @since(version = x.y.z) gates
  • ✅ @deprecated(version = x.y.z) gates

Real-World Examples

  • ✅ WASI specifications (wasi-clocks, wasi-filesystem, wasi-http, wasi-io)
  • ✅ Error contexts
  • ✅ Complex nested types
  • ✅ Multiple interfaces and worlds per file

Test Files Location ​

The test suite uses files from:

ref/wit-bindgen/tests/codegen/

This directory is included as a git submodule and contains the canonical test suite maintained by the WebAssembly community.

Running Grammar Tests ​

Method 1: Using CTest (Recommended)

bash
# From the build directory
cd build
ctest -R wit-grammar-test

# With verbose output
ctest -R wit-grammar-test --verbose

# Run all tests including grammar
ctest

Method 2: Direct Execution

bash
# From project root
./build/test/test-wit-grammar

# With verbose output (shows each file being parsed)
./build/test/test-wit-grammar --verbose

# Custom test directory
./build/test/test-wit-grammar --directory /path/to/wit/files

Method 3: Using VS Code

Use the VS Code debugger with the provided launch configurations:

  • (gdb) test-wit-grammar - Run grammar tests on Linux
  • (gdb) test-wit-grammar (verbose) - Run with verbose output on Linux
  • (win) test-wit-grammar - Run grammar tests on Windows
  • (win) test-wit-grammar (verbose) - Run with verbose output on Windows

Press F5 or use the Run and Debug panel (Ctrl+Shift+D) to select and run a configuration.

Test Output ​

Success Output:

WIT Grammar Test Suite
======================
Test directory: ../ref/wit-bindgen/tests/codegen

Found 95 WIT files

======================
Test Results:
  Total files:  95
  Successful:   95
  Failed:       0

✓ All tests passed!

Failure Output: When parsing fails, detailed error messages are provided:

Failed to parse: example.wit
Errors in example.wit:
  line 5:10 mismatched input 'invalid' expecting {'u8', 'u16', ...}
  
======================
Test Results:
  Total files:  95
  Successful:   94
  Failed:       1

Failed files:
  - example.wit

Troubleshooting Grammar Tests ​

Java Not Found

Error: Java runtime not found. ANTLR4 requires Java to generate code.

Solution: Install Java Runtime Environment (JRE) 8 or later.

ANTLR Jar Not Found

The CMake configuration automatically downloads ANTLR. If this fails:

bash
# Manually download
wget https://www.antlr.org/download/antlr-4.13.2-complete.jar -O antlr-4.13.2-complete.jar

Submodule Not Initialized

Error: wit-bindgen test files not found

Solution:

bash
git submodule update --init ref/wit-bindgen

Build Errors

If the grammar library fails to build:

bash
# Clean build and regenerate
rm -rf build
cmake -B build -DWIT_CODEGEN=ON
cmake --build build --target generate-grammar
cmake --build build --target test-wit-grammar

Grammar Coverage ​

The test suite ensures complete coverage of the WIT specification:

  • ✅ All keywords (as, async, bool, borrow, char, constructor, enum, export, f32, f64, flags, from, func, future, import, include, interface, list, option, own, package, record, resource, result, s8-s64, static, stream, string, tuple, type, u8-u64, use, variant, with, world)
  • ✅ All operators (=, ,, :, ;, (, ), {, }, <, >, *, ->, /, ., @)
  • ✅ Package versions (SemVer 2.0.0)
  • ✅ Comments (line and block)
  • ✅ Nested structures

Running All Tests ​

bash
# Build all tests
cmake --build build

# Run all tests
cd build && ctest

# Run with verbose output
cd build && ctest --verbose

# Run with output on failure
cd build && ctest --output-on-failure

Test Coverage ​

When building with GCC or Clang, coverage instrumentation is automatically enabled. Generate coverage reports:

bash
# After running tests
cd build
lcov --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/*' '*/vcpkg_installed/*' '*/test/*' --output-file coverage_filtered.info
genhtml coverage_filtered.info --output-directory coverage_html

Test Organization ​

test/
├── main.cpp                      # Main test runner (doctest)
├── scratchpad.cpp                # Component model ABI tests
├── host-util.hpp                 # Test utilities
├── host-util.cpp                 # Host function helpers
├── test_grammar.cpp              # WIT grammar parser tests
├── generate_test_stubs.py        # Python stub generator (recommended)
├── generate_test_stubs.sh        # Bash stub generator
├── CMakeLists.txt                # Test build configuration
├── README.md                     # This file (overview)
├── TESTING_GRAMMAR.md            # Detailed grammar testing guide
├── STUB_GENERATION.md            # Detailed stub generation guide
└── STUB_GENERATION_QUICKREF.md  # Quick reference for stub generation

VS Code launch configurations are available in .vscode/launch.json for running and debugging all tests.

Complete Workflow Example ​

Here's a complete example of the test workflow from WIT file to generated stubs:

bash
# 1. Initialize the project
git clone <repo> && cd component-model-cpp
git submodule update --init --recursive

# 2. Build with grammar support
cmake -B build -DWIT_CODEGEN=ON
cmake --build build

# 3. Run grammar tests to validate WIT parsing
cd build && ctest -R wit-grammar-test --verbose

# 4. Generate stubs from all test WIT files
cd ../test
./generate_test_stubs.py -v

# 5. Check the generated stubs
ls generated_stubs/
cat generated_stubs/floats.hpp

# 6. (Optional) Use generated stubs in your project
cp generated_stubs/floats* ../my_project/

Result: You now have:

  • ✅ Validated WIT parser working on 95+ test files
  • ✅ Generated C++ host function stubs with WAMR integration
  • ✅ Ready-to-use code for Component Model development

Dependencies ​

  • doctest: C++ testing framework (from vcpkg)
  • ICU: Unicode string handling (from vcpkg)
  • ANTLR4: Grammar parser runtime (from vcpkg, for grammar tests)

Continuous Integration ​

Tests are designed to run in CI/CD environments:

yaml
# Example GitHub Actions
- name: Run Tests
  run: |
    cmake -B build
    cmake --build build
    cd build && ctest --output-on-failure

- name: Run Grammar Tests (if enabled)
  run: |
    cmake -B build -DWIT_CODEGEN=ON
    cmake --build build --target test-wit-grammar
    cd build && ctest -R wit-grammar-test --output-on-failure

Adding New Tests ​

Component Model Tests ​

Add test cases to scratchpad.cpp using doctest:

cpp
TEST_CASE("My new test") {
    // Your test code
    CHECK(expected == actual);
}

Grammar Tests ​

Grammar tests automatically pick up all .wit files in the test directory. To test additional files:

bash
./build/test/test-wit-grammar --directory /path/to/wit/files