Skip to content
Open
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
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
.git/
Dockerfile*
.dockerignore
*.log*
.env*
coverage/
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
dist/
build/
coverage/
*.min.js
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CI

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

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Install Node dependencies
run: pnpm install --no-frozen-lockfile

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install Python dependencies
run: |
cd backend
pip install -r requirements.txt

- name: Build
run: npm run build

- name: Test Frontend
run: npm run test:frontend

- name: Test Backend
run: npm run test:backend
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ Thumbs.db

# Ignore built ts files
dist/
build/

__pycache__/
*.pyc/
.venv
venv/
*.egg-info/
.pytest_cache/

/.yalc
yalc.lock
Expand All @@ -46,3 +52,9 @@ yalc.lock
backend/out
bin
cli/

.gemini/
GEMINI.md
.serena/
.specify/
specs/
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist/
build/
coverage/
package-lock.json
yarn.lock
pnpm-lock.yaml
10 changes: 10 additions & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = [
"tests",
]
pythonpath = [
".",
"src"
]
2 changes: 2 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest
pytest-mock
15 changes: 15 additions & 0 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import sys
from unittest.mock import MagicMock

def pytest_configure(config):
"""
Mock the scanmem C extension module before any tests run.
This allows testing on non-Linux systems where the C module cannot be compiled.
"""
mock_scanmem = MagicMock()
mock_scanmem.scan = MagicMock(return_value=10) # 10 matches by default
mock_scanmem.read = MagicMock(return_value="0xDEADBEEF")
mock_scanmem.write = MagicMock(return_value=True)

# Inject into sys.modules
sys.modules['scanmem'] = mock_scanmem
22 changes: 22 additions & 0 deletions backend/tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest
import sys
import os

# Add project root to sys.path so we can import main.py
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))

def test_mock_scanmem_injection():
"""Verify that scanmem is mocked correctly"""
import scanmem
assert isinstance(scanmem, object)
assert scanmem.scan(100, "==") == 10

def test_main_import():
"""Verify that main.py can be imported without crashing due to missing dependencies"""
try:
from main import Plugin
assert Plugin is not None
except ImportError as e:
pytest.fail(f"Could not import Plugin from main: {e}")
except Exception as e:
pytest.fail(f"Importing main crashed: {e}")
29 changes: 29 additions & 0 deletions backend/tests/test_scanmem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest
import sys

def test_scan_operation():
"""Test that scanmem.scan is called correctly"""
import scanmem

# Call the mocked function
matches = scanmem.scan("100", "==")

# Verify return value
assert matches == 10

# Verify call arguments
scanmem.scan.assert_called_with("100", "==")

def test_read_operation():
"""Test reading memory"""
import scanmem
val = scanmem.read(0x12345678)
assert val == "0xDEADBEEF"
scanmem.read.assert_called_with(0x12345678)

def test_write_operation():
"""Test writing memory"""
import scanmem
success = scanmem.write(0x12345678, "100")
assert success is True
scanmem.write.assert_called_with(0x12345678, "100")
14 changes: 14 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/tests/setupTests.ts'],
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
'^decky-frontend-lib$': '<rootDir>/tests/__mocks__/decky-frontend-lib.ts',
},
transform: {
'^.+\\.(ts|tsx)$': ['ts-jest', {
tsconfig: 'tsconfig.test.json'
}],
},
};
Loading