mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
wip
This commit is contained in:
parent
931c558b5a
commit
5643c4b921
File diff suppressed because it is too large
Load Diff
@ -29,29 +29,6 @@ pub fn test_home() -> ModuleId {
|
||||
ModuleIds::default().get_or_insert(&"Test".into())
|
||||
}
|
||||
|
||||
/// Without a larger-than-default stack size, some tests
|
||||
/// run out of stack space in debug builds (but don't in --release builds)
|
||||
#[allow(dead_code)]
|
||||
const THREAD_STACK_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
pub fn test_async<F: std::future::Future>(future: F) -> F::Output {
|
||||
use tokio::runtime::Builder;
|
||||
|
||||
// Create the runtime
|
||||
let mut rt = Builder::new()
|
||||
.thread_name("tokio-thread-for-tests")
|
||||
.thread_stack_size(THREAD_STACK_SIZE)
|
||||
// DEBUG: Replace this with .basic_scheduler() to make tests run single-threaded on the main thread.
|
||||
// Doing this makes assertion failures easier to read, but means
|
||||
// the tests can't reveal concurrency bugs, so leave this off by default!
|
||||
.threaded_scheduler()
|
||||
.build()
|
||||
.expect("Error initializing Tokio runtime.");
|
||||
|
||||
// Spawn the root task
|
||||
rt.block_on(future)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn infer_expr(
|
||||
subs: Subs,
|
||||
|
@ -13,7 +13,7 @@ mod helpers;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_load {
|
||||
use crate::helpers::{fixtures_dir, test_async};
|
||||
use crate::helpers::fixtures_dir;
|
||||
use inlinable_string::InlinableString;
|
||||
use roc_can::def::Declaration::*;
|
||||
use roc_can::def::Def;
|
||||
@ -27,7 +27,7 @@ mod test_load {
|
||||
|
||||
// HELPERS
|
||||
|
||||
async fn load_fixture(
|
||||
fn load_fixture(
|
||||
dir_name: &str,
|
||||
module_name: &str,
|
||||
subs_by_module: SubsByModule,
|
||||
@ -39,8 +39,7 @@ mod test_load {
|
||||
src_dir,
|
||||
filename,
|
||||
subs_by_module,
|
||||
)
|
||||
.await;
|
||||
);
|
||||
let loaded_module = loaded.expect("Test module failed to load");
|
||||
|
||||
assert_eq!(loaded_module.can_problems, Vec::new());
|
||||
@ -129,286 +128,256 @@ mod test_load {
|
||||
let subs_by_module = MutMap::default();
|
||||
let src_dir = fixtures_dir().join("interface_with_deps");
|
||||
let filename = src_dir.join("Primary.roc");
|
||||
let loaded = load(
|
||||
&roc_builtins::std::standard_stdlib(),
|
||||
src_dir,
|
||||
filename,
|
||||
subs_by_module,
|
||||
);
|
||||
|
||||
test_async(async {
|
||||
let loaded = load(
|
||||
&roc_builtins::std::standard_stdlib(),
|
||||
src_dir,
|
||||
filename,
|
||||
subs_by_module,
|
||||
)
|
||||
.await;
|
||||
let mut loaded_module = loaded.expect("Test module failed to load");
|
||||
|
||||
let mut loaded_module = loaded.expect("Test module failed to load");
|
||||
assert_eq!(loaded_module.can_problems, Vec::new());
|
||||
assert_eq!(loaded_module.type_problems, Vec::new());
|
||||
|
||||
assert_eq!(loaded_module.can_problems, Vec::new());
|
||||
assert_eq!(loaded_module.type_problems, Vec::new());
|
||||
let def_count: usize = loaded_module
|
||||
.declarations_by_id
|
||||
.remove(&loaded_module.module_id)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|decl| decl.def_count())
|
||||
.sum();
|
||||
|
||||
let def_count: usize = loaded_module
|
||||
.declarations_by_id
|
||||
.remove(&loaded_module.module_id)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|decl| decl.def_count())
|
||||
.sum();
|
||||
let expected_name = loaded_module
|
||||
.interns
|
||||
.module_ids
|
||||
.get_name(loaded_module.module_id)
|
||||
.expect("Test ModuleID not found in module_ids");
|
||||
|
||||
let expected_name = loaded_module
|
||||
.interns
|
||||
.module_ids
|
||||
.get_name(loaded_module.module_id)
|
||||
.expect("Test ModuleID not found in module_ids");
|
||||
|
||||
assert_eq!(expected_name, &InlinableString::from("Primary"));
|
||||
assert_eq!(def_count, 10);
|
||||
});
|
||||
assert_eq!(expected_name, &InlinableString::from("Primary"));
|
||||
assert_eq!(def_count, 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_unit() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("no_deps", "Unit", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("no_deps", "Unit", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"unit" => "Unit",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"unit" => "Unit",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_alias() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module =
|
||||
load_fixture("interface_with_deps", "ImportAlias", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "ImportAlias", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"unit" => "Dep1.Unit",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"unit" => "Dep1.Unit",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_and_typecheck() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module =
|
||||
load_fixture("interface_with_deps", "WithBuiltins", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "WithBuiltins", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"floatTest" => "Float",
|
||||
"divisionFn" => "Float, Float -> Result Float [ DivByZero ]*",
|
||||
"divisionTest" => "Result Float [ DivByZero ]*",
|
||||
"intTest" => "Int",
|
||||
"x" => "Float",
|
||||
"constantNum" => "Num *",
|
||||
"divDep1ByDep2" => "Result Float [ DivByZero ]*",
|
||||
"fromDep2" => "Float",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"floatTest" => "Float",
|
||||
"divisionFn" => "Float, Float -> Result Float [ DivByZero ]*",
|
||||
"divisionTest" => "Result Float [ DivByZero ]*",
|
||||
"intTest" => "Int",
|
||||
"x" => "Float",
|
||||
"constantNum" => "Num *",
|
||||
"divDep1ByDep2" => "Result Float [ DivByZero ]*",
|
||||
"fromDep2" => "Float",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iface_quicksort() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module =
|
||||
load_fixture("interface_with_deps", "Quicksort", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "Quicksort", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"swap" => "Int, Int, List a -> List a",
|
||||
"partition" => "Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]",
|
||||
"quicksort" => "List (Num a), Int, Int -> List (Num a)",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"swap" => "Int, Int, List a -> List a",
|
||||
"partition" => "Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]",
|
||||
"quicksort" => "List (Num a), Int, Int -> List (Num a)",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_quicksort() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("app_with_deps", "Quicksort", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("app_with_deps", "Quicksort", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"swap" => "Int, Int, List a -> List a",
|
||||
"partition" => "Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]",
|
||||
"quicksort" => "List (Num a), Int, Int -> List (Num a)",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"swap" => "Int, Int, List a -> List a",
|
||||
"partition" => "Int, Int, List (Num a) -> [ Pair Int (List (Num a)) ]",
|
||||
"quicksort" => "List (Num a), Int, Int -> List (Num a)",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_astar() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "AStar", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "AStar", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"findPath" => "{ costFunction : (position, position -> Float), end : position, moveFunction : (position -> Set position), start : position } -> Result (List position) [ KeyNotFound ]*",
|
||||
"initialModel" => "position -> Model position",
|
||||
"reconstructPath" => "Map position position, position -> List position",
|
||||
"updateCost" => "position, position, Model position -> Model position",
|
||||
"cheapestOpen" => "(position -> Float), Model position -> Result position [ KeyNotFound ]*",
|
||||
"astar" => "(position, position -> Float), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"findPath" => "{ costFunction : (position, position -> Float), end : position, moveFunction : (position -> Set position), start : position } -> Result (List position) [ KeyNotFound ]*",
|
||||
"initialModel" => "position -> Model position",
|
||||
"reconstructPath" => "Map position position, position -> List position",
|
||||
"updateCost" => "position, position, Model position -> Model position",
|
||||
"cheapestOpen" => "(position -> Float), Model position -> Result position [ KeyNotFound ]*",
|
||||
"astar" => "(position, position -> Float), (position -> Set position), position, Model position -> [ Err [ KeyNotFound ]*, Ok (List position) ]*",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_principal_types() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("no_deps", "Principal", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("no_deps", "Principal", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"intVal" => "Str",
|
||||
"identity" => "a -> a",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"intVal" => "Str",
|
||||
"identity" => "a -> a",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iface_dep_types() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module =
|
||||
load_fixture("interface_with_deps", "Primary", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "Primary", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"blah2" => "Float",
|
||||
"blah3" => "Str",
|
||||
"str" => "Str",
|
||||
"alwaysThree" => "* -> Str",
|
||||
"identity" => "a -> a",
|
||||
"z" => "Str",
|
||||
"w" => "Dep1.Identity {}",
|
||||
"succeed" => "a -> Dep1.Identity a",
|
||||
"yay" => "Res.Res {} err",
|
||||
"withDefault" => "Res.Res a *, a -> a",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"blah2" => "Float",
|
||||
"blah3" => "Str",
|
||||
"str" => "Str",
|
||||
"alwaysThree" => "* -> Str",
|
||||
"identity" => "a -> a",
|
||||
"z" => "Str",
|
||||
"w" => "Dep1.Identity {}",
|
||||
"succeed" => "a -> Dep1.Identity a",
|
||||
"yay" => "Res.Res {} err",
|
||||
"withDefault" => "Res.Res a *, a -> a",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn app_dep_types() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("app_with_deps", "Primary", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("app_with_deps", "Primary", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"blah2" => "Float",
|
||||
"blah3" => "Str",
|
||||
"str" => "Str",
|
||||
"alwaysThree" => "* -> Str",
|
||||
"identity" => "a -> a",
|
||||
"z" => "Str",
|
||||
"w" => "Dep1.Identity {}",
|
||||
"succeed" => "a -> Dep1.Identity a",
|
||||
"yay" => "Res.Res {} err",
|
||||
"withDefault" => "Res.Res a *, a -> a",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"blah2" => "Float",
|
||||
"blah3" => "Str",
|
||||
"str" => "Str",
|
||||
"alwaysThree" => "* -> Str",
|
||||
"identity" => "a -> a",
|
||||
"z" => "Str",
|
||||
"w" => "Dep1.Identity {}",
|
||||
"succeed" => "a -> Dep1.Identity a",
|
||||
"yay" => "Res.Res {} err",
|
||||
"withDefault" => "Res.Res a *, a -> a",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imported_dep_regression() {
|
||||
test_async(async {
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "OneDep", subs_by_module).await;
|
||||
let subs_by_module = MutMap::default();
|
||||
let loaded_module = load_fixture("interface_with_deps", "OneDep", subs_by_module);
|
||||
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"str" => "Str",
|
||||
},
|
||||
);
|
||||
});
|
||||
expect_types(
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"str" => "Str",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn load_records() {
|
||||
// test_async(async {
|
||||
// use roc::types::{ErrorType, Mismatch, Problem, TypeExt};
|
||||
// use roc::types::{ErrorType, Mismatch, Problem, TypeExt};
|
||||
|
||||
// let subs_by_module = MutMap::default();
|
||||
// let loaded_module =
|
||||
// load_fixture("interface_with_deps", "Records", subs_by_module).await;
|
||||
// let subs_by_module = MutMap::default();
|
||||
// let loaded_module =
|
||||
// load_fixture("interface_with_deps", "Records", subs_by_module);
|
||||
|
||||
// // NOTE: `a` here is unconstrained, so unifies with <type error>
|
||||
// let expected_types = hashmap! {
|
||||
// "Records.intVal" => "a",
|
||||
// // NOTE: `a` here is unconstrained, so unifies with <type error>
|
||||
// let expected_types = hashmap! {
|
||||
// "Records.intVal" => "a",
|
||||
// };
|
||||
|
||||
// let a = ErrorType::FlexVar("a".into());
|
||||
|
||||
// let mut record = SendMap::default();
|
||||
// record.insert("x".into(), a);
|
||||
|
||||
// let problem = Problem::Mismatch(
|
||||
// Mismatch::TypeMismatch,
|
||||
// ErrorType::Record(SendMap::default(), TypeExt::Closed),
|
||||
// ErrorType::Record(record, TypeExt::FlexOpen("b".into())),
|
||||
// );
|
||||
|
||||
// assert_eq!(loaded_module.problems, vec![problem]);
|
||||
// assert_eq!(expected_types.len(), loaded_module.declarations.len());
|
||||
|
||||
// let mut subs = loaded_module.solved.into_inner();
|
||||
|
||||
// for decl in loaded_module.declarations {
|
||||
// let def = match decl {
|
||||
// Declare(def) => def,
|
||||
// rec_decl @ DeclareRec(_) => {
|
||||
// panic!(
|
||||
// "Unexpected recursive def in module declarations: {:?}",
|
||||
// rec_decl
|
||||
// );
|
||||
// }
|
||||
// cycle @ InvalidCycle(_, _) => {
|
||||
// panic!("Unexpected cyclic def in module declarations: {:?}", cycle);
|
||||
// }
|
||||
// };
|
||||
|
||||
// let a = ErrorType::FlexVar("a".into());
|
||||
// for (symbol, expr_var) in def.pattern_vars {
|
||||
// let content = subs.get(expr_var).content;
|
||||
|
||||
// let mut record = SendMap::default();
|
||||
// record.insert("x".into(), a);
|
||||
// name_all_type_vars(expr_var, &mut subs);
|
||||
|
||||
// let problem = Problem::Mismatch(
|
||||
// Mismatch::TypeMismatch,
|
||||
// ErrorType::Record(SendMap::default(), TypeExt::Closed),
|
||||
// ErrorType::Record(record, TypeExt::FlexOpen("b".into())),
|
||||
// );
|
||||
// let actual_str = content_to_string(content, &mut subs);
|
||||
// let expected_type = expected_types.get(symbol.as_str()).unwrap_or_else(|| {
|
||||
// panic!("Defs included an unexpected symbol: {:?}", symbol)
|
||||
// });
|
||||
|
||||
// assert_eq!(loaded_module.problems, vec![problem]);
|
||||
// assert_eq!(expected_types.len(), loaded_module.declarations.len());
|
||||
|
||||
// let mut subs = loaded_module.solved.into_inner();
|
||||
|
||||
// for decl in loaded_module.declarations {
|
||||
// let def = match decl {
|
||||
// Declare(def) => def,
|
||||
// rec_decl @ DeclareRec(_) => {
|
||||
// panic!(
|
||||
// "Unexpected recursive def in module declarations: {:?}",
|
||||
// rec_decl
|
||||
// );
|
||||
// }
|
||||
// cycle @ InvalidCycle(_, _) => {
|
||||
// panic!("Unexpected cyclic def in module declarations: {:?}", cycle);
|
||||
// }
|
||||
// };
|
||||
|
||||
// for (symbol, expr_var) in def.pattern_vars {
|
||||
// let content = subs.get(expr_var).content;
|
||||
|
||||
// name_all_type_vars(expr_var, &mut subs);
|
||||
|
||||
// let actual_str = content_to_string(content, &mut subs);
|
||||
// let expected_type = expected_types.get(symbol.as_str()).unwrap_or_else(|| {
|
||||
// panic!("Defs included an unexpected symbol: {:?}", symbol)
|
||||
// });
|
||||
|
||||
// assert_eq!((&symbol, expected_type), (&symbol, &actual_str.as_str()));
|
||||
// }
|
||||
// assert_eq!((&symbol, expected_type), (&symbol, &actual_str.as_str()));
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user