summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2020-10-29 21:18:18 +1100
committerGitHub <noreply@github.com>2020-10-29 21:18:18 +1100
commitb0482400c96476946514f03f27f139dd505b06fb (patch)
treebbca9156c79a5de1e42354b6af5ab73c88ffc05e
parentbfce376c685694569be2cbf0716dd58f898c111e (diff)
fix(cli): make hashes of tsconfig deterministic (#8167)
Fixes #8163
-rw-r--r--cli/module_graph2.rs45
-rw-r--r--cli/tests/module_graph/file_tests-checkwithconfig.ts5
-rw-r--r--cli/tests/module_graph/https_deno.land-std-http-server.ts5
-rw-r--r--cli/tests/module_graph/tsconfig_01.json13
-rw-r--r--cli/tsc_config.rs27
5 files changed, 94 insertions, 1 deletions
diff --git a/cli/module_graph2.rs b/cli/module_graph2.rs
index df2e5fc61..3fc900373 100644
--- a/cli/module_graph2.rs
+++ b/cli/module_graph2.rs
@@ -1735,6 +1735,51 @@ pub mod tests {
}
#[tokio::test]
+ async fn test_graph_check_user_config() {
+ let specifier =
+ ModuleSpecifier::resolve_url_or_path("file:///tests/checkwithconfig.ts")
+ .expect("could not resolve module");
+ let (graph, handler) = setup(specifier.clone()).await;
+ let (_, diagnostics, maybe_ignored_options) = graph
+ .check(CheckOptions {
+ debug: false,
+ emit: true,
+ lib: TypeLib::DenoWindow,
+ maybe_config_path: Some(
+ "tests/module_graph/tsconfig_01.json".to_string(),
+ ),
+ reload: true,
+ })
+ .expect("should have checked");
+ assert!(maybe_ignored_options.is_none());
+ assert!(diagnostics.is_empty());
+ let h = handler.borrow();
+ assert_eq!(h.version_calls.len(), 2);
+ let ver0 = h.version_calls[0].1.clone();
+ let ver1 = h.version_calls[1].1.clone();
+
+ // let's do it all over again to ensure that the versions are determinstic
+ let (graph, handler) = setup(specifier).await;
+ let (_, diagnostics, maybe_ignored_options) = graph
+ .check(CheckOptions {
+ debug: false,
+ emit: true,
+ lib: TypeLib::DenoWindow,
+ maybe_config_path: Some(
+ "tests/module_graph/tsconfig_01.json".to_string(),
+ ),
+ reload: true,
+ })
+ .expect("should have checked");
+ assert!(maybe_ignored_options.is_none());
+ assert!(diagnostics.is_empty());
+ let h = handler.borrow();
+ assert_eq!(h.version_calls.len(), 2);
+ assert!(h.version_calls[0].1 == ver0 || h.version_calls[0].1 == ver1);
+ assert!(h.version_calls[1].1 == ver0 || h.version_calls[1].1 == ver1);
+ }
+
+ #[tokio::test]
async fn test_graph_info() {
let specifier =
ModuleSpecifier::resolve_url_or_path("file:///tests/main.ts")
diff --git a/cli/tests/module_graph/file_tests-checkwithconfig.ts b/cli/tests/module_graph/file_tests-checkwithconfig.ts
new file mode 100644
index 000000000..e7af5fa19
--- /dev/null
+++ b/cli/tests/module_graph/file_tests-checkwithconfig.ts
@@ -0,0 +1,5 @@
+import { ServerRequest } from "https://deno.land/std/http/server.ts";
+
+export default (req: ServerRequest) => {
+ req.respond({ body: `Hello, from Deno v${Deno.version.deno}!` });
+};
diff --git a/cli/tests/module_graph/https_deno.land-std-http-server.ts b/cli/tests/module_graph/https_deno.land-std-http-server.ts
new file mode 100644
index 000000000..0b3c995ec
--- /dev/null
+++ b/cli/tests/module_graph/https_deno.land-std-http-server.ts
@@ -0,0 +1,5 @@
+export class ServerRequest {
+ respond(value: { body: string }) {
+ console.log(value);
+ }
+}
diff --git a/cli/tests/module_graph/tsconfig_01.json b/cli/tests/module_graph/tsconfig_01.json
new file mode 100644
index 000000000..f7496d475
--- /dev/null
+++ b/cli/tests/module_graph/tsconfig_01.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "strict": false,
+ "noImplicitAny": false,
+ "noImplicitThis": false,
+ "alwaysStrict": false,
+ "strictNullChecks": false,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": false,
+ "experimentalDecorators": true,
+ "emitDecoratorMetadata": true
+ }
+}
diff --git a/cli/tsc_config.rs b/cli/tsc_config.rs
index 93f269ed3..93e9dddb2 100644
--- a/cli/tsc_config.rs
+++ b/cli/tsc_config.rs
@@ -8,6 +8,7 @@ use jsonc_parser::JsonValue;
use serde::Deserialize;
use serde::Serialize;
use serde::Serializer;
+use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fmt;
use std::path::Path;
@@ -230,7 +231,10 @@ impl TsConfig {
}
pub fn as_bytes(&self) -> Vec<u8> {
- self.0.to_string().as_bytes().to_owned()
+ let map = self.0.as_object().unwrap();
+ let ordered: BTreeMap<_, _> = map.iter().collect();
+ let value = json!(ordered);
+ value.to_string().as_bytes().to_owned()
}
/// Return the value of the `checkJs` compiler option, defaulting to `false`
@@ -400,4 +404,25 @@ mod tests {
.to_string()
.starts_with("Unterminated object on line 1"));
}
+
+ #[test]
+ fn test_tsconfig_as_bytes() {
+ let mut tsconfig1 = TsConfig::new(json!({
+ "strict": true,
+ "target": "esnext",
+ }));
+ tsconfig1.merge(&json!({
+ "target": "es5",
+ "module": "amd",
+ }));
+ let mut tsconfig2 = TsConfig::new(json!({
+ "target": "esnext",
+ "strict": true,
+ }));
+ tsconfig2.merge(&json!({
+ "module": "amd",
+ "target": "es5",
+ }));
+ assert_eq!(tsconfig1.as_bytes(), tsconfig2.as_bytes());
+ }
}