test(parser): type alias, anon fn, record update and more
This commit is contained in:
@@ -89,3 +89,13 @@ pub fn parser() -> impl Parser<Token, ast::Annotation, Error = ParseError> {
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_annotation;
|
||||
|
||||
#[test]
|
||||
fn type_annotation_with_module_prefix() {
|
||||
assert_annotation!("aiken.Option<Int>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,3 +87,26 @@ pub fn param(is_validator_param: bool) -> impl Parser<Token, ast::UntypedArg, Er
|
||||
arg_name,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_definition;
|
||||
|
||||
#[test]
|
||||
fn function_empty() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
pub fn run() {}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_non_public() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
fn run() {}
|
||||
"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
45
crates/aiken-lang/src/parser/definition/snapshots/fail.snap
Normal file
45
crates/aiken-lang/src/parser/definition/snapshots/fail.snap
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/test.rs
|
||||
description: "Code:\n\n!test invalid_inputs() {\n expect True = False\n\n False\n}\n"
|
||||
---
|
||||
Test(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Sequence {
|
||||
location: 27..55,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 27..46,
|
||||
value: Var {
|
||||
location: 41..46,
|
||||
name: "False",
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 34..38,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
kind: Expect,
|
||||
annotation: None,
|
||||
},
|
||||
Var {
|
||||
location: 50..55,
|
||||
name: "False",
|
||||
},
|
||||
],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..22,
|
||||
name: "invalid_inputs",
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 56,
|
||||
can_error: true,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/function.rs
|
||||
description: "Code:\n\npub fn run() {}\n"
|
||||
---
|
||||
Fn(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Trace {
|
||||
kind: Todo,
|
||||
location: 0..15,
|
||||
then: ErrorTerm {
|
||||
location: 0..15,
|
||||
},
|
||||
text: String {
|
||||
location: 0..15,
|
||||
value: "aiken::todo",
|
||||
},
|
||||
},
|
||||
doc: None,
|
||||
location: 0..12,
|
||||
name: "run",
|
||||
public: true,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 14,
|
||||
can_error: true,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/function.rs
|
||||
description: "Code:\n\nfn run() {}\n"
|
||||
---
|
||||
Fn(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Trace {
|
||||
kind: Todo,
|
||||
location: 0..11,
|
||||
then: ErrorTerm {
|
||||
location: 0..11,
|
||||
},
|
||||
text: String {
|
||||
location: 0..11,
|
||||
value: "aiken::todo",
|
||||
},
|
||||
},
|
||||
doc: None,
|
||||
location: 0..8,
|
||||
name: "run",
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 10,
|
||||
can_error: true,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/type_alias.rs
|
||||
description: "Code:\n\ntype Thing = Int"
|
||||
---
|
||||
TypeAlias(
|
||||
TypeAlias {
|
||||
alias: "Thing",
|
||||
annotation: Constructor {
|
||||
location: 13..16,
|
||||
module: None,
|
||||
name: "Int",
|
||||
arguments: [],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..16,
|
||||
parameters: [],
|
||||
public: false,
|
||||
tipo: (),
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/type_alias.rs
|
||||
description: "Code:\n\npub type Me = String"
|
||||
---
|
||||
TypeAlias(
|
||||
TypeAlias {
|
||||
alias: "Me",
|
||||
annotation: Constructor {
|
||||
location: 14..20,
|
||||
module: None,
|
||||
name: "String",
|
||||
arguments: [],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..20,
|
||||
parameters: [],
|
||||
public: true,
|
||||
tipo: (),
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/definition/type_alias.rs
|
||||
description: "Code:\n\ntype RoyaltyToken = (PolicyId, AssetName)"
|
||||
---
|
||||
TypeAlias(
|
||||
TypeAlias {
|
||||
alias: "RoyaltyToken",
|
||||
annotation: Tuple {
|
||||
location: 20..41,
|
||||
elems: [
|
||||
Constructor {
|
||||
location: 21..29,
|
||||
module: None,
|
||||
name: "PolicyId",
|
||||
arguments: [],
|
||||
},
|
||||
Constructor {
|
||||
location: 31..40,
|
||||
module: None,
|
||||
name: "AssetName",
|
||||
arguments: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..41,
|
||||
parameters: [],
|
||||
public: false,
|
||||
tipo: (),
|
||||
},
|
||||
)
|
||||
@@ -35,3 +35,21 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_definition;
|
||||
|
||||
#[test]
|
||||
fn test_fail() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
!test invalid_inputs() {
|
||||
expect True = False
|
||||
|
||||
False
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,3 +23,32 @@ pub fn parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_definition;
|
||||
|
||||
#[test]
|
||||
fn type_alias_tuple() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
type RoyaltyToken = (PolicyId, AssetName)"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_alias_basic() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
type Thing = Int"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_alias_pub() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
pub type Me = String"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,3 +54,13 @@ pub fn params() -> impl Parser<Token, ast::UntypedArg, Error = ParseError> {
|
||||
arg_name,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_expr;
|
||||
|
||||
#[test]
|
||||
fn anonymous_function_basic() {
|
||||
assert_expr!(r#"fn (a: Int) -> Int { a + 1 }"#);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,3 +43,13 @@ fn assignment(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_expr;
|
||||
|
||||
#[test]
|
||||
fn let_bindings() {
|
||||
assert_expr!(r#"let thing = [ 1, 2, a ]"#);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,3 +84,13 @@ pub fn parser(
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_expr;
|
||||
|
||||
#[test]
|
||||
fn record_update_basic() {
|
||||
assert_expr!(r#"User { ..user, name: "Aiken", age }"#);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/expr/anonymous_function.rs
|
||||
description: "Code:\n\nfn (a: Int) -> Int { a + 1 }"
|
||||
---
|
||||
Fn {
|
||||
location: 0..28,
|
||||
fn_style: Plain,
|
||||
arguments: [
|
||||
Arg {
|
||||
arg_name: Named {
|
||||
name: "a",
|
||||
label: "a",
|
||||
location: 4..5,
|
||||
is_validator_param: false,
|
||||
},
|
||||
location: 4..10,
|
||||
annotation: Some(
|
||||
Constructor {
|
||||
location: 7..10,
|
||||
module: None,
|
||||
name: "Int",
|
||||
arguments: [],
|
||||
},
|
||||
),
|
||||
tipo: (),
|
||||
},
|
||||
],
|
||||
body: BinOp {
|
||||
location: 21..26,
|
||||
name: AddInt,
|
||||
left: Var {
|
||||
location: 21..22,
|
||||
name: "a",
|
||||
},
|
||||
right: Int {
|
||||
location: 25..26,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
return_annotation: Some(
|
||||
Constructor {
|
||||
location: 15..18,
|
||||
module: None,
|
||||
name: "Int",
|
||||
arguments: [],
|
||||
},
|
||||
),
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/expr/assignment.rs
|
||||
description: "Code:\n\nlet thing = [ 1, 2, a ]"
|
||||
---
|
||||
Assignment {
|
||||
location: 0..23,
|
||||
value: List {
|
||||
location: 12..23,
|
||||
elements: [
|
||||
Int {
|
||||
location: 14..15,
|
||||
value: "1",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
Int {
|
||||
location: 17..18,
|
||||
value: "2",
|
||||
base: Decimal {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
Var {
|
||||
location: 20..21,
|
||||
name: "a",
|
||||
},
|
||||
],
|
||||
tail: None,
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..9,
|
||||
name: "thing",
|
||||
},
|
||||
kind: Let,
|
||||
annotation: None,
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/expr/record_update.rs
|
||||
description: "Code:\n\nUser { ..user, name: \"Aiken\", age }"
|
||||
---
|
||||
RecordUpdate {
|
||||
location: 0..35,
|
||||
constructor: Var {
|
||||
location: 0..4,
|
||||
name: "User",
|
||||
},
|
||||
spread: RecordUpdateSpread {
|
||||
base: Var {
|
||||
location: 9..13,
|
||||
name: "user",
|
||||
},
|
||||
location: 7..13,
|
||||
},
|
||||
arguments: [
|
||||
UntypedRecordUpdateArg {
|
||||
label: "name",
|
||||
location: 15..28,
|
||||
value: ByteArray {
|
||||
location: 21..28,
|
||||
bytes: [
|
||||
65,
|
||||
105,
|
||||
107,
|
||||
101,
|
||||
110,
|
||||
],
|
||||
preferred_format: Utf8String,
|
||||
},
|
||||
},
|
||||
UntypedRecordUpdateArg {
|
||||
label: "age",
|
||||
location: 30..33,
|
||||
value: Var {
|
||||
location: 30..33,
|
||||
name: "age",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
source: crates/aiken-lang/src/parser/annotation.rs
|
||||
description: "Code:\n\naiken.Option<Int>"
|
||||
---
|
||||
Constructor {
|
||||
location: 0..17,
|
||||
module: Some(
|
||||
"aiken",
|
||||
),
|
||||
name: "Option",
|
||||
arguments: [
|
||||
Constructor {
|
||||
location: 13..16,
|
||||
module: None,
|
||||
name: "Int",
|
||||
arguments: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -115,6 +115,27 @@ macro_rules! assert_expr {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_annotation {
|
||||
($code:expr) => {
|
||||
use chumsky::Parser;
|
||||
|
||||
let $crate::parser::lexer::LexInfo { tokens, .. } = $crate::parser::lexer::run(indoc::indoc! { $code }).unwrap();
|
||||
|
||||
let stream = chumsky::Stream::from_iter($crate::ast::Span::create(tokens.len()), tokens.into_iter());
|
||||
|
||||
let result = $crate::parser::annotation().parse(stream).unwrap();
|
||||
|
||||
insta::with_settings!({
|
||||
description => concat!("Code:\n\n", indoc::indoc! { $code }),
|
||||
prepend_module_to_snapshot => false,
|
||||
omit_expression => true
|
||||
}, {
|
||||
insta::assert_debug_snapshot!(result);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_module {
|
||||
($code:expr) => {
|
||||
|
||||
Reference in New Issue
Block a user