88import time
99import toml
1010import json
11+ import pathlib
1112from shutil import copy , rmtree
1213from subprocess import check_call , check_output , CalledProcessError
1314
@@ -24,6 +25,7 @@ def split(s):
2425parser .add_argument ('--publish' , action = 'store_true' , help = 'publish the crates' )
2526parser .add_argument ('--build' , action = 'store_true' , help = 'build the crates' )
2627parser .add_argument ('--test' , action = 'store_true' , help = 'test the crates' )
28+ parser .add_argument ('--test_outputs' , action = 'store_true' , help = 'run the unittests' )
2729parser .add_argument ('--clean' , action = 'store_true' , help = 'clean the crates' )
2830parser .add_argument ('--doc' , action = 'store_true' , help = 'build the documentation' )
2931parser .add_argument ('--format' , action = 'store_true' , help = 'format all the non-sys crates' )
@@ -44,7 +46,7 @@ def cargo_cmd(*command):
4446 print ('Processing' , cargo_toml )
4547
4648 for line in fileinput .input (cargo_toml , inplace = 1 ):
47- line = re .sub ('version = "(=?).*" #auto' , 'version = "\g<1>' + args .version + '" #auto' , line )
49+ line = re .sub ('version = "(=?).*" #auto' , r 'version = "\g<1>' + args .version + '" #auto' , line )
4850 print (line , end = '' )
4951
5052if args .publish :
@@ -93,6 +95,49 @@ def cargo_cmd(*command):
9395 check_call (cargo_cmd ('test' ), cwd = crate )
9496 check_call (cargo_cmd ('fmt' , '--check' ), cwd = crate )
9597
98+ if args .test_outputs :
99+ import numpy as np
100+ from PIL import Image
101+
102+ os .makedirs ('test_outputs' , exist_ok = True )
103+ output_dir = os .path .abspath ('test_outputs' )
104+ metadata = json .loads (check_output (cargo_cmd ('metadata' , '--format-version=1' , '--no-deps' ), cwd = 'gnuplot' ).decode ('utf8' ))
105+ for target in metadata ['packages' ][0 ]['targets' ]:
106+ if target ['kind' ] != ['example' ]:
107+ continue
108+
109+ if target ['name' ] in [
110+ 'animation_example' , # Special.
111+ 'inverse_api' , # Special.
112+ 'example3' , # Broken.
113+ ]:
114+ continue
115+
116+ check_call (cargo_cmd ('run' , '--example' , target ['name' ], '--' , '--no-show' , '--output-dir' , output_dir , '--save-png' ), cwd = 'gnuplot' )
117+
118+ golden_images = [pathlib .Path (f ) for f in glob .glob ('golden_outputs/*.png' )]
119+ test_images = [pathlib .Path (f ) for f in glob .glob (f'{ output_dir } /*.png' )]
120+
121+ golden_filenames = set (f .name for f in golden_images )
122+ test_filenames = set (f .name for f in test_images )
123+ if golden_filenames != test_filenames :
124+ missing = set (golden_filenames ) - set (test_filenames )
125+ extra = set (test_filenames ) - set (golden_filenames )
126+ assert False , f"Test images don't match golden images.\n Extra: { extra } \n Missing: { missing } "
127+
128+ for image_name in golden_images :
129+ golden_image_path = pathlib .Path (image_name )
130+ test_image_path = pathlib .Path (output_dir ) / golden_image_path .name
131+ assert test_image_path .exists (), f"{ test_image_path } not found"
132+
133+ golden_image = np .array (Image .open (golden_image_path )).astype (np .float32 )
134+ test_image = np .array (Image .open (test_image_path )).astype (np .float32 )
135+ try :
136+ np .testing .assert_allclose (golden_image , test_image , atol = 5 , err_msg = f"{ golden_image_path .resolve ()} \n { test_image_path .resolve ()} " )
137+ except AssertionError as e :
138+ print (e )
139+
140+
96141if args .clean :
97142 crates_and_doc = ['doc' ]
98143 crates_and_doc .extend (crate_list )
0 commit comments