Contributing to Mock Jutsu
May 15, 2026 · View on GitHub
Mock Jutsu is a zero-dependency, pure-Python algorithmic mock data engine. 192 data types, 6 locales, real checksums and ISO-compliant formats. This guide gets you from zero to your first merged contribution.
Developer: Altan Sezer Ayan
GitHub: https://github.com/altansayan
LinkedIn: https://www.linkedin.com/in/altansezerayan/
Repository: https://github.com/altansayan/mock-jutsu-api
License: MIT — https://github.com/altansayan/mock-jutsu-api/blob/main/LICENSE
Quick Setup
git clone https://github.com/altansayan/mock-jutsu-api.git
cd mock-jutsu-api
pip install -e ".[test]"
playwright install chromium
pytest tests/ -q --no-cov # should be ~2875 passed
How the Codebase Works
Data flow
mockjutsu generate <type>
↓
cli.py (Click)
↓
core.py MockJutsuCore.generate()
↓
generators/<domain>.py
↓
string output
core.py — the dispatcher
Every data type is registered in two places in core.py:
- A type set (e.g.
_HEALTH_TYPES = {'nhs_number', 'icd10', ...}) - A dispatch branch in
generate():elif dt in _HEALTH_TYPES: result = self.health.generate(dt, **kwargs)
cli.py — the reference table
_REFERENCE is a list of tuples that drives:
mockjutsu listoutput- All 6 multilingual HTML documentation files (via
generate_full_docs.py) - Sync guard tests (
test_sync.py)
# (type_name, Category, locale_aware, example_output, cli_cmd, description, extra_param)
('nhs_number', 'Health', False, '943 476 5919', 'generate nhs_number', 'UK NHS Number (Modulo 11).', '-'),
Adding a New Data Type — Step by Step
See also:
GENERATOR_SOP.md— the authoritative 6-step quality checklist that must be completed before any PR is merged.
0. Update compliance files (MANDATORY — do this before writing any code)
Every new type must be registered in the compliance layer first.
compliance/algorithm_vectors.json — add at least one known-valid real-world value:
"my_type": {
"standard": "ISO XXXX or RFC YYYY",
"reference": "https://...",
"rule": "describe the checksum/format rule",
"valid": ["known-valid-value-1", "known-valid-value-2"],
"invalid": ["known-invalid-value"]
}
compliance/format_contracts.json — add the canonical regex pattern:
"my_type": {"pattern": "^[A-Z]{2}\\d{10}$", "example": "AB1234567890"}
tests/test_known_vectors.py — add a vector test function:
def test_my_type_known_vectors():
v = _load_vectors()
for val in v["my_type"]["valid"]:
assert _my_type_check(val), f"Vector failed: {val}"
Run to confirm the vector test passes:
pytest tests/test_known_vectors.py -q --no-cov
If you are also adding a Java counterpart in mock-jutsu-jmeter, update KnownVectorTest.java with the same vectors — compliance/ is the single source of truth for both repos.
1. Write tests first (TDD)
Create tests/test_<domain>.py or extend an existing one.
Reference the real standard (ISO, RFC, NHS spec, etc.).
class TestMyNewType:
def test_format(self):
val = jutsu.generate('my_type')
assert re.match(r'^[A-Z]{2}\d{10}$', val)
def test_bulk_unique(self):
results = jutsu.bulk('my_type', 20)
assert len(set(results)) > 1
Run to confirm they fail (red phase):
pytest tests/test_<domain>.py -q --no-cov
2. Implement the generator
Edit or create src/mockjutsu/generators/<domain>.py.
Rules:
- Zero external dependencies — pure Python stdlib only
- Module-level imports — never
import xinside a function (performance) - Generator class must implement
def generate(self, data_type, **kwargs) -> str - Return
f"ERROR: Unknown type '{data_type}'"for unknown types
import random
import secrets
class MyDomainGenerator:
def generate(self, data_type, **kwargs):
if data_type == 'my_type':
return _generate_my_type()
return f"ERROR: Unknown type '{data_type}'"
def _generate_my_type():
...
Run tests to confirm they pass (green phase):
pytest tests/test_<domain>.py -q --no-cov
3. Register in core.py
# Add type set (top of file, with other _*_TYPES)
_MYDOMAIN_TYPES = {'my_type', 'my_other_type'}
# Import the generator (with other imports)
from .generators.mydomain import MyDomainGenerator
# Instantiate in __init__
self.mydomain = MyDomainGenerator()
# Add dispatch in generate()
elif dt in _MYDOMAIN_TYPES:
result = self.mydomain.generate(dt, **kwargs)
4. Register in cli.py _REFERENCE
# Optional section header (visual separator in CLI list output)
('--MyCategory--', '', False, '', '', '', ''),
# Type row
('my_type', 'MyCategory', False, 'ABC1234567890', 'generate my_type', 'What this generates.', '-'),
If using a new category, also add it to _CAT_ORDER and _CAT_COLORS:
_CAT_ORDER = [..., 'MyCategory']
_CAT_COLORS = {'MyCategory': 'bright_magenta'}
5. Regenerate HTML documentation (MANDATORY)
The 6 multilingual HTML files are auto-generated — never edit them manually. The process has two steps: first generate AI-written content, then build the HTML.
5a. Set up your Gemini API key (one-time)
generate_ai_content.py calls the Gemini API to write the descriptive content
(use-cases, code examples, notes) that appears on each type's documentation page.
Without it, new types will be missing from the HTML and test_sync.py will block your push.
cp .env.example .env
# Then open .env and fill in your key:
# GEMINI_API_KEY=your_gemini_api_key_here
Get a free key at: https://aistudio.google.com/
The script also accepts GOOGLE_API_KEY as a fallback. The .env file is in
.gitignore — never commit your key.
5b. Generate AI content for new types
python generate_ai_content.py
Already-generated types are skipped automatically (SKIP in the output).
Only new or missing types call the API, so this is fast on subsequent runs.
5c. Build the HTML
# Windows PowerShell
$env:PYTHONIOENCODING="utf-8"; python generate_full_docs.py
# Linux / macOS
PYTHONIOENCODING=utf-8 python generate_full_docs.py
Expected output:
Generating HOW-TO 2.0 — 236 functions × 6 languages
...
Done — 1452 pages + 1453 sitemap URLs generated.
README: 236 total types, group counts updated
index.html: 236+ Types updated
6. Run the full test suite
pytest tests/ -q --no-cov # fast check
pytest tests/ --cov=mockjutsu # with coverage (must be ≥ 85%)
7. Performance check
Every type must complete 200 iterations in under 300ms (1.5ms per call).
pytest tests/test_performance.py -q --no-cov
If your type is inherently slow (e.g. involves many random bytes), add it to HEAVY_TYPES
in test_performance.py to exempt it from the latency baseline.
8. Commit and push
git add <files>
git commit -m "feat(<domain>): add <type_name> generator"
git push origin main
The pre-push hook runs automatically before upload:
scripts/audit_compliance.py— checks zero-dependency, structural rulespytest --cov-fail-under=85— full test suite with coverage enforcement
Push is blocked if any check fails.
Sync Guard — What Keeps Everything Consistent
tests/test_sync.py runs on every push and enforces:
| Check | Rule |
|---|---|
test_core_type_in_reference_table | Every type in core.py must be in cli.py _REFERENCE |
test_core_type_visible_in_html_tr | Every _REFERENCE type must have a data-fn row in TR HTML |
test_html_type_count_matches_core | data-fn count in all 6 HTML files must equal _REFERENCE count |
test_no_orphan_types_in_reference | No _REFERENCE type may be missing from core.py |
If you forget to run generate_full_docs.py, the HTML won't have the new data-fn rows,
the count test fails, and push is blocked. This is by design.
CI Pipeline
GitHub Actions runs on every push and PR to main:
- Matrix: Python 3.10, 3.11, 3.12, 3.13
- fail-fast: false — all Python versions report independently
- Steps: checkout → setup-python →
pip install -e ".[test]"→ playwright install → pytest
Python version policy: only active CPython releases. Python 3.9 reached EOL October 2025 and has been removed permanently.
Project Constraints
| Rule | Detail |
|---|---|
| Zero dependencies | Only Python stdlib. import requests → rejected. |
| No lazy imports | Imports inside functions hurt performance at 200 iter/call. |
| No hardcoded years | Use datetime.now().year — hardcoded years break next January. |
| No manual HTML edits | Always run generate_full_docs.py — HTML is generated. |
| Test coverage ≥ 85% | Enforced by pyproject.toml and CI. Currently ~97%. |
| Latency < 1.5ms/call | Enforced by test_performance.py. |
Category Reference
| Category | Contains |
|---|---|
| Identity | TCKN, SSN, NIN, INN, SNILS, passports... |
| Financial | Cards (Luhn), IBAN, EMV, 3DS, credit score... |
| Banking | SWIFT, sort code, routing number, BIK... |
| CapMarkets(Trading) | ISIN, CUSIP, SEDOL, LEI, FIX protocol, PSD2... |
| Health | HL7, FHIR, DICOM, NHS, NPI, ICD-10, BMI... |
| Security | API key, JWT, TOTP, CEF log, X.509, pcap hex... |
| IoT (RFID/NFC/IR) | EPC, NDEF, APDU, NEC/RC5/Pronto IR codes... |
| Hardware | Track2, EMV chip TLV, ISO 9564 PIN block... |
🌍 Global Ecosystem Strategy
We are expanding Mock Jutsu to all major platforms. If you are building a wrapper, ensure it follows the same algorithmic integrity as the core engine.
- PyPI (Python):
pip install mockjutsu(Active) - Homebrew (macOS/Linux):
brew install mockjutsu - NPM (JavaScript):
npx mockjutsuwrapper - NuGet (.NET): Standalone
.exevia PyInstaller - Maven (Java/Kotlin): JNI/ProcessBuilder wrapper
- VS Code Marketplace: Extension for direct IBAN/QR/UUID injection
Getting Help
- Open an issue: https://github.com/altansayan/mock-jutsu-api/issues
- Read the type reference:
mockjutsu list - Browse the interactive docs:
HOW-TO-MockJutsu-EN.html
Stay professional, code with precision. ⚔️