Blankslate

Universal HID tablet configuration toolkit

Launch App
Github Logo

Testing

Blankslate has comprehensive test suites for both Node.js/TypeScript and Python implementations, ensuring feature parity and reliability across platforms.

Test Summary

Platform Tests Test Files Framework
Node.js/TypeScript 613+ 24 Vitest
Python 295 10 pytest
Total 900+ 34 -

Running Tests

Node.js/TypeScript

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Run specific test file
npm test -- test/unit/config.test.ts

# Run tests matching a pattern
npm test -- --grep "walkthrough"

# Watch mode for development
npm run test:watch

Python

# Activate virtual environment first
cd python
source venv/bin/activate

# Run all tests
pytest

# Run with coverage
pytest --cov=blankslate --cov-report=html

# Run specific test file
pytest tests/unit/test_config.py

# Run specific test class or method
pytest tests/unit/test_config.py::TestConfigCreation::test_create_from_dict

# Run with verbose output
pytest -v

# Run only unit tests
pytest tests/unit/

# Run only integration tests
pytest tests/integration/

Test Categories

Unit Tests

Unit tests verify individual functions and classes in isolation.

Node.js (test/unit/)

Test File Tests Description
data-helpers.test.ts 40 Data processing utilities, byte parsing, normalization
finddevice.test.ts 28 Device discovery, WebHID integration, connection handling
config.test.ts 13 Configuration loading, validation, serialization
config-based-mock.test.ts 18 Mock tablet data generation from configs
byte-detector.test.ts 14 Byte analysis, status byte detection, variance calculation
metadata-generator.test.ts 10 Device metadata generation, capability inference
walkthrough-detection.test.ts 9 Core byte detection for walkthrough steps
walkthrough-button-status.test.ts 12 Status byte tracking for XP-Pen and Huion tablets
device-switching.test.ts 8 Multi-device handling, active device tracking
translation-*.test.ts 20 Data translation and edge cases

Python (python/tests/unit/)

Test File Tests Description
test_data_helpers.py 40+ Data processing, byte parsing (mirrors Node.js)
test_config.py 15+ Configuration loading and validation
test_config_based_mock.py 18 Mock tablet data generation
test_byte_detector.py 14 Byte analysis algorithms
test_walkthrough_engine.py 20+ Walkthrough engine logic
test_config_auto_detection.py 5 Auto-detection of tablet configs

Integration Tests

Integration tests verify complete workflows using recorded HID data.

Recording Replay Tests

These tests replay recorded HID packets through the walkthrough engine to verify correct configuration generation.

Test File Tests Description
recording-replay.test.ts 92 XP-Pen Deco 640 driverless mode recordings
recording-replay-driver.test.ts 94 XP-Pen Deco 640 driver mode recordings
recording-replay-huion.test.ts 60 Huion Inspiroy 2M recordings
test_recording_replay.py 57 Python equivalents of above

Recording Reader Tests

These tests verify that processDeviceData correctly interprets recorded HID packets using existing configurations.

Test File Tests Description
recording-reader-huion.test.ts 80 Huion packet interpretation (40 tests × 2 recordings)
test_recording_reader.py 80 Python equivalent

Test categories include:

  • Status byte interpretation (hover, contact, button states)
  • Coordinate parsing (X, Y, little-endian verification)
  • Pressure parsing and normalization
  • Tilt parsing (bipolar encoding)
  • State transitions (hover→contact, button press/release)
  • Raw byte verification

Config Validation Tests

Test File Tests Description
stable-config-validation.test.ts 5 Validates existing config files load correctly
driver-mode-config-validation.test.ts 6 Validates driver-mode specific configs
test_stable_config_validation.py 5 Python equivalents
test_driver_mode_config_validation.py 6 Python equivalents

Test Fixtures

Common Test Fixtures (common-test-fixtures/)

Shared test data used by both Node.js and Python tests:

File Description
xp-pen-deco640-driver.json XP-Pen Deco 640 config (driver mode)
xp-pen-deco640-driverless.json XP-Pen Deco 640 config (driverless mode)
huion-inspiroy2m.json Huion Inspiroy 2M config
xp-pen-deco640-nodriver-recording.json Recorded HID packets (XP-Pen, no driver)
xp-pen-deco640-nodriver-recording2.json Second recording session
xp-pen-deco640-driver-recording.json Recorded HID packets (XP-Pen, with driver)
xp-pen-deco640-driver-recording2.json Second recording session
huion-inspiroy2m-nodriver-recording.json Recorded HID packets (Huion)
huion-inspiroy2m-nodriver-recording2.json Second recording session

Recording Format

Recording files contain captured HID packets organized by walkthrough step:

{
  "metadata": {
    "deviceName": "XP-Pen Deco 640",
    "recordedAt": "2024-01-15T10:30:00Z",
    "driverMode": false
  },
  "steps": {
    "step1-horizontal": {
      "packets": [[2, 160, 100, 50, ...], [2, 160, 110, 50, ...], ...]
    },
    "step2-vertical": {
      "packets": [...]
    },
    ...
  }
}

Writing Tests

Test Structure (Node.js)

import { describe, it, expect, beforeEach } from 'vitest';

describe('FeatureName', () => {
  let instance: MyClass;

  beforeEach(() => {
    instance = new MyClass();
  });

  describe('methodName', () => {
    it('should do something specific', () => {
      // Arrange
      const input = setupTestData();

      // Act
      const result = instance.methodName(input);

      // Assert
      expect(result).toBe(expectedValue);
    });
  });
});

Test Structure (Python)

import pytest
from blankslate.core import MyClass

class TestFeatureName:
    """Tests for specific feature"""

    @pytest.fixture
    def instance(self):
        return MyClass()

    def test_specific_behavior(self, instance):
        """Should do something specific"""
        # Arrange
        input_data = setup_test_data()

        # Act
        result = instance.method_name(input_data)

        # Assert
        assert result == expected_value

Parametrized Tests

For testing multiple inputs with the same logic:

Node.js:

describe.each([
  ['recording1.json'],
  ['recording2.json'],
])('with %s', (filename) => {
  it('should process correctly', () => {
    const data = loadRecording(filename);
    expect(process(data)).toBeDefined();
  });
});

Python:

@pytest.mark.parametrize("filename", [
    "recording1.json",
    "recording2.json",
])
def test_process_correctly(self, filename):
    data = load_recording(filename)
    assert process(data) is not None

Coverage

Viewing Coverage Reports

Node.js:

npm run test:coverage
# Open coverage/index.html in browser

Python:

pytest --cov=blankslate --cov-report=html
# Open htmlcov/index.html in browser

Coverage Targets

Module Target Current
Core data processing 90%+
Byte detection 90%+
Configuration loading 85%+
Walkthrough engine 80%+
CLI tools 50%+ ⚠️
UI components 30%+ ⚠️

Continuous Integration

Tests run automatically on:

  • Pull requests
  • Pushes to main branch
  • Release tags

Both Node.js and Python test suites must pass before merging.