summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2018-10-02 09:38:45 -0700
committerRyan Dahl <ry@tinyclouds.org>2018-10-02 12:38:45 -0400
commiteba58b718860035b830d0739a02c6a382e1f3307 (patch)
tree353e9d10a7efae1bc75b9a5392944e02cb11c02a
parentfc1c54dde052d6a967d5f185604b3f79b1ba2fbb (diff)
Guess extensions on extension not provided (#859)
Fixes #857
-rw-r--r--src/deno_dir.rs97
-rw-r--r--src/http.rs30
-rw-r--r--tests/015_import_no_ext.ts10
-rw-r--r--tests/015_import_no_ext.ts.out8
-rw-r--r--tests/error_006_import_ext_failure.ts1
-rw-r--r--tests/error_006_import_ext_failure.ts.out11
-rw-r--r--tests/subdir/mod3.js1
-rw-r--r--tests/subdir/mod3.ts3
-rw-r--r--tests/subdir/mod4.js1
9 files changed, 134 insertions, 28 deletions
diff --git a/src/deno_dir.rs b/src/deno_dir.rs
index cb769fb86..1e369b40f 100644
--- a/src/deno_dir.rs
+++ b/src/deno_dir.rs
@@ -133,19 +133,41 @@ impl DenoDir {
self: &DenoDir,
module_name: &str,
filename: &str,
- ) -> DenoResult<String> {
- if is_remote(module_name) {
- self.fetch_remote_source(module_name, filename)
- } else if module_name.starts_with(ASSET_PREFIX) {
+ ) -> DenoResult<CodeFetchOutput> {
+ if module_name.starts_with(ASSET_PREFIX) {
panic!("Asset resolution should be done in JS, not Rust.");
- } else {
- assert_eq!(
- module_name, filename,
- "if a module isn't remote, it should have the same filename"
- );
- let src = fs::read_to_string(Path::new(filename))?;
- Ok(src)
}
+ let is_module_remote = is_remote(module_name);
+ let use_extension = |ext| {
+ let module_name = format!("{}{}", module_name, ext);
+ let filename = format!("{}{}", filename, ext);
+ let source_code = if is_module_remote {
+ self.fetch_remote_source(&module_name, &filename)?
+ } else {
+ assert_eq!(
+ module_name, filename,
+ "if a module isn't remote, it should have the same filename"
+ );
+ fs::read_to_string(Path::new(&filename))?
+ };
+ return Ok(CodeFetchOutput {
+ module_name: module_name.to_string(),
+ filename: filename.to_string(),
+ source_code,
+ maybe_output_code: None,
+ });
+ };
+ let default_attempt = use_extension("");
+ if default_attempt.is_ok() {
+ return default_attempt;
+ }
+ debug!("Trying {}.ts...", module_name);
+ let ts_attempt = use_extension(".ts");
+ if ts_attempt.is_ok() {
+ return ts_attempt;
+ }
+ debug!("Trying {}.js...", module_name);
+ use_extension(".js")
}
pub fn code_fetch(
@@ -161,16 +183,7 @@ impl DenoDir {
let (module_name, filename) =
self.resolve_module(module_specifier, containing_file)?;
- let result = self
- .get_source_code(module_name.as_str(), filename.as_str())
- .and_then(|source_code| {
- Ok(CodeFetchOutput {
- module_name,
- filename,
- source_code,
- maybe_output_code: None,
- })
- });
+ let result = self.get_source_code(module_name.as_str(), filename.as_str());
let out = match result {
Err(err) => {
if err.kind() == ErrorKind::NotFound {
@@ -421,6 +434,48 @@ fn test_code_fetch() {
}
#[test]
+fn test_code_fetch_no_ext() {
+ let (_temp_dir, deno_dir) = test_setup();
+
+ let cwd = std::env::current_dir().unwrap();
+ let cwd_string = String::from(cwd.to_str().unwrap()) + "/";
+
+ // Assuming cwd is the deno repo root.
+ let module_specifier = "./js/main";
+ let containing_file = cwd_string.as_str();
+ let r = deno_dir.code_fetch(module_specifier, containing_file);
+ assert!(r.is_ok());
+
+ // Test .ts extension
+ // Assuming cwd is the deno repo root.
+ let module_specifier = "./js/main";
+ let containing_file = cwd_string.as_str();
+ let r = deno_dir.code_fetch(module_specifier, containing_file);
+ assert!(r.is_ok());
+ let code_fetch_output = r.unwrap();
+ // could only test .ends_with to avoid include local abs path
+ assert!(code_fetch_output.module_name.ends_with("/js/main.ts"));
+ assert!(code_fetch_output.filename.ends_with("/js/main.ts"));
+ assert!(code_fetch_output.source_code.len() > 10);
+
+ // Test .js extension
+ // Assuming cwd is the deno repo root.
+ let module_specifier = "./js/mock_builtin";
+ let containing_file = cwd_string.as_str();
+ let r = deno_dir.code_fetch(module_specifier, containing_file);
+ assert!(r.is_ok());
+ let code_fetch_output = r.unwrap();
+ // could only test .ends_with to avoid include local abs path
+ assert!(
+ code_fetch_output
+ .module_name
+ .ends_with("/js/mock_builtin.js")
+ );
+ assert!(code_fetch_output.filename.ends_with("/js/mock_builtin.js"));
+ assert!(code_fetch_output.source_code.len() > 10);
+}
+
+#[test]
fn test_src_file_to_url_1() {
let (_temp_dir, deno_dir) = test_setup();
assert_eq!("hello", deno_dir.src_file_to_url("hello"));
diff --git a/src/http.rs b/src/http.rs
index 5f78cf232..9ef9adb8f 100644
--- a/src/http.rs
+++ b/src/http.rs
@@ -1,10 +1,12 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
-use errors::DenoResult;
+use errors;
+use errors::{DenoError, DenoResult};
use tokio_util;
-use futures::Future;
-use futures::Stream;
+use futures;
+use futures::future::Either;
+use futures::{Future, Stream};
use hyper;
use hyper::client::Client;
use hyper::client::HttpConnector;
@@ -31,11 +33,25 @@ pub fn get_client() -> Client<Connector, hyper::Body> {
pub fn fetch_sync_string(module_name: &str) -> DenoResult<String> {
let url = module_name.parse::<Uri>().unwrap();
let client = get_client();
- let future = client
+ let fetch_future = client
.get(url)
- .and_then(|response| response.into_body().concat2());
- let body = tokio_util::block_on(future)?;
- Ok(String::from_utf8(body.to_vec()).unwrap())
+ .map_err(|err| DenoError::from(err))
+ .and_then(|response| {
+ if !response.status().is_success() {
+ return Either::A(futures::future::err(errors::new(
+ errors::ErrorKind::NotFound,
+ "module not found".to_string(),
+ )));
+ }
+ Either::B(
+ response
+ .into_body()
+ .concat2()
+ .map(|body| String::from_utf8(body.to_vec()).unwrap())
+ .map_err(|err| DenoError::from(err)),
+ )
+ });
+ tokio_util::block_on(fetch_future)
}
/* TODO(ry) Re-enabled this test. Disabling to work around bug in #782.
diff --git a/tests/015_import_no_ext.ts b/tests/015_import_no_ext.ts
new file mode 100644
index 000000000..9bd2acd7e
--- /dev/null
+++ b/tests/015_import_no_ext.ts
@@ -0,0 +1,10 @@
+import { isTSFile, printHello, phNoExt } from "./subdir/mod3";
+console.log(isTSFile);
+console.log(printHello);
+console.log(phNoExt);
+
+import { isMod4 } from "./subdir/mod4";
+console.log(isMod4);
+
+import { printHello as ph } from "http://localhost:4545/tests/subdir/mod2";
+console.log(ph);
diff --git a/tests/015_import_no_ext.ts.out b/tests/015_import_no_ext.ts.out
new file mode 100644
index 000000000..92f21e2a7
--- /dev/null
+++ b/tests/015_import_no_ext.ts.out
@@ -0,0 +1,8 @@
+Downloading http://localhost:4545/tests/subdir/mod2
+Downloading http://localhost:4545/tests/subdir/mod2.ts
+Downloading http://localhost:4545/tests/subdir/print_hello.ts
+true
+[Function: printHello]
+[Function: printHello]
+true
+[Function: printHello]
diff --git a/tests/error_006_import_ext_failure.ts b/tests/error_006_import_ext_failure.ts
new file mode 100644
index 000000000..3c32303a3
--- /dev/null
+++ b/tests/error_006_import_ext_failure.ts
@@ -0,0 +1 @@
+import "./non-existent";
diff --git a/tests/error_006_import_ext_failure.ts.out b/tests/error_006_import_ext_failure.ts.out
new file mode 100644
index 000000000..30c9965da
--- /dev/null
+++ b/tests/error_006_import_ext_failure.ts.out
@@ -0,0 +1,11 @@
+NotFound: Cannot resolve module "./non-existent" from "[WILDCARD]deno/tests/error_006_import_ext_failure.ts"
+ at maybeError (deno/js/errors.ts:[WILDCARD])
+ at maybeThrowError (deno/js/errors.ts:[WILDCARD])
+ at sendSync (deno/js/dispatch.ts:[WILDCARD])
+ at Object.codeFetch (deno/js/os.ts:[WILDCARD])
+ at DenoCompiler.resolveModule (deno/js/compiler.ts:[WILDCARD])
+ at DenoCompiler._resolveModuleName (deno/js/compiler.ts:[WILDCARD])
+ at moduleNames.map.name (deno/js/compiler.ts:[WILDCARD])
+ at Array.map (<anonymous>)
+ at DenoCompiler.resolveModuleNames (deno/js/compiler.ts:[WILDCARD])
+ at Object.compilerHost.resolveModuleNames (deno/third_party/node_modules/typescript/lib/typescript.js:[WILDCARD])
diff --git a/tests/subdir/mod3.js b/tests/subdir/mod3.js
new file mode 100644
index 000000000..ce534f570
--- /dev/null
+++ b/tests/subdir/mod3.js
@@ -0,0 +1 @@
+export const isTSFile = false;
diff --git a/tests/subdir/mod3.ts b/tests/subdir/mod3.ts
new file mode 100644
index 000000000..4f10578bf
--- /dev/null
+++ b/tests/subdir/mod3.ts
@@ -0,0 +1,3 @@
+export const isTSFile = true;
+export { printHello } from "./print_hello.ts";
+export { printHello as phNoExt } from "./print_hello";
diff --git a/tests/subdir/mod4.js b/tests/subdir/mod4.js
new file mode 100644
index 000000000..71332dbc4
--- /dev/null
+++ b/tests/subdir/mod4.js
@@ -0,0 +1 @@
+export const isMod4 = true;