test: add some snapshot tests for export type
This commit is contained in:
parent
5cb1e23008
commit
5fc338a1eb
|
@ -38,11 +38,6 @@ impl Export {
|
||||||
generator: &mut CodeGenerator,
|
generator: &mut CodeGenerator,
|
||||||
modules: &CheckedModules,
|
modules: &CheckedModules,
|
||||||
) -> Result<Export, blueprint::Error> {
|
) -> Result<Export, blueprint::Error> {
|
||||||
let program = generator
|
|
||||||
.generate_raw(&func.body, &func.arguments, &module.name)
|
|
||||||
.to_debruijn()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut definitions = Definitions::new();
|
let mut definitions = Definitions::new();
|
||||||
|
|
||||||
let parameters = func
|
let parameters = func
|
||||||
|
@ -69,6 +64,11 @@ impl Export {
|
||||||
})
|
})
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
|
let program = generator
|
||||||
|
.generate_raw(&func.body, &func.arguments, &module.name)
|
||||||
|
.to_debruijn()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(Export {
|
Ok(Export {
|
||||||
name: format!("{}.{}", &module.name, &func.name),
|
name: format!("{}.{}", &module.name, &func.name),
|
||||||
doc: func.doc.clone(),
|
doc: func.doc.clone(),
|
||||||
|
@ -78,3 +78,106 @@ impl Export {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{CheckedModules, Export};
|
||||||
|
use crate::tests::TestProject;
|
||||||
|
use aiken_lang::{
|
||||||
|
self,
|
||||||
|
ast::{TraceLevel, Tracing},
|
||||||
|
};
|
||||||
|
|
||||||
|
macro_rules! assert_export {
|
||||||
|
($code:expr) => {
|
||||||
|
let mut project = TestProject::new();
|
||||||
|
|
||||||
|
let modules = CheckedModules::singleton(project.check(project.parse(indoc::indoc! { $code })));
|
||||||
|
|
||||||
|
let mut generator = project.new_generator(
|
||||||
|
Tracing::All(TraceLevel::Verbose),
|
||||||
|
);
|
||||||
|
|
||||||
|
let (module, func) = modules
|
||||||
|
.functions()
|
||||||
|
.next()
|
||||||
|
.expect("source code did no yield any exports");
|
||||||
|
|
||||||
|
let export = Export::from_function(func, module, &mut generator, &modules);
|
||||||
|
|
||||||
|
match export {
|
||||||
|
Err(e) => insta::with_settings!({
|
||||||
|
description => concat!("Code:\n\n", indoc::indoc! { $code }),
|
||||||
|
omit_expression => true
|
||||||
|
}, {
|
||||||
|
insta::assert_debug_snapshot!(e);
|
||||||
|
}),
|
||||||
|
|
||||||
|
Ok(validator) => insta::with_settings!({
|
||||||
|
description => concat!("Code:\n\n", indoc::indoc! { $code }),
|
||||||
|
omit_expression => true
|
||||||
|
}, {
|
||||||
|
insta::assert_json_snapshot!(validator);
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_export() {
|
||||||
|
assert_export!(
|
||||||
|
r#"
|
||||||
|
pub fn add(a: Int, b: Int) -> Int {
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn illegal_opaque_type() {
|
||||||
|
assert_export!(
|
||||||
|
r#"
|
||||||
|
pub opaque type Thing {
|
||||||
|
a: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(a: Thing, b: Int) -> Int {
|
||||||
|
a.a + b
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn recursive_types() {
|
||||||
|
assert_export!(
|
||||||
|
r#"
|
||||||
|
pub type Foo<a> {
|
||||||
|
Empty
|
||||||
|
Bar(a, Foo<a>)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(a: Foo<Int>, b: Foo<Int>) -> Int {
|
||||||
|
when (a, b) is {
|
||||||
|
(Empty, Empty) -> 0
|
||||||
|
(Bar(x, y), Bar(c, d)) -> x + c + add(y, d)
|
||||||
|
(Empty, Bar(c, d)) -> c + add(Empty, d)
|
||||||
|
(Bar(x, y), Empty) -> x + add(y, Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_export_generics() {
|
||||||
|
assert_export!(
|
||||||
|
r#"
|
||||||
|
pub fn add(_a: a, _b: b) -> Bool {
|
||||||
|
True
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -477,6 +477,20 @@ impl CheckedModules {
|
||||||
items.into_iter()
|
items.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn functions(&self) -> impl Iterator<Item = (&CheckedModule, &TypedFunction)> {
|
||||||
|
let mut items = vec![];
|
||||||
|
|
||||||
|
for module in self.0.values() {
|
||||||
|
for some_definition in module.ast.definitions() {
|
||||||
|
if let Definition::Fn(def) = some_definition {
|
||||||
|
items.push((module, def));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items.into_iter()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn into_validators(self) -> impl Iterator<Item = CheckedModule> {
|
pub fn into_validators(self) -> impl Iterator<Item = CheckedModule> {
|
||||||
self.0
|
self.0
|
||||||
.into_values()
|
.into_values()
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
source: crates/aiken-project/src/export.rs
|
||||||
|
description: "Code:\n\npub fn add(a: Int, b: Int) -> Int {\n a + b\n}\n"
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"name": "test_module.add",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"title": "a",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Int"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "b",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compiledCode": "500100002322337000046eb4004dd68009",
|
||||||
|
"hash": "bcd6700b4dba798a7d19c5769ef3deb21423f8809594a6942860dd1f",
|
||||||
|
"definitions": {
|
||||||
|
"Int": {
|
||||||
|
"dataType": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
source: crates/aiken-project/src/export.rs
|
||||||
|
description: "Code:\n\npub fn add(_a: a, _b: b) -> Bool {\n True\n}\n"
|
||||||
|
---
|
||||||
|
Schema {
|
||||||
|
error: Error {
|
||||||
|
context: FreeTypeVariable,
|
||||||
|
breadcrumbs: [
|
||||||
|
Var {
|
||||||
|
tipo: RefCell {
|
||||||
|
value: Generic {
|
||||||
|
id: 33,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
alias: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
location: 11..16,
|
||||||
|
source_code: NamedSource {
|
||||||
|
name: "",
|
||||||
|
source: "<redacted>",
|
||||||
|
,
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
source: crates/aiken-project/src/export.rs
|
||||||
|
description: "Code:\n\npub opaque type Thing {\n a: Int\n}\n\npub fn add(a: Thing, b: Int) -> Int {\n a.a + b\n}\n"
|
||||||
|
---
|
||||||
|
Schema {
|
||||||
|
error: Error {
|
||||||
|
context: IllegalOpaqueType,
|
||||||
|
breadcrumbs: [
|
||||||
|
App {
|
||||||
|
public: true,
|
||||||
|
contains_opaque: true,
|
||||||
|
module: "test_module",
|
||||||
|
name: "Thing",
|
||||||
|
args: [],
|
||||||
|
alias: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
location: 47..55,
|
||||||
|
source_code: NamedSource {
|
||||||
|
name: "",
|
||||||
|
source: "<redacted>",
|
||||||
|
,
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
source: crates/aiken-project/src/export.rs
|
||||||
|
description: "Code:\n\npub type Foo<a> {\n Empty\n Bar(a, Foo<a>)\n}\n\npub fn add(a: Foo<Int>, b: Foo<Int>) -> Int {\n when (a, b) is {\n (Empty, Empty) -> 0\n (Bar(x, y), Bar(c, d)) -> x + c + add(y, d)\n (Empty, Bar(c, d)) -> c + add(Empty, d)\n (Bar(x, y), Empty) -> x + add(y, Empty)\n }\n}\n"
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"name": "test_module.add",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"title": "a",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/test_module~1Foo$Int"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "b",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/test_module~1Foo$Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compiledCode": "5901c3010000323232323222323232323253330083002300937540062a666010600460126ea801052000001001132323232533300b3004300c375400c2646464a66601c600e601e6ea80284c8cdc019b80003375a60240026600c0046024602600260206ea8028010c040c044008dd6980780098069baa006001132533300b3005300c375400c2a666016600860186ea801c4c8cdc01bad300f001330034c103d8798000300f3010001300d375400e00200226466e00dd698070009980118071807800a60103d8798000300c375400a600200244464646464a66601e601260206ea800854ccc03cc024c040dd50018a4000002002264a66601e601060206ea80084c8c8c94ccc048c02cc04cdd500309919b80337000066eb4c058004ccc02c02c008c058c05c004c050dd5003002180a180a8011bad301300130113754004002264a66601e601260206ea800854ccc03cc020c040dd500189919b80375a6026002666010010980103d8798000301330140013011375400600200226466e00dd6980900099980380398091809800a60103d879800030103754002601c004601c00266ec0008004dc3a40046e1d20003006002300600133760004002ae6955ceaab9e5742ae89",
|
||||||
|
"hash": "4ce96c928b3be798496fca0ec3666d15d09004115df638801715b5e8",
|
||||||
|
"definitions": {
|
||||||
|
"Int": {
|
||||||
|
"dataType": "integer"
|
||||||
|
},
|
||||||
|
"test_module/Foo$Int": {
|
||||||
|
"title": "Foo",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"title": "Empty",
|
||||||
|
"dataType": "constructor",
|
||||||
|
"index": 0,
|
||||||
|
"fields": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Bar",
|
||||||
|
"dataType": "constructor",
|
||||||
|
"index": 1,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/Int"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/test_module~1Foo$Int"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue