@@ -318,11 +318,15 @@ pub(crate) fn get_target_width(
318
318
319
319
#[ cfg( test) ]
320
320
mod tests {
321
- use std:: path:: { Path , PathBuf } ;
321
+ use std:: {
322
+ path:: { Path , PathBuf } ,
323
+ str:: FromStr ,
324
+ } ;
322
325
326
+ use clap:: Parser ;
323
327
use nargo:: ops:: compile_program;
324
328
use nargo_toml:: PackageSelection ;
325
- use noirc_driver:: CompileOptions ;
329
+ use noirc_driver:: { CompileOptions , CrateName } ;
326
330
use rayon:: prelude:: * ;
327
331
328
332
use crate :: cli:: compile_cmd:: { get_target_width, parse_workspace, read_workspace} ;
@@ -350,47 +354,95 @@ mod tests {
350
354
. map ( |c| c. path ( ) )
351
355
}
352
356
357
+ #[ derive( Parser , Debug ) ]
358
+ #[ command( ignore_errors = true ) ]
359
+ struct Options {
360
+ /// Test name to filter for.
361
+ ///
362
+ /// For example:
363
+ /// ```text
364
+ /// cargo test -p nargo_cli -- test_transform_program_is_idempotent slice_loop
365
+ /// ```
366
+ args : Vec < String > ,
367
+ }
368
+
369
+ impl Options {
370
+ fn package_selection ( & self ) -> PackageSelection {
371
+ match self . args . as_slice ( ) {
372
+ [ _test_name, test_program] => {
373
+ PackageSelection :: Selected ( CrateName :: from_str ( test_program) . unwrap ( ) )
374
+ }
375
+ _ => PackageSelection :: DefaultOrAll ,
376
+ }
377
+ }
378
+ }
379
+
353
380
/// Check that `nargo::ops::transform_program` is idempotent by compiling the
354
381
/// test programs and running them through the optimizer twice.
355
382
///
356
383
/// This test is here purely because of the convenience of having access to
357
384
/// the utility functions to process workspaces.
358
385
#[ test]
359
386
fn test_transform_program_is_idempotent ( ) {
387
+ let opts = Options :: parse ( ) ;
388
+
389
+ let sel = opts. package_selection ( ) ;
390
+ let verbose = matches ! ( sel, PackageSelection :: Selected ( _) ) ;
391
+
360
392
let test_workspaces = read_test_program_dirs ( & test_programs_dir ( ) , "execution_success" )
361
- . filter_map ( |dir| read_workspace ( & dir, PackageSelection :: DefaultOrAll ) . ok ( ) )
393
+ . filter_map ( |dir| read_workspace ( & dir, sel . clone ( ) ) . ok ( ) )
362
394
. collect :: < Vec < _ > > ( ) ;
363
395
364
396
assert ! ( !test_workspaces. is_empty( ) , "should find some test workspaces" ) ;
365
397
366
- test_workspaces. par_iter ( ) . for_each ( |workspace| {
367
- let ( file_manager, parsed_files) = parse_workspace ( workspace) ;
368
- let binary_packages = workspace. into_iter ( ) . filter ( |package| package. is_binary ( ) ) ;
369
-
370
- for package in binary_packages {
371
- let ( program, _warnings) = compile_program (
372
- & file_manager,
373
- & parsed_files,
374
- workspace,
375
- package,
376
- & CompileOptions :: default ( ) ,
377
- None ,
378
- )
379
- . expect ( "failed to compile" ) ;
380
-
381
- let width = get_target_width ( package. expression_width , None ) ;
382
-
383
- let program = nargo:: ops:: transform_program ( program, width) ;
384
- let program_hash_1 = fxhash:: hash64 ( & program) ;
385
- let program = nargo:: ops:: transform_program ( program, width) ;
386
- let program_hash_2 = fxhash:: hash64 ( & program) ;
387
-
388
- assert ! (
389
- program_hash_1 == program_hash_2,
390
- "optimization not idempotent for test program '{}'" ,
391
- package. name
392
- ) ;
393
- }
394
- } ) ;
398
+ test_workspaces
399
+ . par_iter ( )
400
+ //.filter(|workspace| workspace.members.iter().any(|p| p.name == test_workspace_name))
401
+ . for_each ( |workspace| {
402
+ let ( file_manager, parsed_files) = parse_workspace ( workspace) ;
403
+ let binary_packages = workspace. into_iter ( ) . filter ( |package| package. is_binary ( ) ) ;
404
+
405
+ for package in binary_packages {
406
+ let ( program_0, _warnings) = compile_program (
407
+ & file_manager,
408
+ & parsed_files,
409
+ workspace,
410
+ package,
411
+ & CompileOptions :: default ( ) ,
412
+ None ,
413
+ )
414
+ . expect ( "failed to compile" ) ;
415
+
416
+ let width = get_target_width ( package. expression_width , None ) ;
417
+
418
+ let program_1 = nargo:: ops:: transform_program ( program_0, width) ;
419
+ let program_2 = nargo:: ops:: transform_program ( program_1. clone ( ) , width) ;
420
+
421
+ if verbose {
422
+ // Compare where the most likely difference is.
423
+ assert_eq ! (
424
+ program_1. program, program_2. program,
425
+ "optimization not idempotent for test program '{}'" ,
426
+ package. name
427
+ ) ;
428
+
429
+ // Compare the whole content.
430
+ similar_asserts:: assert_eq!(
431
+ serde_json:: to_string_pretty( & program_1) . unwrap( ) ,
432
+ serde_json:: to_string_pretty( & program_2) . unwrap( ) ,
433
+ "optimization not idempotent for test program '{}'" ,
434
+ package. name
435
+ ) ;
436
+ } else {
437
+ // Just compare hashes, which would just state that the program failed.
438
+ // Then we can use the filter option to zoom in one one to see why.
439
+ assert ! (
440
+ fxhash:: hash64( & program_1) == fxhash:: hash64( & program_2) ,
441
+ "optimization not idempotent for test program '{}'" ,
442
+ package. name
443
+ ) ;
444
+ }
445
+ }
446
+ } ) ;
395
447
}
396
448
}
0 commit comments