use rune_testing::*;
#[test]
fn test_small_programs() {
assert_eq!(rune!(u64 => r#"fn main() { 42 }"#), 42u64);
assert_eq!(rune!(() => r#"fn main() {}"#), ());
assert_eq! {
rune! {
i64 => r#"
fn main() {
let a = 1;
let b = 2;
let c = a + b;
let d = c * 2;
let e = d / 3;
e
}
"#
},
2,
};
}
#[test]
fn test_boolean_ops() {
assert_eq! {
rune!(bool => r#"fn main() { true && true }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { true && false }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { false && true }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { false && false }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { true || true }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { true || false }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { false || true }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { false || false }"#),
false,
};
}
#[test]
fn test_if() {
assert_eq! {
rune! {
i64 => r#"
fn main() {
let n = 2;
if n > 5 {
10
} else {
0
}
}
"#
},
0,
};
assert_eq! {
rune!{
i64 => r#"
fn main() {
let n = 6;
if n > 5 {
10
} else {
0
}
}
"#
},
10,
};
}
#[test]
fn test_block() {
assert_eq! {
rune! {
i64 => r#"
fn main() {
let b = 10;
let n = {
let a = 10;
a + b
};
n + 1
}
"#
},
21,
};
}
#[test]
fn test_shadowing() {
assert_eq! {
rune! {
i64 => r#"
fn main() {
let a = 10;
let a = a;
a
}
"#
},
10,
};
}
#[test]
fn test_vectors() {
assert_eq! {
rune!(() => "fn main() { let v = [1, 2, 3, 4, 5]; }"),
(),
};
}
#[test]
fn test_while() {
assert_eq! {
rune!{
i64 => r#"
fn main() {
let a = 0;
while a < 10 {
a = a + 1;
}
a
}
"#
},
10,
};
assert_eq! {
rune! {
i64 => r#"
fn main() {
let a = 0;
let a = while a >= 0 {
if a >= 10 {
break a;
}
a = a + 1;
};
a
}
"#
},
10,
};
}
#[test]
fn test_loop() {
assert_eq! {
rune! {
runestick::VecTuple<(i64, bool)> => r#"
fn main() {
let a = 0;
let value = loop {
if a >= 10 {
break;
}
a = a + 1;
};
[a, value is unit]
}
"#
},
runestick::VecTuple((10, true)),
};
assert_eq! {
rune! {
i64 => r#"
fn main() {
let n = 0;
let n = loop {
if n >= 10 {
break n;
}
n = n + 1;
};
n
}
"#
},
10,
};
}
#[test]
fn test_for() {
assert_eq! {
rune! {
i64 => r#"
use std::iter::range;
fn main() {
let a = 0;
let it = range(0, 10);
for v in it {
a = a + 1;
}
a
}
"#
},
10,
};
assert_eq! {
rune! {
i64 => r#"
use std::iter::range;
fn main() {
let a = 0;
let it = range(0, 100);
let a = for v in it {
if a >= 10 {
break a;
}
a = a + 1;
};
a
}
"#
},
10,
};
assert_eq! {
rune! {
bool => r#"
use std::iter::range;
fn main() {
let a = 0;
let it = range(0, 100);
let a = for v in it {
if a >= 10 {
break;
}
a = a + 1;
};
a is unit
}
"#
},
true,
};
}
#[test]
fn test_return() {
assert_eq! {
rune! {
i64 => r#"
use std::iter::range;
fn main() {
for v in range(0, 20) {
if v == 10 {
return v;
}
}
0
}
"#
},
10,
};
}
#[test]
fn test_is() {
assert_eq! {
rune!(bool => r#"
fn main() {
{} is Object
}"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { #{} is Object }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { () is unit }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn foo() {} fn main() { foo() is unit }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { {} is unit }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { true is bool }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { 'a' is char }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { 42 is int }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { 42.1 is float }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { "hello" is String }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { #{"hello": "world"} is Object }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { ["hello", "world"] is Vec }"#),
true,
};
}
#[test]
fn test_match() {
assert_eq! {
rune!(i64 => r#"fn main() { match 1 { _ => 10 } }"#),
10,
};
assert_eq! {
rune!(i64 => r#"fn main() { match 10 { n => 10 } }"#),
10,
};
assert_eq! {
rune!(char => r#"fn main() { match 'a' { 'a' => 'b', n => n } }"#),
'b',
};
assert_eq! {
rune!(i64 => r#"fn main() { match 10 { n => n } }"#),
10,
};
assert_eq! {
rune!(i64 => r#"fn main() { match 10 { 10 => 5, n => n } }"#),
5,
};
assert_eq! {
rune!(String => r#"fn main() { match "hello world" { "hello world" => "hello john", n => n } }"#),
"hello john",
};
}
#[test]
fn test_vec_match() {
assert_eq! {
rune!(bool => r#"fn main() { match [] { [..] => true } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [] { [..] => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [a, b] => a + 1 == b } }"#),
true,
};
assert_eq! {
rune!(() => r#"fn main() { match [] { [a, b] => a + 1 == b } }"#),
(),
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [a, b] => a + 1 == b, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [a, b, ..] => a + 1 == b, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [1, ..] => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [] => true, _ => false } }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [1, 2] => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, 2] { [1] => true, _ => false } }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, [2, 3]] { [1, [2, ..]] => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, []] { [1, [2, ..]] => true, _ => false } }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, [2, 3]] { [1, [2, 3]] => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match [1, [2, 4]] { [1, [2, 3]] => true, _ => false } }"#),
false,
};
}
#[test]
fn test_object_match() {
assert_eq! {
rune!(bool => r#"fn main() { match #{} { #{..} => true } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{foo: true} { #{foo} => foo, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{} { #{..} => true, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{"foo": 10, "bar": 0} { #{"foo": v, ..} => v == 10, _ => false } }"#),
true,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{"foo": 10, "bar": 0} { #{"foo": v} => v == 10, _ => false } }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{"foo": 10, "bar": #{"baz": [1, 2]}} { #{"foo": v} => v == 10, _ => false } }"#),
false,
};
assert_eq! {
rune!(bool => r#"fn main() { match #{"foo": 10, "bar": #{"baz": [1, 2]}} { #{"foo": v, ..} => v == 10, _ => false } }"#),
true,
};
}
#[test]
fn test_bad_pattern() {
assert_vm_error!(
r#"
fn main() {
let [] = [1, 2, 3];
}
"#,
Panic { reason } => {
assert_eq!(reason.to_string(), "pattern did not match");
}
);
}
#[test]
fn test_destructuring() {
assert_eq! {
rune! {
i64 => r#"
fn foo(n) {
[n, n + 1]
}
fn main() {
let [a, b] = foo(3);
a + b
}
"#
},
7,
};
}
#[test]
fn test_if_pattern() {
assert_eq! {
rune! {
bool => r#"
fn main() {
if let [value] = [()] {
true
} else {
false
}
}
"#
},
true,
};
assert_eq! {
rune! {
bool => r#"
fn main() {
if let [value] = [(), ()] {
true
} else {
false
}
}
"#
},
false,
};
assert_eq! {
rune! {
i64 => r#"
fn main() {
let value = [(), (), 2];
if let [(), ()] = value {
1
} else if let [(), (), c] = value {
c
} else {
3
}
}
"#
},
2,
};
}
#[test]
fn test_break_label() {
assert_eq! {
rune! {
i64 => r#"
use std::iter::range;
fn main() {
let it = range(0, 1000);
let tail = 77;
'label:
while true {
let value = 10;
for n in it {
loop {
let value2 = 20;
break 'label;
}
tail = tail + 1;
}
tail = tail + 1;
}
tail
}
"#
},
77,
};
}
#[test]
fn test_literal() {
assert_eq! {
rune!(char => r#"fn main() { '\u{1F4AF}' }"#),
'💯',
};
}
#[test]
fn test_string_concat() {
assert_eq! {
rune! {
String => r#"
fn main() {
let foo = String::from_str("foo");
foo += "/bar" + "/baz";
foo
}
"#
},
"foo/bar/baz",
};
}
#[test]
fn test_template_string() {
assert_eq! {
rune! {
String => r#"
fn main() {
let name = "John Doe";
`Hello {name}, I am {1 - 10} years old!`
}
"#
},
"Hello John Doe, I am -9 years old!",
};
assert_eq! {
rune! {
String => r#"
fn main() {
let name = "John Doe";
`Hello {name}, I am {{
let a = 20;
a += 2;
a
}} years old!`
}
"#
},
"Hello John Doe, I am 22 years old!",
};
}
#[test]
fn test_variants_as_functions() {
assert_eq! {
rune! {
i64 => r#"
enum Foo { A(a), B(b, c) }
fn construct_tuple(tuple) {
tuple(1, 2)
}
fn main() {
let foo = construct_tuple(Foo::B);
match foo {
Foo::B(a, b) => a + b,
_ => 0,
}
}
"#
},
3,
};
}
#[test]
fn test_struct_matching() {
assert_eq! {
rune! {
i64 => r#"
struct Foo { a, b }
fn main() {
let foo = Foo {
a: 1,
b: 2,
};
match foo {
Foo { a, b } => a + b,
_ => 0,
}
}
"#
},
3,
};
assert_eq! {
rune! {
i64 => r#"
struct Foo { a, b }
fn main() {
let b = 2;
let foo = Foo {
a: 1,
b,
};
match foo {
Foo { a, b } => a + b,
_ => 0,
}
}
"#
},
3,
};
}
#[test]
fn test_iter_drop() {
assert_eq! {
rune! {
i64 => r#"
fn main() {
let sum = 0;
let values = [1, 2, 3, 4];
for v in values.iter() {
break;
}
values.push(5);
for v in values.iter() {
sum += v;
if v == 2 {
break;
}
}
values.push(6);
for v in values.iter() {
sum += v;
}
sum
}
"#
},
24,
};
}
#[test]
fn test_async_fn() {
assert_eq! {
rune! {
i64 => r#"
async fn foo(a, b) {
b / a
}
fn bar(a, b) {
b / a
}
async fn main() {
foo(2, 4).await + bar(2, 8)
}
"#
},
6,
};
}
#[test]
fn test_complex_field_access() {
assert_eq! {
rune! {
Option<i64> => r#"
fn foo() {
#{hello: #{world: 42}}
}
fn main() {
Some((foo()).hello["world"])
}
"#
},
Some(42),
};
}
#[test]
fn test_index_get() {
assert_eq! {
rune! {
i64 => r#"
struct Named(a, b, c);
enum Enum { Named(a, b, c) }
fn a() { [1, 2, 3] }
fn b() { (2, 3, 4) }
fn c() { Named(3, 4, 5) }
fn d() { Enum::Named(4, 5, 6) }
fn main() {
(a())[1] + (b())[1] + (c())[1] + (d())[1] + (a()).2 + (b()).2 + (c()).2 + (d()).2
}
"#
},
32,
};
}