@@ -288,24 +288,79 @@ def test_environment(self):
288288 e = cf .environment (display = False )
289289 ep = cf .environment (display = False , paths = False )
290290
291+ # Basic structure
291292 self .assertIsInstance (e , list )
292293 self .assertIsInstance (ep , list )
294+ self .assertEqual (len (e ), len (ep ))
295+ self .assertTrue (all (isinstance (s , str ) for s in e ))
296+ self .assertTrue (all (isinstance (s , str ) for s in ep ))
297+
298+ # Extract component names
299+ names_e = [s .split (":" )[0 ] for s in e ]
300+ names_ep = [s .split (":" )[0 ] for s in ep ]
301+
302+ # Expected full set of components
303+ expected = [
304+ "Platform" ,
305+ "Python" ,
306+ "packaging" ,
307+ "numpy" ,
308+ "cfdm.core" ,
309+ "udunits2 library" ,
310+ "HDF5 library" ,
311+ "netcdf library" ,
312+ "netCDF4" ,
313+ "h5netcdf" ,
314+ "h5py" ,
315+ "pyfive" ,
316+ "zarr" ,
317+ "fsspec" ,
318+ "scipy" ,
319+ "dask" ,
320+ "distributed" ,
321+ "cftime" ,
322+ "cfunits" ,
323+ "cfdm" ,
324+ "esmpy/ESMF" ,
325+ "psutil" ,
326+ "matplotlib" ,
327+ "activestorage" ,
328+ "cartopy" ,
329+ "cfplot" ,
330+ "cf" ,
331+ ]
332+
333+ # Ensure all expected components are present
334+ self .assertEqual (sorted (names_e ), sorted (expected ))
335+ self .assertEqual (sorted (names_ep ), sorted (expected ))
336+
337+ # Specific known entries (sanity checks)
338+ self .assertIn (
339+ f"Python: { platform .python_version ()} { sys .executable } " , e
340+ )
341+ self .assertTrue (
342+ any (
343+ s .startswith (f"Python: { platform .python_version ()} " )
344+ for s in ep
345+ )
346+ )
293347
294- components = ["Platform: " , "netCDF4: " , "numpy: " , "cftime: " ]
295- for component in components :
296- self .assertTrue (any (s .startswith (component ) for s in e ))
297- self .assertTrue (any (s .startswith (component ) for s in ep ))
298- for component in [
299- f"cf: { cf .__version__ } { os .path .abspath (cf .__file__ )} " ,
300- f"Python: { platform .python_version ()} { sys .executable } " ,
301- ]:
302- self .assertIn (component , e )
303- self .assertNotIn (component , ep ) # paths shouldn't be present here
304- for component in [
305- f"cf: { cf .__version__ } " ,
306- f"Python: { platform .python_version ()} " ,
307- ]:
308- self .assertIn (component , ep )
348+ self .assertIn (
349+ f"cf: { cf .__version__ } { os .path .abspath (cf .__file__ )} " , e
350+ )
351+ self .assertIn (f"cf: { cf .__version__ } " , ep )
352+
353+ # Each entry without paths should match the start of the
354+ # corresponding entry with paths
355+ for full , short in zip (e , ep ):
356+ name_full , val_full = full .split (": " , 1 )
357+ name_short , val_short = short .split (": " , 1 )
358+
359+ self .assertEqual (name_full , name_short )
360+ self .assertTrue (
361+ val_full .startswith (val_short ),
362+ msg = f"Mismatch for { name_full } : '{ val_full } ' vs '{ val_short } '" ,
363+ )
309364
310365 def test_indices_shape (self ):
311366 import dask .array as da
0 commit comments