Adds a PTY reporter for local development that gives a summary of the
longest running pending tests and also recent failures.
This can be disabled by setting `DENO_TEST_UTIL_REPORTER=log`
If a test is flaky on the CI, it will now force the flaky test to run
all by itself. Once it passes or fails in isolation, it will then
restore having tests run in parallel.
Notable changes:
- Respect progress callback function option.
- Set default backup rate to 100 to follow Node's implementation.
- Various validation and error handling.
Note that the op implementation in this PR is still sync.
Given this code:
```js
import { backup, DatabaseSync } from "node:sqlite";
const populate = (database, rows) => {
database.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT);");
let values = "";
for (let i = 0; i < rows; i++) {
values += `(${i}, 'Name ${i}'),`;
}
values = values.slice(0, -1);
database.exec(`INSERT INTO test (id, name) VALUES ${values}`);
};
const backupPath = "backup.sqlite";
const database = new DatabaseSync(":memory:");
populate(database, 1000);
const t0 = performance.now();
await backup(database, backupPath, { rate: 1 });
const t1 = performance.now();
database.close();
console.log(`Backup completed in ${(t1 - t0).toFixed(2)} ms`);
```
Results:
```bash
# Node.js v25.2.1
➜ node ./backup-benchmark.js
Backup completed in 0.71 ms
# This PR (debug build mode)
➜ ddeno -A ./backup-benchmark.js
Backup completed in 0.71 ms
# Deno v2.6.0
➜ deno -A ./backup-benchmark.js
Backup completed in 1272.16 ms
```
The current implementation is slow because it sleeps 250ms after each
`sqlite3_backup_step` call.
1. Marks all integration tests as flaky on the CI and outputs when
they're flaky so we can track it.
2. Uses a custom test runner for integration tests, giving us full
control over how they're run.
3. Runs watcher tests sequentially for more stability.
1. Moves `unit` and `unit_node` tests to use file_test_runner.
1. Marks all spec, unit, and node_unit tests as flaky on the CI and
outputs when they're flaky so we can track it.
1. Reduces CI concurrency to 1 on 3 flaky test failures (for now...
would be more ideal to lower it slowly maybe, which is easily possible
with this pr)
1. Adds a 100ms delay between flaky test failures.
## Summary
Aligns Deno's Node.js compatibility layer (`node:net`, `node:http`,
`node:https`,
`node:http2`, `node:dns`) with Node.js v18.4.0+ behavior by returning
the `family`
property as a string (`"IPv4"` or `"IPv6"`) rather than a number in
`server.address()`
and socket address methods.
Node.js briefly changed `family` from string to number in v18.0.0
(nodejs/node#41431),
but reverted in v18.4.0 (nodejs/node#43054) due to ecosystem breakage
(nodejs/node#43014).
This fix ensures compatibility with npm packages that rely on the string
format, which
has been the stable API since Node.js v18.4.0.
## Changes
- Modified `ext/node/polyfills/http.ts` to add `family` property to
`address()` return
- Modified `ext/node/polyfills/internal_binding/tcp_wrap.ts` to return
string `family`
instead of number in `getsockname()`, `getpeername()`, and `#connect()`
- Modified `ext/node/polyfills/net.ts` to fix `socket.remoteFamily`
getter (no longer
needs conversion since `family` is now a string)
- Modified `ext/node/polyfills/dns.ts` and
`ext/node/polyfills/internal/dns/promises.ts` to accept string family
values (`"IPv4"`,
`"IPv6"`) in `lookup()`, matching [Node.js
behavior](https://nodejs.org/api/dns.html#dnslookuphostname-options-callback)
- Added tests in `tests/unit_node/http_test.ts`,
`tests/unit_node/http2_test.ts`,
`tests/unit_node/https_test.ts`, `tests/unit_node/dns_test.ts`, and
`tests/unit_node/net_test.ts`
## Node.js Compatibility Note
For non-IP addresses (when `isIP()` returns 0), the `family` property is
`undefined`.
This matches Node.js C++ behavior in
[`AddressToJS`](https://github.com/nodejs/node/blob/main/src/tcp_wrap.cc)
where family
is only set for `AF_INET` (`"IPv4"`) and `AF_INET6` (`"IPv6"`), and left
undefined
otherwise.
## Refs
- nodejs/node#43054
- nodejs/node@70b516e
<!--
Before submitting a PR, please read
https://docs.deno.com/runtime/manual/references/contributing
1. Give the PR a descriptive title.
Examples of good title:
- fix(std/http): Fix race condition in server
- docs(console): Update docstrings
- feat(doc): Handle nested reexports
Examples of bad title:
- fix#7123
- update docs
- fix bugs
2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
7. Open as a draft PR if your work is still in progress. The CI won't
run
all steps, but you can add '[ci]' to a commit message to force it to.
8. If you would like to run the benchmarks on the CI, add the 'ci-bench'
label.
-->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Daniel Rahmanto <daniel.rahmanto@gmail.com>
## Summary
This PR fixes the behavior of `url.domainToASCII` to match Node.js by
returning an empty string when an invalid domain is passed, instead of
throwing an error.
## Changes
- Modified `op_node_idna_domain_to_ascii` in `ext/node/ops/idna.rs` to
return an empty string on error instead of propagating the error
- Updated documentation in `ext/node/polyfills/internal/idna.ts` to
clarify this behavior
- Added spec test in `tests/specs/node/url_domain_to_ascii/` to verify
the fix
## Test Plan
### Manual Testing
Tested with the example from the issue:
```javascript
import url from 'node:url';
console.log(url.domainToASCII('xn--iñvalid.com')); // Returns empty string instead of throwing
```
Also tested with various valid and invalid domains to ensure
compatibility:
- Valid domains: `example.com` → `example.com`
- Valid unicode: `münchen.de` → `xn--mnchen-3ya.de`
- Invalid punycode: `xn--iñvalid.com` → `` (empty string)
- Invalid domain: `xn--` → `` (empty string)
### Automated Tests
Added spec test that verifies the behavior matches Node.js for both
valid and invalid domains.
## Closes
Fixes#31133
---
_This PR was autogenerated and may require review and adjustments._
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Daniel Rahmanto <daniel.rahmanto@gmail.com>
## Summary
In Node.js, `tty.ReadStream` sets `isTTY` as a simple instance property
(`this.isTTY = true`), making it naturally writable. Deno's polyfill
used a getter-only property definition, preventing assignment.
Some npm packages need to override `isTTY` at runtime. For example,
Playwright's test server sets `process.stdin.isTTY = undefined` to
prevent reporters from blocking on user input during UI mode
(microsoft/playwright#37867).
This aligns stdin with the stdout/stderr fix from #26130, ensuring all
stdio streams behave consistently with Node.js.
## Refs
-
6a1a3ba045/lib/tty.js (L71)
-
3a5a32d26d/packages/playwright/src/runner/testServer.ts (L257-L266)
Co-authored-by: Claude <noreply@anthropic.com>
Closes#26300
Allows the following node compatibility tests to pass:
-
https://github.com/nodejs/node/blob/v24.2.0/test/parallel/test-dns-lookupService-promises.js
-
https://github.com/nodejs/node/blob/v24.2.0/test/parallel/test-dns-lookupService.js
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added `dns.lookupService()` for reverse DNS lookups, supporting both
callback and Promise-based APIs.
* Returns hostname and service information for a given IP address and
port combination.
* **Tests**
* Added unit tests for new DNS lookupService functionality across
callback and Promise variants.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Previously, running this code causes segfault:
```ts
import { DatabaseSync } from "node:sqlite";
const db = new DatabaseSync(':memory:');
const stmt = db.prepare('SELECT 1 AS value');
db.close();
stmt.get(); // segmentation fault (core dumped)
```
Changes in this PR also allows the
https://github.com/nodejs/node/blob/v24.2.0/test/parallel/test-sqlite-statement-sync-columns.js
test to pass.
Fixes#31172
## Description
The `deepStrictEqual` function was using `asserts.equal()` which doesn't
properly handle boxed primitives like Number objects. Changed it to use
`isDeepStrictEqual()` from `comparisons.ts` which correctly handles
Number, String, Boolean, BigInt, and Symbol objects.
## Changes
- Modified `ext/node/polyfills/assert.ts`:
- Added import for `isDeepStrictEqual` from
`ext:deno_node/internal/util/comparisons.ts`
- Updated `deepStrictEqual` function to use `isDeepStrictEqual()`
instead of `asserts.equal()`
- Added test cases in `tests/unit_node/assert_test.ts`:
- Test that `deepStrictEqual` throws `AssertionError` for different
Number objects
- Test that `deepStrictEqual` passes for equal Number objects
## Testing
Added unit tests to verify:
- `deepStrictEqual` throws `AssertionError` for different Number objects
(e.g., `new Number(1)` vs `new Number(2)`)
- `deepStrictEqual` passes for equal Number objects (e.g., `new
Number(1)` vs `new Number(1)`)
## Related Issue
#31172 - `assert.deepStrictEqual` does not throw exception for Number
objects
---------
Co-authored-by: Daniel Rahmanto <daniel.rahmanto@gmail.com>
Introduces the emitWarning function from the process module to enable
warning capabilities within the console constructor implementation.
This fixes a bug where the `time`, `countReset` and `timeLogImpl`
functions would throw an error due to trying to call `emitWarning`, they
would throw an error for an undefined variable named `emitWarning` or if
a global function had that name` they would call that function, which is
not expected behaviour here.
---------
Signed-off-by: Jake Champion <me@jakechampion.name>
Closes#30013
The `'exit'` event in `node:worker_threads` was not consistently fired,
or in some cases emitted multiple times, diverging from Node.js
behavior.
Fixes a panic that occurred when using nested session.post() calls in
the node:inspector module. The issue manifested when callbacks from
inspector commands (like Profiler.enable) called session.post() again,
causing a re-entrant invocation of op_inspector_dispatch.
Fixes https://github.com/denoland/deno/issues/31020
Towards #29972
- `fs.read` and `fs.readSync`: accepts object option parameter.
- `fs.write` and `fs.writeSync`: negative position value defaults to the
current seek position.
- Allows several node compatibility tests to pass.
Closes#30972
Other changes:
- Re-enables ignored tests on `tests/unit_node/_fs/_fs_write_test.ts`
- Ported the polyfill to `.ts`, though defining the types are tricky
since our implementation (ported from node) mutates a lot of variables.
Discovered on #30905, though not directly addressing the main issue
Given this code:
```ts
console.log(globalThis.process.env)
```
Deno 2.5.4:
```bash
➜ deno index.ts
✅ Granted env access to "Symbol(Deno.customInspect)".
✅ Granted env access to "Symbol(Deno.privateCustomInspect)".
✅ Granted env access to "Symbol(nodejs.util.inspect.custom)".
✅ Granted env access to "constructor".
✅ Granted env access to "Symbol(Symbol.iterator)".
✅ Granted env access.
[..result..]
```
This PR:
```bash
➜ deno index.ts
✅ Granted env access to "constructor".
✅ Granted env access.
[..result..]
```
Futhermore, it allows the following tests to pass:
-
https://github.com/nodejs/node/blob/v24.2.0/test/parallel/test-process-env-deprecation.js
-
https://github.com/nodejs/node/blob/v24.2.0/test/parallel/test-process-env-ignore-getter-setter.js
Closes#30936
The `compressIPv6` function is causing this issue. Maybe it was used in
the past to compress IPv6 address returned from the op function, though
I might be wrong about this.
Both `Deno.resolveDns` and the `resolve6` polyfill use `op_dns_resolve`
op function, which returns a result that already matches with the
Node.js' `resolve6`. The incorrect result is due to our `resolve6`
polyfill applying the `compressIPv6` function to the result.