1+ import pytest
2+ from py_spring_model .core .session_context_holder import SessionContextHolder , Transactional
3+ from py_spring_model .core .model import PySpringModel
4+
5+
6+ class TestSessionDepth :
7+ """Test the explicit session depth tracking functionality"""
8+
9+ def setup_method (self ):
10+ """Clean up any existing sessions before each test"""
11+ SessionContextHolder .clear_session ()
12+
13+ def teardown_method (self ):
14+ """Clean up after each test"""
15+ SessionContextHolder .clear_session ()
16+
17+ def test_session_depth_starts_at_zero (self ):
18+ """Test that session depth starts at 0"""
19+ assert SessionContextHolder .get_session_depth () == 0
20+
21+ def test_session_depth_increments_and_decrements (self ):
22+ """Test that session depth properly increments and decrements"""
23+ # Initially 0
24+ assert SessionContextHolder .get_session_depth () == 0
25+
26+ # Enter first level
27+ depth1 = SessionContextHolder .enter_session ()
28+ assert depth1 == 1
29+ assert SessionContextHolder .get_session_depth () == 1
30+
31+ # Enter second level
32+ depth2 = SessionContextHolder .enter_session ()
33+ assert depth2 == 2
34+ assert SessionContextHolder .get_session_depth () == 2
35+
36+ # Exit second level
37+ depth_after_exit1 = SessionContextHolder .exit_session ()
38+ assert depth_after_exit1 == 1
39+ assert SessionContextHolder .get_session_depth () == 1
40+
41+ # Exit first level
42+ depth_after_exit2 = SessionContextHolder .exit_session ()
43+ assert depth_after_exit2 == 0
44+ assert SessionContextHolder .get_session_depth () == 0
45+
46+ def test_session_cleared_only_at_outermost_level (self ):
47+ """Test that session is only cleared when depth reaches 0"""
48+ # Enter first level and create session
49+ SessionContextHolder .enter_session ()
50+ session = SessionContextHolder .get_or_create_session ()
51+ assert SessionContextHolder .has_session ()
52+
53+ # Enter second level - session should still exist
54+ SessionContextHolder .enter_session ()
55+ assert SessionContextHolder .has_session ()
56+ assert SessionContextHolder .get_session_depth () == 2
57+
58+ # Exit second level - session should still exist
59+ SessionContextHolder .exit_session ()
60+ assert SessionContextHolder .has_session ()
61+ assert SessionContextHolder .get_session_depth () == 1
62+
63+ # Exit first level - session should be cleared
64+ SessionContextHolder .exit_session ()
65+ assert not SessionContextHolder .has_session ()
66+ assert SessionContextHolder .get_session_depth () == 0
67+
68+ def test_clear_session_resets_depth (self ):
69+ """Test that clear_session() resets the depth to 0"""
70+ SessionContextHolder .enter_session ()
71+ SessionContextHolder .enter_session ()
72+ assert SessionContextHolder .get_session_depth () == 2
73+
74+ SessionContextHolder .clear_session ()
75+ assert SessionContextHolder .get_session_depth () == 0
76+
77+ @pytest .mark .parametrize ("nesting_levels" , [1 , 2 , 3 , 5 ])
78+ def test_transactional_depth_tracking (self , nesting_levels ):
79+ """Test that @Transactional properly tracks depth at various nesting levels"""
80+ depth_records = []
81+
82+ def create_nested_function (level : int ):
83+ @Transactional
84+ def nested_func ():
85+ current_depth = SessionContextHolder .get_session_depth ()
86+ depth_records .append (current_depth )
87+ if level > 1 :
88+ create_nested_function (level - 1 )()
89+ return nested_func
90+
91+ # Create and execute nested function
92+ outermost_func = create_nested_function (nesting_levels )
93+ outermost_func ()
94+
95+ # Verify depth progression
96+ assert len (depth_records ) == nesting_levels
97+ for i , recorded_depth in enumerate (depth_records ):
98+ expected_depth = i + 1
99+ assert recorded_depth == expected_depth , f"At level { i + 1 } , expected depth { expected_depth } , got { recorded_depth } "
100+
101+ # Verify session is cleaned up
102+ assert SessionContextHolder .get_session_depth () == 0
103+ assert not SessionContextHolder .has_session ()
104+
105+ def test_depth_prevents_negative_values (self ):
106+ """Test that depth counter prevents going below 0"""
107+ assert SessionContextHolder .get_session_depth () == 0
108+
109+ # Try to exit when already at 0
110+ new_depth = SessionContextHolder .exit_session ()
111+ assert new_depth == 0
112+ assert SessionContextHolder .get_session_depth () == 0
0 commit comments