binja-test-mocks


Namebinja-test-mocks JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryMock Binary Ninja API for testing Binary Ninja plugins without requiring a license
upload_time2025-07-19 10:36:12
maintainerNone
docs_urlNone
authormblsha
requires_python>=3.10
licenseMIT
keywords binary ninja testing mocks reverse engineering
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # binja-test-mocks

[![CI](https://github.com/mblsha/binja-test-mocks/actions/workflows/tests.yml/badge.svg)](https://github.com/mblsha/binja-test-mocks/actions/workflows/tests.yml)
[![PyPI version](https://badge.fury.io/py/binja-test-mocks.svg)](https://badge.fury.io/py/binja-test-mocks)
[![Python versions](https://img.shields.io/pypi/pyversions/binja-test-mocks.svg)](https://pypi.org/project/binja-test-mocks/)

Mock Binary Ninja API for testing Binary Ninja plugins without requiring a Binary Ninja license.

## Overview

`binja-test-mocks` provides a comprehensive set of mock objects and utilities that allow you to:
- Unit test Binary Ninja plugins without a Binary Ninja installation
- Run type checking with mypy/pyright using accurate type stubs
- Develop and test plugins in CI/CD environments

## Installation

```bash
pip install binja-test-mocks
```

For development:
```bash
pip install -e /path/to/binja-test-mocks
```

## Quick Start

### Basic Usage

```python
# In your test files, set the environment variable before imports
import os
os.environ["FORCE_BINJA_MOCK"] = "1"

# Import the mock API before importing your plugin
from binja_test_mocks import binja_api  # noqa: F401

# Now you can import your plugin modules that use Binary Ninja
from your_plugin import YourArchitecture
```

### Example Test

```python
import os
os.environ["FORCE_BINJA_MOCK"] = "1"

from binja_test_mocks import binja_api  # noqa: F401
from binja_test_mocks.mock_llil import MockLowLevelILFunction
from your_plugin.arch import MyArchitecture

def test_instruction_lifting():
    # Create mock LLIL function
    il = MockLowLevelILFunction()
    
    # Test your architecture's IL generation
    arch = MyArchitecture()
    arch.get_instruction_low_level_il(b"\x90", 0x1000, il)
    
    # Verify the generated IL
    assert len(il.operations) == 1
    assert il.operations[0].op == "NOP"
```

## Components

### Mock Modules

- **binja_api.py**: Core mock loader that intercepts Binary Ninja imports
- **mock_llil.py**: Mock Low Level IL classes and operations
- **mock_binaryview.py**: Mock BinaryView for testing file format plugins
- **mock_analysis.py**: Mock analysis information (branches, calls, etc.)
- **tokens.py**: Token generation utilities for disassembly
- **coding.py**: Binary encoding/decoding helpers
- **eval_llil.py**: LLIL expression evaluator for testing

### Type Stubs

Complete type stubs for Binary Ninja API in `stubs/binaryninja/`:
- architecture.pyi
- binaryview.pyi
- lowlevelil.pyi
- enums.pyi
- types.pyi
- function.pyi
- log.pyi
- interaction.pyi

## Integration Examples

### Plugin Structure

```python
# your_plugin/__init__.py
import sys
from pathlib import Path

# Add plugin directory to path
plugin_dir = str(Path(__file__).resolve().parent)
if plugin_dir not in sys.path:
    sys.path.insert(0, plugin_dir)

# For testing, load mock API
import os
if os.environ.get("FORCE_BINJA_MOCK") == "1":
    from binja_test_mocks import binja_api  # noqa: F401

# Your normal plugin code
from binaryninja import Architecture
from .arch import MyArchitecture

MyArchitecture.register()
```

### Type Checking Configuration

#### mypy.ini
```ini
[mypy]
mypy_path = /path/to/binja-test-mocks/src/binja_test_mocks/stubs
plugins = mypy_binja_plugin

[mypy-binaryninja.*]
ignore_missing_imports = False
```

#### pyrightconfig.json
```json
{
  "extraPaths": [
    "/path/to/binja-test-mocks/src/binja_test_mocks/stubs"
  ],
  "typeCheckingMode": "strict"
}
```

### Running Tests

```bash
# Set environment variable and run pytest
FORCE_BINJA_MOCK=1 pytest

# Or use a test runner script
python -m binja_test_mocks.scripts.run_tests
```

## Advanced Usage

### Custom Mock Behavior

```python
from binja_test_mocks.mock_llil import MockLowLevelILFunction

class CustomMockIL(MockLowLevelILFunction):
    def __init__(self):
        super().__init__()
        self.custom_data = []
    
    def append(self, expr):
        self.custom_data.append(expr)
        return super().append(expr)
```

### Testing Binary Views

```python
from binja_test_mocks.mock_binaryview import MockBinaryView

def test_binary_view_parsing():
    data = b"\x4d\x5a\x90\x00"  # PE header
    bv = MockBinaryView(data)
    
    # Your binary view implementation
    my_view = MyBinaryView(bv)
    assert my_view.init()
```

## Migration from binja_helpers

If you're migrating from the old `binja_helpers`:

1. Update imports:
   ```python
   # Old
   from binja_helpers import binja_api
   
   # New
   from binja_test_mocks import binja_api
   ```

2. Update path additions if needed:
   ```python
   # Old
   sys.path.insert(0, str(plugin_dir / "binja_helpers_tmp"))
   
   # New - not needed if installed via pip
   ```

## Contributing

Contributions are welcome! Please ensure:
- All tests pass with `pytest`
- Type checking passes with `mypy` and `pyright`
- Code is formatted with `ruff`

## License

MIT License - see LICENSE file for details.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "binja-test-mocks",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "binary ninja, testing, mocks, reverse engineering",
    "author": "mblsha",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/1e/21/ab1aa17da4e38e32eb16ad3ae0bfd54fca534e0c0cb4699806dd600c9036/binja_test_mocks-0.1.0.tar.gz",
    "platform": null,
    "description": "# binja-test-mocks\n\n[![CI](https://github.com/mblsha/binja-test-mocks/actions/workflows/tests.yml/badge.svg)](https://github.com/mblsha/binja-test-mocks/actions/workflows/tests.yml)\n[![PyPI version](https://badge.fury.io/py/binja-test-mocks.svg)](https://badge.fury.io/py/binja-test-mocks)\n[![Python versions](https://img.shields.io/pypi/pyversions/binja-test-mocks.svg)](https://pypi.org/project/binja-test-mocks/)\n\nMock Binary Ninja API for testing Binary Ninja plugins without requiring a Binary Ninja license.\n\n## Overview\n\n`binja-test-mocks` provides a comprehensive set of mock objects and utilities that allow you to:\n- Unit test Binary Ninja plugins without a Binary Ninja installation\n- Run type checking with mypy/pyright using accurate type stubs\n- Develop and test plugins in CI/CD environments\n\n## Installation\n\n```bash\npip install binja-test-mocks\n```\n\nFor development:\n```bash\npip install -e /path/to/binja-test-mocks\n```\n\n## Quick Start\n\n### Basic Usage\n\n```python\n# In your test files, set the environment variable before imports\nimport os\nos.environ[\"FORCE_BINJA_MOCK\"] = \"1\"\n\n# Import the mock API before importing your plugin\nfrom binja_test_mocks import binja_api  # noqa: F401\n\n# Now you can import your plugin modules that use Binary Ninja\nfrom your_plugin import YourArchitecture\n```\n\n### Example Test\n\n```python\nimport os\nos.environ[\"FORCE_BINJA_MOCK\"] = \"1\"\n\nfrom binja_test_mocks import binja_api  # noqa: F401\nfrom binja_test_mocks.mock_llil import MockLowLevelILFunction\nfrom your_plugin.arch import MyArchitecture\n\ndef test_instruction_lifting():\n    # Create mock LLIL function\n    il = MockLowLevelILFunction()\n    \n    # Test your architecture's IL generation\n    arch = MyArchitecture()\n    arch.get_instruction_low_level_il(b\"\\x90\", 0x1000, il)\n    \n    # Verify the generated IL\n    assert len(il.operations) == 1\n    assert il.operations[0].op == \"NOP\"\n```\n\n## Components\n\n### Mock Modules\n\n- **binja_api.py**: Core mock loader that intercepts Binary Ninja imports\n- **mock_llil.py**: Mock Low Level IL classes and operations\n- **mock_binaryview.py**: Mock BinaryView for testing file format plugins\n- **mock_analysis.py**: Mock analysis information (branches, calls, etc.)\n- **tokens.py**: Token generation utilities for disassembly\n- **coding.py**: Binary encoding/decoding helpers\n- **eval_llil.py**: LLIL expression evaluator for testing\n\n### Type Stubs\n\nComplete type stubs for Binary Ninja API in `stubs/binaryninja/`:\n- architecture.pyi\n- binaryview.pyi\n- lowlevelil.pyi\n- enums.pyi\n- types.pyi\n- function.pyi\n- log.pyi\n- interaction.pyi\n\n## Integration Examples\n\n### Plugin Structure\n\n```python\n# your_plugin/__init__.py\nimport sys\nfrom pathlib import Path\n\n# Add plugin directory to path\nplugin_dir = str(Path(__file__).resolve().parent)\nif plugin_dir not in sys.path:\n    sys.path.insert(0, plugin_dir)\n\n# For testing, load mock API\nimport os\nif os.environ.get(\"FORCE_BINJA_MOCK\") == \"1\":\n    from binja_test_mocks import binja_api  # noqa: F401\n\n# Your normal plugin code\nfrom binaryninja import Architecture\nfrom .arch import MyArchitecture\n\nMyArchitecture.register()\n```\n\n### Type Checking Configuration\n\n#### mypy.ini\n```ini\n[mypy]\nmypy_path = /path/to/binja-test-mocks/src/binja_test_mocks/stubs\nplugins = mypy_binja_plugin\n\n[mypy-binaryninja.*]\nignore_missing_imports = False\n```\n\n#### pyrightconfig.json\n```json\n{\n  \"extraPaths\": [\n    \"/path/to/binja-test-mocks/src/binja_test_mocks/stubs\"\n  ],\n  \"typeCheckingMode\": \"strict\"\n}\n```\n\n### Running Tests\n\n```bash\n# Set environment variable and run pytest\nFORCE_BINJA_MOCK=1 pytest\n\n# Or use a test runner script\npython -m binja_test_mocks.scripts.run_tests\n```\n\n## Advanced Usage\n\n### Custom Mock Behavior\n\n```python\nfrom binja_test_mocks.mock_llil import MockLowLevelILFunction\n\nclass CustomMockIL(MockLowLevelILFunction):\n    def __init__(self):\n        super().__init__()\n        self.custom_data = []\n    \n    def append(self, expr):\n        self.custom_data.append(expr)\n        return super().append(expr)\n```\n\n### Testing Binary Views\n\n```python\nfrom binja_test_mocks.mock_binaryview import MockBinaryView\n\ndef test_binary_view_parsing():\n    data = b\"\\x4d\\x5a\\x90\\x00\"  # PE header\n    bv = MockBinaryView(data)\n    \n    # Your binary view implementation\n    my_view = MyBinaryView(bv)\n    assert my_view.init()\n```\n\n## Migration from binja_helpers\n\nIf you're migrating from the old `binja_helpers`:\n\n1. Update imports:\n   ```python\n   # Old\n   from binja_helpers import binja_api\n   \n   # New\n   from binja_test_mocks import binja_api\n   ```\n\n2. Update path additions if needed:\n   ```python\n   # Old\n   sys.path.insert(0, str(plugin_dir / \"binja_helpers_tmp\"))\n   \n   # New - not needed if installed via pip\n   ```\n\n## Contributing\n\nContributions are welcome! Please ensure:\n- All tests pass with `pytest`\n- Type checking passes with `mypy` and `pyright`\n- Code is formatted with `ruff`\n\n## License\n\nMIT License - see LICENSE file for details.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Mock Binary Ninja API for testing Binary Ninja plugins without requiring a license",
    "version": "0.1.0",
    "project_urls": {
        "Homepage": "https://github.com/mblsha/binja-test-mocks",
        "Issues": "https://github.com/mblsha/binja-test-mocks/issues",
        "Repository": "https://github.com/mblsha/binja-test-mocks"
    },
    "split_keywords": [
        "binary ninja",
        " testing",
        " mocks",
        " reverse engineering"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8d6c9d4d082970219ad5ea97fade58abd4a6247647ddf51f1600828492527b6b",
                "md5": "7f642ad39425442549027b12cb6fc897",
                "sha256": "621f5504b6bfd43ca31adb33e0ca1959b06860176eb256e4cf2be7692533fbb6"
            },
            "downloads": -1,
            "filename": "binja_test_mocks-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7f642ad39425442549027b12cb6fc897",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 25127,
            "upload_time": "2025-07-19T10:36:10",
            "upload_time_iso_8601": "2025-07-19T10:36:10.829287Z",
            "url": "https://files.pythonhosted.org/packages/8d/6c/9d4d082970219ad5ea97fade58abd4a6247647ddf51f1600828492527b6b/binja_test_mocks-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1e21ab1aa17da4e38e32eb16ad3ae0bfd54fca534e0c0cb4699806dd600c9036",
                "md5": "9b49156cc89fe5b6f17b018b773f8106",
                "sha256": "4924cbdd6827f627d393ecfda5a0cb4661e63cf8db2071d14831c42aace5ec07"
            },
            "downloads": -1,
            "filename": "binja_test_mocks-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9b49156cc89fe5b6f17b018b773f8106",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 22223,
            "upload_time": "2025-07-19T10:36:12",
            "upload_time_iso_8601": "2025-07-19T10:36:12.380711Z",
            "url": "https://files.pythonhosted.org/packages/1e/21/ab1aa17da4e38e32eb16ad3ae0bfd54fca534e0c0cb4699806dd600c9036/binja_test_mocks-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-19 10:36:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mblsha",
    "github_project": "binja-test-mocks",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "binja-test-mocks"
}
        
Elapsed time: 1.15300s