@ -843,6 +843,146 @@ class AutoRoutingTest(unittest.TestCase):
self . assertIsNotNone ( result )
self . assertIsNotNone ( result )
self . assertIn ( " UserPath " , result [ " carrier_kinds " ] )
self . assertIn ( " UserPath " , result [ " carrier_kinds " ] )
def test_route_graph_bridges_endpoint_to_nearby_segment_projection ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 50 , 8 , 20 ) , app . Vector ( 50 , 50 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " UserPath " ,
)
network = routing_network . build_route_graph ( doc , adjoining_duct_tolerance = 15.0 )
start_key , _start_distance = routing_network . nearest_node ( network , app . Vector ( 50 , 50 , 20 ) )
end_key , _end_distance = routing_network . nearest_node ( network , app . Vector ( 100 , 0 , 20 ) )
result = routing_network . shortest_path_with_carriers ( network , start_key , end_key )
self . assertEqual ( 1 , network [ " bridged_segment_count " ] )
self . assertIsNotNone ( result )
self . assertIn ( ( 50000 , 0 , 20000 ) , result [ " path " ] )
def test_auto_routing_uses_endpoint_to_segment_projection_bridge ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalBranch " , " terminal-branch " , app . Vector ( 50 , 50 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalMain " , " terminal-main " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 50 , 8 , 20 ) , app . Vector ( 50 , 50 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " UserPath " ,
)
result = auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
options = { " adjoining_duct_tolerance " : 15.0 } ,
)
self . assertEqual ( " Routed " , result [ " route_status " ] )
self . assertEqual ( 1 , result [ " network " ] [ " bridged_segments " ] )
self . assertEqual ( 1 , result [ " route_track " ] [ " bridged_segments " ] )
self . assertTrue ( any ( segment . get ( " is_bridge " ) for segment in result [ " route_track " ] [ " segments " ] ) )
self . assertIn ( " UserPath " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertIn ( " WireDuct " , result [ " route_track " ] [ " carrier_kinds " ] )
def test_auto_routing_does_not_use_terminal_access_to_bridge_main_path_gap ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 40 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 40 , 0 , 20 ) , app . Vector ( 60 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " TerminalAccess " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 60 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
with self . assertRaises ( auto_routing . AutoRoutingError ) :
auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
options = { " terminal_access_max_distance " : 5.0 } ,
)
def test_route_graph_projection_bridge_respects_blocked_bbox ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 50 , 8 , 20 ) , app . Vector ( 50 , 50 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " UserPath " ,
)
blocked_bboxes = [
{
" xmin " : 45.0 ,
" xmax " : 55.0 ,
" ymin " : 2.0 ,
" ymax " : 6.0 ,
" zmin " : 15.0 ,
" zmax " : 25.0 ,
}
]
network = routing_network . build_route_graph (
doc ,
blocked_bboxes = blocked_bboxes ,
adjoining_duct_tolerance = 15.0 ,
)
start_key , _start_distance = routing_network . nearest_node ( network , app . Vector ( 50 , 50 , 20 ) )
end_key , _end_distance = routing_network . nearest_node ( network , app . Vector ( 100 , 0 , 20 ) )
result = routing_network . shortest_path_with_carriers ( network , start_key , end_key )
self . assertEqual ( 0 , network [ " bridged_segment_count " ] )
self . assertGreaterEqual ( network [ " blocked_segment_count " ] , 1 )
self . assertIsNone ( result )
def test_auto_routing_respects_adjoining_duct_tolerance_option ( self ) :
def test_auto_routing_respects_adjoining_duct_tolerance_option ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -1644,6 +1784,97 @@ class AutoRoutingTest(unittest.TestCase):
end_point = access_carriers [ 0 ] . Points [ - 1 ]
end_point = access_carriers [ 0 ] . Points [ - 1 ]
self . assertEqual ( ( 50.0 , 0.0 , 20.0 ) , ( end_point . x , end_point . y , end_point . z ) )
self . assertEqual ( ( 50.0 , 0.0 , 20.0 ) , ( end_point . x , end_point . y , end_point . z ) )
def test_terminal_access_prefers_larger_connected_network_over_nearer_isolated_stub ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 1 , 20 ) , app . Vector ( 5 , 1 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[
app . Vector ( 0 , 10 , 20 ) ,
app . Vector ( 40 , 10 , 20 ) ,
app . Vector ( 80 , 10 , 20 ) ,
app . Vector ( 120 , 10 , 20 ) ,
] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
created = routing_network . create_terminal_access_carriers_from_document (
doc ,
project_uuid = " project-1 " ,
)
self . assertEqual ( 1 , len ( created ) )
end_point = created [ 0 ] . Points [ - 1 ]
self . assertEqual ( ( 0.0 , 10.0 , 20.0 ) , ( end_point . x , end_point . y , end_point . z ) )
def test_connection_entry_candidates_prefer_wire_duct_over_terminal_access ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 0 , 10 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " TerminalAccess " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 10 , 20 ) , app . Vector ( 100 , 10 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
network = routing_network . build_route_graph ( doc )
ranked = routing_network . rank_connection_point_candidates (
network ,
routing_network . connection_point_candidates ( network , app . Vector ( 0 , 0 , 20 ) , limit = 0 ) ,
)
first_kind = getattr ( ranked [ 0 ] [ " carrier " ] , " QetRouteCarrierKind " , " " )
self . assertEqual ( " WireDuct " , first_kind )
def test_terminal_access_prefers_wire_duct_over_nearer_routing_range ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 1 , 20 ) , app . Vector ( 120 , 1 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " RoutingRange " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 10 , 20 ) , app . Vector ( 120 , 10 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
created = routing_network . create_terminal_access_carriers_from_document (
doc ,
project_uuid = " project-1 " ,
)
self . assertEqual ( 1 , len ( created ) )
end_point = created [ 0 ] . Points [ - 1 ]
self . assertEqual ( ( 0.0 , 10.0 , 20.0 ) , ( end_point . x , end_point . y , end_point . z ) )
def test_eplan_connection_route_enters_network_at_segment_projection ( self ) :
def test_eplan_connection_route_enters_network_at_segment_projection ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -1840,6 +2071,8 @@ class AutoRoutingTest(unittest.TestCase):
self . assertEqual ( " terminal-long-access " , payload [ " long_terminal_accesses " ] [ 0 ] [ " terminal_uuid " ] )
self . assertEqual ( " terminal-long-access " , payload [ " long_terminal_accesses " ] [ 0 ] [ " terminal_uuid " ] )
self . assertEqual ( 900.0 , payload [ " long_terminal_accesses " ] [ 0 ] [ " terminal_access_length_mm " ] )
self . assertEqual ( 900.0 , payload [ " long_terminal_accesses " ] [ 0 ] [ " terminal_access_length_mm " ] )
self . assertIn ( " 端子接入过长 " , message )
self . assertIn ( " 端子接入过长 " , message )
self . assertIn ( " TerminalLongAccess " , message )
self . assertIn ( " terminal-long-access " , message )
self . assertIn ( " 900.0 mm " , message )
self . assertIn ( " 900.0 mm " , message )
def test_check_routing_path_network_warns_for_invalid_terminal_local_route_points ( self ) :
def test_check_routing_path_network_warns_for_invalid_terminal_local_route_points ( self ) :
@ -2042,7 +2275,7 @@ class AutoRoutingTest(unittest.TestCase):
message = auto_routing . format_routing_path_network_report ( diagnostic )
message = auto_routing . format_routing_path_network_report ( diagnostic )
self . assertIn ( " 桥接 1 段相邻 主路径" , message )
self . assertIn ( " 桥接 1 段相邻 /投影 主路径" , message )
def test_check_routing_path_network_uses_adjoining_duct_tolerance_option ( self ) :
def test_check_routing_path_network_uses_adjoining_duct_tolerance_option ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
@ -2194,7 +2427,7 @@ class AutoRoutingTest(unittest.TestCase):
app . ActiveDocument = doc
app . ActiveDocument = doc
terminal_objects . ensure_root_group ( doc , " project-1 " )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 0 , 0 , 0 ) )
routing_network . create_route_carrier (
routing_network . create_route_carrier (
doc ,
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 44 , 0 , 20 ) ] ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 44 , 0 , 20 ) ] ,
@ -2337,6 +2570,39 @@ class AutoRoutingTest(unittest.TestCase):
self . assertEqual ( " z " , report [ " routes " ] [ 1 ] [ " lane " ] [ " axis " ] )
self . assertEqual ( " z " , report [ " routes " ] [ 1 ] [ " lane " ] [ " axis " ] )
self . assertEqual ( 8.0 , report [ " routes " ] [ 1 ] [ " lane " ] [ " offset_mm " ] )
self . assertEqual ( 8.0 , report [ " routes " ] [ 1 ] [ " lane " ] [ " offset_mm " ] )
def test_auto_routing_controller_exposes_lane_max_offset ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , _auto_routing = _reload_modules ( )
auto_routing_panel = importlib . import_module ( " AutoRoutingPanel " )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
app . ActiveDocument = doc
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
controller = auto_routing_panel . AutoRoutingController ( )
controller . set_lane_spacing ( 10.0 )
controller . set_lane_axis ( " y " )
controller . set_lane_max_offset ( 18.0 )
result = _auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
route_index = 21 ,
options = controller . routing_options ( ) ,
)
self . assertEqual ( 18.0 , controller . routing_options ( ) [ " lane_max_offset " ] )
self . assertEqual ( 18.0 , result [ " lane " ] [ " max_offset_mm " ] )
self . assertEqual ( 18.0 , result [ " lane " ] [ " offset_mm " ] )
def test_auto_routing_panel_command_button_style_keeps_text_visible ( self ) :
def test_auto_routing_panel_command_button_style_keeps_text_visible ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , _auto_routing = _reload_modules ( )
_terminal_objects , _wiring_objects , _routing_network , _auto_routing = _reload_modules ( )
@ -2638,6 +2904,77 @@ class AutoRoutingTest(unittest.TestCase):
self . assertGreaterEqual ( result [ " network " ] [ " blocked_segments " ] , 1 )
self . assertGreaterEqual ( result [ " network " ] [ " blocked_segments " ] , 1 )
self . assertIn ( 50.0 , [ point . y for point in result [ " points " ] ] )
self . assertIn ( 50.0 , [ point . y for point in result [ " points " ] ] )
def test_eplan_connection_route_prefers_entry_candidate_without_access_collision ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 20 , 0 , 0 ) , app . Vector ( 100 , 0 , 0 ) ] ,
label = " Near Duct " ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 30 , 0 ) , app . Vector ( 100 , 30 , 0 ) ] ,
label = " Clear Duct " ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
obstacle = doc . addObject ( " Part::Feature " , " AccessObstacle " )
obstacle . Label = " Access Obstacle "
obstacle . Shape = FakeShape ( FakeBoundBox ( 10 , 15 , - 5 , 5 , - 5 , 5 ) )
result = auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
options = { " terminal_exit_length " : 0.0 , " lane_spacing " : 0.0 } ,
)
labels = [
segment [ " carrier " ] [ " label " ]
for segment in result [ " route_track " ] [ " segments " ]
]
self . assertIn ( " Clear Duct " , labels )
self . assertNotIn ( " Near Duct " , labels )
self . assertEqual ( 0 , result [ " collision_count " ] )
def test_eplan_connection_route_chooses_clear_orthogonal_access_order ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 30 , 30 , 0 ) , app . Vector ( 100 , 30 , 0 ) ] ,
label = " Only Duct " ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
obstacle = doc . addObject ( " Part::Feature " , " AccessOrderObstacle " )
obstacle . Shape = FakeShape ( FakeBoundBox ( 10 , 20 , - 5 , 5 , - 5 , 5 ) )
result = auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
options = { " terminal_exit_length " : 0.0 , " lane_spacing " : 0.0 } ,
)
point_tuples = [ ( point . x , point . y , point . z ) for point in result [ " points " ] ]
self . assertIn ( ( 0.0 , 30.0 , 0.0 ) , point_tuples )
self . assertNotIn ( ( 30.0 , 0.0 , 0.0 ) , point_tuples )
self . assertEqual ( 0 , result [ " collision_count " ] )
def test_eplan_connection_route_marks_collision_warning_against_obstacle_bbox ( self ) :
def test_eplan_connection_route_marks_collision_warning_against_obstacle_bbox ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -2771,7 +3108,7 @@ class AutoRoutingTest(unittest.TestCase):
doc = FakeDocument ( )
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 0 , 0 , 0 ) )
payload = {
payload = {
" project_uuid " : " project-1 " ,
" project_uuid " : " project-1 " ,
" wires " : [
" wires " : [
@ -2857,9 +3194,67 @@ class AutoRoutingTest(unittest.TestCase):
self . assertIn ( " WireDuct " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertIn ( " WireDuct " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertNotIn ( " RoutingRange " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertNotIn ( " RoutingRange " , result [ " route_track " ] [ " carrier_kinds " ] )
def test_ route_eplan_connections_from_payload_skips_tasks_when_carriers_have_no_segments ( self ) :
def test_ eplan_connection_route_prefers_wire_duct_when_routing_range_is_only_moderately_shorter ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , wiring_objects , _routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 10 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 10 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " RoutingRange " ,
)
routing_network . create_route_carrier (
doc ,
[
app . Vector ( 0 , 0 , 20 ) ,
app . Vector ( 0 , 145 , 20 ) ,
app . Vector ( 10 , 145 , 20 ) ,
app . Vector ( 10 , 0 , 20 ) ,
] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
result = auto_routing . route_eplan_connection_between_terminals ( doc , start , end )
self . assertIn ( " WireDuct " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertNotIn ( " RoutingRange " , result [ " route_track " ] [ " carrier_kinds " ] )
def test_eplan_connection_route_considers_primary_entry_beyond_nearest_surface_candidates ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
for y in range ( 1 , 11 ) :
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , y , 20 ) , app . Vector ( 100 , y , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " RoutingRange " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 20 , 20 ) , app . Vector ( 100 , 20 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
result = auto_routing . route_eplan_connection_between_terminals ( doc , start , end )
self . assertIn ( " WireDuct " , result [ " route_track " ] [ " carrier_kinds " ] )
self . assertNotIn ( " RoutingRange " , result [ " route_track " ] [ " carrier_kinds " ] )
def test_route_eplan_connections_from_payload_skips_tasks_when_carriers_have_no_segments ( self ) :
_install_fake_freecad ( )
terminal_objects , wiring_objects , _routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
terminal_objects . ensure_root_group ( doc , " project-1 " )
@ -2898,7 +3293,11 @@ class AutoRoutingTest(unittest.TestCase):
] ,
] ,
}
}
report = auto_routing . route_eplan_connections_from_payload ( doc , payload )
report = auto_routing . route_eplan_connections_from_payload (
doc ,
payload ,
options = { " network_entry_max_distance " : 30.0 } ,
)
self . assertEqual ( 1 , report [ " route_network_carriers " ] )
self . assertEqual ( 1 , report [ " route_network_carriers " ] )
self . assertEqual ( 0 , report [ " route_network_segments " ] )
self . assertEqual ( 0 , report [ " route_network_segments " ] )
@ -2909,6 +3308,79 @@ class AutoRoutingTest(unittest.TestCase):
self . assertEqual ( [ ] , report [ " errors " ] )
self . assertEqual ( [ ] , report [ " errors " ] )
self . assertEqual ( [ ] , wiring_objects . iter_routed_wire_objects ( doc ) )
self . assertEqual ( [ ] , wiring_objects . iter_routed_wire_objects ( doc ) )
def test_route_eplan_connections_classifies_disconnected_network_as_missing_route_network ( self ) :
_install_fake_freecad ( )
terminal_objects , wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 10 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 1000 , 0 , 20 ) , app . Vector ( 1010 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
payload = {
" project_uuid " : " project-1 " ,
" wires " : [
{
" wire_id " : " wire-a " ,
" wire_label " : " N4111 " ,
" start_terminal_uuid " : " terminal-start " ,
" start_element_uuid " : " QF1 " ,
" start_terminal_display " : " A1 " ,
" end_terminal_uuid " : " terminal-end " ,
" end_element_uuid " : " KM1 " ,
" end_terminal_display " : " 13 " ,
} ,
] ,
}
report = auto_routing . route_eplan_connections_from_payload (
doc ,
payload ,
options = { " network_entry_max_distance " : 30.0 } ,
)
self . assertEqual ( 0 , report [ " routed " ] )
self . assertEqual ( 1 , report [ " skipped_missing_route_network " ] )
self . assertEqual ( 1 , report [ " route_status_counts " ] [ " MissingRouteNetwork " ] )
self . assertEqual ( [ ] , report [ " errors " ] )
self . assertEqual ( " wire-a " , report [ " missing_route_network_samples " ] [ 0 ] [ " wire_uuid " ] )
self . assertEqual ( [ ] , wiring_objects . iter_routed_wire_objects ( doc ) )
def test_network_entry_uses_terminal_access_max_distance_when_smaller ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 500 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 10 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
route = auto_routing . build_network_route (
start ,
end ,
options = { " terminal_access_max_distance " : 30.0 } ,
doc = doc ,
)
self . assertIsNone ( route )
def test_route_eplan_connections_writes_diagnostic_object_for_missing_terminal ( self ) :
def test_route_eplan_connections_writes_diagnostic_object_for_missing_terminal ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
@ -2988,6 +3460,48 @@ class AutoRoutingTest(unittest.TestCase):
self . assertEqual ( " wire-a " , diagnostic_payload [ " route_samples " ] [ 0 ] [ " wire_uuid " ] )
self . assertEqual ( " wire-a " , diagnostic_payload [ " route_samples " ] [ 0 ] [ " wire_uuid " ] )
self . assertEqual ( " Routed " , diagnostic_payload [ " route_samples " ] [ 0 ] [ " route_status " ] )
self . assertEqual ( " Routed " , diagnostic_payload [ " route_samples " ] [ 0 ] [ " route_status " ] )
def test_compact_route_sample_prefers_route_track_bridged_segment_count ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
sample = auto_routing . _compact_route_sample (
{
" wire_uuid " : " wire-bridge " ,
" route_track " : {
" bridged_segments " : 1 ,
} ,
" network " : {
" bridged_segments " : 3 ,
} ,
}
)
self . assertEqual ( 1 , sample [ " network " ] [ " bridged_segments " ] )
def test_compact_route_sample_ignores_bridge_only_carrier_summary ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
sample = auto_routing . _compact_route_sample (
{
" wire_uuid " : " wire-bridge " ,
" route_track " : {
" carrier_kinds " : { " RoutingRange " : 1 } ,
" carrier_names " : [ " VirtualBridge " ] ,
" segments " : [
{
" is_bridge " : True ,
" carrier " : { " name " : " VirtualBridge " , " kind " : " RoutingRange " } ,
} ,
{
" carrier " : { " name " : " WireDuctA " , " kind " : " WireDuct " } ,
} ,
] ,
} ,
}
)
self . assertEqual ( { " WireDuct " : 1 } , sample [ " carrier_kinds " ] )
self . assertEqual ( [ " WireDuctA " ] , sample [ " carrier_names " ] )
def test_route_eplan_connections_batch_diagnostic_includes_quality_warnings ( self ) :
def test_route_eplan_connections_batch_diagnostic_includes_quality_warnings ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -3029,6 +3543,38 @@ class AutoRoutingTest(unittest.TestCase):
diagnostic_payload [ " route_quality_warning_samples " ] [ 0 ] [ " carrier_kinds " ] ,
diagnostic_payload [ " route_quality_warning_samples " ] [ 0 ] [ " carrier_kinds " ] ,
)
)
def test_compact_batch_report_includes_entry_distance_warning_samples ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" terminal_access_warning_distance " : 100.0 ,
" routes " : [
{
" wire_uuid " : " wire-long-entry " ,
" wire_label " : " N-LONG " ,
" network " : {
" entry_distance " : 125.0 ,
" exit_distance " : 20.0 ,
} ,
}
] ,
}
payload = auto_routing . _compact_routing_connection_batch_report ( report )
self . assertEqual ( 1 , payload [ " route_entry_distance_warning_count " ] )
self . assertEqual (
" wire-long-entry " ,
payload [ " route_entry_distance_warning_samples " ] [ 0 ] [ " wire_uuid " ] ,
)
self . assertEqual (
[ " entry " ] ,
payload [ " route_entry_distance_warning_samples " ] [ 0 ] [ " warning_sides " ] ,
)
def test_route_eplan_connections_reports_total_connection_route_length ( self ) :
def test_route_eplan_connections_reports_total_connection_route_length ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -3245,6 +3791,83 @@ class AutoRoutingTest(unittest.TestCase):
self . assertIn ( " 路径示例:导线 N4111 经过 QF1:A1、线槽A、过线孔A。 " , message )
self . assertIn ( " 路径示例:导线 N4111 经过 QF1:A1、线槽A、过线孔A。 " , message )
def test_route_report_source_sample_skips_bridge_segments ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
{
" wire_label " : " N4111 " ,
" route_track " : {
" segments " : [
{ " carrier " : { " kind " : " WireDuct " , " source_label " : " 线槽A " } } ,
{ " is_bridge " : True , " carrier " : { " kind " : " WireDuct " , " source_label " : " 虚拟桥接 " } } ,
{ " carrier " : { " kind " : " UserPath " , " source_label " : " 用户路径B " } } ,
]
} ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 路径示例:导线 N4111 经过 线槽A、用户路径B。 " , message )
self . assertNotIn ( " 虚拟桥接 " , message )
def test_route_track_segment_keys_skip_bridge_segments ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
route_track = {
" segments " : [
{
" from_key " : [ 0 , 0 , 0 ] ,
" to_key " : [ 100 , 0 , 0 ] ,
" carrier " : { " name " : " WireDuctA " } ,
} ,
{
" is_bridge " : True ,
" from_key " : [ 100 , 0 , 0 ] ,
" to_key " : [ 100 , 10 , 0 ] ,
" carrier " : { " name " : " VirtualBridge " } ,
} ,
]
}
keys = auto_routing . _route_track_segment_keys ( route_track )
self . assertEqual ( 1 , len ( keys ) )
self . assertEqual ( " WireDuctA " , keys [ 0 ] [ 0 ] )
def test_route_quality_warning_ignores_bridge_only_routing_range ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
{
" wire_label " : " N4111 " ,
" route_track " : {
" carrier_kinds " : { " RoutingRange " : 1 } ,
" segments " : [
{
" is_bridge " : True ,
" carrier " : { " kind " : " RoutingRange " , " source_label " : " 虚拟布线面桥接 " } ,
}
] ,
} ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertNotIn ( " 路径质量提示 " , message )
def test_route_report_includes_network_bridge_and_blocked_segment_counts ( self ) :
def test_route_report_includes_network_bridge_and_blocked_segment_counts ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
@ -3264,7 +3887,31 @@ class AutoRoutingTest(unittest.TestCase):
message = auto_routing . format_eplan_connection_route_report ( report )
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 路径网络:自动桥接 1 段相邻主路径,避障屏蔽 2 段。 " , message )
self . assertIn ( " 路径网络:自动桥接 1 段相邻/投影主路径,避障屏蔽 2 段。 " , message )
def test_route_report_prefers_route_track_bridged_segment_count ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
{
" network " : {
" bridged_segments " : 3 ,
} ,
" route_track " : {
" bridged_segments " : 1 ,
} ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 路径网络:自动桥接 1 段相邻/投影主路径。 " , message )
self . assertNotIn ( " 自动桥接 3 段 " , message )
def test_route_report_includes_parallel_lane_summary ( self ) :
def test_route_report_includes_parallel_lane_summary ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
@ -3274,14 +3921,43 @@ class AutoRoutingTest(unittest.TestCase):
" collision_warnings " : 0 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
" routes " : [
{ " lane " : { " index " : 0 , " axis " : " y " , " spacing_mm " : 10.0 , " offset_mm" : 0.0 } } ,
{ " lane " : { " index " : 0 , " axis " : " y " , " spacing_mm " : 10.0 , " max_offset_mm" : 30.0 , " offset_mm" : 0.0 } } ,
{ " lane " : { " index " : 2 , " axis " : " y " , " spacing_mm " : 10.0 , " offset_mm" : - 10.0 } } ,
{ " lane " : { " index " : 2 , " axis " : " y " , " spacing_mm " : 10.0 , " max_offset_mm" : 30.0 , " offset_mm" : - 10.0 } } ,
] ,
] ,
}
}
message = auto_routing . format_eplan_connection_route_report ( report )
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 并行错位:最大 lane 2, 间距 10.0 mm。 " , message )
self . assertIn ( " 并行错位:最大 lane 2, 间距 10.0 mm, 最大偏移 30.0 mm。 " , message )
def test_eplan_connection_lane_offset_is_capped_for_dense_parallel_routes ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
start = _terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
end = _terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 0 , 20 ) , app . Vector ( 100 , 0 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
result = auto_routing . route_eplan_connection_between_terminals (
doc ,
start ,
end ,
route_index = 21 ,
options = { " lane_spacing " : 10.0 , " lane_axis " : " y " } ,
)
self . assertEqual ( 30.0 , result [ " lane " ] [ " offset_mm " ] )
self . assertLessEqual (
max ( abs ( point . y ) for point in result [ " points " ] ) ,
30.0 ,
)
def test_route_report_includes_replaced_routed_connection_count ( self ) :
def test_route_report_includes_replaced_routed_connection_count ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
@ -3370,6 +4046,86 @@ class AutoRoutingTest(unittest.TestCase):
self . assertIn ( " 容量提示:最大并行线数 3, 路径最小容量 2。 " , message )
self . assertIn ( " 容量提示:最大并行线数 3, 路径最小容量 2。 " , message )
def test_route_report_ignores_bridge_segments_for_capacity_pressure ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 3 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
{
" lane " : { " index " : 2 , " spacing_mm " : 10.0 } ,
" route_track " : {
" segments " : [
{ " is_bridge " : True , " carrier " : { " kind " : " UserPath " , " capacity " : 1 } } ,
{ " carrier " : { " kind " : " WireDuct " , " capacity " : 4 } } ,
]
} ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertNotIn ( " 容量提示 " , message )
def test_route_report_includes_entry_candidate_rank_when_route_uses_fallback_entry ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" routes " : [
{
" wire_label " : " N1 " ,
" network " : {
" entry_candidate_rank " : 3 ,
" exit_candidate_rank " : 1 ,
" entry_candidate_score " : 125.0 ,
} ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 接入候选 " , message )
self . assertIn ( " 起点第 3 个 " , message )
def test_route_report_warns_when_network_entry_distance_is_long ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" routed " : 1 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" terminal_access_warning_distance " : 100.0 ,
" routes " : [
{
" wire_label " : " N1 " ,
" network " : {
" entry_distance " : 125.0 ,
" exit_distance " : 20.0 ,
} ,
} ,
{
" wire_label " : " N2 " ,
" network " : {
" entry_distance " : 20.0 ,
" exit_distance " : 150.0 ,
} ,
} ,
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 接入距离提示: 2 条导线 " , message )
self . assertIn ( " 示例导线 N1 " , message )
self . assertIn ( " 起点接入 125.0 mm " , message )
def test_route_report_capacity_pressure_is_checked_per_route ( self ) :
def test_route_report_capacity_pressure_is_checked_per_route ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
@ -3445,6 +4201,47 @@ class AutoRoutingTest(unittest.TestCase):
self . assertEqual ( 1 , route [ " network " ] [ " carriers " ] )
self . assertEqual ( 1 , route [ " network " ] [ " carriers " ] )
self . assertEqual ( " WireDuct " , route [ " route_track " ] [ " segments " ] [ 0 ] [ " carrier " ] [ " kind " ] )
self . assertEqual ( " WireDuct " , route [ " route_track " ] [ " segments " ] [ 0 ] [ " carrier " ] [ " kind " ] )
def test_route_eplan_connections_can_skip_nearer_isolated_entry_network ( self ) :
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
app = sys . modules [ " FreeCAD " ]
doc = FakeDocument ( )
terminal_objects . ensure_root_group ( doc , " project-1 " )
_terminal ( doc , terminal_objects , " TerminalStart " , " terminal-start " , app . Vector ( 0 , 0 , 0 ) )
_terminal ( doc , terminal_objects , " TerminalEnd " , " terminal-end " , app . Vector ( 100 , 0 , 0 ) )
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 1 , 20 ) , app . Vector ( 5 , 1 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
routing_network . create_route_carrier (
doc ,
[ app . Vector ( 0 , 10 , 20 ) , app . Vector ( 100 , 10 , 20 ) ] ,
project_uuid = " project-1 " ,
kind = " WireDuct " ,
)
payload = {
" project_uuid " : " project-1 " ,
" wires " : [
{
" wire_id " : " wire-1 " ,
" wire_label " : " N4111 " ,
" start_terminal_uuid " : " terminal-start " ,
" end_terminal_uuid " : " terminal-end " ,
}
] ,
}
report = auto_routing . route_eplan_connections_from_payload ( doc , payload )
self . assertEqual ( 1 , report [ " routed " ] )
self . assertEqual ( 0 , len ( report [ " errors " ] ) )
route = report [ " routes " ] [ 0 ]
self . assertEqual ( " network-dijkstra-v1 " , route [ " algorithm " ] )
self . assertGreater ( route [ " network " ] [ " entry_distance " ] , 1.0 )
self . assertGreater ( route [ " network " ] [ " entry_candidate_rank " ] , 1 )
def test_route_eplan_connections_report_includes_routing_path_network_diagnostic ( self ) :
def test_route_eplan_connections_report_includes_routing_path_network_diagnostic ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
terminal_objects , _wiring_objects , routing_network , auto_routing = _reload_modules ( )
@ -4178,6 +4975,36 @@ class AutoRoutingTest(unittest.TestCase):
self . assertIn ( " 缺少布线路径网络 3 条 " , message )
self . assertIn ( " 缺少布线路径网络 3 条 " , message )
self . assertIn ( " 请先生成线槽、布线面或布线路径网络 " , message )
self . assertIn ( " 请先生成线槽、布线面或布线路径网络 " , message )
def test_route_eplan_connections_report_includes_missing_route_network_sample ( self ) :
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
report = {
" total_wires " : 1 ,
" routed " : 0 ,
" collision_warnings " : 0 ,
" skipped_missing_terminal " : 0 ,
" skipped_missing_route_network " : 1 ,
" missing_route_network_samples " : [
{
" wire_uuid " : " wire-1 " ,
" wire_label " : " N4111 " ,
" start_terminal_uuid " : " terminal-start " ,
" start_element_uuid " : " QF1 " ,
" start_terminal_display " : " A1 " ,
" end_terminal_uuid " : " terminal-end " ,
" end_element_uuid " : " KM1 " ,
" end_terminal_display " : " 13 " ,
" error " : " 没有可用的布线路径网络:起点和终点无法连通 " ,
}
] ,
}
message = auto_routing . format_eplan_connection_route_report ( report )
self . assertIn ( " 缺路径网络示例:导线 N4111 " , message )
self . assertIn ( " QF1/A1 (terminal-start) -> KM1/13 (terminal-end) " , message )
self . assertIn ( " 原因:没有可用的布线路径网络:起点和终点无法连通 " , message )
def test_route_eplan_connections_report_includes_readable_missing_endpoint_labels ( self ) :
def test_route_eplan_connections_report_includes_readable_missing_endpoint_labels ( self ) :
_install_fake_freecad ( )
_install_fake_freecad ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )
_terminal_objects , _wiring_objects , _routing_network , auto_routing = _reload_modules ( )