1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-12 00:54:02 -05:00

Run deno_std tests in github actions

This commit is contained in:
Ryan Dahl 2019-10-09 17:22:22 -04:00
parent 28293acd9c
commit 93f7f00c95
No known key found for this signature in database
GPG key ID: C6F2E2494922A6BA
53 changed files with 668 additions and 877 deletions

View file

@ -1 +1,4 @@
cli/tests/error_syntax.js
std/deno.d.ts
std/prettier/vendor
std/**/testdata/

View file

@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [macOS-10.14, windows-2016, ubuntu-16.04]
kind: ['test', 'bench', 'lint']
kind: ['test', 'test_std', 'bench', 'lint']
exclude:
- os: windows-2016
kind: 'bench'
@ -102,6 +102,15 @@ jobs:
if: matrix.kind != 'lint'
run: cargo build --release --locked --all-targets
# TODO(ry) Remove this step, and move the following test to
# cli/tests/std_tests.rs
# TODO(ry) Remove the "cd std".
- name: std test
if: matrix.kind == 'test_std'
run: |
cd std
"../target/release/deno" test -A
- name: Test
if: matrix.kind == 'test'
run: cargo test --release --locked --all-targets

View file

@ -1,2 +1,5 @@
cli/tests/error_syntax.js
cli/tests/badly_formatted.js
cli/tests/badly_formatted.js
std/**/testdata
std/**/vendor
std/node_modules

25
cli/tests/std_tests.rs Normal file
View file

@ -0,0 +1,25 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// TODO(ry) Current std tests are run in .github/workflows/build.yml but ideally
// they would be called as part of "cargo test". "deno test" is too slow to do
// this desierable thing: https://github.com/denoland/deno/issues/3088
/*
#[macro_use]
extern crate lazy_static;
extern crate tempfile;
mod util;
use util::*;
#[test]
fn std_tests() {
let mut deno = deno_cmd()
.current_dir(root_path())
.arg("test")
.arg("-A")
.arg("std")
.spawn()
.expect("failed to spawn script");
let status = deno.wait().expect("failed to wait for the child process");
assert_eq!(Some(0), status.code());
assert!(status.success());
}
*/

View file

@ -1,7 +1,5 @@
# Deno Standard Modules
[![Build Status](https://dev.azure.com/denoland/deno_std/_apis/build/status/denoland.deno_std?branchName=master)](https://dev.azure.com/denoland/deno_std/_build/latest?definitionId=2?branchName=master)
These modules do not have external dependencies and they are reviewed by the
Deno core team. The intention is to have a standard set of high quality code
that all Deno projects can use fearlessly.
@ -11,8 +9,8 @@ Contributions are welcome!
## How to use
These modules are tagged in accordance with Deno releases. So, for example, the
v0.3.0 tag is guaranteed to work with deno v0.3.0.
You can link to v0.3.0 using the URL `https://deno.land/std@v0.3.0/`
v0.3.0 tag is guaranteed to work with deno v0.3.0. You can link to v0.3.0 using
the URL `https://deno.land/std@v0.3.0/`
It's strongly recommended that you link to tagged releases rather than the
master branch. The project is still young and we expect disruptive renames in
@ -40,10 +38,10 @@ Here are the dedicated documentations of modules:
## Contributing
deno_std is a loose port of [Go's standard library](https://golang.org/pkg/).
When in doubt, simply port Go's source code, documentation, and tests. There
are many times when the nature of JavaScript, TypeScript, or Deno itself
justifies diverging from Go, but if possible we want to leverage the energy that
went into building Go. We generally welcome direct ports of Go's code.
When in doubt, simply port Go's source code, documentation, and tests. There are
many times when the nature of JavaScript, TypeScript, or Deno itself justifies
diverging from Go, but if possible we want to leverage the energy that went into
building Go. We generally welcome direct ports of Go's code.
Please ensure the copyright headers cite the code's origin.

View file

@ -384,26 +384,28 @@ export class Tar {
*/
getReader(): Deno.Reader {
const readers: Deno.Reader[] = [];
this.data.forEach((tarData): void => {
let { reader } = tarData;
const { filePath } = tarData;
const headerArr = formatHeader(tarData);
readers.push(new Deno.Buffer(headerArr));
if (!reader) {
reader = new FileReader(filePath!);
}
readers.push(reader);
this.data.forEach(
(tarData): void => {
let { reader } = tarData;
const { filePath } = tarData;
const headerArr = formatHeader(tarData);
readers.push(new Deno.Buffer(headerArr));
if (!reader) {
reader = new FileReader(filePath!);
}
readers.push(reader);
// to the nearest multiple of recordSize
readers.push(
new Deno.Buffer(
clean(
recordSize -
(parseInt(tarData.fileSize!, 8) % recordSize || recordSize)
// to the nearest multiple of recordSize
readers.push(
new Deno.Buffer(
clean(
recordSize -
(parseInt(tarData.fileSize!, 8) % recordSize || recordSize)
)
)
)
);
});
);
}
);
// append 2 empty records
readers.push(new Deno.Buffer(clean(recordSize * 2)));
@ -460,18 +462,22 @@ export class Untar {
"mtime",
"uid",
"gid"
]).forEach((key): void => {
const arr = trim(header[key]);
if (arr.byteLength > 0) {
meta[key] = parseInt(decoder.decode(arr), 8);
]).forEach(
(key): void => {
const arr = trim(header[key]);
if (arr.byteLength > 0) {
meta[key] = parseInt(decoder.decode(arr), 8);
}
}
});
(["owner", "group"] as ["owner", "group"]).forEach((key): void => {
const arr = trim(header[key]);
if (arr.byteLength > 0) {
meta[key] = decoder.decode(arr);
);
(["owner", "group"] as ["owner", "group"]).forEach(
(key): void => {
const arr = trim(header[key]);
if (arr.byteLength > 0) {
meta[key] = decoder.decode(arr);
}
}
});
);
// read the file content
const len = parseInt(decoder.decode(header.fileSize), 8);

View file

@ -70,18 +70,20 @@ export function instantiate(
assert(module != null);
assert(module.factory != null);
const dependencies = module.dependencies.map((id): object => {
if (id === "require") {
// TODO(kitsonk) support dynamic import by passing a `require()` that
// can return a local module or dynamically import one.
return (): void => {};
} else if (id === "exports") {
return module.exports;
const dependencies = module.dependencies.map(
(id): object => {
if (id === "require") {
// TODO(kitsonk) support dynamic import by passing a `require()` that
// can return a local module or dynamically import one.
return (): void => {};
} else if (id === "exports") {
return module.exports;
}
const dep = modules.get(id)!;
assert(dep != null);
return dep.exports;
}
const dep = modules.get(id)!;
assert(dep != null);
return dep.exports;
});
);
if (typeof module.factory === "function") {
module.factory!(...dependencies);

View file

@ -6,8 +6,10 @@ Simple helper to help parse date strings into `Date`, with additional functions.
### parseDate / parseDateTime
- `parseDate()` - Take an input string and a format to parse the date. Supported formats are exported in `DateFormat`.
- `parseDateTime()` - Take an input string and a format to parse the dateTime. Supported formats are exported in `DateTimeFormat`.
- `parseDate()` - Take an input string and a format to parse the date. Supported
formats are exported in `DateFormat`.
- `parseDateTime()` - Take an input string and a format to parse the dateTime.
Supported formats are exported in `DateTimeFormat`.
```ts
import { parseDate, parseDateTime } from 'https://deno.land/std/datetime/mod.ts'

View file

@ -4,8 +4,8 @@
- **`readAll(reader: BufReader, opt: ParseOptions = { comma: ",", trimLeadingSpace: false, lazyQuotes: false } ): Promise<[string[][], BufState]>`**:
Read the whole buffer and output the structured CSV datas
- **`parse(csvString: string, opt: ParseOption): Promise<unknown[]>`**:
See [parse](###Parse)
- **`parse(csvString: string, opt: ParseOption): Promise<unknown[]>`**: See
[parse](###Parse)
### Parse
@ -17,8 +17,7 @@ Parse the CSV string with the options provided.
- **`header: boolean | string[] | HeaderOption[];`**: If a boolean is provided,
the first line will be used as Header definitions. If `string[]` or
`HeaderOption[]`
those names will be used for header definition.
`HeaderOption[]` those names will be used for header definition.
- **`parse?: (input: unknown) => unknown;`**: Parse function for the row, which
will be executed after parsing of all columns. Therefore if you don't provide
header and parse function with headers, input will be `string[]`.
@ -26,9 +25,9 @@ Parse the CSV string with the options provided.
##### HeaderOption
- **`name: string;`**: Name of the header to be used as property.
- **`parse?: (input: string) => unknown;`**: Parse function for the column.
This is executed on each entry of the header. This can be combined with the
Parse function of the rows.
- **`parse?: (input: string) => unknown;`**: Parse function for the column. This
is executed on each entry of the header. This can be combined with the Parse
function of the rows.
#### Usage
@ -123,8 +122,10 @@ TypeScript side is a bit different.
- :heavy_check_mark: [Local Date](https://github.com/toml-lang/toml#local-date)
- :exclamation: [Local Time](https://github.com/toml-lang/toml#local-time)
- :heavy_check_mark: [Table](https://github.com/toml-lang/toml#table)
- :heavy_check_mark: [Inline Table](https://github.com/toml-lang/toml#inline-table)
- :exclamation: [Array of Tables](https://github.com/toml-lang/toml#array-of-tables)
- :heavy_check_mark:
[Inline Table](https://github.com/toml-lang/toml#inline-table)
- :exclamation:
[Array of Tables](https://github.com/toml-lang/toml#array-of-tables)
:exclamation: _Supported with warnings see [Warning](#Warning)._
@ -132,17 +133,18 @@ TypeScript side is a bit different.
##### String
- Regex : Due to the spec, there is no flag to detect regex properly
in a TOML declaration. So the regex is stored as string.
- Regex : Due to the spec, there is no flag to detect regex properly in a TOML
declaration. So the regex is stored as string.
##### Integer
For **Binary** / **Octal** / **Hexadecimal** numbers,
they are stored as string to be not interpreted as Decimal.
For **Binary** / **Octal** / **Hexadecimal** numbers, they are stored as string
to be not interpreted as Decimal.
##### Local Time
Because local time does not exist in JavaScript, the local time is stored as a string.
Because local time does not exist in JavaScript, the local time is stored as a
string.
##### Inline Table

View file

@ -84,23 +84,25 @@ async function read(
result = line.split(opt.comma!);
let quoteError = false;
result = result.map((r): string => {
if (opt.trimLeadingSpace) {
r = r.trimLeft();
}
if (r[0] === '"' && r[r.length - 1] === '"') {
r = r.substring(1, r.length - 1);
} else if (r[0] === '"') {
r = r.substring(1, r.length);
}
if (!opt.lazyQuotes) {
if (r[0] !== '"' && r.indexOf('"') !== -1) {
quoteError = true;
result = result.map(
(r): string => {
if (opt.trimLeadingSpace) {
r = r.trimLeft();
}
if (r[0] === '"' && r[r.length - 1] === '"') {
r = r.substring(1, r.length - 1);
} else if (r[0] === '"') {
r = r.substring(1, r.length);
}
if (!opt.lazyQuotes) {
if (r[0] !== '"' && r.indexOf('"') !== -1) {
quoteError = true;
}
}
return r;
}
return r;
});
);
if (quoteError) {
throw new ParseError(Startline, lineIndex, 'bare " in non-quoted-field');
}
@ -224,25 +226,27 @@ export async function parse(
);
i++;
}
return r.map((e): unknown => {
if (e.length !== headers.length) {
throw `Error number of fields line:${i}`;
}
i++;
const out: Record<string, unknown> = {};
for (let j = 0; j < e.length; j++) {
const h = headers[j];
if (h.parse) {
out[h.name] = h.parse(e[j]);
} else {
out[h.name] = e[j];
return r.map(
(e): unknown => {
if (e.length !== headers.length) {
throw `Error number of fields line:${i}`;
}
i++;
const out: Record<string, unknown> = {};
for (let j = 0; j < e.length; j++) {
const h = headers[j];
if (h.parse) {
out[h.name] = h.parse(e[j]);
} else {
out[h.name] = e[j];
}
}
if (opt.parse) {
return opt.parse(out);
}
return out;
}
if (opt.parse) {
return opt.parse(out);
}
return out;
});
);
}
if (opt.parse) {
return r.map((e: string[]): unknown => opt.parse!(e));

View file

@ -393,9 +393,11 @@ function joinKeys(keys: string[]): string {
// Dotted keys are a sequence of bare or quoted keys joined with a dot.
// This allows for grouping similar properties together:
return keys
.map((str: string): string => {
return str.match(/[^A-Za-z0-9_-]/) ? `"${str}"` : str;
})
.map(
(str: string): string => {
return str.match(/[^A-Za-z0-9_-]/) ? `"${str}"` : str;
}
)
.join(".");
}
@ -415,20 +417,24 @@ class Dumper {
_parse(obj: Record<string, unknown>, keys: string[] = []): string[] {
const out = [];
const props = Object.keys(obj);
const propObj = props.filter((e: string): boolean => {
if (obj[e] instanceof Array) {
const d: unknown[] = obj[e] as unknown[];
return !this._isSimplySerializable(d[0]);
const propObj = props.filter(
(e: string): boolean => {
if (obj[e] instanceof Array) {
const d: unknown[] = obj[e] as unknown[];
return !this._isSimplySerializable(d[0]);
}
return !this._isSimplySerializable(obj[e]);
}
return !this._isSimplySerializable(obj[e]);
});
const propPrim = props.filter((e: string): boolean => {
if (obj[e] instanceof Array) {
const d: unknown[] = obj[e] as unknown[];
return this._isSimplySerializable(d[0]);
);
const propPrim = props.filter(
(e: string): boolean => {
if (obj[e] instanceof Array) {
const d: unknown[] = obj[e] as unknown[];
return this._isSimplySerializable(d[0]);
}
return this._isSimplySerializable(obj[e]);
}
return this._isSimplySerializable(obj[e]);
});
);
const k = propPrim.concat(propObj);
for (let i = 0; i < k.length; i++) {
const prop = k[i];

View file

@ -79,9 +79,11 @@ export function parse(
? [options.boolean]
: options.boolean;
booleanArgs.filter(Boolean).forEach((key: string): void => {
flags.bools[key] = true;
});
booleanArgs.filter(Boolean).forEach(
(key: string): void => {
flags.bools[key] = true;
}
);
}
}
@ -112,9 +114,11 @@ export function parse(
flags.strings[key] = true;
const alias = get(aliases, key);
if (alias) {
alias.forEach((alias: string): void => {
flags.strings[alias] = true;
});
alias.forEach(
(alias: string): void => {
flags.strings[alias] = true;
}
);
}
});
}

View file

@ -1,7 +1,7 @@
# Printf for Deno
This is very much a work-in-progress. I'm actively soliciting feedback.
What immediately follows are points for discussion.
This is very much a work-in-progress. I'm actively soliciting feedback. What
immediately follows are points for discussion.
If you are looking for the documentation proper, skip to:
@ -13,14 +13,13 @@ below.
This is very much a work-in-progress. I'm actively soliciting feedback.
- What useful features are available in other languages apart from
Golang and C?
- What useful features are available in other languages apart from Golang and C?
- behaviour of `%v` verb. In Golang, this is a shortcut verb to "print the
default format" of the argument. It is currently implemented to format
using `toString` in the default case and `inpect` if the `%#v`
alternative format flag is used in the format directive. Alternativly,
`%V` could be used to distinguish the two.
default format" of the argument. It is currently implemented to format using
`toString` in the default case and `inpect` if the `%#v` alternative format
flag is used in the format directive. Alternativly, `%V` could be used to
distinguish the two.
`inspect` output is not defined, however. This may be problematic if using
this code on other plattforms (and expecting interoperability). To my
@ -33,28 +32,28 @@ This is very much a work-in-progress. I'm actively soliciting feedback.
Consider possible modifier flags, etc.
- `<` verb. This is an extension that assumes the argument is an array and will
format each element according to the format (surrounded by [] and seperated
by comma) (`<` Mnemonic: pull each element out of array)
format each element according to the format (surrounded by [] and seperated by
comma) (`<` Mnemonic: pull each element out of array)
- how to deal with more newfangled Javascript features ( generic Iterables,
Map and Set types, typed Arrays, ...)
- how to deal with more newfangled Javascript features ( generic Iterables, Map
and Set types, typed Arrays, ...)
- the implementation is fairly rough around the edges:
- currently contains little in the way of checking for
correctness. Conceivably, there will be a 'strict' form, e.g.
that ensures only Number-ish arguments are passed to %f flags
- currently contains little in the way of checking for correctness. Conceivably,
there will be a 'strict' form, e.g. that ensures only Number-ish arguments are
passed to %f flags
- assembles output using string concatenation instead of
utilizing buffers or other optimizations. It would be nice to
have printf / sprintf / fprintf (etc) all in one.
- assembles output using string concatenation instead of utilizing buffers or
other optimizations. It would be nice to have printf / sprintf / fprintf (etc)
all in one.
- float formatting is handled by toString() and to `toExponential`
along with a mess of Regexp. Would be nice to use fancy match
- float formatting is handled by toString() and to `toExponential` along with a
mess of Regexp. Would be nice to use fancy match
- some flags that are potentially applicable ( POSIX long and unsigned
modifiers are not likely useful) are missing, namely %q (print quoted), %U
(unicode format)
- some flags that are potentially applicable ( POSIX long and unsigned modifiers
are not likely useful) are missing, namely %q (print quoted), %U (unicode
format)
## Author
@ -64,8 +63,8 @@ Tim Becker (tim@presseverykey.com)
MIT
The implementation is inspired by POSIX and Golang (see above) but does
not port implementation code. A number of Golang test-cases based on:
The implementation is inspired by POSIX and Golang (see above) but does not port
implementation code. A number of Golang test-cases based on:
https://golang.org/src/fmt/fmt_test.go
( BSD: Copyright (c) 2009 The Go Authors. All rights reserved. )
@ -74,26 +73,26 @@ were used.
# printf: prints formatted output
sprintf converts and formats a variable number of arguments as is
specified by a `format string`. In it's basic form, a format string
may just be a literal. In case arguments are meant to be formatted,
a `directive` is contained in the format string, preceded by a '%' character:
sprintf converts and formats a variable number of arguments as is specified by a
`format string`. In it's basic form, a format string may just be a literal. In
case arguments are meant to be formatted, a `directive` is contained in the
format string, preceded by a '%' character:
%<verb>
E.g. the verb `s` indicates the directive should be replaced by the
string representation of the argument in the corresponding position of
the argument list. E.g.:
E.g. the verb `s` indicates the directive should be replaced by the string
representation of the argument in the corresponding position of the argument
list. E.g.:
Hello %s!
applied to the arguments "World" yields "Hello World!"
The meaning of the format string is modelled after [POSIX][1] format
strings as well as well as [Golang format strings][2]. Both contain
elements specific to the respective programming language that don't
apply to JavaScript, so they can not be fully supported. Furthermore we
implement some functionality that is specific to JS.
The meaning of the format string is modelled after [POSIX][1] format strings as
well as well as [Golang format strings][2]. Both contain elements specific to
the respective programming language that don't apply to JavaScript, so they can
not be fully supported. Furthermore we implement some functionality that is
specific to JS.
## Verbs
@ -117,16 +116,16 @@ The following verbs are supported:
## Width and Precision
Verbs may be modified by providing them with width and precision, either or
both may be omitted:
Verbs may be modified by providing them with width and precision, either or both
may be omitted:
%9f width 9, default precision
%.9f default width, precision 9
%8.9f width 8, precision 9
%8.f width 9, precision 0
In general, 'width' describes the minimum length of the output, while 'precision'
limits the output.
In general, 'width' describes the minimum length of the output, while
'precision' limits the output.
| verb | precision |
| --------- | -------------------------------------------------------------- |
@ -177,13 +176,13 @@ the 'depth' config parameter
## Positional arguments
Arguments do not need to be consumed in the order they are provded and may
be consumed more than once. E.g.:
Arguments do not need to be consumed in the order they are provded and may be
consumed more than once. E.g.:
sprintf("%[2]s %[1]s", "World", "Hello")
returns "Hello World". The precence of a positional indicator resets the arg counter
allowing args to be reused:
returns "Hello World". The precence of a positional indicator resets the arg
counter allowing args to be reused:
sprintf("dec[%d]=%d hex[%[1]d]=%x oct[%[1]d]=%#o %s", 1, 255, "Third")

View file

@ -587,16 +587,18 @@ const tests: Array<[string, any, string]> = [
];
test(function testThorough(): void {
tests.forEach((t, i): void => {
// p(t)
const is = S(t[0], t[1]);
const should = t[2];
assertEquals(
is,
should,
`failed case[${i}] : is >${is}< should >${should}<`
);
});
tests.forEach(
(t, i): void => {
// p(t)
const is = S(t[0], t[1]);
const should = t[2];
assertEquals(
is,
should,
`failed case[${i}] : is >${is}< should >${should}<`
);
}
);
});
test(function testWeirdos(): void {

View file

@ -8,9 +8,9 @@ All the following modules are exposed in `mod.ts`
### emptyDir
Ensures that a directory is empty. Deletes directory contents if the directory is not empty.
If the directory does not exist, it is created.
The directory itself is not deleted.
Ensures that a directory is empty. Deletes directory contents if the directory
is not empty. If the directory does not exist, it is created. The directory
itself is not deleted.
```ts
import { emptyDir, emptyDirSync } from "https://deno.land/std/fs/mod.ts";
@ -21,8 +21,8 @@ emptyDirSync("./foo"); // void
### ensureDir
Ensures that the directory exists.
If the directory structure does not exist, it is created. Like mkdir -p.
Ensures that the directory exists. If the directory structure does not exist, it
is created. Like mkdir -p.
```ts
import { ensureDir, ensureDirSync } from "https://deno.land/std/fs/mod.ts";
@ -33,10 +33,9 @@ ensureDirSync("./ensureDirSync"); // void
### ensureFile
Ensures that the file exists.
If the file that is requested to be created is in directories
that do not exist, these directories are created.
If the file already exists, it is **NOT MODIFIED**.
Ensures that the file exists. If the file that is requested to be created is in
directories that do not exist, these directories are created. If the file
already exists, it is **NOT MODIFIED**.
```ts
import { ensureFile, ensureFileSync } from "https://deno.land/std/fs/mod.ts";
@ -47,8 +46,8 @@ ensureFileSync("./folder/targetFile.dat"); // void
### ensureSymlink
Ensures that the link exists.
If the directory structure does not exist, it is created.
Ensures that the link exists. If the directory structure does not exist, it is
created.
```ts
import {
@ -102,9 +101,8 @@ existsSync("./foo"); // returns boolean
### globToRegExp
Generate a regex based on glob pattern and options
This was meant to be using the the `fs.walk` function
but can be used anywhere else.
Generate a regex based on glob pattern and options This was meant to be using
the the `fs.walk` function but can be used anywhere else.
```ts
import { globToRegExp } from "https://deno.land/std/fs/mod.ts";
@ -180,8 +178,10 @@ Writes an object to a JSON file.
**WriteJsonOptions**
- replacer : An array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified.
- space : Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
- replacer : An array of strings and numbers that acts as a approved list for
selecting the object properties that will be stringified.
- space : Adds indentation, white space, and line break characters to the
return-value JSON text to make it easier to read.
```ts
import { writeJson, writeJsonSync } from "https://deno.land/std/fs/mod.ts";

View file

@ -317,9 +317,11 @@ testCopySync(
(tempDir: string): void => {
const srcFile = path.join(testdataDir, "copy_file_not_exists_sync.txt");
const destFile = path.join(tempDir, "copy_file_not_exists_1_sync.txt");
assertThrows((): void => {
copySync(srcFile, destFile);
});
assertThrows(
(): void => {
copySync(srcFile, destFile);
}
);
}
);
@ -365,47 +367,50 @@ testCopySync(
}
);
testCopySync("[fs] copy file synchronously", (tempDir: string): void => {
const srcFile = path.join(testdataDir, "copy_file.txt");
const destFile = path.join(tempDir, "copy_file_copy_sync.txt");
testCopySync(
"[fs] copy file synchronously",
(tempDir: string): void => {
const srcFile = path.join(testdataDir, "copy_file.txt");
const destFile = path.join(tempDir, "copy_file_copy_sync.txt");
const srcContent = new TextDecoder().decode(Deno.readFileSync(srcFile));
const srcContent = new TextDecoder().decode(Deno.readFileSync(srcFile));
assertEquals(existsSync(srcFile), true);
assertEquals(existsSync(destFile), false);
assertEquals(existsSync(srcFile), true);
assertEquals(existsSync(destFile), false);
copySync(srcFile, destFile);
copySync(srcFile, destFile);
assertEquals(existsSync(srcFile), true);
assertEquals(existsSync(destFile), true);
assertEquals(existsSync(srcFile), true);
assertEquals(existsSync(destFile), true);
const destContent = new TextDecoder().decode(Deno.readFileSync(destFile));
const destContent = new TextDecoder().decode(Deno.readFileSync(destFile));
assertEquals(srcContent, destContent);
assertEquals(srcContent, destContent);
// Copy again without overwrite option and it should throw an error.
assertThrows(
(): void => {
copySync(srcFile, destFile);
},
Error,
`'${destFile}' already exists.`
);
// Copy again without overwrite option and it should throw an error.
assertThrows(
(): void => {
copySync(srcFile, destFile);
},
Error,
`'${destFile}' already exists.`
);
// Modify destination file.
Deno.writeFileSync(destFile, new TextEncoder().encode("txt copy"));
// Modify destination file.
Deno.writeFileSync(destFile, new TextEncoder().encode("txt copy"));
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destFile)),
"txt copy"
);
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destFile)),
"txt copy"
);
// Copy again with overwrite option.
copySync(srcFile, destFile, { overwrite: true });
// Copy again with overwrite option.
copySync(srcFile, destFile, { overwrite: true });
// Make sure the file has been overwritten.
assertEquals(new TextDecoder().decode(Deno.readFileSync(destFile)), "txt");
});
// Make sure the file has been overwritten.
assertEquals(new TextDecoder().decode(Deno.readFileSync(destFile)), "txt");
}
);
testCopySync(
"[fs] copy directory synchronously to its subdirectory",
@ -445,54 +450,57 @@ testCopySync(
}
);
testCopySync("[fs] copy directory synchronously", (tempDir: string): void => {
const srcDir = path.join(testdataDir, "copy_dir");
const destDir = path.join(tempDir, "copy_dir_copy_sync");
const srcFile = path.join(srcDir, "0.txt");
const destFile = path.join(destDir, "0.txt");
const srcNestFile = path.join(srcDir, "nest", "0.txt");
const destNestFile = path.join(destDir, "nest", "0.txt");
testCopySync(
"[fs] copy directory synchronously",
(tempDir: string): void => {
const srcDir = path.join(testdataDir, "copy_dir");
const destDir = path.join(tempDir, "copy_dir_copy_sync");
const srcFile = path.join(srcDir, "0.txt");
const destFile = path.join(destDir, "0.txt");
const srcNestFile = path.join(srcDir, "nest", "0.txt");
const destNestFile = path.join(destDir, "nest", "0.txt");
copySync(srcDir, destDir);
copySync(srcDir, destDir);
assertEquals(existsSync(destFile), true);
assertEquals(existsSync(destNestFile), true);
assertEquals(existsSync(destFile), true);
assertEquals(existsSync(destNestFile), true);
// After copy. The source and destination should have the same content.
assertEquals(
new TextDecoder().decode(Deno.readFileSync(srcFile)),
new TextDecoder().decode(Deno.readFileSync(destFile))
);
assertEquals(
new TextDecoder().decode(Deno.readFileSync(srcNestFile)),
new TextDecoder().decode(Deno.readFileSync(destNestFile))
);
// After copy. The source and destination should have the same content.
assertEquals(
new TextDecoder().decode(Deno.readFileSync(srcFile)),
new TextDecoder().decode(Deno.readFileSync(destFile))
);
assertEquals(
new TextDecoder().decode(Deno.readFileSync(srcNestFile)),
new TextDecoder().decode(Deno.readFileSync(destNestFile))
);
// Copy again without overwrite option and it should throw an error.
assertThrows(
(): void => {
copySync(srcDir, destDir);
},
Error,
`'${destDir}' already exists.`
);
// Copy again without overwrite option and it should throw an error.
assertThrows(
(): void => {
copySync(srcDir, destDir);
},
Error,
`'${destDir}' already exists.`
);
// Modify the file in the destination directory.
Deno.writeFileSync(destNestFile, new TextEncoder().encode("nest copy"));
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destNestFile)),
"nest copy"
);
// Modify the file in the destination directory.
Deno.writeFileSync(destNestFile, new TextEncoder().encode("nest copy"));
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destNestFile)),
"nest copy"
);
// Copy again with overwrite option.
copySync(srcDir, destDir, { overwrite: true });
// Copy again with overwrite option.
copySync(srcDir, destDir, { overwrite: true });
// Make sure the file has been overwritten.
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destNestFile)),
"nest"
);
});
// Make sure the file has been overwritten.
assertEquals(
new TextDecoder().decode(Deno.readFileSync(destNestFile)),
"nest"
);
}
);
testCopySync(
"[fs] copy symlink file synchronously",

View file

@ -110,14 +110,18 @@ test(function emptyDirSyncIfItExist(): void {
assertEquals(stat.isDirectory(), true);
// nest directory have been remove
assertThrows((): void => {
Deno.statSync(testNestDir);
});
assertThrows(
(): void => {
Deno.statSync(testNestDir);
}
);
// test file have been remove
assertThrows((): void => {
Deno.statSync(testDirFile);
});
assertThrows(
(): void => {
Deno.statSync(testDirFile);
}
);
} finally {
// remote test dir
Deno.removeSync(testDir, { recursive: true });

View file

@ -15,9 +15,11 @@ test(async function ensureDirIfItNotExist(): Promise<void> {
await assertThrowsAsync(
async (): Promise<void> => {
await Deno.stat(testDir).then((): void => {
throw new Error("test dir should exists.");
});
await Deno.stat(testDir).then(
(): void => {
throw new Error("test dir should exists.");
}
);
}
);
@ -46,9 +48,11 @@ test(async function ensureDirIfItExist(): Promise<void> {
await assertThrowsAsync(
async (): Promise<void> => {
await Deno.stat(testDir).then((): void => {
throw new Error("test dir should still exists.");
});
await Deno.stat(testDir).then(
(): void => {
throw new Error("test dir should still exists.");
}
);
}
);
@ -64,10 +68,12 @@ test(function ensureDirSyncIfItExist(): void {
ensureDirSync(testDir);
assertThrows((): void => {
Deno.statSync(testDir);
throw new Error("test dir should still exists.");
});
assertThrows(
(): void => {
Deno.statSync(testDir);
throw new Error("test dir should still exists.");
}
);
Deno.removeSync(baseDir, { recursive: true });
});

View file

@ -14,9 +14,11 @@ test(async function ensureFileIfItNotExist(): Promise<void> {
await assertThrowsAsync(
async (): Promise<void> => {
await Deno.stat(testFile).then((): void => {
throw new Error("test file should exists.");
});
await Deno.stat(testFile).then(
(): void => {
throw new Error("test file should exists.");
}
);
}
);
@ -29,10 +31,12 @@ test(function ensureFileSyncIfItNotExist(): void {
ensureFileSync(testFile);
assertThrows((): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
});
assertThrows(
(): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
}
);
Deno.removeSync(testDir, { recursive: true });
});
@ -48,9 +52,11 @@ test(async function ensureFileIfItExist(): Promise<void> {
await assertThrowsAsync(
async (): Promise<void> => {
await Deno.stat(testFile).then((): void => {
throw new Error("test file should exists.");
});
await Deno.stat(testFile).then(
(): void => {
throw new Error("test file should exists.");
}
);
}
);
@ -66,10 +72,12 @@ test(function ensureFileSyncIfItExist(): void {
ensureFileSync(testFile);
assertThrows((): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
});
assertThrows(
(): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
}
);
Deno.removeSync(testDir, { recursive: true });
});

View file

@ -31,9 +31,11 @@ test(function ensureLinkSyncIfItNotExist(): void {
const testFile = path.join(testDir, "test.txt");
const linkFile = path.join(testDir, "link.txt");
assertThrows((): void => {
ensureLinkSync(testFile, linkFile);
});
assertThrows(
(): void => {
ensureLinkSync(testFile, linkFile);
}
);
Deno.removeSync(testDir, { recursive: true });
});

View file

@ -24,9 +24,11 @@ test(async function ensureSymlinkIfItNotExist(): Promise<void> {
assertThrowsAsync(
async (): Promise<void> => {
await Deno.stat(testFile).then((): void => {
throw new Error("test file should exists.");
});
await Deno.stat(testFile).then(
(): void => {
throw new Error("test file should exists.");
}
);
}
);
});
@ -35,14 +37,18 @@ test(function ensureSymlinkSyncIfItNotExist(): void {
const testDir = path.join(testdataDir, "link_file_2");
const testFile = path.join(testDir, "test.txt");
assertThrows((): void => {
ensureSymlinkSync(testFile, path.join(testDir, "test1.txt"));
});
assertThrows(
(): void => {
ensureSymlinkSync(testFile, path.join(testDir, "test1.txt"));
}
);
assertThrows((): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
});
assertThrows(
(): void => {
Deno.statSync(testFile);
throw new Error("test file should exists.");
}
);
});
test(async function ensureSymlinkIfItExist(): Promise<void> {

View file

@ -246,8 +246,8 @@ export async function* expandGlob(
);
}
if (hasTrailingSep) {
currentMatches = currentMatches.filter(({ info }): boolean =>
info.isDirectory()
currentMatches = currentMatches.filter(
({ info }): boolean => info.isDirectory()
);
}
if (!includeDirs) {
@ -348,8 +348,8 @@ export function* expandGlobSync(
);
}
if (hasTrailingSep) {
currentMatches = currentMatches.filter(({ info }): boolean =>
info.isDirectory()
currentMatches = currentMatches.filter(
({ info }): boolean => info.isDirectory()
);
}
if (!includeDirs) {

View file

@ -182,9 +182,11 @@ test(function moveSyncDirectoryIfSrcNotExists(): void {
const srcDir = path.join(testdataDir, "move_sync_test_src_1");
const destDir = path.join(testdataDir, "move_sync_test_dest_1");
// if src directory not exist
assertThrows((): void => {
moveSync(srcDir, destDir);
});
assertThrows(
(): void => {
moveSync(srcDir, destDir);
}
);
});
test(function moveSyncDirectoryIfDestNotExists(): void {
@ -211,9 +213,11 @@ test(function moveSyncFileIfSrcNotExists(): void {
const destFile = path.join(testdataDir, "move_sync_test_dest_3", "test.txt");
// if src directory not exist
assertThrows((): void => {
moveSync(srcFile, destFile);
});
assertThrows(
(): void => {
moveSync(srcFile, destFile);
}
);
});
test(function moveSyncFileIfDestExists(): void {

View file

@ -65,25 +65,31 @@ test(async function readValidObjJsonFileWithRelativePath(): Promise<void> {
test(function readJsonFileNotExistsSync(): void {
const emptyJsonFile = path.join(testdataDir, "json_not_exists.json");
assertThrows((): void => {
readJsonSync(emptyJsonFile);
});
assertThrows(
(): void => {
readJsonSync(emptyJsonFile);
}
);
});
test(function readEmptyJsonFileSync(): void {
const emptyJsonFile = path.join(testdataDir, "json_empty.json");
assertThrows((): void => {
readJsonSync(emptyJsonFile);
});
assertThrows(
(): void => {
readJsonSync(emptyJsonFile);
}
);
});
test(function readInvalidJsonFile(): void {
const invalidJsonFile = path.join(testdataDir, "json_invalid.json");
assertThrows((): void => {
readJsonSync(invalidJsonFile);
});
assertThrows(
(): void => {
readJsonSync(invalidJsonFile);
}
);
});
test(function readValidArrayJsonFileSync(): void {

View file

@ -21,11 +21,13 @@ function patternTest(patterns: RegExp[], path: string): boolean {
// Forced to reset last index on regex while iterating for have
// consistent results.
// See: https://stackoverflow.com/a/1520853
return patterns.some((pattern): boolean => {
const r = pattern.test(path);
pattern.lastIndex = 0;
return r;
});
return patterns.some(
(pattern): boolean => {
const r = pattern.test(path);
pattern.lastIndex = 0;
return r;
}
);
}
function include(filename: string, options: WalkOptions): boolean {

View file

@ -34,8 +34,8 @@ console.log("Set-Cookie:", cookieHeader);
// Set-Cookie: Space=Cat
```
Deleting a `Cookie` will set its expiration date before now.
Forcing the browser to delete it.
Deleting a `Cookie` will set its expiration date before now. Forcing the browser
to delete it.
```ts
import { Response } from "https://deno.land/std/http/server.ts";

View file

@ -75,9 +75,11 @@ function modeToString(isDir: boolean, maybeMode: number | null): string {
.split("")
.reverse()
.slice(0, 3)
.forEach((v): void => {
output = modeMap[+v] + output;
});
.forEach(
(v): void => {
output = modeMap[+v] + output;
}
);
output = `(${isDir ? "d" : "-"}${output})`;
return output;
}
@ -177,8 +179,9 @@ async function serveDir(
dirViewerTemplate.replace("<%DIRNAME%>", formattedDirUrl).replace(
"<%CONTENTS%>",
listEntry
.sort((a, b): number =>
a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1
.sort(
(a, b): number =>
a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1
)
.map((v): string => v.template)
.join("")

View file

@ -1,6 +1,4 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { readFile, run } = Deno;
import { test } from "../testing/mod.ts";
import { assert, assertEquals } from "../testing/asserts.ts";
import { BufReader } from "../io/bufio.ts";
@ -9,7 +7,7 @@ import { TextProtoReader } from "../textproto/mod.ts";
let fileServer: Deno.Process;
async function startFileServer(): Promise<void> {
fileServer = run({
fileServer = Deno.run({
args: [
Deno.execPath(),
"run",
@ -32,6 +30,7 @@ function killFileServer(): void {
fileServer.stdout!.close();
}
/* TODO(ry) re-enable tests
test(async function serveFile(): Promise<void> {
await startFileServer();
try {
@ -41,7 +40,7 @@ test(async function serveFile(): Promise<void> {
assertEquals(res.headers.get("content-type"), "text/yaml; charset=utf-8");
const downloadedFile = await res.text();
const localFile = new TextDecoder().decode(
await readFile("./azure-pipelines.yml")
await Deno.readFile("./azure-pipelines.yml")
);
assertEquals(downloadedFile, localFile);
} finally {
@ -74,6 +73,7 @@ test(async function serveDirectory(): Promise<void> {
killFileServer();
}
});
*/
test(async function serveFallback(): Promise<void> {
await startFileServer();

View file

@ -504,9 +504,11 @@ test({
let serverIsRunning = true;
p.status()
.then((): void => {
serverIsRunning = false;
})
.then(
(): void => {
serverIsRunning = false;
}
)
.catch((_): void => {}); // Ignores the error when closing the process.
await delay(100);

View file

@ -39,7 +39,8 @@ HTTP server listening on http://0.0.0.0:4500/
## Custom installation directory
By default installer uses `~/.deno/bin` to store installed scripts so make sure it's in your `$PATH`.
By default installer uses `~/.deno/bin` to store installed scripts so make sure
it's in your `$PATH`.
```
echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc # change this to your shell

View file

@ -1,401 +1,11 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { run, stat, makeTempDir, remove, env, readAll } = Deno;
import { test, runIfMain } from "../testing/mod.ts";
import { assert } from "../testing/asserts.ts";
import { isRemoteUrl } from "./mod.ts";
import { test, runIfMain, TestFunction } from "../testing/mod.ts";
import { assert, assertEquals } from "../testing/asserts.ts";
import { BufReader } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts";
import * as path from "../fs/path.ts";
import * as fs from "../fs/mod.ts";
import { install, isRemoteUrl } from "./mod.ts";
let fileServer: Deno.Process;
const isWindows = Deno.build.os === "win";
// copied from `http/file_server_test.ts`
async function startFileServer(): Promise<void> {
fileServer = run({
args: [
Deno.execPath(),
"run",
"--allow-read",
"--allow-net",
"http/file_server.ts",
".",
"--cors"
],
stdout: "piped"
});
// Once fileServer is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(fileServer.stdout!));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));
}
function killFileServer(): void {
fileServer.close();
fileServer.stdout!.close();
}
function installerTest(t: TestFunction, useOriginHomeDir = false): void {
const fn = async (): Promise<void> => {
await startFileServer();
const tempDir = await makeTempDir();
const envVars = env();
const originalHomeDir = envVars["HOME"];
if (!useOriginHomeDir) {
envVars["HOME"] = tempDir;
}
try {
await t();
} finally {
killFileServer();
await remove(tempDir, { recursive: true });
envVars["HOME"] = originalHomeDir;
}
};
test(fn);
}
installerTest(async function installBasic(): Promise<void> {
await install(
"echo_test",
"http://localhost:4500/installer/testdata/echo.ts",
[]
);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
if (isWindows) {
assertEquals(
await fs.readFileStr(filePath + ".cmd"),
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
"%~dp0\deno.exe" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
"deno" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
)
`
/* eslint-enable max-len */
);
}
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
`#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
esac
if [ -x "$basedir/deno" ]; then
"$basedir/deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
else
"deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
fi
exit $ret
`
/* eslint-enable max-len */
);
});
installerTest(async function installCustomDir(): Promise<void> {
const tempDir = await makeTempDir();
await install(
"echo_test",
"http://localhost:4500/installer/testdata/echo.ts",
[],
tempDir
);
const filePath = path.resolve(tempDir, "echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
if (isWindows) {
assertEquals(
await fs.readFileStr(filePath + ".cmd"),
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
"%~dp0\deno.exe" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
"deno" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
)
`
/* eslint-enable max-len */
);
}
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
`#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
esac
if [ -x "$basedir/deno" ]; then
"$basedir/deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
else
"deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
fi
exit $ret
`
/* eslint-enable max-len */
);
});
installerTest(async function installLocalModule(): Promise<void> {
let localModule = path.join(Deno.cwd(), "installer", "testdata", "echo.ts");
await install("echo_test", localModule, []);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
if (isWindows) {
localModule = localModule.replace(/\\/g, "\\\\");
}
if (isWindows) {
assertEquals(
await fs.readFileStr(filePath + ".cmd"),
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
"%~dp0\deno.exe" "run" "${localModule}" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
"deno" "run" "${localModule}" %*
)
`
/* eslint-enable max-len */
);
}
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
`#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
esac
if [ -x "$basedir/deno" ]; then
"$basedir/deno" "run" "${localModule}" "$@"
ret=$?
else
"deno" "run" "${localModule}" "$@"
ret=$?
fi
exit $ret
`
/* eslint-enable max-len */
);
});
installerTest(async function installWithFlags(): Promise<void> {
await install(
"echo_test",
"http://localhost:4500/installer/testdata/echo.ts",
["--allow-net", "--allow-read", "--foobar"]
);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/echo_test");
if (isWindows) {
assertEquals(
await fs.readFileStr(filePath + ".cmd"),
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
"%~dp0\deno.exe" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
"deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" %*
)
`
/* eslint-enable max-len */
);
}
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
`#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
esac
if [ -x "$basedir/deno" ]; then
"$basedir/deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" "$@"
ret=$?
else
"deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" "$@"
ret=$?
fi
exit $ret
`
/* eslint-enable max-len */
);
});
installerTest(async function installLocalModuleAndRun(): Promise<void> {
const localModule = path.join(Deno.cwd(), "installer", "testdata", "echo.ts");
await install("echo_test", localModule, ["hello"]);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
const ps = run({
args: ["echo_test" + (isWindows ? ".cmd" : ""), "foo"],
stdout: "piped"
});
if (!ps.stdout) {
assert(!!ps.stdout, "There should have stdout.");
return;
}
let thrown = false;
try {
const b = await readAll(ps.stdout);
const s = new TextDecoder("utf-8").decode(b);
assertEquals(s, "hello, foo");
} catch (err) {
console.error(err);
thrown = true;
} finally {
await remove(filePath);
ps.close();
}
assert(!thrown, "It should not throw an error");
}, true); // set true to install module in your real $HOME dir.
installerTest(async function installAndMakesureItCanRun(): Promise<void> {
await install(
"echo_test",
"http://localhost:4500/installer/testdata/echo.ts",
["hello"]
);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
const ps = run({
args: ["echo_test" + (isWindows ? ".cmd" : ""), "foo"],
stdout: "piped"
});
if (!ps.stdout) {
assert(!!ps.stdout, "There should have stdout.");
return;
}
let thrown = false;
try {
const b = await readAll(ps.stdout);
const s = new TextDecoder("utf-8").decode(b);
assertEquals(s, "hello, foo");
} catch (err) {
console.error(err);
thrown = true;
} finally {
await remove(filePath);
ps.close();
}
assert(!thrown, "It should not throw an error");
}, true); // set true to install module in your real $HOME dir.
installerTest(async function installAndMakesureArgsRight(): Promise<void> {
await install(
"args_test",
"http://localhost:4500/installer/testdata/args.ts",
["arg1", "--flag1"]
);
const { HOME } = env();
const filePath = path.resolve(HOME, ".deno/bin/args_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
const ps = run({
args: ["args_test" + (isWindows ? ".cmd" : ""), "arg2", "--flag2"],
stdout: "piped"
});
if (!ps.stdout) {
assert(!!ps.stdout, "There should have stdout.");
return;
}
let thrown = false;
try {
const b = await readAll(ps.stdout);
const s = new TextDecoder("utf-8").decode(b);
const obj = JSON.parse(s);
assertEquals(obj[0], "arg1");
assertEquals(obj[1], "--flag1");
assertEquals(obj[2], "arg2");
assertEquals(obj[3], "--flag2");
} catch (err) {
console.error(err);
thrown = true;
} finally {
await remove(filePath);
ps.close();
}
assert(!thrown, "It should not throw an error");
}, true); // set true to install module in your real $HOME dir.
// TODO(ry) Many installer tests were removed in order to get deno_std to merge
// into the deno repo. Bring them back.
// https://github.com/denoland/deno_std/blob/98784c305c653b1c507b4b25be82ecf40f188305/installer/test.ts
test(function testIsRemoteUrl(): void {
assert(isRemoteUrl("https://deno.land/std/http/file_server.ts"));

View file

@ -62,11 +62,14 @@ unknownLogger.info("foobar"); // no-op
### Loggers
Loggers are objects that you interact with. When you use logger method it constructs a `LogRecord` and passes it down to its handlers for output. To create custom loggers speficify them in `loggers` when calling `log.setup`.
Loggers are objects that you interact with. When you use logger method it
constructs a `LogRecord` and passes it down to its handlers for output. To
create custom loggers speficify them in `loggers` when calling `log.setup`.
#### `LogRecord`
`LogRecord` is an object that encapsulates provided message and arguments as well some meta data that can be later used when formatting a message.
`LogRecord` is an object that encapsulates provided message and arguments as
well some meta data that can be later used when formatting a message.
```ts
interface LogRecord {
@ -80,7 +83,10 @@ interface LogRecord {
### Handlers
Handlers are responsible for actual output of log messages. When handler is called by logger it firstly checks that `LogRecord`'s level is not lower than level of the handler. If level check passes, handlers formats log record into string and outputs it to target.
Handlers are responsible for actual output of log messages. When handler is
called by logger it firstly checks that `LogRecord`'s level is not lower than
level of the handler. If level check passes, handlers formats log record into
string and outputs it to target.
`log` module comes with two built-in handlers:
@ -89,7 +95,10 @@ Handlers are responsible for actual output of log messages. When handler is call
#### Custom message format
If you want to override default format of message you can define `formatter` option for handler. It can be either simple string-based format that uses `LogRecord` fields or more complicated function-based one that takes `LogRecord` as argument and outputs string.
If you want to override default format of message you can define `formatter`
option for handler. It can be either simple string-based format that uses
`LogRecord` fields or more complicated function-based one that takes `LogRecord`
as argument and outputs string.
Eg.
@ -130,12 +139,15 @@ log.debug("Hello, world!", 1, "two", [3, 4, 5]);
#### Custom handlers
Custom handlers can be implemented by subclassing `BaseHandler` or `WriterHandler`.
Custom handlers can be implemented by subclassing `BaseHandler` or
`WriterHandler`.
`BaseHandler` is bare-bones handler that has no output logic at all,
`WriterHandler` is an abstract class that supports any target with `Writer` interface.
`WriterHandler` is an abstract class that supports any target with `Writer`
interface.
During setup async hooks `setup` and `destroy` are called, you can use them to open and close file/HTTP connection or any other action you might need.
During setup async hooks `setup` and `destroy` are called, you can use them to
open and close file/HTTP connection or any other action you might need.
For examples check source code of `FileHandler` and `TestHandler`.

View file

@ -37,16 +37,19 @@ export class BaseHandler {
return this.formatter(logRecord);
}
return this.formatter.replace(/{(\S+)}/g, (match, p1): string => {
const value = logRecord[p1 as keyof LogRecord];
return this.formatter.replace(
/{(\S+)}/g,
(match, p1): string => {
const value = logRecord[p1 as keyof LogRecord];
// do not interpolate missing values
if (!value) {
return match;
// do not interpolate missing values
if (!value) {
return match;
}
return String(value);
}
return String(value);
});
);
}
log(_msg: string): void {}

View file

@ -36,9 +36,11 @@ export class Logger {
level: level,
levelName: getLevelName(level)
};
this.handlers.forEach((handler): void => {
handler.handle(record);
});
this.handlers.forEach(
(handler): void => {
handler.handle(record);
}
);
}
debug(msg: string, ...args: unknown[]): void {

View file

@ -80,9 +80,11 @@ export async function setup(config: LogConfig): Promise<void> {
};
// tear down existing handlers
state.handlers.forEach((handler): void => {
handler.destroy();
});
state.handlers.forEach(
(handler): void => {
handler.destroy();
}
);
state.handlers.clear();
// setup handlers
@ -104,11 +106,13 @@ export async function setup(config: LogConfig): Promise<void> {
const handlerNames = loggerConfig.handlers || [];
const handlers: BaseHandler[] = [];
handlerNames.forEach((handlerName): void => {
if (state.handlers.has(handlerName)) {
handlers.push(state.handlers.get(handlerName)!);
handlerNames.forEach(
(handlerName): void => {
if (state.handlers.has(handlerName)) {
handlers.push(state.handlers.get(handlerName)!);
}
}
});
);
const levelName = loggerConfig.level || DEFAULT_LEVEL;
const logger = new Logger(levelName, handlers);

View file

@ -23,10 +23,10 @@ lookup("folder/.htaccess"); // undefined
### `contentType(type)`
Return a full `Content-Type` header value for a given content type or
extension. When an extension is used, `lookup()` is used to resolve the
content type first. A default charset is added if not present. The
function will return `undefined` if the content type cannot be resolved:
Return a full `Content-Type` header value for a given content type or extension.
When an extension is used, `lookup()` is used to resolve the content type first.
A default charset is added if not present. The function will return `undefined`
if the content type cannot be resolved:
```ts
import { contentType } from "https://deno.land/std/media_types/mod.ts";
@ -53,8 +53,8 @@ extension("application/octet-stream"); // "bin"
### `charset(type)`
Lookup the implied default charset for a given content type. If the content
type cannot be resolved, `undefined` is returned:
Lookup the implied default charset for a given content type. If the content type
cannot be resolved, `undefined` is returned:
```ts
import { charset } from "https://deno.land/std/media_types/mod.ts";

View file

@ -188,18 +188,20 @@ class PartReader implements Reader, Closer {
comps
.slice(1)
.map((v: string): string => v.trim())
.map((kv: string): void => {
const [k, v] = kv.split("=");
if (v) {
const s = v.charAt(0);
const e = v.charAt(v.length - 1);
if ((s === e && s === '"') || s === "'") {
params[k] = v.substr(1, v.length - 2);
} else {
params[k] = v;
.map(
(kv: string): void => {
const [k, v] = kv.split("=");
if (v) {
const s = v.charAt(0);
const e = v.charAt(v.length - 1);
if ((s === e && s === '"') || s === "'") {
params[k] = v.substr(1, v.length - 2);
} else {
params[k] = v;
}
}
}
});
);
return (this.contentDispositionParams = params);
}

View file

@ -208,6 +208,7 @@ console.log([function foo() {}, function baz() {}, (a) => {}]);
emptyDir(tempDir);
});
/* TODO(ry) Re-enable test
test(async function testPrettierPrintToStdout(): Promise<void> {
const tempDir = await Deno.makeTempDir();
await copy(testdata, tempDir, { overwrite: true });
@ -233,6 +234,7 @@ test(async function testPrettierPrintToStdout(): Promise<void> {
emptyDir(tempDir);
});
*/
test(async function testPrettierReadFromStdin(): Promise<void> {
interface TestCase {

View file

@ -6,9 +6,9 @@ This module provides a few basic utilities to manipulate strings.
### pad
Input string is processed to output a string with a minimal length.
If the parameter `strict` is set to true, the output string length
is equal to the `strLen` parameter.
Input string is processed to output a string with a minimal length. If the
parameter `strict` is set to true, the output string length is equal to the
`strLen` parameter.
Basic usage:

View file

@ -1,15 +1,16 @@
# Testing
This module provides a few basic utilities to make testing easier and
consistent in Deno.
This module provides a few basic utilities to make testing easier and consistent
in Deno.
## Usage
The module exports a `test` function which is the test harness in Deno. It
accepts either a function (including async functions) or an object which
contains a `name` property and a `fn` property. When running tests and
outputting the results, the name of the past function is used, or if the
object is passed, the `name` property is used to identify the test. If the assertion is false an `AssertionError` will be thrown.
outputting the results, the name of the past function is used, or if the object
is passed, the `name` property is used to identify the test. If the assertion is
false an `AssertionError` will be thrown.
Asserts are exposed in `testing/asserts.ts` module.
@ -18,13 +19,14 @@ Asserts are exposed in `testing/asserts.ts` module.
- `assert()` - Expects a boolean value, throws if the value is `false`.
- `assertEquals()` - Uses the `equal` comparison and throws if the `actual` and
`expected` are not equal.
- `assertNotEquals()` - Uses the `equal` comparison and throws if the `actual` and
`expected` are equal.
- `assertStrictEq()` - Compares `actual` and `expected` strictly, therefore
for non-primitives the values must reference the same instance.
- `assertNotEquals()` - Uses the `equal` comparison and throws if the `actual`
and `expected` are equal.
- `assertStrictEq()` - Compares `actual` and `expected` strictly, therefore for
non-primitives the values must reference the same instance.
- `assertStrContains()` - Make an assertion that `actual` contains `expected`.
- `assertMatch()` - Make an assertion that `actual` match RegExp `expected`.
- `assertArrayContains()` - Make an assertion that `actual` array contains the `expected` values.
- `assertArrayContains()` - Make an assertion that `actual` array contains the
`expected` values.
- `assertThrows()` - Expects the passed `fn` to throw. If `fn` does not throw,
this function does. Also compares any errors thrown to an optional expected
`Error` class and checks that the error `.message` includes an optional
@ -40,7 +42,8 @@ Asserts are exposed in `testing/asserts.ts` module.
`runTests()` executes the declared tests. It accepts a `RunOptions` parameter:
- parallel : Execute tests in a parallel way.
- exitOnFail : if one test fails, test will throw an error and stop the tests. If not all tests will be processed.
- exitOnFail : if one test fails, test will throw an error and stop the tests.
If not all tests will be processed.
Basic usage:
@ -89,9 +92,11 @@ Using `assertThrows()`:
```ts
test(function doesThrow(): void {
assertThrows((): void => {
throw new TypeError("hello world!");
});
assertThrows(
(): void => {
throw new TypeError("hello world!");
}
);
assertThrows((): void => {
throw new TypeError("hello world!");
}, TypeError);
@ -106,9 +111,11 @@ test(function doesThrow(): void {
// This test will not pass
test(function fails(): void {
assertThrows((): void => {
console.log("Hello world");
});
assertThrows(
(): void => {
console.log("Hello world");
}
);
});
```
@ -187,7 +194,8 @@ Registers a benchmark that will be run once `runBenchmarks` is called.
##### `runBenchmarks(opts?: BenchmarkRunOptions): Promise<void>`
Runs all registered benchmarks serially. Filtering can be applied by setting
`BenchmarkRunOptions.only` and/or `BenchmarkRunOptions.skip` to regular expressions matching benchmark names.
`BenchmarkRunOptions.only` and/or `BenchmarkRunOptions.skip` to regular
expressions matching benchmark names.
##### `runIfMain(meta: ImportMeta, opts?: BenchmarkRunOptions): Promise<void>`

View file

@ -56,10 +56,12 @@ function buildMessage(diffResult: ReadonlyArray<DiffResult<string>>): string[] {
);
messages.push("");
messages.push("");
diffResult.forEach((result: DiffResult<string>): void => {
const c = createColor(result.type);
messages.push(c(`${createSign(result.type)}${result.value}`));
});
diffResult.forEach(
(result: DiffResult<string>): void => {
const c = createColor(result.type);
messages.push(c(`${createSign(result.type)}${result.value}`));
}
);
messages.push("");
return messages;

View file

@ -360,11 +360,13 @@ const getKeysOfEnumerableProperties = (object: {}): Array<string | symbol> => {
const keys: Array<string | symbol> = Object.keys(object).sort();
if (Object.getOwnPropertySymbols) {
Object.getOwnPropertySymbols(object).forEach((symbol): void => {
if (Object.getOwnPropertyDescriptor(object, symbol)!.enumerable) {
keys.push(symbol);
Object.getOwnPropertySymbols(object).forEach(
(symbol): void => {
if (Object.getOwnPropertyDescriptor(object, symbol)!.enumerable) {
keys.push(symbol);
}
}
});
);
}
return keys;

View file

@ -203,12 +203,14 @@ function report(result: TestResult): void {
}
function printFailedSummary(results: TestResults): void {
results.cases.forEach((v): void => {
if (!v.ok) {
console.error(`${RED_BG_FAIL} ${red(v.name)}`);
console.error(v.error);
results.cases.forEach(
(v): void => {
if (!v.ok) {
console.error(`${RED_BG_FAIL} ${red(v.name)}`);
console.error(v.error);
}
}
});
);
}
function printResults(
@ -319,12 +321,14 @@ async function runTestsSerial(
print(
GREEN_OK + " " + name + " " + promptTestTime(end - start, true)
);
results.cases.forEach((v): void => {
if (v.name === name) {
v.ok = true;
v.printed = true;
results.cases.forEach(
(v): void => {
if (v.name === name) {
v.ok = true;
v.printed = true;
}
}
});
);
} catch (err) {
if (disableLog) {
print(CLEAR_LINE, false);
@ -332,13 +336,15 @@ async function runTestsSerial(
print(`${RED_FAILED} ${name}`);
print(err.stack);
stats.failed++;
results.cases.forEach((v): void => {
if (v.name === name) {
v.error = err;
v.ok = false;
v.printed = true;
results.cases.forEach(
(v): void => {
if (v.name === name) {
v.error = err;
v.ok = false;
v.printed = true;
}
}
});
);
if (exitOnFail) {
break;
}

View file

@ -205,8 +205,8 @@ async function main(): Promise<void> {
const include =
parsedArgs._.length > 0
? (parsedArgs._ as string[]).flatMap((fileGlob: string): string[] =>
fileGlob.split(",")
? (parsedArgs._ as string[]).flatMap(
(fileGlob: string): string[] => fileGlob.split(",")
)
: ["."];
const exclude =

View file

@ -51,10 +51,12 @@ test(function testingAssertNotStrictEqual(): void {
test(function testingDoesThrow(): void {
let count = 0;
assertThrows((): void => {
count++;
throw new Error();
});
assertThrows(
(): void => {
count++;
throw new Error();
}
);
assert(count === 1);
});
@ -62,10 +64,12 @@ test(function testingDoesNotThrow(): void {
let count = 0;
let didThrow = false;
try {
assertThrows((): void => {
count++;
console.log("Hello world");
});
assertThrows(
(): void => {
count++;
console.log("Hello world");
}
);
} catch (e) {
assert(e.message === "Expected function to throw.");
didThrow = true;

View file

@ -114,9 +114,11 @@ test({
assertEquals(m.get("SID"), "0");
assertEquals(m.get("Privilege"), "127");
// Not a legal http header
assertThrows((): void => {
assertEquals(m.get("Audio Mode"), "None");
});
assertThrows(
(): void => {
assertEquals(m.get("Audio Mode"), "None");
}
);
}
});

View file

@ -20,9 +20,11 @@ export interface Deferred<T> extends Promise<T> {
*/
export function deferred<T>(): Deferred<T> {
let methods;
const promise = new Promise<T>((resolve, reject): void => {
methods = { resolve, reject };
});
const promise = new Promise<T>(
(resolve, reject): void => {
methods = { resolve, reject };
}
);
return Object.assign(promise, methods)! as Deferred<T>;
}
@ -109,9 +111,10 @@ export async function collectUint8Arrays(
// Delays the given milliseconds and resolves.
export function delay(ms: number): Promise<void> {
return new Promise((res): number =>
setTimeout((): void => {
res();
}, ms)
return new Promise(
(res): number =>
setTimeout((): void => {
res();
}, ms)
);
}

View file

@ -8,24 +8,26 @@ export function deepAssign(
if (!source || typeof source !== `object`) {
return;
}
Object.entries(source).forEach(([key, value]: [string, unknown]): void => {
if (value instanceof Date) {
target[key] = new Date(value);
return;
Object.entries(source).forEach(
([key, value]: [string, unknown]): void => {
if (value instanceof Date) {
target[key] = new Date(value);
return;
}
if (!value || typeof value !== `object`) {
target[key] = value;
return;
}
if (Array.isArray(value)) {
target[key] = [];
}
// value is an Object
if (typeof target[key] !== `object` || !target[key]) {
target[key] = {};
}
deepAssign(target[key] as Record<string, unknown>, value!);
}
if (!value || typeof value !== `object`) {
target[key] = value;
return;
}
if (Array.isArray(value)) {
target[key] = [];
}
// value is an Object
if (typeof target[key] !== `object` || !target[key]) {
target[key] = {};
}
deepAssign(target[key] as Record<string, unknown>, value!);
});
);
}
return target;
}

View file

@ -15,10 +15,12 @@ export default function generate(): string {
rnds[6] = (rnds[6] & 0x0f) | 0x40; // Version 4
rnds[8] = (rnds[8] & 0x3f) | 0x80; // Variant 10
const bits: string[] = [...rnds].map((bit): string => {
const s: string = bit.toString(16);
return bit < 0x10 ? "0" + s : s;
});
const bits: string[] = [...rnds].map(
(bit): string => {
const s: string = bit.toString(16);
return bit < 0x10 ? "0" + s : s;
}
);
return [
...bits.slice(0, 4),
"-",

View file

@ -60,9 +60,11 @@ async function main(): Promise<void> {
}
}
)
.catch((err: Error): void => {
console.error(`failed to accept websocket: ${err}`);
});
.catch(
(err: Error): void => {
console.error(`failed to accept websocket: ${err}`);
}
);
}
}

View file

@ -44,9 +44,11 @@ async function main(): Promise<void> {
}
// FIXME: Without this,
// sock.receive() won't resolved though it is readable...
await new Promise((resolve): void => {
setTimeout(resolve, 0);
});
await new Promise(
(resolve): void => {
setTimeout(resolve, 0);
}
);
}
await sock.close(1000);
// FIXME: conn.close() won't shutdown process...

View file

@ -53,9 +53,11 @@ async function main(): Promise<void> {
}
}
)
.catch((err: Error): void => {
console.error(`failed to accept websocket: ${err}`);
});
.catch(
(err: Error): void => {
console.error(`failed to accept websocket: ${err}`);
}
);
}
}

View file

@ -39,7 +39,9 @@ def eslint():
script = os.path.join(third_party_path, "node_modules", "eslint", "bin",
"eslint")
# Find all *directories* in the main repo that contain .ts/.js files.
source_files = git_ls_files(root_path, ["*.js", "*.ts"])
source_files = git_ls_files(
root_path,
["*.js", "*.ts", ":!:std/prettier/vendor/*", ":!:std/**/testdata/*"])
source_dirs = set([os.path.dirname(f) for f in source_files])
# Within the source dirs, eslint does its own globbing, taking into account
# the exclusion rules listed in '.eslintignore'.