From a2c2cd76d256a4e6ca66b9b1bd756fb17e600ef5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 30 Aug 2019 20:05:12 +0200 Subject: Rework test harness to prepare for new types of tests --- dhall/src/tests.rs | 323 ++++++++++++++++++++++++----------------------------- 1 file changed, 147 insertions(+), 176 deletions(-) (limited to 'dhall/src/tests.rs') diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 3055717..ae41038 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -22,13 +22,13 @@ right: `{}`"#, #[macro_export] macro_rules! make_spec_test { - ($type:ident, $status:ident, $name:ident, $path:expr) => { + ($type:expr, $name:ident) => { #[test] #[allow(non_snake_case)] fn $name() { + use crate::tests::Test::*; use crate::tests::*; - match run_test_stringy_error($path, Feature::$type, Status::$status) - { + match run_test_stringy_error($type) { Ok(_) => {} Err(s) => panic!(s), } @@ -44,24 +44,22 @@ use crate::error::{Error, Result}; use crate::phase::Parsed; #[allow(dead_code)] -#[derive(Copy, Clone)] -pub enum Feature { - Parser, - Printer, - BinaryEncoding, - BinaryDecoding, - Import, - Normalization, - AlphaNormalization, - Typecheck, - TypeInference, -} - -#[allow(dead_code)] -#[derive(Copy, Clone)] -pub enum Status { - Success, - Failure, +#[derive(Clone)] +pub enum Test<'a> { + ParserSuccess(&'a str, &'a str), + ParserFailure(&'a str), + Printer(&'a str, &'a str), + BinaryEncoding(&'a str, &'a str), + BinaryDecodingSuccess(&'a str, &'a str), + BinaryDecodingFailure(&'a str), + ImportSuccess(&'a str, &'a str), + ImportFailure(&'a str), + TypecheckSuccess(&'a str, &'a str), + TypecheckFailure(&'a str), + TypeInferenceSuccess(&'a str, &'a str), + TypeInferenceFailure(&'a str), + Normalization(&'a str, &'a str), + AlphaNormalization(&'a str, &'a str), } fn parse_file_str(file_path: &str) -> Result { @@ -70,180 +68,153 @@ fn parse_file_str(file_path: &str) -> Result { #[allow(dead_code)] pub fn run_test_stringy_error( - base_path: &str, - feature: Feature, - status: Status, + test: Test<'_>, ) -> std::result::Result<(), String> { - let base_path: String = base_path.to_string(); - run_test(&base_path, feature, status) - .map_err(|e| e.to_string()) - .map(|_| ()) + run_test(test).map_err(|e| e.to_string()).map(|_| ()) } -#[allow(clippy::single_match)] -pub fn run_test( - base_path: &str, - feature: Feature, - status: Status, -) -> Result<()> { - use self::Feature::*; - use self::Status::*; - let base_path = base_path.to_owned(); - match status { - Success => { - match feature { - BinaryDecoding => { - let expr_file_path = base_path.clone() + "A.dhallb"; - let expr_file_path = PathBuf::from(&expr_file_path); - let mut expr_data = Vec::new(); - { - File::open(&expr_file_path)? - .read_to_end(&mut expr_data)?; - } - let expr = Parsed::parse_binary(&expr_data)?; - let expected_file_path = base_path + "B.dhall"; - let expected = parse_file_str(&expected_file_path)?; - assert_eq_pretty!(expr, expected); - - return Ok(()); +pub fn run_test(test: Test<'_>) -> Result<()> { + use self::Test::*; + match test { + ParserSuccess(expr_file_path, expected_file_path) => { + let expr = parse_file_str(&expr_file_path)?; + // This exercices both parsing and binary decoding + // Compare parse/decoded + let expected = + Parsed::parse_binary_file(&PathBuf::from(expected_file_path))?; + assert_eq_pretty!(expr, expected); + } + ParserFailure(file_path) => { + let err = parse_file_str(&file_path).unwrap_err(); + match &err { + Error::Parse(_) => {} + Error::IO(e) if e.kind() == std::io::ErrorKind::InvalidData => { } - _ => {} + e => panic!("Expected parse error, got: {:?}", e), } - let expr_file_path = base_path.clone() + "A.dhall"; + } + BinaryEncoding(expr_file_path, expected_file_path) => { let expr = parse_file_str(&expr_file_path)?; - - match feature { - Parser => { - // This exercices both parsing and binary decoding - // Compare parse/decoded - let expected_file_path = base_path + "B.dhallb"; - let expected_file_path = PathBuf::from(&expected_file_path); - let mut expected_data = Vec::new(); - { - File::open(&expected_file_path)? - .read_to_end(&mut expected_data)?; - } - let expected = Parsed::parse_binary(&expected_data)?; - assert_eq_pretty!(expr, expected); - - return Ok(()); - } - Printer => { - // Round-trip pretty-printer - let expr_string = expr.to_string(); - let expected = expr; - let expr: Parsed = Parsed::parse_str(&expr_string)?; - assert_eq!(expr, expected); - - return Ok(()); - } - BinaryEncoding => { - let expected_file_path = base_path + "B.dhallb"; - let expected_file_path = PathBuf::from(&expected_file_path); - let mut expected_data = Vec::new(); - { - File::open(&expected_file_path)? - .read_to_end(&mut expected_data)?; - } - let expr_data = expr.encode()?; - - // Compare bit-by-bit - if expr_data != expected_data { - // use std::io::Write; - // File::create(&expected_file_path)?.write_all(&expr_data)?; - // Pretty-print difference - assert_eq_pretty!( - serde_cbor::de::from_slice::< - serde_cbor::value::Value, - >(&expr_data) - .unwrap(), - serde_cbor::de::from_slice::< - serde_cbor::value::Value, - >(&expected_data) - .unwrap() - ); - // If difference was not visible in the cbor::Value - assert_eq!(expr_data, expected_data); - } - - return Ok(()); - } - _ => {} + let mut expected_data = Vec::new(); + { + File::open(&PathBuf::from(&expected_file_path))? + .read_to_end(&mut expected_data)?; } + let expr_data = expr.encode()?; + + // Compare bit-by-bit + if expr_data != expected_data { + // use std::io::Write; + // File::create(&expected_file_path)?.write_all(&expr_data)?; + // Pretty-print difference + assert_eq_pretty!( + serde_cbor::de::from_slice::( + &expr_data + ) + .unwrap(), + serde_cbor::de::from_slice::( + &expected_data + ) + .unwrap() + ); + // If difference was not visible in the cbor::Value + assert_eq!(expr_data, expected_data); + } + } + BinaryDecodingSuccess(expr_file_path, expected_file_path) => { + let expr = + Parsed::parse_binary_file(&PathBuf::from(expr_file_path))?; + let expected = parse_file_str(&expected_file_path)?; + assert_eq_pretty!(expr, expected); + } + BinaryDecodingFailure(file_path) => { + Parsed::parse_binary_file(&PathBuf::from(file_path)).unwrap_err(); + } + Printer(expr_file_path, _) => { + let expected = parse_file_str(&expr_file_path)?; + // Round-trip pretty-printer + let expr: Parsed = Parsed::parse_str(&expected.to_string())?; + assert_eq!(expr, expected); + } + ImportSuccess(expr_file_path, expected_file_path) => { + let expr = parse_file_str(&expr_file_path)? + .resolve()? + .typecheck()? + .normalize(); + let expected = parse_file_str(&expected_file_path)? + .resolve()? + .typecheck()? + .normalize(); - let expr = expr.resolve()?; - - let expected_file_path = base_path + "B.dhall"; + assert_eq_display!(expr, expected); + } + ImportFailure(file_path) => { + parse_file_str(&file_path)?.resolve().unwrap_err(); + } + TypecheckSuccess(expr_file_path, expected_file_path) => { + let expr = parse_file_str(&expr_file_path)?.resolve()?; let expected = parse_file_str(&expected_file_path)? .resolve()? .typecheck()? .normalize(); - match feature { - Parser | Printer | BinaryEncoding | BinaryDecoding => { - unreachable!() - } - Import => { - let expr = expr.typecheck()?.normalize(); - assert_eq_display!(expr, expected); - } - Typecheck => { - expr.typecheck_with(&expected.into_typed())?.get_type()?; - } - TypeInference => { - let expr = expr.typecheck()?; - let ty = expr.get_type()?.normalize(); - assert_eq_display!(ty, expected); - } - Normalization => { - let expr = expr.typecheck()?.normalize(); - assert_eq_display!(expr, expected); - } - AlphaNormalization => { - let expr = expr.typecheck()?.normalize().to_expr_alpha(); - assert_eq_display!(expr, expected.to_expr()); + expr.typecheck_with(&expected.into_typed())?.get_type()?; + } + TypecheckFailure(file_path) => { + let res = parse_file_str(&file_path)?.skip_resolve()?.typecheck(); + match res { + Err(_) => {} + // If e did typecheck, check that it doesn't have a type + Ok(e) => { + e.get_type().unwrap_err(); } } } - Failure => { - let file_path = base_path + ".dhall"; - match feature { - Parser => { - let err = parse_file_str(&file_path).unwrap_err(); - match &err { - Error::Parse(_) => {} - Error::IO(e) - if e.kind() == std::io::ErrorKind::InvalidData => {} - e => panic!("Expected parse error, got: {:?}", e), - } - } - Printer | BinaryEncoding => unreachable!(), - BinaryDecoding => { - let expr_file_path = file_path + "b"; - let mut expr_data = Vec::new(); - { - File::open(&PathBuf::from(&expr_file_path))? - .read_to_end(&mut expr_data)?; - } - Parsed::parse_binary(&expr_data).unwrap_err(); - } - Import => { - parse_file_str(&file_path)?.resolve().unwrap_err(); - } - Normalization | AlphaNormalization => unreachable!(), - Typecheck | TypeInference => { - let res = - parse_file_str(&file_path)?.skip_resolve()?.typecheck(); - match res { - Err(_) => {} - // If e did typecheck, check that it doesn't have a type - Ok(e) => { - e.get_type().unwrap_err(); - } - } + TypeInferenceSuccess(expr_file_path, expected_file_path) => { + let expr = + parse_file_str(&expr_file_path)?.resolve()?.typecheck()?; + let ty = expr.get_type()?.normalize(); + let expected = parse_file_str(&expected_file_path)? + .resolve()? + .typecheck()? + .normalize(); + assert_eq_display!(ty, expected); + } + TypeInferenceFailure(file_path) => { + let res = parse_file_str(&file_path)?.skip_resolve()?.typecheck(); + match res { + Err(_) => {} + // If e did typecheck, check that it doesn't have a type + Ok(e) => { + e.get_type().unwrap_err(); } } } + Normalization(expr_file_path, expected_file_path) => { + let expr = parse_file_str(&expr_file_path)? + .resolve()? + .typecheck()? + .normalize(); + let expected = parse_file_str(&expected_file_path)? + .resolve()? + .typecheck()? + .normalize(); + + assert_eq_display!(expr, expected); + } + AlphaNormalization(expr_file_path, expected_file_path) => { + let expr = parse_file_str(&expr_file_path)? + .resolve()? + .typecheck()? + .normalize() + .to_expr_alpha(); + let expected = parse_file_str(&expected_file_path)? + .resolve()? + .typecheck()? + .normalize(); + + assert_eq_display!(expr, expected.to_expr()); + } } Ok(()) } -- cgit v1.2.3