@@ -95,3 +95,107 @@ fn are_versions_different(actual: &str, expected: &str) -> Option<bool> {
9595 let expected = expected. get ( 1 ) ?. as_str ( ) . to_string ( ) ;
9696 Some ( actual != expected)
9797}
98+
99+ #[ cfg( test) ]
100+ mod tests {
101+ use super :: * ;
102+ use pet_core:: {
103+ manager:: EnvManager ,
104+ python_environment:: { PythonEnvironmentBuilder , PythonEnvironmentKind } ,
105+ telemetry:: TelemetryEvent ,
106+ } ;
107+ use std:: path:: PathBuf ;
108+
109+ struct NoopReporter ;
110+ impl Reporter for NoopReporter {
111+ fn report_manager ( & self , _: & EnvManager ) { }
112+ fn report_environment ( & self , _: & PythonEnvironment ) { }
113+ fn report_telemetry ( & self , _: & TelemetryEvent ) { }
114+ }
115+
116+ fn make_env (
117+ executable : PathBuf ,
118+ prefix : PathBuf ,
119+ version : & str ,
120+ symlinks : Vec < PathBuf > ,
121+ ) -> PythonEnvironment {
122+ PythonEnvironmentBuilder :: new ( Some ( PythonEnvironmentKind :: Venv ) )
123+ . executable ( Some ( executable) )
124+ . prefix ( Some ( prefix) )
125+ . version ( Some ( version. to_string ( ) ) )
126+ . symlinks ( Some ( symlinks) )
127+ . build ( )
128+ }
129+
130+ #[ test]
131+ fn same_prefix_is_not_flagged ( ) {
132+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
133+ let prefix = dir. path ( ) . to_path_buf ( ) ;
134+ let exe = prefix. join ( "bin" ) . join ( "python" ) ;
135+
136+ let env = make_env ( exe. clone ( ) , prefix. clone ( ) , "3.12.7" , vec ! [ exe. clone( ) ] ) ;
137+ let resolved = make_env ( exe. clone ( ) , prefix, "3.12.7" , vec ! [ exe] ) ;
138+
139+ // Should not warn — prefixes are identical
140+ let result = report_inaccuracies_identified_after_resolving ( & NoopReporter , & env, & resolved) ;
141+ assert ! ( result. is_some( ) ) ;
142+ }
143+
144+ #[ cfg( unix) ]
145+ #[ test]
146+ fn symlinked_prefix_is_not_flagged ( ) {
147+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
148+ let real_prefix = dir. path ( ) . join ( "versioned" ) . join ( "myvenv-1.0.51" ) ;
149+ std:: fs:: create_dir_all ( & real_prefix) . unwrap ( ) ;
150+ let symlink_prefix = dir. path ( ) . join ( "myvenv" ) ;
151+ std:: os:: unix:: fs:: symlink ( & real_prefix, & symlink_prefix) . unwrap ( ) ;
152+
153+ let exe = symlink_prefix. join ( "bin" ) . join ( "python" ) ;
154+
155+ // Discovery sees the symlink path as prefix
156+ let env = make_env ( exe. clone ( ) , symlink_prefix, "3.12.7" , vec ! [ exe. clone( ) ] ) ;
157+ // Resolution (spawning Python) returns the canonical path
158+ let resolved = make_env ( exe. clone ( ) , real_prefix, "3.12.7" , vec ! [ exe] ) ;
159+
160+ // Should NOT warn — both paths resolve to the same directory
161+ let result = report_inaccuracies_identified_after_resolving ( & NoopReporter , & env, & resolved) ;
162+ assert ! ( result. is_some( ) ) ;
163+ }
164+
165+ #[ test]
166+ fn different_prefix_is_flagged ( ) {
167+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
168+ let prefix_a = dir. path ( ) . join ( "env_a" ) ;
169+ let prefix_b = dir. path ( ) . join ( "env_b" ) ;
170+ std:: fs:: create_dir_all ( & prefix_a) . unwrap ( ) ;
171+ std:: fs:: create_dir_all ( & prefix_b) . unwrap ( ) ;
172+
173+ let exe = prefix_a. join ( "bin" ) . join ( "python" ) ;
174+
175+ let env = make_env ( exe. clone ( ) , prefix_a, "3.12.7" , vec ! [ exe. clone( ) ] ) ;
176+ let resolved = make_env ( exe. clone ( ) , prefix_b, "3.12.7" , vec ! [ exe] ) ;
177+
178+ // Should warn — prefixes are genuinely different
179+ // The function still returns Some(()), but the warn! macro fires internally.
180+ let result = report_inaccuracies_identified_after_resolving ( & NoopReporter , & env, & resolved) ;
181+ assert ! ( result. is_some( ) ) ;
182+ }
183+
184+ #[ test]
185+ fn none_prefix_is_not_flagged ( ) {
186+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
187+ let prefix = dir. path ( ) . to_path_buf ( ) ;
188+ let exe = prefix. join ( "bin" ) . join ( "python" ) ;
189+
190+ // env has no prefix
191+ let env = PythonEnvironmentBuilder :: new ( Some ( PythonEnvironmentKind :: Venv ) )
192+ . executable ( Some ( exe. clone ( ) ) )
193+ . version ( Some ( "3.12.7" . to_string ( ) ) )
194+ . symlinks ( Some ( vec ! [ exe. clone( ) ] ) )
195+ . build ( ) ;
196+ let resolved = make_env ( exe. clone ( ) , prefix, "3.12.7" , vec ! [ exe] ) ;
197+
198+ let result = report_inaccuracies_identified_after_resolving ( & NoopReporter , & env, & resolved) ;
199+ assert ! ( result. is_some( ) ) ;
200+ }
201+ }
0 commit comments