feat: add ability to reference validators in tests closes #632

This commit is contained in:
rvcas 2023-07-12 18:29:03 -04:00
parent 13ee62c05c
commit e7c1b28b52
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
5 changed files with 86 additions and 34 deletions

View File

@ -14,6 +14,7 @@
- **aiken-lang**: Parsing of error / todo keywords in when cases - **aiken-lang**: Parsing of error / todo keywords in when cases
- **aiken-lang**: Parsing of negative integer patterns and constants - **aiken-lang**: Parsing of negative integer patterns and constants
- **aiken-lang**: automatically infer unused validator args as `Data` - **aiken-lang**: automatically infer unused validator args as `Data`
- **aiken-lang**: test crashing when referencing validators
- **aiken**: mem and cpu values were not showing in white terminals, switched to cyan - **aiken**: mem and cpu values were not showing in white terminals, switched to cyan
### Changed ### Changed

View File

@ -88,6 +88,23 @@ impl<'a> CodeGenerator<'a> {
self.defined_functions = IndexMap::new(); self.defined_functions = IndexMap::new();
} }
pub fn insert_function(
&mut self,
module_name: String,
function_name: String,
variant_name: String,
value: &'a TypedFunction,
) -> Option<&'a TypedFunction> {
self.functions.insert(
FunctionAccessKey {
module_name,
function_name,
variant_name,
},
value,
)
}
pub fn generate( pub fn generate(
&mut self, &mut self,
TypedValidator { TypedValidator {

View File

@ -162,7 +162,7 @@ impl fmt::Display for Token {
Token::Fn => "fn", Token::Fn => "fn",
Token::If => "if", Token::If => "if",
Token::Else => "else", Token::Else => "else",
Token::Use => "import", Token::Use => "use",
Token::Let => "let", Token::Let => "let",
Token::Opaque => "opaque", Token::Opaque => "opaque",
Token::Pub => "pub", Token::Pub => "pub",

View File

@ -16,7 +16,7 @@ mod tests;
use crate::blueprint::Blueprint; use crate::blueprint::Blueprint;
use aiken_lang::{ use aiken_lang::{
ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction}, ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction, Validator},
builtins, builtins,
gen_uplc::builder::{DataTypeKey, FunctionAccessKey}, gen_uplc::builder::{DataTypeKey, FunctionAccessKey},
tipo::TypeInfo, tipo::TypeInfo,
@ -638,6 +638,7 @@ where
tracing: bool, tracing: bool,
) -> Result<Vec<Script>, Error> { ) -> Result<Vec<Script>, Error> {
let mut scripts = Vec::new(); let mut scripts = Vec::new();
let mut testable_validators = Vec::new();
let match_tests = match_tests.map(|mt| { let match_tests = match_tests.map(|mt| {
mt.into_iter() mt.into_iter()
@ -669,46 +670,86 @@ where
} }
for def in checked_module.ast.definitions() { for def in checked_module.ast.definitions() {
if let Definition::Test(func) = def { match def {
if let Some(match_tests) = &match_tests { Definition::Validator(Validator {
let is_match = match_tests.iter().any(|(module, names)| { params,
let matched_module = fun,
module.is_empty() || checked_module.name.contains(module); other_fun,
..
}) => {
let mut fun = fun.clone();
let matched_name = match names { fun.arguments = params.clone().into_iter().chain(fun.arguments).collect();
None => true,
Some(names) => names.iter().any(|name| {
if exact_match {
name == &func.name
} else {
func.name.contains(name)
}
}),
};
matched_module && matched_name testable_validators.push((&checked_module.name, fun));
});
if is_match { if let Some(other) = other_fun {
let mut other = other.clone();
other.arguments =
params.clone().into_iter().chain(other.arguments).collect();
testable_validators.push((&checked_module.name, other));
}
}
Definition::Test(func) => {
if let Some(match_tests) = &match_tests {
let is_match = match_tests.iter().any(|(module, names)| {
let matched_module =
module.is_empty() || checked_module.name.contains(module);
let matched_name = match names {
None => true,
Some(names) => names.iter().any(|name| {
if exact_match {
name == &func.name
} else {
func.name.contains(name)
}
}),
};
matched_module && matched_name
});
if is_match {
scripts.push((
checked_module.input_path.clone(),
checked_module.name.clone(),
func,
))
}
} else {
scripts.push(( scripts.push((
checked_module.input_path.clone(), checked_module.input_path.clone(),
checked_module.name.clone(), checked_module.name.clone(),
func, func,
)) ))
} }
} else {
scripts.push((
checked_module.input_path.clone(),
checked_module.name.clone(),
func,
))
} }
_ => (),
} }
} }
} }
let mut programs = Vec::new(); let mut programs = Vec::new();
let mut generator = self.checked_modules.new_generator(
&self.functions,
&self.data_types,
&self.module_types,
tracing,
);
for (module_name, testable_validator) in &testable_validators {
generator.insert_function(
module_name.to_string(),
testable_validator.name.clone(),
String::new(),
testable_validator,
);
}
for (input_path, module_name, func_def) in scripts { for (input_path, module_name, func_def) in scripts {
let Function { let Function {
name, name,
@ -724,13 +765,6 @@ where
}) })
} }
let mut generator = self.checked_modules.new_generator(
&self.functions,
&self.data_types,
&self.module_types,
tracing,
);
let evaluation_hint = func_def.test_hint().map(|(bin_op, left_src, right_src)| { let evaluation_hint = func_def.test_hint().map(|(bin_op, left_src, right_src)| {
let left = generator let left = generator
.clone() .clone()

View File

@ -335,7 +335,7 @@ impl CheckedModules {
Definition::TypeAlias(_) Definition::TypeAlias(_)
| Definition::ModuleConstant(_) | Definition::ModuleConstant(_)
| Definition::Test(_) | Definition::Test(_)
| Definition::Validator { .. } | Definition::Validator(_)
| Definition::Use(_) => {} | Definition::Use(_) => {}
} }
} }