Skip to content

v0.1.54 - MockDevice Refactoring (2025-12-14)

What Changed?

This release refactors MockDevice to use real device responses from the refs/ directory instead of hardcoded responses. All device response data now comes from actual device responses captured during testing, ensuring compatibility with firmware v1.17.1. The refactoring reduces code complexity by ~200 lines and improves maintainability.


What's New

Main Feature: File-Based Response Loading for MockDevice

What it does: MockDevice now dynamically loads device responses from JSON files in the refs/ directory. Commands are validated against get_usage.json and responses are automatically served without hardcoded dictionaries.

How to use it: MockDevice usage remains the same for end users, but internally it now uses real device responses:

from kazunoko import MockDevice, Command

# Create mock device with real device responses
device = MockDevice()

# Query commands - responses come from refs/ files
response = device.query("GET_STATUS")
print(response.version)  # "1.17.1" (real device value)

# Use with Command class
cmd = Command(device)
status = cmd.status()
version = cmd.version()

Installation

Quick Start

# Get the release
git checkout v0.1.54

# Setup
task env:setup

# Run CLI
uv run kazunoko --help

# Test MockDevice
uv run python3 -c "from kazunoko import MockDevice; d = MockDevice(); print(d.query('GET_VERSION').version)"

What's Different from the Last Version?

✅ Added

  • _load_available_commands(): Loads 40+ commands from get_usage.json at runtime
  • _load_response_from_refs(): Dynamically loads response JSON files (case-insensitive)
  • Support for refs/ directory in package distribution via [tool.uv_build]

🔧 Changed

  • MockDevice responses: Now loaded from refs/ instead of hardcoded dictionaries
  • MockDevice.init(): Removed responses parameter (no custom responses)
  • Response type: All MockDevice responses now have type: "mock"
  • Command validation: Uses available_commands from get_usage.json

🗑️ Removed

  • 200+ lines of hardcoded response dictionaries
  • _update_state() method (state management not needed)
  • _reset_state() method
  • State variables: poll_count, threshold, version, uptime
  • custom_responses parameter from MockDevice.init()

Is It Safe to Upgrade?

Backward Compatible: Partial ⚠️

Breaking Changes:

  • MockDevice(responses={...}) is no longer supported
  • If you pass a responses dict to MockDevice, it will be ignored

Safe for:

  • Using MockDevice() without parameters
  • Using MockDevice with Command class
  • Using MockDevice with MockGenerator for event simulation
  • All CLI functionality remains unchanged

Migration:

If you were using custom responses:

# Old (no longer works)
device = MockDevice(responses={"GET_STATUS": {...}})

# New approach
device = MockDevice()
# Add response file to refs/get_status.json instead

Tests Passed

  • ✅ Builds without errors
  • ✅ 40 commands loaded from get_usage.json
  • ✅ GET_STATUS response matches firmware v1.17.1
  • ✅ GET_VERSION returns "1.17.1"
  • ✅ Unknown command returns error response with type: "mock"
  • ✅ Timestamp fields (received_us, sent_at) are removed from responses

Release Details

  • Date: 2025-12-14
  • Version: v0.1.54
  • Files Changed: 2 (mock.py, pyproject.toml)
  • Commits: 59464c4 (refactor: Replace hardcoded MockDevice responses with refs/ files)

Benefits

  • Real Device Compatibility: Uses actual device responses (v1.17.1)
  • Maintainability: Update refs/ JSON files instead of editing code
  • Extensibility: Add new commands by creating JSON files only
  • Code Quality: Reduced complexity, better SRP, DRY principle
  • Single Source of Truth: All responses come from refs/

Next Steps

  • Consider adding state management layer for stateful commands (SET_THRESHOLD, SET_POLL_COUNT, etc.)
  • Add events.jsonl default loading to MockGenerator
  • Expand refs/ directory with more command responses as needed