(Init): Added shit

This commit is contained in:
2026-05-29 00:41:12 +00:00
commit 72005fd71d
52 changed files with 12875 additions and 0 deletions

162
tests/test_state.py Normal file
View File

@@ -0,0 +1,162 @@
"""Unit tests for the AppState manager.
Tests state initialization, dirty tracking, undo/redo integration,
commit_save, discard, and node serialization helpers — without requiring
a live GTK session or filesystem access.
"""
from __future__ import annotations
import unittest
from unittest.mock import patch
from nirimod.kdl_parser import KdlNode, KdlRawString, parse_kdl, write_kdl
from nirimod.state import AppState
class TestAppStateInit(unittest.TestCase):
"""AppState starts in a clean, non-dirty state."""
def test_initial_state(self):
state = AppState()
self.assertEqual(state.nodes, [])
self.assertEqual(state.saved_kdl, "")
self.assertFalse(state.is_dirty)
self.assertFalse(state.niri_running)
self.assertFalse(state.has_touchpad)
def test_initial_undo_empty(self):
state = AppState()
self.assertFalse(state.undo.can_undo())
self.assertFalse(state.undo.can_redo())
class TestDirtyTracking(unittest.TestCase):
def test_mark_dirty(self):
state = AppState()
self.assertFalse(state.is_dirty)
state.mark_dirty()
self.assertTrue(state.is_dirty)
def test_mark_clean(self):
state = AppState()
state.mark_dirty()
state.mark_clean()
self.assertFalse(state.is_dirty)
class TestUndoRedo(unittest.TestCase):
def _make_state_with_nodes(self, kdl: str) -> AppState:
state = AppState()
state.nodes = parse_kdl(kdl)
state._saved_kdl = kdl
return state
def test_push_and_apply_undo(self):
state = self._make_state_with_nodes("gaps 8\n")
before = "gaps 8\n"
after = "gaps 16\n"
state.push_undo("change gaps", before, after)
self.assertTrue(state.undo.can_undo())
entry = state.apply_undo()
self.assertIsNotNone(entry)
self.assertEqual(state.nodes[0].get_child("gaps") if state.nodes and state.nodes[0].children else None, None)
# After undo, nodes should be from the 'before' snapshot
kdl_out = write_kdl(state.nodes)
self.assertIn("8", kdl_out)
def test_apply_undo_empty_returns_none(self):
state = AppState()
result = state.apply_undo()
self.assertIsNone(result)
def test_apply_redo_empty_returns_none(self):
state = AppState()
result = state.apply_redo()
self.assertIsNone(result)
def test_undo_sets_dirty(self):
state = self._make_state_with_nodes("gaps 8\n")
state.push_undo("x", "gaps 16\n", "gaps 24\n")
state.apply_undo()
self.assertTrue(state.is_dirty)
def test_redo_after_undo(self):
state = self._make_state_with_nodes("gaps 8\n")
state.push_undo("x", "gaps 8\n", "gaps 16\n")
state.apply_undo()
self.assertTrue(state.undo.can_redo())
entry = state.apply_redo()
self.assertIsNotNone(entry)
kdl_out = write_kdl(state.nodes)
self.assertIn("16", kdl_out)
class TestCommitSave(unittest.TestCase):
def test_commit_save_clears_undo_and_dirty(self):
state = AppState()
state.push_undo("x", "a", "b")
state.mark_dirty()
state.commit_save("new kdl\n")
self.assertEqual(state.saved_kdl, "new kdl\n")
self.assertFalse(state.is_dirty)
self.assertFalse(state.undo.can_undo())
class TestDiscard(unittest.TestCase):
def test_discard_restores_saved_kdl(self):
state = AppState()
state._saved_kdl = "gaps 8\n"
state.nodes = parse_kdl("gaps 16\n")
state.mark_dirty()
state.push_undo("x", "gaps 8\n", "gaps 16\n")
state.discard()
self.assertFalse(state.is_dirty)
self.assertFalse(state.undo.can_undo())
kdl_out = write_kdl(state.nodes)
self.assertIn("8", kdl_out)
def test_discard_empty_saved_kdl(self):
state = AppState()
state._saved_kdl = ""
state.discard()
self.assertEqual(state.nodes, [])
class TestWriteCurrentKdl(unittest.TestCase):
def test_write_current_kdl(self):
state = AppState()
state.nodes = [KdlNode("prefer-no-csd")]
out = state.write_current_kdl()
self.assertIn("prefer-no-csd", out)
def test_write_raw_string(self):
# A string containing a double-quote forces the hash-delimited raw form
node = KdlNode("env", args=[KdlRawString('has "double" quotes')])
out = write_kdl([node])
self.assertIn('r#"', out)
class TestLoad(unittest.TestCase):
def test_load_detects_runtime(self):
state = AppState()
# state.py does: from nirimod import niri_ipc
# We patch at the canonical module location so all references see the mock.
with (
patch("nirimod.niri_ipc.is_niri_running", return_value=True),
patch("nirimod.niri_ipc.has_touchpad", return_value=True),
patch("nirimod.kdl_parser.NIRI_CONFIG") as mock_cfg,
):
mock_cfg.exists.return_value = False
state.load()
self.assertTrue(state.niri_running)
self.assertTrue(state.has_touchpad)
self.assertFalse(state.is_dirty)
if __name__ == "__main__":
unittest.main()