From 3468e1fcf8a3c9163cee714f0a3da9ab5acf4b01 Mon Sep 17 00:00:00 2001 From: Romain Prignon Date: Thu, 27 May 2021 08:33:33 +0200 Subject: [PATCH] fix(#10733): empty tsconfig.json file does not cause error (#10734) Fixes #10733 --- cli/config_file.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/cli/config_file.rs b/cli/config_file.rs index 1875f9906d..a8bd40e699 100644 --- a/cli/config_file.rs +++ b/cli/config_file.rs @@ -1,6 +1,7 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use crate::fs_util::canonicalize_path; +use deno_core::error::anyhow; use deno_core::error::AnyError; use deno_core::error::Context; use deno_core::serde::Deserialize; @@ -293,7 +294,23 @@ impl ConfigFile { } pub fn new(text: &str, path: &Path) -> Result { - let jsonc = jsonc_parser::parse_to_serde_value(text)?.unwrap(); + let jsonc = match jsonc_parser::parse_to_serde_value(text) { + Ok(None) => json!({}), + Ok(Some(value)) if value.is_object() => value, + Ok(Some(_)) => { + return Err(anyhow!( + "config file JSON {:?} should be an object", + path.to_str().unwrap() + )) + } + Err(e) => { + return Err(anyhow!( + "Unable to parse config file JSON {:?} because of {}", + path.to_str().unwrap(), + e.to_string() + )) + } + }; let json: ConfigFileJson = serde_json::from_value(jsonc)?; Ok(Self { @@ -393,6 +410,42 @@ mod tests { ); } + #[test] + fn test_parse_config_with_empty_file() { + let config_text = ""; + let config_path = PathBuf::from("/deno/tsconfig.json"); + let config_file = ConfigFile::new(config_text, &config_path).unwrap(); + let (options_value, _) = + config_file.as_compiler_options().expect("error parsing"); + assert!(options_value.is_object()); + } + + #[test] + fn test_parse_config_with_commented_file() { + let config_text = r#"//{"foo":"bar"}"#; + let config_path = PathBuf::from("/deno/tsconfig.json"); + let config_file = ConfigFile::new(config_text, &config_path).unwrap(); + let (options_value, _) = + config_file.as_compiler_options().expect("error parsing"); + assert!(options_value.is_object()); + } + + #[test] + fn test_parse_config_with_invalid_file() { + let config_text = "{foo:bar}"; + let config_path = PathBuf::from("/deno/tsconfig.json"); + // Emit error: Unable to parse config file JSON "" because of Unexpected token on line 1 column 6. + assert!(ConfigFile::new(config_text, &config_path).is_err()); + } + + #[test] + fn test_parse_config_with_not_object_file() { + let config_text = "[]"; + let config_path = PathBuf::from("/deno/tsconfig.json"); + // Emit error: config file JSON "" should be an object + assert!(ConfigFile::new(config_text, &config_path).is_err()); + } + #[test] fn test_tsconfig_merge_user_options() { let mut tsconfig = TsConfig::new(json!({