Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursorrules
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# NDI Cursor Rules

## 1. Project Context
This is the NDI (Neuroscience Data Interface) Python port. It is a "Lead-Follow" project where the MATLAB codebase is the Source of Truth.
This is the NDI (Neuroscience ndi_gui_Data Interface) Python port. It is a "Lead-Follow" project where the MATLAB codebase is the Source of Truth.

## 2. Core Instructions
Before proposing or writing any code, you MUST read and adhere to the following project-specific files:
Expand Down
122 changes: 122 additions & 0 deletions .github/workflows/test-symmetry.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Test Cross-Language Symmetry

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
symmetry:
name: MATLAB ↔ Python symmetry tests
runs-on: ubuntu-latest

steps:
# ── Checkout both repos ────────────────────────────────────────────
- name: Check out NDI-python
uses: actions/checkout@v4
with:
path: NDI-python

- name: Check out NDI-matlab
uses: actions/checkout@v4
with:
repository: VH-Lab/NDI-matlab
path: NDI-matlab

# ── Runtime setup ──────────────────────────────────────────────────
- name: Start virtual display server
run: |
sudo apt-get install -y xvfb
Xvfb :99 &
echo "DISPLAY=:99" >> $GITHUB_ENV

- name: Set up MATLAB
uses: matlab-actions/setup-matlab@v2
with:
release: latest
cache: true
products: |
Communications_Toolbox
Statistics_and_Machine_Learning_Toolbox
Signal_Processing_Toolbox

- name: Install MatBox
uses: ehennestad/matbox-actions/install-matbox@v1

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install NDI-python
working-directory: NDI-python
run: |
python -m pip install --upgrade pip
python ndi_install.py --dev --no-validate --verbose

# ── Stage 1: MATLAB makeArtifacts ──────────────────────────────────
- name: "Stage 1: MATLAB makeArtifacts"
uses: matlab-actions/run-command@v2
with:
command: |
cd("NDI-matlab");
addpath(genpath("src"));
addpath(genpath("tests"));
addpath(genpath("tools"));
matbox.installRequirements(fullfile(pwd, "tests"));

import matlab.unittest.TestSuite
import matlab.unittest.TestRunner

suite = TestSuite.fromPackage("ndi.symmetry.makeArtifacts", "IncludingSubpackages", true);
fprintf("\n=== MATLAB makeArtifacts: %d test(s) ===\n", numel(suite));
assert(~isempty(suite), "No MATLAB makeArtifacts tests found.")

runner = TestRunner.withTextOutput("Verbosity", "Detailed");
results = runner.run(suite);

fprintf("\n=== MATLAB makeArtifacts: %d passed, %d failed ===\n", ...
nnz([results.Passed]), nnz([results.Failed]));
assert(all(~[results.Failed]), "MATLAB makeArtifacts failed")

# ── Stage 2: Python makeArtifacts + readArtifacts ──────────────────
- name: "Stage 2: Python symmetry tests (make + read)"
working-directory: NDI-python
run: |
echo "=== Running Python makeArtifacts ==="
pytest tests/symmetry/make_artifacts/ -v --tb=short

echo ""
echo "=== Running Python readArtifacts (reads both MATLAB and Python artifacts) ==="
pytest tests/symmetry/read_artifacts/ -v --tb=short

# ── Stage 3: MATLAB readArtifacts ──────────────────────────────────
- name: "Stage 3: MATLAB readArtifacts (reads Python artifacts)"
uses: matlab-actions/run-command@v2
with:
command: |
cd("NDI-matlab");
addpath(genpath("src"));
addpath(genpath("tests"));
addpath(genpath("tools"));
matbox.installRequirements(fullfile(pwd, "tests"));

import matlab.unittest.TestSuite
import matlab.unittest.TestRunner

suite = TestSuite.fromPackage("ndi.symmetry.readArtifacts", "IncludingSubpackages", true);
fprintf("\n=== MATLAB readArtifacts: %d test(s) ===\n", numel(suite));
assert(~isempty(suite), "No MATLAB readArtifacts tests found.")

runner = TestRunner.withTextOutput("Verbosity", "Detailed");
results = runner.run(suite);

fprintf("\n=== MATLAB readArtifacts: %d passed, %d failed ===\n", ...
nnz([results.Passed]), nnz([results.Failed]));
assert(all(~[results.Failed]), "MATLAB readArtifacts failed")
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 1. Role & Mission

You are an AI Developer for the NDI (Neuroscience Data Interface) project. Your mission is to maintain 1:1 functional and semantic parity between the mature MATLAB (Source of Truth) codebase and the Python port.
You are an AI Developer for the NDI (Neuroscience ndi_gui_Data Interface) project. Your mission is to maintain 1:1 functional and semantic parity between the mature MATLAB (Source of Truth) codebase and the Python port.

## 2. The Mandatory Knowledge Base

Expand Down Expand Up @@ -34,5 +34,5 @@ Every sub-package contains a file named `ndi_matlab_python_bridge.yaml`.

## 5. Directory Mapping Reference

- **MATLAB Source:** `VH-Lab/NDI-matlab` (GitHub)
- **MATLAB Source:** `VH-ndi_gui_Lab/NDI-matlab` (GitHub)
- **Python Target:** `src/ndi/[namespace]/` (Mirrors MATLAB `+namespace/`)
Loading
Loading