mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
Remove support for extensionless import (#1396)
This commit is contained in:
parent
bee55fcd20
commit
6cc998f28b
25 changed files with 196 additions and 241 deletions
|
@ -1,5 +1,5 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test, assert, assertEqual } from "./test_util";
|
import { test, assert, assertEqual } from "./test_util.ts";
|
||||||
import * as deno from "deno";
|
import * as deno from "deno";
|
||||||
import * as ts from "typescript";
|
import * as ts from "typescript";
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ function stringifyWithQuotes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @internal
|
/** TODO Do not expose this from "deno" namespace. */
|
||||||
export function stringifyArgs(
|
export function stringifyArgs(
|
||||||
// tslint:disable-next-line:no-any
|
// tslint:disable-next-line:no-any
|
||||||
args: any[],
|
args: any[],
|
||||||
|
@ -354,8 +354,8 @@ type PrintFunc = (x: string, isErr?: boolean) => void;
|
||||||
const countMap = new Map<string, number>();
|
const countMap = new Map<string, number>();
|
||||||
const timerMap = new Map<string, number>();
|
const timerMap = new Map<string, number>();
|
||||||
|
|
||||||
|
/** TODO Do not expose this from "deno". */
|
||||||
export class Console {
|
export class Console {
|
||||||
// @internal
|
|
||||||
constructor(private printFunc: PrintFunc) {}
|
constructor(private printFunc: PrintFunc) {}
|
||||||
|
|
||||||
/** Writes the arguments to stdout */
|
/** Writes the arguments to stdout */
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { Console, libdeno, stringifyArgs, inspect } from "deno";
|
||||||
import { test, assert, assertEqual } from "./test_util.ts";
|
import { test, assert, assertEqual } from "./test_util.ts";
|
||||||
import { stringifyArgs, inspect } from "./console.ts";
|
|
||||||
|
|
||||||
import { Console } from "./console.ts";
|
|
||||||
import { libdeno } from "./libdeno";
|
|
||||||
const console = new Console(libdeno.print);
|
const console = new Console(libdeno.print);
|
||||||
|
|
||||||
// tslint:disable-next-line:no-any
|
// tslint:disable-next-line:no-any
|
||||||
|
|
|
@ -55,6 +55,13 @@ export { run, RunOptions, Process, ProcessStatus } from "./process";
|
||||||
export { inspect } from "./console";
|
export { inspect } from "./console";
|
||||||
export const args: string[] = [];
|
export const args: string[] = [];
|
||||||
|
|
||||||
|
// TODO Don't expose Console nor stringifyArgs.
|
||||||
|
export { Console, stringifyArgs } from "./console";
|
||||||
|
// TODO Don't expose DomIterableMixin.
|
||||||
|
export { DomIterableMixin } from "./mixins/dom_iterable";
|
||||||
|
// TODO Don't expose deferred.
|
||||||
|
export { deferred } from "./util";
|
||||||
|
|
||||||
// Provide the compiler API in an obfuscated way
|
// Provide the compiler API in an obfuscated way
|
||||||
import * as compiler from "./compiler";
|
import * as compiler from "./compiler";
|
||||||
// @internal
|
// @internal
|
||||||
|
|
|
@ -36,7 +36,7 @@ type ReferrerPolicy =
|
||||||
| "origin-when-cross-origin"
|
| "origin-when-cross-origin"
|
||||||
| "unsafe-url";
|
| "unsafe-url";
|
||||||
export type BlobPart = BufferSource | Blob | string;
|
export type BlobPart = BufferSource | Blob | string;
|
||||||
export type FormDataEntryValue = File | string;
|
export type FormDataEntryValue = DomFile | string;
|
||||||
export type EventListenerOrEventListenerObject =
|
export type EventListenerOrEventListenerObject =
|
||||||
| EventListener
|
| EventListener
|
||||||
| EventListenerObject;
|
| EventListenerObject;
|
||||||
|
@ -175,7 +175,10 @@ interface Event {
|
||||||
readonly NONE: number;
|
readonly NONE: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface File extends Blob {
|
/* TODO(ry) Re-expose this interface. There is currently some interference
|
||||||
|
* between deno's File and this one.
|
||||||
|
*/
|
||||||
|
export interface DomFile extends Blob {
|
||||||
readonly lastModified: number;
|
readonly lastModified: number;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,10 @@ testPerm({ net: true }, async function fetchMultipartFormDataSuccess() {
|
||||||
assert(formData.has("field_1"));
|
assert(formData.has("field_1"));
|
||||||
assertEqual(formData.get("field_1").toString(), "value_1 \r\n");
|
assertEqual(formData.get("field_1").toString(), "value_1 \r\n");
|
||||||
assert(formData.has("field_2"));
|
assert(formData.has("field_2"));
|
||||||
|
/* TODO(ry) Re-enable this test once we bring back the global File type.
|
||||||
const file = formData.get("field_2") as File;
|
const file = formData.get("field_2") as File;
|
||||||
assertEqual(file.name, "file.js");
|
assertEqual(file.name, "file.js");
|
||||||
|
*/
|
||||||
// Currently we cannot read from file...
|
// Currently we cannot read from file...
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
// TODO Rename this file to js/dom_file.ts it's currently too similarly named to
|
||||||
|
// js/files.ts
|
||||||
|
|
||||||
import * as domTypes from "./dom_types";
|
import * as domTypes from "./dom_types";
|
||||||
import * as blob from "./blob";
|
import * as blob from "./blob";
|
||||||
|
|
||||||
export class DenoFile extends blob.DenoBlob implements domTypes.File {
|
// TODO Rename this to DomFileImpl
|
||||||
|
export class DenoFile extends blob.DenoBlob implements domTypes.DomFile {
|
||||||
lastModified: number;
|
lastModified: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,12 @@ test(function formDataSetEmptyBlobSuccess() {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.set("a", new Blob([]), "blank.txt");
|
formData.set("a", new Blob([]), "blank.txt");
|
||||||
const file = formData.get("a");
|
const file = formData.get("a");
|
||||||
|
/* TODO Fix this test.
|
||||||
assert(file instanceof File);
|
assert(file instanceof File);
|
||||||
if (typeof file !== "string") {
|
if (typeof file !== "string") {
|
||||||
assertEqual(file.name, "blank.txt");
|
assertEqual(file.name, "blank.txt");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function formDataParamsForEachSuccess() {
|
test(function formDataParamsForEachSuccess() {
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
import * as blob from "./blob";
|
import * as blob from "./blob";
|
||||||
import * as consoleTypes from "./console";
|
import * as consoleTypes from "./console";
|
||||||
import * as domTypes from "./dom_types";
|
import * as domTypes from "./dom_types";
|
||||||
import * as file from "./file";
|
|
||||||
import * as formData from "./form_data";
|
import * as formData from "./form_data";
|
||||||
import * as fetchTypes from "./fetch";
|
import * as fetchTypes from "./fetch";
|
||||||
import * as headers from "./headers";
|
import * as headers from "./headers";
|
||||||
|
@ -55,8 +54,13 @@ window.setInterval = timers.setInterval;
|
||||||
// being used, which it cannot statically determine within this module.
|
// being used, which it cannot statically determine within this module.
|
||||||
window.Blob = blob.DenoBlob;
|
window.Blob = blob.DenoBlob;
|
||||||
export type Blob = blob.DenoBlob;
|
export type Blob = blob.DenoBlob;
|
||||||
window.File = file.DenoFile;
|
|
||||||
export type File = file.DenoFile;
|
// TODO(ry) Do not export a class implementing the DOM, export the DOM
|
||||||
|
// interface. See this comment for implementation hint:
|
||||||
|
// https://github.com/denoland/deno/pull/1396#discussion_r243711502
|
||||||
|
// window.File = file.DenoFile;
|
||||||
|
// export type File = file.DenoFile;
|
||||||
|
|
||||||
window.URL = url.URL;
|
window.URL = url.URL;
|
||||||
export type URL = url.URL;
|
export type URL = url.URL;
|
||||||
window.URLSearchParams = urlSearchParams.URLSearchParams;
|
window.URLSearchParams = urlSearchParams.URLSearchParams;
|
||||||
|
|
|
@ -41,5 +41,4 @@ interface Libdeno {
|
||||||
}
|
}
|
||||||
|
|
||||||
const window = globalEval("this");
|
const window = globalEval("this");
|
||||||
// @internal
|
|
||||||
export const libdeno = window.libdeno as Libdeno;
|
export const libdeno = window.libdeno as Libdeno;
|
||||||
|
|
|
@ -11,6 +11,7 @@ type Constructor<T = {}> = new (...args: any[]) => T;
|
||||||
/** Mixes in a DOM iterable methods into a base class, assumes that there is
|
/** Mixes in a DOM iterable methods into a base class, assumes that there is
|
||||||
* a private data iterable that is part of the base class, located at
|
* a private data iterable that is part of the base class, located at
|
||||||
* `[dataSymbol]`.
|
* `[dataSymbol]`.
|
||||||
|
* TODO Don't expose DomIterableMixin from "deno" namespace.
|
||||||
*/
|
*/
|
||||||
export function DomIterableMixin<K, V, TBase extends Constructor>(
|
export function DomIterableMixin<K, V, TBase extends Constructor>(
|
||||||
// tslint:disable-next-line:variable-name
|
// tslint:disable-next-line:variable-name
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test, assert, assertEqual } from "../test_util.ts";
|
import { test, assert, assertEqual } from "../test_util.ts";
|
||||||
import { DomIterableMixin } from "./dom_iterable.ts";
|
import { DomIterableMixin } from "deno";
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
const dataSymbol = Symbol("data symbol");
|
const dataSymbol = Symbol("data symbol");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
import * as deno from "deno";
|
import * as deno from "deno";
|
||||||
import { testPerm, assert, assertEqual } from "./test_util.ts";
|
import { testPerm, assert, assertEqual } from "./test_util.ts";
|
||||||
import { deferred } from "./util.ts";
|
import { deferred } from "deno";
|
||||||
|
|
||||||
testPerm({ net: true }, function netListenClose() {
|
testPerm({ net: true }, function netListenClose() {
|
||||||
const listener = deno.listen("tcp", "127.0.0.1:4500");
|
const listener = deno.listen("tcp", "127.0.0.1:4500");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { test, assert, assertEqual } from "./test_util";
|
import { test, assert, assertEqual } from "./test_util.ts";
|
||||||
import * as deno from "deno";
|
import * as deno from "deno";
|
||||||
|
|
||||||
// tslint:disable-next-line:no-any
|
// tslint:disable-next-line:no-any
|
||||||
|
|
|
@ -13,7 +13,67 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { assert, assertEqual, equal } from "./util";
|
// Do not add imports in this file in order to be compatible with Node.
|
||||||
|
|
||||||
|
export function assertEqual(actual: unknown, expected: unknown, msg?: string) {
|
||||||
|
if (!equal(actual, expected)) {
|
||||||
|
let actualString: string;
|
||||||
|
let expectedString: string;
|
||||||
|
try {
|
||||||
|
actualString = String(actual);
|
||||||
|
} catch (e) {
|
||||||
|
actualString = "[Cannot display]";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
expectedString = String(expected);
|
||||||
|
} catch (e) {
|
||||||
|
expectedString = "[Cannot display]";
|
||||||
|
}
|
||||||
|
console.error(
|
||||||
|
"assertEqual failed. actual =",
|
||||||
|
actualString,
|
||||||
|
"expected =",
|
||||||
|
expectedString
|
||||||
|
);
|
||||||
|
if (!msg) {
|
||||||
|
msg = `actual: ${actualString} expected: ${expectedString}`;
|
||||||
|
}
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function assert(expr: boolean, msg = "") {
|
||||||
|
if (!expr) {
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(ry) Use unknown here for parameters types.
|
||||||
|
// tslint:disable-next-line:no-any
|
||||||
|
export function equal(c: any, d: any): boolean {
|
||||||
|
const seen = new Map();
|
||||||
|
return (function compare(a, b) {
|
||||||
|
if (Object.is(a, b)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a && typeof a === "object" && b && typeof b === "object") {
|
||||||
|
if (seen.get(a) === b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Object.keys(a).length !== Object.keys(b).length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const key in { ...a, ...b }) {
|
||||||
|
if (!compare(a[key], b[key])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seen.set(a, b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})(c, d);
|
||||||
|
}
|
||||||
|
|
||||||
export type TestFunction = () => void | Promise<void>;
|
export type TestFunction = () => void | Promise<void>;
|
||||||
|
|
||||||
|
|
|
@ -13,43 +13,41 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { test } from "./testing.ts";
|
import { test, assert, assertEqual, equal } from "./testing.ts";
|
||||||
import { assert } from "./util.ts";
|
|
||||||
import * as util from "./util.ts";
|
|
||||||
|
|
||||||
test(function util_equal() {
|
test(function testingEqual() {
|
||||||
assert(util.equal("world", "world"));
|
assert(equal("world", "world"));
|
||||||
assert(!util.equal("hello", "world"));
|
assert(!equal("hello", "world"));
|
||||||
assert(util.equal(5, 5));
|
assert(equal(5, 5));
|
||||||
assert(!util.equal(5, 6));
|
assert(!equal(5, 6));
|
||||||
assert(util.equal(NaN, NaN));
|
assert(equal(NaN, NaN));
|
||||||
assert(util.equal({ hello: "world" }, { hello: "world" }));
|
assert(equal({ hello: "world" }, { hello: "world" }));
|
||||||
assert(!util.equal({ world: "hello" }, { hello: "world" }));
|
assert(!equal({ world: "hello" }, { hello: "world" }));
|
||||||
assert(
|
assert(
|
||||||
util.equal(
|
equal(
|
||||||
{ hello: "world", hi: { there: "everyone" } },
|
{ hello: "world", hi: { there: "everyone" } },
|
||||||
{ hello: "world", hi: { there: "everyone" } }
|
{ hello: "world", hi: { there: "everyone" } }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
!util.equal(
|
!equal(
|
||||||
{ hello: "world", hi: { there: "everyone" } },
|
{ hello: "world", hi: { there: "everyone" } },
|
||||||
{ hello: "world", hi: { there: "everyone else" } }
|
{ hello: "world", hi: { there: "everyone else" } }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function util_assertEqual() {
|
test(function testingAssertEqual() {
|
||||||
const a = Object.create(null);
|
const a = Object.create(null);
|
||||||
a.b = "foo";
|
a.b = "foo";
|
||||||
util.assertEqual(a, a);
|
assertEqual(a, a);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function util_assertEqualActualUncoercable() {
|
test(function testingAssertEqualActualUncoercable() {
|
||||||
let didThrow = false;
|
let didThrow = false;
|
||||||
const a = Object.create(null);
|
const a = Object.create(null);
|
||||||
try {
|
try {
|
||||||
util.assertEqual(a, "bar");
|
assertEqual(a, "bar");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
didThrow = true;
|
didThrow = true;
|
||||||
console.log(e.message);
|
console.log(e.message);
|
||||||
|
@ -58,11 +56,11 @@ test(function util_assertEqualActualUncoercable() {
|
||||||
assert(didThrow);
|
assert(didThrow);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function util_assertEqualExpectedUncoercable() {
|
test(function testingAssertEqualExpectedUncoercable() {
|
||||||
let didThrow = false;
|
let didThrow = false;
|
||||||
const a = Object.create(null);
|
const a = Object.create(null);
|
||||||
try {
|
try {
|
||||||
util.assertEqual("bar", a);
|
assertEqual("bar", a);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
didThrow = true;
|
didThrow = true;
|
||||||
console.log(e.message);
|
console.log(e.message);
|
|
@ -1,74 +0,0 @@
|
||||||
/*!
|
|
||||||
Copyright 2018 Propel http://propel.site/. All rights reserved.
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function assertEqual(actual: unknown, expected: unknown, msg?: string) {
|
|
||||||
if (!equal(actual, expected)) {
|
|
||||||
let actualString: string;
|
|
||||||
let expectedString: string;
|
|
||||||
try {
|
|
||||||
actualString = String(actual);
|
|
||||||
} catch (e) {
|
|
||||||
actualString = "[Cannot display]";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
expectedString = String(expected);
|
|
||||||
} catch (e) {
|
|
||||||
expectedString = "[Cannot display]";
|
|
||||||
}
|
|
||||||
console.error(
|
|
||||||
"assertEqual failed. actual =",
|
|
||||||
actualString,
|
|
||||||
"expected =",
|
|
||||||
expectedString
|
|
||||||
);
|
|
||||||
if (!msg) {
|
|
||||||
msg = `actual: ${actualString} expected: ${expectedString}`;
|
|
||||||
}
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function assert(expr: boolean, msg = "") {
|
|
||||||
if (!expr) {
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(ry) Use unknown here for parameters types.
|
|
||||||
// tslint:disable-next-line:no-any
|
|
||||||
export function equal(c: any, d: any): boolean {
|
|
||||||
const seen = new Map();
|
|
||||||
return (function compare(a, b) {
|
|
||||||
if (Object.is(a, b)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (a && typeof a === "object" && b && typeof b === "object") {
|
|
||||||
if (seen.get(a) === b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (Object.keys(a).length !== Object.keys(b).length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const key in { ...a, ...b }) {
|
|
||||||
if (!compare(a[key], b[key])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
seen.set(a, b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
})(c, d);
|
|
||||||
}
|
|
|
@ -2,16 +2,18 @@
|
||||||
|
|
||||||
// This test is executed as part of tools/test.py
|
// This test is executed as part of tools/test.py
|
||||||
// But it can also be run manually: ./target/debug/deno js/unit_tests.ts
|
// But it can also be run manually: ./target/debug/deno js/unit_tests.ts
|
||||||
import "../website/app_test.js";
|
|
||||||
import "./blob_test.ts";
|
import "./blob_test.ts";
|
||||||
import "./buffer_test.ts";
|
import "./buffer_test.ts";
|
||||||
import "./chmod_test.ts";
|
import "./chmod_test.ts";
|
||||||
import "./compiler_test.ts";
|
import "./compiler_test.ts";
|
||||||
import "./console_test.ts";
|
import "./console_test.ts";
|
||||||
import "./copy_file_test.ts";
|
import "./copy_file_test.ts";
|
||||||
import "./dir_test";
|
import "./dir_test.ts";
|
||||||
import "./fetch_test.ts";
|
import "./fetch_test.ts";
|
||||||
import "./file_test.ts";
|
// TODO The global "File" has been temporarily disabled. See the note in
|
||||||
|
// js/globals.ts
|
||||||
|
// import "./file_test.ts";
|
||||||
import "./files_test.ts";
|
import "./files_test.ts";
|
||||||
import "./form_data_test.ts";
|
import "./form_data_test.ts";
|
||||||
import "./headers_test.ts";
|
import "./headers_test.ts";
|
||||||
|
@ -37,3 +39,5 @@ import "./truncate_test.ts";
|
||||||
import "./url_test.ts";
|
import "./url_test.ts";
|
||||||
import "./url_search_params_test.ts";
|
import "./url_search_params_test.ts";
|
||||||
import "./write_file_test.ts";
|
import "./write_file_test.ts";
|
||||||
|
|
||||||
|
// TODO import "../website/app_test.js";
|
||||||
|
|
|
@ -103,15 +103,15 @@ export function containsOnlyASCII(str: string): boolean {
|
||||||
return /^[\x00-\x7F]*$/.test(str);
|
return /^[\x00-\x7F]*$/.test(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @internal
|
|
||||||
export interface Deferred {
|
export interface Deferred {
|
||||||
promise: Promise<void>;
|
promise: Promise<void>;
|
||||||
resolve: Function;
|
resolve: Function;
|
||||||
reject: Function;
|
reject: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a wrapper around a promise that could be resolved externally. */
|
/** Create a wrapper around a promise that could be resolved externally.
|
||||||
// @internal
|
* TODO Do not expose this from "deno" namespace.
|
||||||
|
*/
|
||||||
export function deferred(): Deferred {
|
export function deferred(): Deferred {
|
||||||
let resolve: Function | undefined;
|
let resolve: Function | undefined;
|
||||||
let reject: Function | undefined;
|
let reject: Function | undefined;
|
||||||
|
|
175
src/deno_dir.rs
175
src/deno_dir.rs
|
@ -142,36 +142,31 @@ impl DenoDir {
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
filename: &str,
|
filename: &str,
|
||||||
) -> DenoResult<Option<CodeFetchOutput>> {
|
) -> DenoResult<Option<CodeFetchOutput>> {
|
||||||
let extensions = ["", ".ts", ".js"];
|
let p = Path::new(&filename);
|
||||||
for ext in extensions.iter() {
|
// We write a special ".mime" file into the `.deno/deps` directory along side the
|
||||||
let filename = [filename, ext].concat();
|
// cached file, containing just the media type.
|
||||||
let module_name = [module_name, ext].concat();
|
let media_type_filename = [&filename, ".mime"].concat();
|
||||||
let p = Path::new(&filename);
|
let mt = Path::new(&media_type_filename);
|
||||||
// We write a special ".mime" file into the `.deno/deps` directory along side the
|
eprint!("Downloading {}...", &module_name); // no newline
|
||||||
// cached file, containing just the media type.
|
let maybe_source = http_util::fetch_sync_string(&module_name);
|
||||||
let media_type_filename = [&filename, ".mime"].concat();
|
if let Ok((source, content_type)) = maybe_source {
|
||||||
let mt = Path::new(&media_type_filename);
|
eprintln!(""); // next line
|
||||||
eprint!("Downloading {}...", &module_name); // no newline
|
match p.parent() {
|
||||||
let maybe_source = http_util::fetch_sync_string(&module_name);
|
Some(ref parent) => fs::create_dir_all(parent),
|
||||||
if let Ok((source, content_type)) = maybe_source {
|
None => Ok(()),
|
||||||
eprintln!(""); // next line
|
}?;
|
||||||
match p.parent() {
|
deno_fs::write_file(&p, &source, 0o666)?;
|
||||||
Some(ref parent) => fs::create_dir_all(parent),
|
deno_fs::write_file(&mt, content_type.as_bytes(), 0o666)?;
|
||||||
None => Ok(()),
|
return Ok(Some(CodeFetchOutput {
|
||||||
}?;
|
module_name: module_name.to_string(),
|
||||||
deno_fs::write_file(&p, &source, 0o666)?;
|
filename: filename.to_string(),
|
||||||
deno_fs::write_file(&mt, content_type.as_bytes(), 0o666)?;
|
media_type: map_content_type(&p, Some(&content_type)),
|
||||||
return Ok(Some(CodeFetchOutput {
|
source_code: source,
|
||||||
module_name,
|
maybe_output_code: None,
|
||||||
filename: filename.clone(), // TODO: no clone after NLL rfc
|
maybe_source_map: None,
|
||||||
media_type: map_content_type(&p, Some(&content_type)),
|
}));
|
||||||
source_code: source,
|
} else {
|
||||||
maybe_output_code: None,
|
eprintln!(" NOT FOUND");
|
||||||
maybe_source_map: None,
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
eprintln!(" NOT FOUND");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -182,33 +177,33 @@ impl DenoDir {
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
filename: &str,
|
filename: &str,
|
||||||
) -> DenoResult<Option<CodeFetchOutput>> {
|
) -> DenoResult<Option<CodeFetchOutput>> {
|
||||||
let extensions = ["", ".ts", ".js"];
|
let p = Path::new(&filename);
|
||||||
for ext in extensions.iter() {
|
let media_type_filename = [&filename, ".mime"].concat();
|
||||||
let filename = [filename, ext].concat();
|
let mt = Path::new(&media_type_filename);
|
||||||
let module_name = [module_name, ext].concat();
|
let source_code = match fs::read(p) {
|
||||||
let p = Path::new(&filename);
|
Err(e) => {
|
||||||
if !p.exists() {
|
if e.kind() == std::io::ErrorKind::NotFound {
|
||||||
continue;
|
return Ok(None);
|
||||||
|
} else {
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let media_type_filename = [&filename, ".mime"].concat();
|
Ok(c) => c,
|
||||||
let mt = Path::new(&media_type_filename);
|
};
|
||||||
let source_code = fs::read(&p)?;
|
// .mime file might not exists
|
||||||
// .mime file might not exists
|
// this is okay for local source: maybe_content_type_str will be None
|
||||||
// this is okay for local source: maybe_content_type_str will be None
|
let maybe_content_type_string = fs::read_to_string(&mt).ok();
|
||||||
let maybe_content_type_string = fs::read_to_string(&mt).ok();
|
// Option<String> -> Option<&str>
|
||||||
// Option<String> -> Option<&str>
|
let maybe_content_type_str =
|
||||||
let maybe_content_type_str =
|
maybe_content_type_string.as_ref().map(String::as_str);
|
||||||
maybe_content_type_string.as_ref().map(String::as_str);
|
Ok(Some(CodeFetchOutput {
|
||||||
return Ok(Some(CodeFetchOutput {
|
module_name: module_name.to_string(),
|
||||||
module_name,
|
filename: filename.to_string(),
|
||||||
filename: filename.clone(), // TODO: no clone after NLL rfc
|
media_type: map_content_type(&p, maybe_content_type_str),
|
||||||
media_type: map_content_type(&p, maybe_content_type_str),
|
source_code,
|
||||||
source_code,
|
maybe_output_code: None,
|
||||||
maybe_output_code: None,
|
maybe_source_map: None,
|
||||||
maybe_source_map: None,
|
}))
|
||||||
}));
|
|
||||||
}
|
|
||||||
Ok(None) // cannot find locally
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prototype: https://github.com/denoland/deno/blob/golang/os.go#L122-L138
|
// Prototype: https://github.com/denoland/deno/blob/golang/os.go#L122-L138
|
||||||
|
@ -222,19 +217,32 @@ impl DenoDir {
|
||||||
// 1. This is a remote module, but no reload provided
|
// 1. This is a remote module, but no reload provided
|
||||||
// 2. This is a local module
|
// 2. This is a local module
|
||||||
if !is_module_remote || !self.reload {
|
if !is_module_remote || !self.reload {
|
||||||
let maybe_local_source =
|
debug!(
|
||||||
self.fetch_local_source(&module_name, &filename)?;
|
"fetch local or reload {} is_module_remote {}",
|
||||||
if let Some(output) = maybe_local_source {
|
module_name, is_module_remote
|
||||||
return Ok(output);
|
);
|
||||||
|
match self.fetch_local_source(&module_name, &filename)? {
|
||||||
|
Some(output) => {
|
||||||
|
debug!("found local source ");
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
debug!("fetch_local_source returned None");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not remote file, stop here!
|
// If not remote file, stop here!
|
||||||
if !is_module_remote {
|
if !is_module_remote {
|
||||||
|
debug!("not remote file stop here");
|
||||||
return Err(DenoError::from(std::io::Error::new(
|
return Err(DenoError::from(std::io::Error::new(
|
||||||
std::io::ErrorKind::NotFound,
|
std::io::ErrorKind::NotFound,
|
||||||
format!("cannot find local file '{}'", filename),
|
format!("cannot find local file '{}'", filename),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("is remote but didn't find module");
|
||||||
|
|
||||||
// not cached/local, try remote
|
// not cached/local, try remote
|
||||||
let maybe_remote_source =
|
let maybe_remote_source =
|
||||||
self.fetch_remote_source(&module_name, &filename)?;
|
self.fetch_remote_source(&module_name, &filename)?;
|
||||||
|
@ -514,6 +522,7 @@ fn filter_shebang(code: Vec<u8>) -> Vec<u8> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
use tokio_util;
|
||||||
|
|
||||||
fn test_setup() -> (TempDir, DenoDir) {
|
fn test_setup() -> (TempDir, DenoDir) {
|
||||||
let temp_dir = TempDir::new().expect("tempdir fail");
|
let temp_dir = TempDir::new().expect("tempdir fail");
|
||||||
|
@ -606,10 +615,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_source_code() {
|
fn test_get_source_code() {
|
||||||
use tokio_util;
|
let (temp_dir, deno_dir) = test_setup();
|
||||||
// http_util::fetch_sync_string requires tokio
|
// http_util::fetch_sync_string requires tokio
|
||||||
tokio_util::init(|| {
|
tokio_util::init(|| {
|
||||||
let (temp_dir, deno_dir) = test_setup();
|
|
||||||
let module_name = "http://localhost:4545/tests/subdir/mod2.ts";
|
let module_name = "http://localhost:4545/tests/subdir/mod2.ts";
|
||||||
let filename = deno_fs::normalize_path(
|
let filename = deno_fs::normalize_path(
|
||||||
deno_dir
|
deno_dir
|
||||||
|
@ -620,6 +628,7 @@ mod tests {
|
||||||
let mime_file_name = format!("{}.mime", &filename);
|
let mime_file_name = format!("{}.mime", &filename);
|
||||||
|
|
||||||
let result = deno_dir.get_source_code(module_name, &filename);
|
let result = deno_dir.get_source_code(module_name, &filename);
|
||||||
|
println!("module_name {} filename {}", module_name, filename);
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let r = result.unwrap();
|
let r = result.unwrap();
|
||||||
let expected: &[u8] =
|
let expected: &[u8] =
|
||||||
|
@ -739,48 +748,6 @@ mod tests {
|
||||||
//println!("code_fetch_output {:?}", code_fetch_output);
|
//println!("code_fetch_output {:?}", code_fetch_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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 specifier = "./js/main";
|
|
||||||
let referrer = cwd_string.as_str();
|
|
||||||
let r = deno_dir.code_fetch(specifier, referrer);
|
|
||||||
assert!(r.is_ok());
|
|
||||||
|
|
||||||
// Test .ts extension
|
|
||||||
// Assuming cwd is the deno repo root.
|
|
||||||
let specifier = "./js/main";
|
|
||||||
let referrer = cwd_string.as_str();
|
|
||||||
let r = deno_dir.code_fetch(specifier, referrer);
|
|
||||||
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 specifier = "./js/mock_builtin";
|
|
||||||
let referrer = cwd_string.as_str();
|
|
||||||
let r = deno_dir.code_fetch(specifier, referrer);
|
|
||||||
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]
|
#[test]
|
||||||
fn test_src_file_to_url_1() {
|
fn test_src_file_to_url_1() {
|
||||||
let (_temp_dir, deno_dir) = test_setup();
|
let (_temp_dir, deno_dir) = test_setup();
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
args: tests/015_import_no_ext.ts --reload
|
|
||||||
output: tests/015_import_no_ext.ts.out
|
|
|
@ -1,10 +0,0 @@
|
||||||
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);
|
|
|
@ -1,5 +0,0 @@
|
||||||
true
|
|
||||||
[Function: printHello]
|
|
||||||
[Function: printHello]
|
|
||||||
true
|
|
||||||
[Function: printHello]
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Run ./tools/http_server.py too in order for this test to run.
|
// Run ./tools/http_server.py too in order for this test to run.
|
||||||
import { assert } from "../js/testing/util.ts";
|
import { assert } from "../js/testing/testing.ts";
|
||||||
|
|
||||||
// TODO Top level await https://github.com/denoland/deno/issues/471
|
// TODO Top level await https://github.com/denoland/deno/issues/471
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export const isTSFile = true;
|
|
||||||
export { printHello } from "./print_hello.ts";
|
|
||||||
export { printHello as phNoExt } from "./print_hello";
|
|
Loading…
Reference in a new issue