diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79053fc..c0869c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,235 +20,235 @@ on: - 'docs/**' - '.gitignore' -env: - MIX_ENV: test - -jobs: - compile: - name: Compilation - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: '1.18.3' - otp-version: '27.3' - - - name: Cache deps - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-27.3-1.18.3- - - - name: Install dependencies - run: mix deps.get - - - name: Compile dependencies - run: mix deps.compile - - - name: Compile project with warnings as errors - run: mix compile --warnings-as-errors - - format: - name: Code Formatting - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: '1.18.3' - otp-version: '27.3' - - - name: Check formatting - run: mix format --check-formatted - - test: - name: Test (Elixir ${{matrix.elixir}} / OTP ${{matrix.otp}}) - runs-on: ubuntu-latest - needs: [format, compile] - - strategy: - fail-fast: false - matrix: - include: - # Latest stable versions - - elixir: '1.18.3' - otp: '27.3' - coverage: true - # Previous versions for compatibility - - elixir: '1.17.3' - otp: '26.2' - coverage: false - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: ${{ matrix.elixir }} - otp-version: ${{ matrix.otp }} - - - name: Cache deps - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}- - - - name: Install dependencies - run: mix deps.get - - - name: Compile dependencies - run: mix deps.compile - - - name: Compile project - run: mix compile - - - name: Run tests with coverage - if: ${{ matrix.coverage }} - run: mix coveralls.json - - - name: Upload coverage to Codecov - if: ${{ matrix.coverage }} - uses: codecov/codecov-action@v4 - with: - file: ./cover/excoveralls.json - fail_ci_if_error: false - token: ${{ secrets.CODECOV_TOKEN }} - - - name: Run tests - if: ${{ !matrix.coverage }} - run: mix test - - credo: - name: Static Code Analysis (Credo) - runs-on: ubuntu-latest - needs: compile - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: '1.18.3' - otp-version: '27.3' - - - name: Cache deps - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-27.3-1.18.3- - - - name: Install dependencies - run: mix deps.get - - - name: Compile dependencies - run: mix deps.compile - - - name: Compile project - run: mix compile - - - name: Run Credo - run: mix credo --strict - - dialyzer: - name: Static Type Analysis (Dialyzer) - runs-on: ubuntu-latest - needs: compile - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: '1.18.3' - otp-version: '27.3' - - - name: Cache deps - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-27.3-1.18.3- - - - name: Cache Dialyzer PLTs - uses: actions/cache@v4 - with: - path: priv/plts - key: dialyzer-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} - restore-keys: | - dialyzer-${{ runner.os }}-27.3-1.18.3- - - - name: Install dependencies - run: mix deps.get - - - name: Compile dependencies - run: mix deps.compile - - - name: Compile project - run: mix compile - - - name: Run Dialyzer - run: mix dialyzer - - regression-tests: - name: Regression Test Suite - runs-on: ubuntu-latest - needs: compile - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Elixir - uses: erlef/setup-beam@v1 - with: - elixir-version: '1.18.3' - otp-version: '27.3' - - - name: Cache deps - uses: actions/cache@v4 - with: - path: | - deps - _build - key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} - restore-keys: | - deps-${{ runner.os }}-27.3-1.18.3- - - - name: Install dependencies - run: mix deps.get - - - name: Compile project - run: mix compile - - - name: Run regression tests - run: mix test.regression +# env: +# MIX_ENV: test +# +# jobs: +# compile: +# name: Compilation +# runs-on: ubuntu-latest +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: '1.18.3' +# otp-version: '27.3' +# +# - name: Cache deps +# uses: actions/cache@v4 +# with: +# path: | +# deps +# _build +# key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# deps-${{ runner.os }}-27.3-1.18.3- +# +# - name: Install dependencies +# run: mix deps.get +# +# - name: Compile dependencies +# run: mix deps.compile +# +# - name: Compile project with warnings as errors +# run: mix compile --warnings-as-errors +# +# format: +# name: Code Formatting +# runs-on: ubuntu-latest +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: '1.18.3' +# otp-version: '27.3' +# +# - name: Check formatting +# run: mix format --check-formatted +# +# test: +# name: Test (Elixir ${{matrix.elixir}} / OTP ${{matrix.otp}}) +# runs-on: ubuntu-latest +# needs: [format, compile] +# +# strategy: +# fail-fast: false +# matrix: +# include: +# # Latest stable versions +# - elixir: '1.18.3' +# otp: '27.3' +# coverage: true +# # Previous versions for compatibility +# - elixir: '1.17.3' +# otp: '26.2' +# coverage: false +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: ${{ matrix.elixir }} +# otp-version: ${{ matrix.otp }} +# +# - name: Cache deps +# uses: actions/cache@v4 +# with: +# path: | +# deps +# _build +# key: deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# deps-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}- +# +# - name: Install dependencies +# run: mix deps.get +# +# - name: Compile dependencies +# run: mix deps.compile +# +# - name: Compile project +# run: mix compile +# +# - name: Run tests with coverage +# if: ${{ matrix.coverage }} +# run: mix coveralls.json +# +# - name: Upload coverage to Codecov +# if: ${{ matrix.coverage }} +# uses: codecov/codecov-action@v4 +# with: +# file: ./cover/excoveralls.json +# fail_ci_if_error: false +# token: ${{ secrets.CODECOV_TOKEN }} +# +# - name: Run tests +# if: ${{ !matrix.coverage }} +# run: mix test +# +# credo: +# name: Static Code Analysis (Credo) +# runs-on: ubuntu-latest +# needs: compile +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: '1.18.3' +# otp-version: '27.3' +# +# - name: Cache deps +# uses: actions/cache@v4 +# with: +# path: | +# deps +# _build +# key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# deps-${{ runner.os }}-27.3-1.18.3- +# +# - name: Install dependencies +# run: mix deps.get +# +# - name: Compile dependencies +# run: mix deps.compile +# +# - name: Compile project +# run: mix compile +# +# - name: Run Credo +# run: mix credo --strict +# +# dialyzer: +# name: Static Type Analysis (Dialyzer) +# runs-on: ubuntu-latest +# needs: compile +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: '1.18.3' +# otp-version: '27.3' +# +# - name: Cache deps +# uses: actions/cache@v4 +# with: +# path: | +# deps +# _build +# key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# deps-${{ runner.os }}-27.3-1.18.3- +# +# - name: Cache Dialyzer PLTs +# uses: actions/cache@v4 +# with: +# path: priv/plts +# key: dialyzer-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# dialyzer-${{ runner.os }}-27.3-1.18.3- +# +# - name: Install dependencies +# run: mix deps.get +# +# - name: Compile dependencies +# run: mix deps.compile +# +# - name: Compile project +# run: mix compile +# +# - name: Run Dialyzer +# run: mix dialyzer +# +# regression-tests: +# name: Regression Test Suite +# runs-on: ubuntu-latest +# needs: compile +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Set up Elixir +# uses: erlef/setup-beam@v1 +# with: +# elixir-version: '1.18.3' +# otp-version: '27.3' +# +# - name: Cache deps +# uses: actions/cache@v4 +# with: +# path: | +# deps +# _build +# key: deps-${{ runner.os }}-27.3-1.18.3-${{ hashFiles('**/mix.lock') }} +# restore-keys: | +# deps-${{ runner.os }}-27.3-1.18.3- +# +# - name: Install dependencies +# run: mix deps.get +# +# - name: Compile project +# run: mix compile +# +# - name: Run regression tests +# run: mix test.regression diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 510c478..541ceab 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,72 +16,72 @@ on: - 'README.md' - 'docs/**' -jobs: - lint-docs: - name: Lint Documentation - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Lint Markdown files - uses: DavidAnson/markdownlint-cli2-action@v13 - with: - globs: | - **/*.md - !node_modules/**/*.md - - - name: Check for broken links - uses: gaurav-nelson/github-action-markdown-link-check@v1 - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'yes' - config-file: '.github/workflows/markdown-link-check-config.json' - - validate-memory: - name: Validate Memory Files - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Check CLAUDE.md structure - run: | - echo "Validating CLAUDE.md structure..." - if ! grep -q "## Commands" CLAUDE.md; then - echo "❌ CLAUDE.md missing Commands section" - exit 1 - fi - if ! grep -q "## Architecture" CLAUDE.md; then - echo "❌ CLAUDE.md missing Architecture section" - exit 1 - fi - echo "✅ CLAUDE.md structure looks good" - - - name: Check README.md structure - run: | - echo "Validating README.md structure..." - if ! grep -q "## Features" README.md; then - echo "❌ README.md missing Features section" - exit 1 - fi - if ! grep -q "## Current Status" README.md; then - echo "❌ README.md missing Current Status section" - exit 1 - fi - echo "✅ README.md structure looks good" - - - name: Validate documentation consistency - run: | - echo "Checking for API consistency between CLAUDE.md and README.md..." - - # Check that both files reference SC.Validator (not SC.Document.Validator) - if grep -q "SC\.Document\.Validator" CLAUDE.md README.md; then - echo "❌ Found outdated SC.Document.Validator references - should be SC.Validator" - grep -n "SC\.Document\.Validator" CLAUDE.md README.md || true - exit 1 - fi - - echo "✅ API references look consistent" \ No newline at end of file +# jobs: +# lint-docs: +# name: Lint Documentation +# runs-on: ubuntu-latest +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Lint Markdown files +# uses: DavidAnson/markdownlint-cli2-action@v13 +# with: +# globs: | +# **/*.md +# !node_modules/**/*.md +# +# - name: Check for broken links +# uses: gaurav-nelson/github-action-markdown-link-check@v1 +# with: +# use-quiet-mode: 'yes' +# use-verbose-mode: 'yes' +# config-file: '.github/workflows/markdown-link-check-config.json' +# +# validate-memory: +# name: Validate Memory Files +# runs-on: ubuntu-latest +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Check CLAUDE.md structure +# run: | +# echo "Validating CLAUDE.md structure..." +# if ! grep -q "## Commands" CLAUDE.md; then +# echo "❌ CLAUDE.md missing Commands section" +# exit 1 +# fi +# if ! grep -q "## Architecture" CLAUDE.md; then +# echo "❌ CLAUDE.md missing Architecture section" +# exit 1 +# fi +# echo "✅ CLAUDE.md structure looks good" +# +# - name: Check README.md structure +# run: | +# echo "Validating README.md structure..." +# if ! grep -q "## Features" README.md; then +# echo "❌ README.md missing Features section" +# exit 1 +# fi +# if ! grep -q "## Current Status" README.md; then +# echo "❌ README.md missing Current Status section" +# exit 1 +# fi +# echo "✅ README.md structure looks good" +# +# - name: Validate documentation consistency +# run: | +# echo "Checking for API consistency between CLAUDE.md and README.md..." +# +# # Check that both files reference SC.Validator (not SC.Document.Validator) +# if grep -q "SC\.Document\.Validator" CLAUDE.md README.md; then +# echo "❌ Found outdated SC.Document.Validator references - should be SC.Validator" +# grep -n "SC\.Document\.Validator" CLAUDE.md README.md || true +# exit 1 +# fi +# +# echo "✅ API references look consistent" diff --git a/CHANGELOG.md b/CHANGELOG.md index 050ee84..bb721c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] - -### ⚠️ DEPRECATED +## ⚠️ DEPRECATED **This `sc` package has been renamed to `statifier`** @@ -18,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Deprecation Warnings**: All public functions now emit deprecation warnings - **No New Features**: All future development continues in the `statifier` package +--- + ### Added #### Phase 1 Enhanced Expression Evaluation diff --git a/README.md b/README.md index 9fee1fc..595bb34 100644 --- a/README.md +++ b/README.md @@ -1,532 +1,14 @@ -# ⚠️ DEPRECATED: SC - StateCharts for Elixir +# ⚠️ DEPRECATED: SC > **This project has been renamed to [Statifier](https://github.com/riddler/statifier)** > All active development continues at **** -> Please migrate to `{:statifier, "~> 1.1"}` for ongoing updates and support. - -[![CI](https://github.com/riddler/sc/workflows/CI/badge.svg?branch=main)](https://github.com/riddler/sc/actions) -[![Coverage](https://codecov.io/gh/riddler/sc/branch/main/graph/badge.svg)](https://codecov.io/gh/riddler/sc) +> Please migrate to `{:statifier, "~> 1.9"}` for ongoing updates and support. --- **⚠️ MIGRATION NOTICE**: This SC project has been renamed to **[Statifier](https://github.com/riddler/statifier)** for better discoverability and communication. All modules have been renamed from `SC.*` to `Statifier.*`. **New Repository**: -**New Hex Package**: `{:statifier, "~> 1.1"}` +**New Hex Package**: `{:statifier, "~> 1.9"}` --- - -An Elixir implementation of SCXML (State Chart XML) state charts with a focus on W3C compliance. - -## Features - -- ✅ **Complete SCXML Parser** - Converts XML documents to structured data with precise location tracking -- ✅ **State Chart Interpreter** - Runtime engine for executing SCXML state charts -- ✅ **Modular Validation** - Document validation with focused sub-validators for maintainability -- ✅ **Compound States** - Support for hierarchical states with automatic initial child entry -- ✅ **Initial State Elements** - Full support for `` elements with transitions (W3C compliant) -- ✅ **Parallel States** - Support for concurrent state regions with simultaneous execution -- ✅ **Eventless Transitions** - Automatic transitions without event attributes (W3C compliant) -- ✅ **Conditional Transitions** - Full support for `cond` attributes with expression evaluation -- ✅ **Assign Elements** - Complete `` element support with location-based assignment and nested property access -- ✅ **Value Evaluation** - Non-boolean expression evaluation using Predicator v3.0 for actual data values -- ✅ **Data Model Integration** - StateChart data model with dynamic variable assignment and persistence -- ✅ **O(1) Performance** - Optimized state and transition lookups via Maps -- ✅ **Event Processing** - Internal and external event queues per SCXML specification -- ✅ **Parse → Validate → Optimize Architecture** - Clean separation of concerns -- ✅ **Feature Detection** - Automatic SCXML feature detection for test validation -- ✅ **Regression Testing** - Automated tracking of passing tests to prevent regressions -- ✅ **Git Hooks** - Pre-push validation workflow to catch issues early -- ✅ **Test Infrastructure** - Compatible with SCION and W3C test suites -- ✅ **Code Quality** - Full Credo compliance with proper module aliasing - -## Current Status - -### Working Features - -- ✅ **Basic state transitions** and event-driven changes -- ✅ **Hierarchical states** with optimized O(1) state lookup and automatic initial child entry -- ✅ **Initial state elements** - Full `` element support with transitions and comprehensive validation -- ✅ **Parallel states** with concurrent execution of multiple regions and proper cross-boundary exit semantics -- ✅ **Eventless transitions** - Automatic transitions without event attributes (also called NULL transitions in SCXML spec), with cycle detection and microstep processing -- ✅ **Conditional transitions** - Full `cond` attribute support with Predicator v3.0 expression evaluation and SCXML `In()` function -- ✅ **Assign elements** - Complete `` element support with location-based assignment, nested property access, and mixed notation -- ✅ **Value evaluation system** - SC.ValueEvaluator module for non-boolean expression evaluation and data model operations -- ✅ **Enhanced expression evaluation** - Predicator v3.0 integration with deep property access and type-safe operations -- ✅ **Transition conflict resolution** - Child state transitions take priority over ancestor transitions per W3C specification -- ✅ **SCXML-compliant processing** - Proper microstep/macrostep execution model with exit set computation and LCCA algorithms -- ✅ **Modular validation** - Refactored from 386-line monolith into focused sub-validators -- ✅ **Feature detection** - Automatic SCXML feature detection prevents false positive test results -- ✅ **SAX-based XML parsing** with accurate location tracking for error reporting -- ✅ **Performance optimizations** - O(1) state/transition lookups, optimized active configuration -- ✅ **Source field optimization** - Transitions include source state for faster event processing - -### Planned Features - -- History states (``) -- Internal and targetless transitions -- More executable content (`