feat: add ability to reference validators in tests closes #632
This commit is contained in:
parent
13ee62c05c
commit
e7c1b28b52
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue