Skip to content

Commit c2f26b8

Browse files
author
Ralph Kuepper
committed
test(compile): cover compiled package builtin imports
1 parent 8f026e5 commit c2f26b8

7 files changed

Lines changed: 204 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Added regression coverage for Node builtin named imports used from natively
2+
compiled dependencies. The exact `@hono/node-server` fallback from
3+
`options.createServer` to its module-scope `http.createServer` import now has an
4+
offline compiler fixture and a real-package listen/fetch/close release smoke,
5+
covering both `http` and `node:http` spellings without relying on app-level
6+
imports.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//! Regression test for #8749: a Node builtin named import used from a
2+
//! `compilePackages` dependency must retain its runtime binding.
3+
//!
4+
//! `@hono/node-server` imports `createServer` from `http`, selects it through a
5+
//! module-scope fallback (`options.createServer || createServerHTTP`), and calls
6+
//! the selected function later from `serve()`. App-level imports already
7+
//! worked; the binding was lost specifically while compiling the dependency.
8+
9+
use std::path::PathBuf;
10+
use std::process::Command;
11+
12+
fn perry_bin() -> PathBuf {
13+
PathBuf::from(env!("CARGO_BIN_EXE_perry"))
14+
}
15+
16+
#[test]
17+
fn builtin_named_import_survives_module_scope_fallback_in_compiled_package() {
18+
let dir = tempfile::tempdir().expect("tempdir");
19+
let root = dir.path();
20+
21+
std::fs::write(
22+
root.join("package.json"),
23+
r#"{
24+
"name": "compiled-builtin-import-consumer",
25+
"private": true,
26+
"type": "module",
27+
"perry": {
28+
"compilePackages": ["fake-node-server"],
29+
"allow": { "compilePackages": ["fake-node-server"] }
30+
}
31+
}"#,
32+
)
33+
.expect("write consumer package.json");
34+
35+
let pkg = root.join("node_modules").join("fake-node-server");
36+
std::fs::create_dir_all(&pkg).expect("mkdir fake-node-server");
37+
std::fs::write(
38+
pkg.join("package.json"),
39+
r#"{
40+
"name": "fake-node-server",
41+
"version": "1.0.0",
42+
"type": "module",
43+
"exports": "./index.mjs"
44+
}"#,
45+
)
46+
.expect("write dependency package.json");
47+
std::fs::write(
48+
pkg.join("index.mjs"),
49+
r#"
50+
import { createServer as createServerHTTP } from "http";
51+
import { createServer as createServerNodeHTTP } from "node:http";
52+
53+
const options = {};
54+
const selectedHTTP = options.createServer || createServerHTTP;
55+
const selectedNodeHTTP = options.createServer || createServerNodeHTTP;
56+
57+
export function inspectBindings() {
58+
const serverHTTP = selectedHTTP({}, () => {});
59+
const serverNodeHTTP = selectedNodeHTTP({}, () => {});
60+
return [
61+
typeof createServerHTTP,
62+
typeof createServerNodeHTTP,
63+
typeof selectedHTTP,
64+
typeof selectedNodeHTTP,
65+
typeof serverHTTP.listen,
66+
typeof serverNodeHTTP.listen,
67+
].join(",");
68+
}
69+
"#,
70+
)
71+
.expect("write compiled dependency");
72+
73+
let entry = root.join("main.ts");
74+
std::fs::write(
75+
&entry,
76+
r#"
77+
import { inspectBindings } from "fake-node-server";
78+
console.log(inspectBindings());
79+
process.exit(0);
80+
"#,
81+
)
82+
.expect("write entry");
83+
84+
let output = root.join("main_bin");
85+
let compile = Command::new(perry_bin())
86+
.current_dir(root)
87+
.arg("compile")
88+
.arg(&entry)
89+
.arg("-o")
90+
.arg(&output)
91+
.arg("--no-cache")
92+
.output()
93+
.expect("run perry compile");
94+
assert!(
95+
compile.status.success(),
96+
"perry compile failed\nstdout:\n{}\nstderr:\n{}",
97+
String::from_utf8_lossy(&compile.stdout),
98+
String::from_utf8_lossy(&compile.stderr)
99+
);
100+
101+
let run = Command::new(&output).output().expect("run compiled binary");
102+
assert!(
103+
run.status.success(),
104+
"compiled binary failed\nstatus: {:?}\nstdout:\n{}\nstderr:\n{}",
105+
run.status,
106+
String::from_utf8_lossy(&run.stdout),
107+
String::from_utf8_lossy(&run.stderr)
108+
);
109+
assert_eq!(
110+
String::from_utf8_lossy(&run.stdout),
111+
"function,function,function,function,function,function\n",
112+
"both builtin spellings must stay bound through the dependency's module global"
113+
);
114+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Issue #8749: @hono/node-server selects its imported node:http factory
2+
// through `options.createServer || createServerHTTP` inside compiled package
3+
// code. Exercise the real package through listen, fetch, response, and close.
4+
import { serve } from "@hono/node-server";
5+
6+
const port = 38139;
7+
const server = serve({
8+
fetch: () => new Response("ok"),
9+
port,
10+
});
11+
12+
setTimeout(async () => {
13+
const response = await fetch(`http://127.0.0.1:${port}/`);
14+
console.log(`status=${response.status}`);
15+
console.log(`body=${await response.text()}`);
16+
server.close();
17+
process.exit(0);
18+
}, 100);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
status=200
2+
body=ok
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
# Issue #8749: real-package smoke for @hono/node-server's module-scope
3+
# `options.createServer || createServerHTTP` binding under compilePackages.
4+
5+
set -uo pipefail
6+
cd "$(dirname "$0")"
7+
. "$(dirname "$0")/../_fixture_lib.sh"
8+
9+
fixture_setup "hono-node-server" || exit 1
10+
fixture_compile_run_diff "hono-node-server"

tests/release/packages/hono-node-server/package-lock.json

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "perry-release-fixture-hono-node-server",
3+
"version": "0.0.0",
4+
"private": true,
5+
"type": "module",
6+
"description": "Tier-3 fixture for @hono/node-server's compiled-package Node builtin imports.",
7+
"dependencies": {
8+
"@hono/node-server": "1.19.17",
9+
"hono": "4.13.4"
10+
},
11+
"perry": {
12+
"compilePackages": ["@hono/node-server", "hono"],
13+
"allow": {
14+
"compilePackages": ["@hono/node-server", "hono"]
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)