Add 'Collecting' step to 'check' command output + warning for suspicious test filter
Fixes #1092. Signed-off-by: KtorZ <5680256+KtorZ@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									58d782fa78
								
							
						
					
					
						commit
						3c2b631813
					
				|  | @ -19,6 +19,7 @@ | ||||||
| 
 | 
 | ||||||
| - **aiken-lang**: The compiler now raises a warning when attempting to destructure a record constructor without using named fields. See [#1084](https://github.com/aiken-lang/aiken/issues/1084). @KtorZ | - **aiken-lang**: The compiler now raises a warning when attempting to destructure a record constructor without using named fields. See [#1084](https://github.com/aiken-lang/aiken/issues/1084). @KtorZ | ||||||
| - **aiken-lang**: Fix blueprint schema definitions related to pairs (no longer omit (sometimes) Pairs definitions, and generate them as data List). See [#1086](https://github.com/aiken-lang/aiken/issues/1086) and [#970](https://github.com/aiken-lang/aiken/issues/970). @KtorZ | - **aiken-lang**: Fix blueprint schema definitions related to pairs (no longer omit (sometimes) Pairs definitions, and generate them as data List). See [#1086](https://github.com/aiken-lang/aiken/issues/1086) and [#970](https://github.com/aiken-lang/aiken/issues/970). @KtorZ | ||||||
|  | - **aiken-project**: Improve feedback returned when matching tests or modules - see [#1092](https://github.com/aiken-lang/aiken/issues/1092). @KtorZ | ||||||
| 
 | 
 | ||||||
| ## v1.1.10 - 2025-01-21 | ## v1.1.10 - 2025-01-21 | ||||||
| 
 | 
 | ||||||
|  | @ -31,7 +32,7 @@ | ||||||
| ### Changed | ### Changed | ||||||
| 
 | 
 | ||||||
| - **aiken-project**: The `aiken.toml` file no longer supports `v1` and `v2` for the plutus version field. @rvcas | - **aiken-project**: The `aiken.toml` file no longer supports `v1` and `v2` for the plutus version field. @rvcas | ||||||
| - **aiken-project**: `Error::TomlLoading` now looks much better - [see](https://github.com/aiken-lang/aiken/issues/1032#issuecomment-2562122101). @rvcas | - **aiken-project**: `Error::TomlLoading` now looks much better - see [#1032](https://github.com/aiken-lang/aiken/issues/1032#issuecomment-2562122101). @rvcas | ||||||
| - **aiken-lang**: 10-20% optimization improvements via case-constr, rearranging function definitions (while maintaining dependency ordering), | - **aiken-lang**: 10-20% optimization improvements via case-constr, rearranging function definitions (while maintaining dependency ordering), | ||||||
|                   and allowing inlining in if_then_else_error cases which preserve the same error semantics for a program. @Microproofs |                   and allowing inlining in if_then_else_error cases which preserve the same error semantics for a program. @Microproofs | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -594,6 +594,8 @@ pub enum Warning { | ||||||
|     CompilerVersionMismatch { demanded: String, current: String }, |     CompilerVersionMismatch { demanded: String, current: String }, | ||||||
|     #[error("No configuration found for environment {env}.")] |     #[error("No configuration found for environment {env}.")] | ||||||
|     NoConfigurationForEnv { env: String }, |     NoConfigurationForEnv { env: String }, | ||||||
|  |     #[error("Suspicious test filter (-m) yielding no test scenarios.")] | ||||||
|  |     SuspiciousTestMatch { test: String }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ExtraData for Warning { | impl ExtraData for Warning { | ||||||
|  | @ -603,7 +605,8 @@ impl ExtraData for Warning { | ||||||
|             | Warning::DependencyAlreadyExists { .. } |             | Warning::DependencyAlreadyExists { .. } | ||||||
|             | Warning::InvalidModuleName { .. } |             | Warning::InvalidModuleName { .. } | ||||||
|             | Warning::CompilerVersionMismatch { .. } |             | Warning::CompilerVersionMismatch { .. } | ||||||
|             | Warning::NoConfigurationForEnv { .. } => None, |             | Warning::NoConfigurationForEnv { .. } | ||||||
|  |             | Warning::SuspiciousTestMatch { .. } => None, | ||||||
|             Warning::Type { warning, .. } => warning.extra_data(), |             Warning::Type { warning, .. } => warning.extra_data(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -616,7 +619,8 @@ impl GetSource for Warning { | ||||||
|             Warning::NoValidators |             Warning::NoValidators | ||||||
|             | Warning::DependencyAlreadyExists { .. } |             | Warning::DependencyAlreadyExists { .. } | ||||||
|             | Warning::NoConfigurationForEnv { .. } |             | Warning::NoConfigurationForEnv { .. } | ||||||
|             | Warning::CompilerVersionMismatch { .. } => None, |             | Warning::CompilerVersionMismatch { .. } | ||||||
|  |             | Warning::SuspiciousTestMatch { .. } => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -627,7 +631,8 @@ impl GetSource for Warning { | ||||||
|             | Warning::InvalidModuleName { .. } |             | Warning::InvalidModuleName { .. } | ||||||
|             | Warning::DependencyAlreadyExists { .. } |             | Warning::DependencyAlreadyExists { .. } | ||||||
|             | Warning::NoConfigurationForEnv { .. } |             | Warning::NoConfigurationForEnv { .. } | ||||||
|             | Warning::CompilerVersionMismatch { .. } => None, |             | Warning::CompilerVersionMismatch { .. } | ||||||
|  |             | Warning::SuspiciousTestMatch { .. } => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -644,7 +649,8 @@ impl Diagnostic for Warning { | ||||||
|             | Warning::InvalidModuleName { .. } |             | Warning::InvalidModuleName { .. } | ||||||
|             | Warning::NoConfigurationForEnv { .. } |             | Warning::NoConfigurationForEnv { .. } | ||||||
|             | Warning::DependencyAlreadyExists { .. } |             | Warning::DependencyAlreadyExists { .. } | ||||||
|             | Warning::CompilerVersionMismatch { .. } => None, |             | Warning::CompilerVersionMismatch { .. } | ||||||
|  |             | Warning::SuspiciousTestMatch { .. } => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -655,7 +661,8 @@ impl Diagnostic for Warning { | ||||||
|             | Warning::NoValidators |             | Warning::NoValidators | ||||||
|             | Warning::DependencyAlreadyExists { .. } |             | Warning::DependencyAlreadyExists { .. } | ||||||
|             | Warning::NoConfigurationForEnv { .. } |             | Warning::NoConfigurationForEnv { .. } | ||||||
|             | Warning::CompilerVersionMismatch { .. } => None, |             | Warning::CompilerVersionMismatch { .. } | ||||||
|  |             | Warning::SuspiciousTestMatch { .. } => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -676,6 +683,7 @@ impl Diagnostic for Warning { | ||||||
|             Warning::NoConfigurationForEnv { .. } => { |             Warning::NoConfigurationForEnv { .. } => { | ||||||
|                 Some(Box::new("aiken::project::config::missing::env")) |                 Some(Box::new("aiken::project::config::missing::env")) | ||||||
|             } |             } | ||||||
|  |             Warning::SuspiciousTestMatch { .. } => Some(Box::new("aiken::check::suspicious_match")), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -696,6 +704,12 @@ impl Diagnostic for Warning { | ||||||
|             Warning::NoConfigurationForEnv { .. } => Some(Box::new( |             Warning::NoConfigurationForEnv { .. } => Some(Box::new( | ||||||
|                 "When configuration keys are missing for a target environment, no 'config' module will be created. This may lead to issues down the line.", |                 "When configuration keys are missing for a target environment, no 'config' module will be created. This may lead to issues down the line.", | ||||||
|             )), |             )), | ||||||
|  |             Warning::SuspiciousTestMatch { test } => Some(Box::new( | ||||||
|  |                 format!( | ||||||
|  |                     "Did you mean to match all tests within a specific module? Like so:\n\n╰─▶ {}", | ||||||
|  |                     format!("-m \"{test}.{{..}}\"").if_supports_color(Stderr, |s| s.bold()), | ||||||
|  |                 ) | ||||||
|  |             )), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -980,12 +980,35 @@ where | ||||||
|                         "" |                         "" | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                     let match_names = match_split_dot.next().map(|names| { |                     let match_names = match_split_dot.next().and_then(|names| { | ||||||
|                         let names = names.replace(&['{', '}'][..], ""); |                         let names = names.replace(&['{', '}'][..], ""); | ||||||
| 
 |  | ||||||
|                         let names_split_comma = names.split(','); |                         let names_split_comma = names.split(','); | ||||||
| 
 | 
 | ||||||
|                         names_split_comma.map(str::to_string).collect() |                         let result = names_split_comma | ||||||
|  |                             .filter_map(|s| { | ||||||
|  |                                 let s = s.trim(); | ||||||
|  |                                 if s.is_empty() { | ||||||
|  |                                     None | ||||||
|  |                                 } else { | ||||||
|  |                                     Some(s.to_string()) | ||||||
|  |                                 } | ||||||
|  |                             }) | ||||||
|  |                             .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|  |                         if result.is_empty() { | ||||||
|  |                             None | ||||||
|  |                         } else { | ||||||
|  |                             Some(result) | ||||||
|  |                         } | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                     self.event_listener.handle_event(Event::CollectingTests { | ||||||
|  |                         matching_module: if match_module.is_empty() { | ||||||
|  |                             None | ||||||
|  |                         } else { | ||||||
|  |                             Some(match_module.to_string()) | ||||||
|  |                         }, | ||||||
|  |                         matching_names: match_names.clone().unwrap_or_default(), | ||||||
|                     }); |                     }); | ||||||
| 
 | 
 | ||||||
|                     (match_module.to_string(), match_names) |                     (match_module.to_string(), match_names) | ||||||
|  | @ -993,6 +1016,13 @@ where | ||||||
|                 .collect::<Vec<(String, Option<Vec<String>>)>>() |                 .collect::<Vec<(String, Option<Vec<String>>)>>() | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|  |         if match_tests.is_none() { | ||||||
|  |             self.event_listener.handle_event(Event::CollectingTests { | ||||||
|  |                 matching_module: None, | ||||||
|  |                 matching_names: vec![], | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         for checked_module in self.checked_modules.values() { |         for checked_module in self.checked_modules.values() { | ||||||
|             if checked_module.package != self.config.name.to_string() { |             if checked_module.package != self.config.name.to_string() { | ||||||
|                 continue; |                 continue; | ||||||
|  | @ -1064,6 +1094,27 @@ where | ||||||
|             )); |             )); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         // NOTE: The filtering syntax for tests isn't quite obvious. A common pitfall when willing
 | ||||||
|  |         // to match over a top-level module is to simple pass in `-m module_name`, which will be
 | ||||||
|  |         // treated as a match for a test name.
 | ||||||
|  |         //
 | ||||||
|  |         // In this case, we raise an additional warning to suggest a different match syntax, which
 | ||||||
|  |         // may be quite helpful in teaching users how to deal with module filtering.
 | ||||||
|  |         match match_tests.as_deref() { | ||||||
|  |             Some(&[(ref s, Some(ref names))]) if tests.is_empty() => { | ||||||
|  |                 if let [test] = names.as_slice() { | ||||||
|  |                     self.warnings.push(Warning::SuspiciousTestMatch { | ||||||
|  |                         test: if s.is_empty() { | ||||||
|  |                             test.to_string() | ||||||
|  |                         } else { | ||||||
|  |                             s.to_string() | ||||||
|  |                         }, | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _ => (), | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         Ok(tests) |         Ok(tests) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -43,6 +43,10 @@ pub enum Event { | ||||||
|         name: String, |         name: String, | ||||||
|         path: PathBuf, |         path: PathBuf, | ||||||
|     }, |     }, | ||||||
|  |     CollectingTests { | ||||||
|  |         matching_module: Option<String>, | ||||||
|  |         matching_names: Vec<String>, | ||||||
|  |     }, | ||||||
|     RunningTests, |     RunningTests, | ||||||
|     RunningBenchmarks, |     RunningBenchmarks, | ||||||
|     FinishedTests { |     FinishedTests { | ||||||
|  |  | ||||||
|  | @ -117,6 +117,53 @@ impl EventListener for Terminal { | ||||||
|                     name.if_supports_color(Stderr, |s| s.bright_blue()), |                     name.if_supports_color(Stderr, |s| s.bright_blue()), | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|  |             Event::CollectingTests { | ||||||
|  |                 matching_module, | ||||||
|  |                 matching_names, | ||||||
|  |             } => { | ||||||
|  |                 eprintln!( | ||||||
|  |                     "{:>13} {tests} {module}", | ||||||
|  |                     "Collecting" | ||||||
|  |                         .if_supports_color(Stderr, |s| s.bold()) | ||||||
|  |                         .if_supports_color(Stderr, |s| s.purple()), | ||||||
|  |                     tests = if matching_names.is_empty() { | ||||||
|  |                         if matching_module.is_some() { | ||||||
|  |                             "all tests scenarios" | ||||||
|  |                                 .if_supports_color(Stderr, |s| s.bold()) | ||||||
|  |                                 .to_string() | ||||||
|  |                         } else { | ||||||
|  |                             "all tests scenarios".to_string() | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         format!( | ||||||
|  |                             "test{} {}", | ||||||
|  |                             if matching_names.len() > 1 { "s" } else { "" }, | ||||||
|  |                             matching_names | ||||||
|  |                                 .iter() | ||||||
|  |                                 .map(|s| format!("*{s}*")) | ||||||
|  |                                 .collect::<Vec<_>>() | ||||||
|  |                                 .join(", ") | ||||||
|  |                                 .if_supports_color(Stderr, |s| s.bold()) | ||||||
|  |                         ) | ||||||
|  |                     }, | ||||||
|  |                     module = match matching_module { | ||||||
|  |                         None => format!( | ||||||
|  |                             "across {}", | ||||||
|  |                             if matching_names.is_empty() { | ||||||
|  |                                 "all modules".to_string() | ||||||
|  |                             } else { | ||||||
|  |                                 "all modules" | ||||||
|  |                                     .if_supports_color(Stderr, |s| s.bold()) | ||||||
|  |                                     .to_string() | ||||||
|  |                             } | ||||||
|  |                         ), | ||||||
|  |                         Some(module) => format!( | ||||||
|  |                             "within module(s): {}", | ||||||
|  |                             format!("*{module}*").if_supports_color(Stderr, |s| s.bold()) | ||||||
|  |                         ), | ||||||
|  |                     } | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|             Event::RunningTests => { |             Event::RunningTests => { | ||||||
|                 eprintln!( |                 eprintln!( | ||||||
|                     "{} {}", |                     "{} {}", | ||||||
|  |  | ||||||
|  | @ -123,6 +123,7 @@ where | ||||||
| 
 | 
 | ||||||
|     if !json { |     if !json { | ||||||
|         for warning in &warnings { |         for warning in &warnings { | ||||||
|  |             eprintln!(); | ||||||
|             warning.report() |             warning.report() | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 KtorZ
						KtorZ