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:
parent
28293acd9c
commit
93f7f00c95
53 changed files with 668 additions and 877 deletions
|
@ -1 +1,4 @@
|
|||
cli/tests/error_syntax.js
|
||||
std/deno.d.ts
|
||||
std/prettier/vendor
|
||||
std/**/testdata/
|
||||
|
|
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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
25
cli/tests/std_tests.rs
Normal 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());
|
||||
}
|
||||
*/
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 });
|
||||
});
|
||||
|
|
|
@ -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 });
|
||||
});
|
||||
|
|
|
@ -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 });
|
||||
});
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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("")
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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>`
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
"-",
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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'.
|
||||
|
|
Loading…
Reference in a new issue