mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00
add some basic tests
This commit is contained in:
parent
ac662c8e10
commit
7f318d9e1c
@ -25,31 +25,10 @@ pub mod prelude_compile {
|
|||||||
|
|
||||||
/// can be used to extend the mers config.
|
/// can be used to extend the mers config.
|
||||||
/// with this, you can add values (usually functions),
|
/// with this, you can add values (usually functions),
|
||||||
/// or add your own types to the language:
|
/// or your own custom types to the language.
|
||||||
///
|
///
|
||||||
/// use mers_lib::prelude_extend_config::Config;
|
/// Your customizations will only be available if you use
|
||||||
/// fn add_thing(cfg: Config) -> Config {
|
/// the infos you got from calling `.infos()` on your `Config` after customizing it.
|
||||||
/// // use the methods on Config to add things (see the Config source code for examples)
|
|
||||||
/// cfg.add_var("my_var".to_owned(), todo!())
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// then use the Config when compiling and running your code, and your customizations will be available.
|
|
||||||
pub mod prelude_extend_config {
|
pub mod prelude_extend_config {
|
||||||
pub use crate::program::configs::Config;
|
pub use crate::program::configs::Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_examples() {
|
|
||||||
for example in std::fs::read_dir("../examples").unwrap() {
|
|
||||||
let path = example.unwrap().path();
|
|
||||||
eprintln!("Checking file {path:?}.");
|
|
||||||
let src = prelude_compile::Source::new_from_file(path).unwrap();
|
|
||||||
let (mut i1, _, mut i3) = prelude_compile::Config::new().bundle_std().infos();
|
|
||||||
prelude_compile::parse(&mut src.clone(), &std::sync::Arc::new(src))
|
|
||||||
.unwrap()
|
|
||||||
.compile(&mut i1, program::parsed::CompInfo::default())
|
|
||||||
.unwrap()
|
|
||||||
.check(&mut i3, None)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
91
mers_lib/tests/lang.rs
Normal file
91
mers_lib/tests/lang.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use std::{fmt::Debug, sync::Arc};
|
||||||
|
|
||||||
|
use mers_lib::prelude_compile::*;
|
||||||
|
|
||||||
|
use mers_lib::{
|
||||||
|
data::{self, Data, Type},
|
||||||
|
errors::CheckError,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn variable() -> Res {
|
||||||
|
for n in -100..=100 {
|
||||||
|
let n = n * n;
|
||||||
|
assert_eq!(
|
||||||
|
run_code(Config::new(), format!("x := {n}, x"))?,
|
||||||
|
TypedData(
|
||||||
|
Type::new(data::int::IntT),
|
||||||
|
Data::new(data::int::Int(n as _))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mutating_a_variable() -> Res {
|
||||||
|
assert_eq!(
|
||||||
|
run_code(Config::new(), "x := 5, &x = 2, x")?,
|
||||||
|
TypedData(Type::new(data::int::IntT), Data::new(data::int::Int(2)))
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn variable_shadowing() -> Res {
|
||||||
|
assert_eq!(
|
||||||
|
run_code(Config::new(), "x := 5, { x := 2, &x = 3 }, x")?,
|
||||||
|
TypedData(Type::new(data::int::IntT), Data::new(data::int::Int(5)))
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn identity_function() -> Res {
|
||||||
|
assert_eq!(
|
||||||
|
run_code(Config::new(), "id := x -> x, 4.id")?,
|
||||||
|
TypedData(Type::new(data::int::IntT), Data::new(data::int::Int(4)))
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
type Res = Result<(), CheckError>;
|
||||||
|
|
||||||
|
fn run_code(cfg: Config, code: impl Into<String>) -> Result<TypedData, CheckError> {
|
||||||
|
let mut src = Source::new_from_string(code.into());
|
||||||
|
let srca = Arc::new(src.clone());
|
||||||
|
let parsed = parse(&mut src, &srca)?;
|
||||||
|
let (mut i1, mut i2, mut i3) = cfg.infos();
|
||||||
|
let compiled = parsed.compile(&mut i1, Default::default())?;
|
||||||
|
let output_type = compiled.check(&mut i3, Default::default())?;
|
||||||
|
let output_data = compiled.run(&mut i2)?;
|
||||||
|
Ok(TypedData(output_type, output_data))
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TypedData(Type, Data);
|
||||||
|
impl Debug for TypedData {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "Type: {}, Data: {}", self.0, self.1.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialEq for TypedData {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
let t1 = self.0.is_same_type_as(&other.0);
|
||||||
|
let t2 = other.0.is_same_type_as(&self.0);
|
||||||
|
let d1 = self.1 == other.1;
|
||||||
|
let d2 = other.1 == self.1;
|
||||||
|
if t1 && !t2 {
|
||||||
|
panic!("self is same type as other, but other is not same type as self (non-symmetrical eq)! self={}, other={}", self.0, other.0);
|
||||||
|
}
|
||||||
|
if t2 && !t1 {
|
||||||
|
panic!("other is same type as self, but self is not same type as other (non-symmetrical eq)! other={}, self={}", other.0, self.0);
|
||||||
|
}
|
||||||
|
if d1 && !d2 {
|
||||||
|
panic!("self is same data as other, but other is not same data as self (non-symmetrical eq)! self={}, other={}", self.1.get(), other.1.get());
|
||||||
|
}
|
||||||
|
if d2 && !d1 {
|
||||||
|
panic!("other is same data as self, but self is not same data as other (non-symmetrical eq)! other={}, self={}", other.1.get(), self.1.get());
|
||||||
|
}
|
||||||
|
t1 && d1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user