diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs
index c757eb7a..098b80f2 100644
--- a/crates/aiken-lang/src/ast.rs
+++ b/crates/aiken-lang/src/ast.rs
@@ -801,7 +801,7 @@ impl Pattern {
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum AssignmentKind {
Let,
- Assert,
+ Expect,
}
impl AssignmentKind {
@@ -809,8 +809,15 @@ impl AssignmentKind {
matches!(self, AssignmentKind::Let)
}
- pub fn is_assert(&self) -> bool {
- matches!(self, AssignmentKind::Assert)
+ pub fn is_expect(&self) -> bool {
+ matches!(self, AssignmentKind::Expect)
+ }
+
+ pub fn location_offset(&self) -> usize {
+ match self {
+ AssignmentKind::Let => 3,
+ AssignmentKind::Expect => 6,
+ }
}
}
diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs
index 5a411b94..1fe00e8f 100644
--- a/crates/aiken-lang/src/format.rs
+++ b/crates/aiken-lang/src/format.rs
@@ -606,7 +606,7 @@ impl<'comments> Formatter<'comments> {
let keyword = match kind {
Some(AssignmentKind::Let) => "let ",
- Some(AssignmentKind::Assert) => "assert ",
+ Some(AssignmentKind::Expect) => "expect ",
None => "try ",
};
diff --git a/crates/aiken-lang/src/parser.rs b/crates/aiken-lang/src/parser.rs
index 383257cb..c9944a15 100644
--- a/crates/aiken-lang/src/parser.rs
+++ b/crates/aiken-lang/src/parser.rs
@@ -1028,7 +1028,7 @@ pub fn expr_parser(
},
);
- let assert_parser = just(Token::Assert)
+ let expect_parser = just(Token::Expect)
.ignore_then(pattern_parser())
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
.then_ignore(just(Token::Equal))
@@ -1038,7 +1038,7 @@ pub fn expr_parser(
location: span,
value: Box::new(value),
pattern,
- kind: ast::AssignmentKind::Assert,
+ kind: ast::AssignmentKind::Expect,
annotation,
},
);
@@ -1093,7 +1093,7 @@ pub fn expr_parser(
block_parser,
when_parser,
let_parser,
- assert_parser,
+ expect_parser,
if_parser,
));
diff --git a/crates/aiken-lang/src/parser/lexer.rs b/crates/aiken-lang/src/parser/lexer.rs
index 84aaa4d2..9b390364 100644
--- a/crates/aiken-lang/src/parser/lexer.rs
+++ b/crates/aiken-lang/src/parser/lexer.rs
@@ -87,7 +87,8 @@ pub fn lexer() -> impl Parser, Error = ParseError> {
"trace" => Token::Trace,
"error" => Token::ErrorTerm,
"as" => Token::As,
- "assert" => Token::Assert,
+ "assert" => Token::Expect,
+ "expect" => Token::Expect,
"const" => Token::Const,
"fn" => Token::Fn,
"test" => Token::Test,
diff --git a/crates/aiken-lang/src/parser/token.rs b/crates/aiken-lang/src/parser/token.rs
index 24c53c2d..e94de71c 100644
--- a/crates/aiken-lang/src/parser/token.rs
+++ b/crates/aiken-lang/src/parser/token.rs
@@ -60,11 +60,12 @@ pub enum Token {
NewLine,
// Keywords (alphabetically):
As,
- Assert,
Const,
Fn,
If,
Else,
+ ErrorTerm,
+ Expect,
Is,
Let,
Opaque,
@@ -75,7 +76,6 @@ pub enum Token {
Type,
When,
Trace,
- ErrorTerm,
}
impl fmt::Display for Token {
@@ -140,7 +140,7 @@ impl fmt::Display for Token {
Token::EmptyLine => "EMPTYLINE",
Token::NewLine => "NEWLINE",
Token::As => "as",
- Token::Assert => "assert",
+ Token::Expect => "expect",
Token::When => "when",
Token::Is => "is",
Token::Const => "const",
diff --git a/crates/aiken-lang/src/tests/parser.rs b/crates/aiken-lang/src/tests/parser.rs
index a3b042a6..129af56a 100644
--- a/crates/aiken-lang/src/tests/parser.rs
+++ b/crates/aiken-lang/src/tests/parser.rs
@@ -324,6 +324,77 @@ fn empty_function() {
)
}
+#[test]
+fn expect() {
+ let code = indoc! {r#"
+ pub fn run() {
+ expect Some(x) = something.field
+ x.other_field
+ }
+ "#};
+
+ assert_definitions(
+ code,
+ vec![ast::UntypedDefinition::Fn(Function {
+ arguments: vec![],
+ body: expr::UntypedExpr::Sequence {
+ location: Span::new((), 19..69),
+ expressions: vec![
+ expr::UntypedExpr::Assignment {
+ location: Span::new((), 19..51),
+ value: expr::UntypedExpr::FieldAccess {
+ location: Span::new((), 36..51),
+ label: "field".to_string(),
+ container: expr::UntypedExpr::Var {
+ location: Span::new((), 36..45),
+ name: "something".to_string(),
+ }
+ .into(),
+ }
+ .into(),
+ pattern: ast::Pattern::Constructor {
+ is_record: false,
+ location: Span::new((), 26..33),
+ name: "Some".to_string(),
+ arguments: vec![ast::CallArg {
+ label: None,
+ location: Span::new((), 31..32),
+ value: ast::Pattern::Var {
+ location: Span::new((), 31..32),
+ name: "x".to_string(),
+ },
+ }],
+ module: None,
+ constructor: (),
+ with_spread: false,
+ tipo: (),
+ },
+ kind: ast::AssignmentKind::Expect,
+ annotation: None,
+ },
+ expr::UntypedExpr::FieldAccess {
+ location: Span::new((), 56..69),
+ label: "other_field".to_string(),
+ container: expr::UntypedExpr::Var {
+ location: Span::new((), 56..57),
+ name: "x".to_string(),
+ }
+ .into(),
+ },
+ ],
+ },
+ doc: None,
+
+ location: Span::new((), 0..12),
+ name: "run".to_string(),
+ public: true,
+ return_annotation: None,
+ return_type: (),
+ end_position: 70,
+ })],
+ )
+}
+
#[test]
fn plus_binop() {
let code = indoc! {r#"
diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs
index 2c0fed74..c481ffbf 100644
--- a/crates/aiken-lang/src/tipo/error.rs
+++ b/crates/aiken-lang/src/tipo/error.rs
@@ -333,7 +333,7 @@ Perhaps, try the following:
#[diagnostic(code("illegal::module_name"))]
#[diagnostic(help(r#"You cannot use keywords as part of a module path name. As a quick reminder, here's a list of all the keywords (and thus, of invalid module path names):
- as, assert, check, const, else, fn, if, is, let, opaque, pub, test, todo, trace, type, use, when"#))]
+ as, expect, check, const, else, fn, if, is, let, opaque, pub, test, todo, trace, type, use, when"#))]
KeywordInModuleName { name: String, keyword: String },
#[error("I discovered a function which is ending with an assignment.\n")]
@@ -1076,6 +1076,21 @@ pub enum Warning {
sample: UntypedExpr,
},
+ #[error("I found an {} trying to match a type with one constructor", "expect".purple())]
+ #[diagnostic(
+ code("single_constructor_expect"),
+ help("If your type has one constructor, unless you are casting {} {}, you can\nprefer using a {} binding like so...\n\n{}", "FROM".bold(), "Data".purple(), "let".purple(), format_suggestion(sample))
+ )]
+ SingleConstructorExpect {
+ #[label("use let")]
+ location: Span,
+ #[label("only one constructor")]
+ pattern_location: Span,
+ #[label("is not Data")]
+ value_location: Span,
+ sample: UntypedExpr,
+ },
+
#[error("I found a todo left in the code.\n")]
#[diagnostic(help("You probably want to replace that one with real code... eventually."))]
#[diagnostic(code("todo"))]
diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs
index 3787b991..cb745d35 100644
--- a/crates/aiken-lang/src/tipo/expr.rs
+++ b/crates/aiken-lang/src/tipo/expr.rs
@@ -817,15 +817,18 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
fn infer_assignment(
&mut self,
- pattern: UntypedPattern,
- value: UntypedExpr,
+ untyped_pattern: UntypedPattern,
+ untyped_value: UntypedExpr,
kind: AssignmentKind,
annotation: &Option,
location: Span,
) -> Result {
- let typed_value = self.in_new_scope(|value_typer| value_typer.infer(value.clone()))?;
+ let typed_value =
+ self.in_new_scope(|value_typer| value_typer.infer(untyped_value.clone()))?;
let mut value_typ = typed_value.tipo();
+ let value_is_data = value_typ.is_data();
+
// Check that any type annotation is accurate.
let pattern = if let Some(ann) = annotation {
let ann_typ = self
@@ -836,25 +839,25 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
ann_typ.clone(),
value_typ.clone(),
typed_value.type_defining_location(),
- (kind.is_let() && ann_typ.is_data()) || (kind.is_assert() && value_typ.is_data()),
+ (kind.is_let() && ann_typ.is_data()) || (kind.is_expect() && value_is_data),
)?;
value_typ = ann_typ.clone();
// Ensure the pattern matches the type of the value
PatternTyper::new(self.environment, &self.hydrator).unify(
- pattern,
+ untyped_pattern.clone(),
value_typ.clone(),
Some(ann_typ),
)?
} else {
- if value_typ.is_data() && !pattern.is_var() && !pattern.is_discard() {
+ if value_is_data && !untyped_pattern.is_var() && !untyped_pattern.is_discard() {
return Err(Error::CastDataNoAnn {
location,
value: UntypedExpr::Assignment {
location,
- value: value.into(),
- pattern,
+ value: untyped_value.into(),
+ pattern: untyped_pattern,
kind,
annotation: Some(Annotation::Constructor {
location: Span::empty(),
@@ -868,7 +871,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
// Ensure the pattern matches the type of the value
PatternTyper::new(self.environment, &self.hydrator).unify(
- pattern,
+ untyped_pattern.clone(),
value_typ.clone(),
None,
)?
@@ -877,7 +880,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
// We currently only do limited exhaustiveness checking of custom types
// at the top level of patterns.
// Do not perform exhaustiveness checking if user explicitly used `assert`.
- if kind != AssignmentKind::Assert {
+ if kind != AssignmentKind::Expect {
if let Err(unmatched) = self.environment.check_exhaustiveness(
vec![pattern.clone()],
collapse_links(value_typ.clone()),
@@ -888,6 +891,33 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
unmatched,
});
}
+ } else if !value_is_data
+ && self
+ .environment
+ .check_exhaustiveness(
+ vec![pattern.clone()],
+ collapse_links(value_typ.clone()),
+ location,
+ )
+ .is_ok()
+ {
+ self.environment
+ .warnings
+ .push(Warning::SingleConstructorExpect {
+ location: Span {
+ start: location.start,
+ end: kind.location_offset(),
+ },
+ pattern_location: dbg!(untyped_pattern.location()),
+ value_location: dbg!(untyped_value.location()),
+ sample: UntypedExpr::Assignment {
+ location: Span::empty(),
+ value: Box::new(untyped_value),
+ pattern: untyped_pattern,
+ kind: AssignmentKind::Let,
+ annotation: None,
+ },
+ })
}
Ok(TypedExpr::Assignment {
diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs
index 54037cfd..2aead900 100644
--- a/crates/aiken-lang/src/tipo/infer.rs
+++ b/crates/aiken-lang/src/tipo/infer.rs
@@ -20,6 +20,8 @@ use super::{
TypeInfo, ValueConstructor, ValueConstructorVariant,
};
+const PUB_OFFSET: usize = 3;
+
impl UntypedModule {
pub fn infer(
mut self,
@@ -162,7 +164,7 @@ fn infer_definition(
environment.warnings.push(Warning::PubInValidatorModule {
location: Span {
start: location.start,
- end: location.start + 3,
+ end: location.start + PUB_OFFSET,
},
})
}
@@ -270,7 +272,7 @@ fn infer_definition(
environment.warnings.push(Warning::PubInValidatorModule {
location: Span {
start: location.start,
- end: location.start + 3,
+ end: location.start + PUB_OFFSET,
},
})
}
@@ -306,7 +308,7 @@ fn infer_definition(
environment.warnings.push(Warning::PubInValidatorModule {
location: Span {
start: location.start,
- end: location.start + 3,
+ end: location.start + PUB_OFFSET,
},
})
}
@@ -449,7 +451,7 @@ fn infer_definition(
environment.warnings.push(Warning::PubInValidatorModule {
location: Span {
start: location.start,
- end: location.start + 3,
+ end: location.start + PUB_OFFSET,
},
})
}
@@ -511,8 +513,11 @@ fn validate_module_name(name: &str) -> Result<(), Error> {
fn str_to_keyword(word: &str) -> Option {
// Alphabetical keywords:
match word {
+ "assert" => Some(Token::Expect),
+ "expect" => Some(Token::Expect),
+ "else" => Some(Token::Else),
+ "is" => Some(Token::Is),
"as" => Some(Token::As),
- "assert" => Some(Token::Assert),
"when" => Some(Token::When),
"const" => Some(Token::Const),
"fn" => Some(Token::Fn),
diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs
index 15384e91..a2679763 100644
--- a/crates/aiken-lang/src/uplc.rs
+++ b/crates/aiken-lang/src/uplc.rs
@@ -1578,7 +1578,7 @@ impl<'a> CodeGenerator<'a> {
pattern_vec.append(value_vec);
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -1604,7 +1604,7 @@ impl<'a> CodeGenerator<'a> {
pattern_vec.append(value_vec);
}
list @ Pattern::List { .. } => {
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -1629,7 +1629,7 @@ impl<'a> CodeGenerator<'a> {
}
// TODO: Check constr for assert on all cases
constr @ Pattern::Constructor { .. } => {
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -1653,7 +1653,7 @@ impl<'a> CodeGenerator<'a> {
}
}
tuple @ Pattern::Tuple { .. } => {
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -2503,7 +2503,7 @@ impl<'a> CodeGenerator<'a> {
let id = self.id_gen.next();
let list_name = format!("__list_{id}");
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -2556,7 +2556,7 @@ impl<'a> CodeGenerator<'a> {
let id = self.id_gen.next();
let constr_name = format!("{constr_name}_{id}");
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
@@ -2605,7 +2605,7 @@ impl<'a> CodeGenerator<'a> {
let id = self.id_gen.next();
let tuple_name = format!("__tuple_name_{id}");
- if matches!(assignment_properties.kind, AssignmentKind::Assert)
+ if matches!(assignment_properties.kind, AssignmentKind::Expect)
&& assignment_properties.value_type.is_data()
&& !tipo.is_data()
{
diff --git a/examples/acceptance_tests/008/lib/tests.ak b/examples/acceptance_tests/008/lib/tests.ak
index 689fb805..d9fcc3ed 100644
--- a/examples/acceptance_tests/008/lib/tests.ak
+++ b/examples/acceptance_tests/008/lib/tests.ak
@@ -5,17 +5,17 @@ pub fn is_empty(bytes: ByteArray) -> Bool {
}
test is_empty_1() {
- is_empty(#[]) == True
+ is_empty(#"") == True
}
test is_empty_1_alt() {
- is_empty(#[])
+ is_empty(#"")
}
test is_empty_2() {
- is_empty(#[1]) == False
+ is_empty(#"01") == False
}
test is_empty_2_alt() {
- !is_empty(#[1])
+ !is_empty(#"01")
}
diff --git a/examples/acceptance_tests/009/lib/tests.ak b/examples/acceptance_tests/009/lib/tests.ak
index b4ef2b0d..c3384d04 100644
--- a/examples/acceptance_tests/009/lib/tests.ak
+++ b/examples/acceptance_tests/009/lib/tests.ak
@@ -5,5 +5,5 @@ pub fn is_empty(bytes: ByteArray) -> Bool {
}
test is_empty_1() {
- is_empty(#[]) == True
+ is_empty(#"") == True
}
diff --git a/examples/acceptance_tests/016/lib/tests.ak b/examples/acceptance_tests/016/lib/tests.ak
index 9c658c82..72462cea 100644
--- a/examples/acceptance_tests/016/lib/tests.ak
+++ b/examples/acceptance_tests/016/lib/tests.ak
@@ -13,6 +13,6 @@ pub fn drop(bytes: ByteArray, n: Int) -> ByteArray {
}
test drop_1() {
- let x = #[1, 2, 3, 4, 5, 6, 7]
- drop(x, 2) == #[3, 4, 5, 6, 7]
+ let x = #"01020304050607"
+ drop(x, 2) == #"0304050607"
}
diff --git a/examples/acceptance_tests/017/lib/tests.ak b/examples/acceptance_tests/017/lib/tests.ak
index af71db7b..62863b0d 100644
--- a/examples/acceptance_tests/017/lib/tests.ak
+++ b/examples/acceptance_tests/017/lib/tests.ak
@@ -9,5 +9,5 @@ pub fn take(bytes: ByteArray, n: Int) -> ByteArray {
}
test take_1() {
- take(#[1, 2, 3], 2) == #[1, 2]
+ take(#"010203", 2) == #"0102"
}
diff --git a/examples/acceptance_tests/023/lib/tests.ak b/examples/acceptance_tests/023/lib/tests.ak
index cdafc006..761e86ef 100644
--- a/examples/acceptance_tests/023/lib/tests.ak
+++ b/examples/acceptance_tests/023/lib/tests.ak
@@ -18,11 +18,7 @@ pub fn insert(
AssocList { inner: do_insert(m.inner, k, v) }
}
-fn do_insert(
- elems: List<(key, value)>,
- k: key,
- v: value,
-) -> List<(key, value)> {
+fn do_insert(elems: List<(key, value)>, k: key, v: value) -> List<(key, value)> {
when elems is {
[] -> [(k, v)]
[(k2, v2), ..rest] ->
diff --git a/examples/acceptance_tests/029/lib/tests.ak b/examples/acceptance_tests/029/lib/tests.ak
index 6d74cfac..bc3f1835 100644
--- a/examples/acceptance_tests/029/lib/tests.ak
+++ b/examples/acceptance_tests/029/lib/tests.ak
@@ -25,11 +25,7 @@ pub fn insert(
AssocList { inner: do_insert(m.inner, k, v) }
}
-fn do_insert(
- elems: List<(key, value)>,
- k: key,
- v: value,
-) -> List<(key, value)> {
+fn do_insert(elems: List<(key, value)>, k: key, v: value) -> List<(key, value)> {
when elems is {
[] -> [(k, v)]
[(k2, v2), ..rest] ->
diff --git a/examples/acceptance_tests/035/lib/aiken/dict.ak b/examples/acceptance_tests/035/lib/aiken/dict.ak
index 9640ff8f..a2bbcc2f 100644
--- a/examples/acceptance_tests/035/lib/aiken/dict.ak
+++ b/examples/acceptance_tests/035/lib/aiken/dict.ak
@@ -20,7 +20,7 @@ pub fn insert(
) -> Dict {
Dict {
inner: do_insert_with(self.inner, k, v, fn(_, left, _right) { Some(left) })}
-
+
}
pub fn union_with(
diff --git a/examples/acceptance_tests/035/lib/tests.ak b/examples/acceptance_tests/035/lib/tests.ak
index 60279bab..2cf7eade 100644
--- a/examples/acceptance_tests/035/lib/tests.ak
+++ b/examples/acceptance_tests/035/lib/tests.ak
@@ -22,7 +22,7 @@ pub fn from_asset(
}
pub fn from_lovelace(quantity: Int) -> Value {
- from_asset(#[], #[], quantity)
+ from_asset(#"", #"", quantity)
}
pub fn add(left v0: Value, right v1: Value) -> Value {
diff --git a/examples/acceptance_tests/036/validators/spend.ak b/examples/acceptance_tests/036/validators/spend.ak
index 23094f20..f68427db 100644
--- a/examples/acceptance_tests/036/validators/spend.ak
+++ b/examples/acceptance_tests/036/validators/spend.ak
@@ -3,7 +3,7 @@ use aiken/list
use aiken/transaction.{Output, ScriptContext}
use aiken/transaction/value.{PolicyId}
-const my_policy_id: PolicyId = #[0, 0, 0, 0, 0]
+const my_policy_id: PolicyId = #"0000000000"
pub fn has_policy_id(self: Output, policy_id: PolicyId) -> Bool {
self.value
diff --git a/examples/acceptance_tests/039/lib/tests.ak b/examples/acceptance_tests/039/lib/tests.ak
index 22b1bc55..66c5933b 100644
--- a/examples/acceptance_tests/039/lib/tests.ak
+++ b/examples/acceptance_tests/039/lib/tests.ak
@@ -37,52 +37,52 @@ pub fn update_door_locked_and_wheels(
test update_owner1() {
let initial_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 45 },
}
let final_car =
Car {
- owner: #[244, 244, 244, 244],
+ owner: #"f4f4f4f4",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 45 },
}
- update_owner(#[244, 244, 244, 244], initial_car) == final_car
+ update_owner(#"f4f4f4f4", initial_car) == final_car
}
test update_vin1() {
let initial_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 45 },
}
let final_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[2, 2, 2, 2, 2, 2, 2, 2, 2],
+ vin: #"020202020202020202",
door: Door { locked: False, hinge_angle: 45 },
}
- update_vin(#[2, 2, 2, 2, 2, 2, 2, 2, 2], initial_car) == final_car
+ update_vin(#"020202020202020202", initial_car) == final_car
}
test update_door_angle1() {
let initial_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 45 },
}
let final_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 90 },
}
update_door_angle(90, initial_car) == final_car
@@ -91,16 +91,16 @@ test update_door_angle1() {
test update_door_locked_and_wheels1() {
let initial_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 4,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: False, hinge_angle: 45 },
}
let final_car =
Car {
- owner: #[],
+ owner: #"",
wheels: 5,
- vin: #[1, 1, 1, 1, 1, 1, 1],
+ vin: #"01010101010101",
door: Door { locked: True, hinge_angle: 45 },
}
update_door_locked_and_wheels(True, 5, initial_car) == final_car
diff --git a/examples/acceptance_tests/040/lib/tests.ak b/examples/acceptance_tests/040/lib/tests.ak
index 5cdb783d..3bd58bd9 100644
--- a/examples/acceptance_tests/040/lib/tests.ak
+++ b/examples/acceptance_tests/040/lib/tests.ak
@@ -28,6 +28,6 @@ test update_owner1() {
builtin.list_data([]),
],
)
- assert Ford { owner, wheels, truck_bed_limit, .. }: Car = initial_car
+ expect Ford { owner, wheels, truck_bed_limit, .. }: Car = initial_car
owner == #"" && wheels == 4 && truck_bed_limit == 10000
}
diff --git a/examples/acceptance_tests/047/lib/tests.ak b/examples/acceptance_tests/047/lib/tests.ak
deleted file mode 100644
index e69de29b..00000000
diff --git a/examples/acceptance_tests/050/lib/tests.ak b/examples/acceptance_tests/050/lib/tests.ak
index 4416c0bc..dca9b864 100644
--- a/examples/acceptance_tests/050/lib/tests.ak
+++ b/examples/acceptance_tests/050/lib/tests.ak
@@ -13,19 +13,19 @@ test let_1() {
test let_2() {
let x: Data = 1
- assert y: Int = x
+ expect y: Int = x
y == 1
}
test assert_1() {
- assert thing: Thing = builtin.constr_data(0, [builtin.i_data(1)])
+ expect thing: Thing = builtin.constr_data(0, [builtin.i_data(1)])
thing.wow == 1
}
fn cast_to_thing(x: Data) -> Thing {
- assert x: Thing = x
+ expect x: Thing = x
x
}
diff --git a/examples/acceptance_tests/fmt b/examples/acceptance_tests/fmt
new file mode 100755
index 00000000..4e424e97
--- /dev/null
+++ b/examples/acceptance_tests/fmt
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+if [ -z $1 ]; then
+ echo -e "\033[31mMissing argument: \033[1mACCEPTANCE_TEST\033[0m"
+ echo ""
+ echo -e "\033[1mUsage: \033[0m"
+ echo " run.sh {ACCEPTANCE_TEST}"
+ echo ""
+ echo -e "\033[1mExample: \033[0m"
+ echo " run.sh 034"
+ exit 1
+fi
+
+WORKDIR="$(dirname -- "${BASH_SOURCE[0]}")"
+TARGET="$WORKDIR/$(basename $1)"
+
+TMP=$(mktemp)
+RESULT=$(cargo run --quiet -- fmt $TARGET 2>$TMP)
+
+if [ "$?" -eq "0" ]; then
+ echo "✅ $(basename $TARGET)"
+else
+ echo "❌ $(basename $TARGET)"
+ cat $TMP
+ exit 1
+fi
diff --git a/examples/acceptance_tests/fmt-all b/examples/acceptance_tests/fmt-all
new file mode 100755
index 00000000..fd06db44
--- /dev/null
+++ b/examples/acceptance_tests/fmt-all
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+find . -regex ".*[0-9]\{3\}" -type d | xargs -P 8 -I {} -- ./fmt {}