From 24ff14dc98b83ddc12239a0eae4852c9cd87d41f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 1 Mar 2020 16:37:10 +0000 Subject: Add a lot of import tests --- dhall/tests/import/failure/unit/EnvUnset.dhall | 1 + dhall/tests/import/failure/unit/EnvUnsetAsText.dhall | 1 + 2 files changed, 2 insertions(+) create mode 100644 dhall/tests/import/failure/unit/EnvUnset.dhall create mode 100644 dhall/tests/import/failure/unit/EnvUnsetAsText.dhall (limited to 'dhall/tests/import/failure') diff --git a/dhall/tests/import/failure/unit/EnvUnset.dhall b/dhall/tests/import/failure/unit/EnvUnset.dhall new file mode 100644 index 0000000..af77cce --- /dev/null +++ b/dhall/tests/import/failure/unit/EnvUnset.dhall @@ -0,0 +1 @@ +env:DHALL_TEST_UNSET diff --git a/dhall/tests/import/failure/unit/EnvUnsetAsText.dhall b/dhall/tests/import/failure/unit/EnvUnsetAsText.dhall new file mode 100644 index 0000000..9a9db6d --- /dev/null +++ b/dhall/tests/import/failure/unit/EnvUnsetAsText.dhall @@ -0,0 +1 @@ +env:DHALL_TEST_UNSET as Text -- cgit v1.3.1 From 386f34af802a812c2af8ece2cc427cfb5a7c1fe8 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 1 Mar 2020 17:26:59 +0000 Subject: Implement `missing` and `env:VAR` imports --- dhall/build.rs | 13 ++----------- dhall/src/error/mod.rs | 2 ++ dhall/src/semantics/resolve/resolve.rs | 24 ++++++++++++++++-------- dhall/src/tests.rs | 2 ++ dhall/tests/import/failure/missing.txt | 1 + dhall/tests/import/failure/unit/EnvUnset.txt | 1 + update-tests.sh | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 dhall/tests/import/failure/missing.txt create mode 100644 dhall/tests/import/failure/unit/EnvUnset.txt (limited to 'dhall/tests/import/failure') diff --git a/dhall/build.rs b/dhall/build.rs index 6165be2..0ff5acc 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -258,18 +258,11 @@ fn generate_tests() -> std::io::Result<()> { || path == "hashFromCache" || path == "headerForwarding" || path == "noHeaderForwarding" - || path == "unit/asLocation/Remote" - || path == "unit/AlternativeChain1" - || path == "unit/AlternativeChain2" - || path == "unit/AlternativeEnv" || path == "unit/AlternativeHashMismatch" - || path == "unit/AlternativeImportError" - || path == "unit/AlternativeNoError3" - || path == "unit/AlternativeSubExpr" || path == "unit/AsText" - || path == "unit/EnvSet" || path == "unit/EnvSetAsText" || path == "unit/SimpleRemote" + || path == "unit/asLocation/Remote" }), input_type: FileType::Text, output_type: Some(FileType::Text), @@ -283,11 +276,9 @@ fn generate_tests() -> std::io::Result<()> { false || path == "alternativeEnv" || path == "alternativeEnvMissing" + || path == "customHeadersUsingBoundVariable" || path == "hashMismatch" - || path == "missing" || path == "referentiallyInsane" - || path == "customHeadersUsingBoundVariable" - || path == "unit/EnvUnset" || path == "unit/EnvUnsetAsText" }), input_type: FileType::Text, diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs index 8829d47..5632ea6 100644 --- a/dhall/src/error/mod.rs +++ b/dhall/src/error/mod.rs @@ -26,6 +26,8 @@ pub(crate) enum ErrorKind { #[derive(Debug)] pub(crate) enum ImportError { + Missing, + MissingEnvVar, UnexpectedImport(Import<()>), ImportCycle(ImportStack, Import<()>), } diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs index b27dd2c..bf7aabb 100644 --- a/dhall/src/semantics/resolve/resolve.rs +++ b/dhall/src/semantics/resolve/resolve.rs @@ -1,6 +1,7 @@ use itertools::Itertools; use std::borrow::Cow; -use std::path::{Path, PathBuf}; +use std::env; +use std::path::PathBuf; use crate::error::ErrorBuilder; use crate::error::{Error, ImportError}; @@ -47,8 +48,21 @@ fn resolve_one_import( FilePrefix::Here => cwd.join(path_buf), _ => unimplemented!("{:?}", import), }; - Ok(load_import(env, &path_buf)?) + + let parsed = Parsed::parse_file(&path_buf)?; + let typed = resolve_with_env(env, parsed)?.typecheck()?; + Ok((typed.normalize().to_hir(), typed.ty().clone())) + } + ImportLocation::Env(var_name) => { + let val = match env::var(var_name) { + Ok(val) => val, + Err(_) => Err(ImportError::MissingEnvVar)?, + }; + let parsed = Parsed::parse_str(&val)?; + let typed = resolve_with_env(env, parsed)?.typecheck()?; + Ok((typed.normalize().to_hir(), typed.ty().clone())) } + ImportLocation::Missing => Err(ImportError::Missing.into()), _ => unimplemented!("{:?}", import), } } @@ -122,12 +136,6 @@ fn resolve_one_import( } } -fn load_import(env: &mut ImportEnv, f: &Path) -> Result { - let parsed = Parsed::parse_file(f)?; - let typed = resolve_with_env(env, parsed)?.typecheck()?; - Ok((typed.normalize().to_hir(), typed.ty().clone())) -} - /// Desugar the first level of the expression. fn desugar(expr: &Expr) -> Cow<'_, Expr> { match expr.kind() { diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 044b185..369c6cc 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -247,6 +247,8 @@ fn run_test(test: Test) -> Result<()> { env::set_current_dir( PathBuf::from(env!("CARGO_MANIFEST_DIR")).parent().unwrap(), )?; + // Set environment variable for import tests. + env::set_var("DHALL_TEST_VAR", "6 * 7"); match test { ParserSuccess(expr, expected) => { diff --git a/dhall/tests/import/failure/missing.txt b/dhall/tests/import/failure/missing.txt new file mode 100644 index 0000000..4666330 --- /dev/null +++ b/dhall/tests/import/failure/missing.txt @@ -0,0 +1 @@ +Missing diff --git a/dhall/tests/import/failure/unit/EnvUnset.txt b/dhall/tests/import/failure/unit/EnvUnset.txt new file mode 100644 index 0000000..482b68c --- /dev/null +++ b/dhall/tests/import/failure/unit/EnvUnset.txt @@ -0,0 +1 @@ +MissingEnvVar diff --git a/update-tests.sh b/update-tests.sh index 6192763..7be40c4 100755 --- a/update-tests.sh +++ b/update-tests.sh @@ -13,7 +13,7 @@ END ) cd "$(dirname "$0")" || exit 1 -export DHALL_TEST_VAR=42 +export DHALL_TEST_VAR="6 * 7" if [ ! -x "$(which dhall)" ] ; then echo "Error: 'dhall' executable not found in PATH" -- cgit v1.3.1 From df4495f30708180591b630bb720cfe81ff4118ce Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 1 Mar 2020 18:18:01 +0000 Subject: Implement `as Text` imports --- dhall/build.rs | 18 +++++++----------- dhall/src/semantics/parse.rs | 5 ++--- dhall/src/semantics/resolve/resolve.rs | 21 ++++++++++++++++++++- dhall/tests/import/failure/alternativeEnv.txt | 1 + .../tests/import/failure/alternativeEnvMissing.txt | 1 + dhall/tests/import/failure/unit/EnvUnsetAsText.txt | 1 + dhall/tests/import/success/unit/EnvSetAsTextB.dhall | 2 +- 7 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 dhall/tests/import/failure/alternativeEnv.txt create mode 100644 dhall/tests/import/failure/alternativeEnvMissing.txt create mode 100644 dhall/tests/import/failure/unit/EnvUnsetAsText.txt (limited to 'dhall/tests/import/failure') diff --git a/dhall/build.rs b/dhall/build.rs index 0ff5acc..29219ff 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -249,18 +249,15 @@ fn generate_tests() -> std::io::Result<()> { too_slow_path: Box::new(|_path: &str| false), exclude_path: Box::new(|path: &str| { false - || path == "alternativeEnvNatural" - || path == "alternativeEnvSimple" + // TODO: import hash || path == "alternativeHashMismatch" + || path == "hashFromCache" + || path == "unit/AlternativeHashMismatch" + // TODO: remote imports || path == "asLocation" - || path == "asText" || path == "customHeaders" - || path == "hashFromCache" || path == "headerForwarding" || path == "noHeaderForwarding" - || path == "unit/AlternativeHashMismatch" - || path == "unit/AsText" - || path == "unit/EnvSetAsText" || path == "unit/SimpleRemote" || path == "unit/asLocation/Remote" }), @@ -274,12 +271,11 @@ fn generate_tests() -> std::io::Result<()> { too_slow_path: Box::new(|_path: &str| false), exclude_path: Box::new(|path: &str| { false - || path == "alternativeEnv" - || path == "alternativeEnvMissing" - || path == "customHeadersUsingBoundVariable" + // TODO: import hash || path == "hashMismatch" + // TODO: remote imports + || path == "customHeadersUsingBoundVariable" || path == "referentiallyInsane" - || path == "unit/EnvUnsetAsText" }), input_type: FileType::Text, output_type: Some(FileType::UI), diff --git a/dhall/src/semantics/parse.rs b/dhall/src/semantics/parse.rs index ee35536..ffd5eca 100644 --- a/dhall/src/semantics/parse.rs +++ b/dhall/src/semantics/parse.rs @@ -9,9 +9,8 @@ use crate::syntax::parse_expr; use crate::Parsed; pub(crate) fn parse_file(f: &Path) -> Result { - let mut buffer = String::new(); - File::open(f)?.read_to_string(&mut buffer)?; - let expr = parse_expr(&*buffer)?; + let text = std::fs::read_to_string(f)?; + let expr = parse_expr(&text)?; let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); Ok(Parsed(expr, root)) } diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs index ad2cd75..f419858 100644 --- a/dhall/src/semantics/resolve/resolve.rs +++ b/dhall/src/semantics/resolve/resolve.rs @@ -99,7 +99,26 @@ fn resolve_one_import( let typed = resolve_with_env(env, parsed)?.typecheck()?; Ok((typed.normalize().to_hir(), typed.ty().clone())) } - ImportMode::RawText => unimplemented!("{:?}", import), + ImportMode::RawText => { + let text = match &import.location { + ImportLocation::Local(prefix, path) => { + let path = compute_relative_path(root, prefix, path); + std::fs::read_to_string(path)? + } + ImportLocation::Env(var_name) => match env::var(var_name) { + Ok(val) => val, + Err(_) => Err(ImportError::MissingEnvVar)?, + }, + ImportLocation::Missing => Err(ImportError::Missing)?, + _ => unimplemented!("{:?}", import), + }; + + let hir = Hir::new( + HirKind::Expr(ExprKind::TextLit(text.into())), + Span::Artificial, + ); + Ok((hir, Type::from_builtin(Builtin::Text))) + } ImportMode::Location => { let (field_name, arg) = match &import.location { ImportLocation::Local(prefix, path) => { diff --git a/dhall/tests/import/failure/alternativeEnv.txt b/dhall/tests/import/failure/alternativeEnv.txt new file mode 100644 index 0000000..482b68c --- /dev/null +++ b/dhall/tests/import/failure/alternativeEnv.txt @@ -0,0 +1 @@ +MissingEnvVar diff --git a/dhall/tests/import/failure/alternativeEnvMissing.txt b/dhall/tests/import/failure/alternativeEnvMissing.txt new file mode 100644 index 0000000..4666330 --- /dev/null +++ b/dhall/tests/import/failure/alternativeEnvMissing.txt @@ -0,0 +1 @@ +Missing diff --git a/dhall/tests/import/failure/unit/EnvUnsetAsText.txt b/dhall/tests/import/failure/unit/EnvUnsetAsText.txt new file mode 100644 index 0000000..482b68c --- /dev/null +++ b/dhall/tests/import/failure/unit/EnvUnsetAsText.txt @@ -0,0 +1 @@ +MissingEnvVar diff --git a/dhall/tests/import/success/unit/EnvSetAsTextB.dhall b/dhall/tests/import/success/unit/EnvSetAsTextB.dhall index 192548e..a79bb82 100644 --- a/dhall/tests/import/success/unit/EnvSetAsTextB.dhall +++ b/dhall/tests/import/success/unit/EnvSetAsTextB.dhall @@ -1 +1 @@ -"42" +"6 * 7" -- cgit v1.3.1 From 31cefbdf0364a3d224420365049885051734669b Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 4 Mar 2020 21:36:41 +0000 Subject: Cache imports correctly --- dhall/build.rs | 3 --- dhall/src/error/mod.rs | 4 ++-- dhall/src/semantics/resolve/env.rs | 24 ++++++++++++------------ dhall/src/semantics/resolve/resolve.rs | 14 +++++++------- dhall/tests/import/failure/cycle.txt | 2 +- 5 files changed, 22 insertions(+), 25 deletions(-) (limited to 'dhall/tests/import/failure') diff --git a/dhall/build.rs b/dhall/build.rs index 565c37e..4bd56a3 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -324,9 +324,6 @@ fn generate_tests() -> std::io::Result<()> { // Too slow, but also not all features implemented // For now needs support for hashed imports || path == "prelude" - // TODO: remote imports - || path == "CacheImports" - || path == "CacheImportsCanonicalize" }), input_type: FileType::Text, output_type: Some(FileType::Text), diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs index 29dd5ad..6dd8393 100644 --- a/dhall/src/error/mod.rs +++ b/dhall/src/error/mod.rs @@ -1,6 +1,6 @@ use std::io::Error as IOError; -use crate::semantics::resolve::ImportStack; +use crate::semantics::resolve::{ImportLocation, ImportStack}; use crate::syntax::{Import, ParseError}; mod builder; @@ -29,7 +29,7 @@ pub(crate) enum ImportError { Missing, MissingEnvVar, UnexpectedImport(Import<()>), - ImportCycle(ImportStack, Import<()>), + ImportCycle(ImportStack, ImportLocation), Url(url::ParseError), } diff --git a/dhall/src/semantics/resolve/env.rs b/dhall/src/semantics/resolve/env.rs index 43676cc..2342dcc 100644 --- a/dhall/src/semantics/resolve/env.rs +++ b/dhall/src/semantics/resolve/env.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::error::{Error, ImportError}; -use crate::semantics::{AlphaVar, Import, TypedHir, VarEnv}; +use crate::semantics::{AlphaVar, ImportLocation, TypedHir, VarEnv}; use crate::syntax::{Label, V}; /// Environment for resolving names. @@ -10,8 +10,8 @@ pub(crate) struct NameEnv { names: Vec