Compare commits

...

4 Commits

Author SHA1 Message Date
pfg
b94a0879dc fix 07392.test.ts in ci? 2025-08-21 17:23:57 -07:00
pfg
1fda101c0d add reproduciton for 07392 2025-08-21 15:16:39 -07:00
pfg
e3378b2c98 fix fuzzy-wuzzy 2025-08-21 15:16:39 -07:00
pfg
2f6e99c244 disable the Bun.jest function 2025-08-21 15:16:39 -07:00
8 changed files with 130 additions and 35 deletions

View File

@@ -2225,6 +2225,10 @@ extern "C" JSC::EncodedJSValue Bun__Jest__testModuleObject(Zig::GlobalObject* gl
{
return JSValue::encode(globalObject->lazyTestModuleObject());
}
extern "C" JSC::EncodedJSValue Bun__ExpectTypeOf__getSingleton(Zig::GlobalObject* globalObject)
{
return JSValue::encode(globalObject->lazyExpectTypeOfSingleton());
}
static inline JSC::EncodedJSValue ZigGlobalObject__readableStreamToArrayBufferBody(Zig::GlobalObject* globalObject, JSC::EncodedJSValue readableStreamValue)
{
@@ -2867,6 +2871,17 @@ void GlobalObject::finishCreation(VM& vm)
init.set(result.toObject(globalObject));
});
m_lazyExpectTypeOfSingleton.initLater(
[](const Initializer<JSObject>& init) {
Zig::GlobalObject* globalObject = jsCast<Zig::GlobalObject*>(init.owner);
auto& vm = globalObject->vm();
// Create a single ExpectTypeOf instance that will be reused
// Pass nullptr as ctx since ExpectTypeOf has no data
auto* expectTypeOf = WebCore::JSExpectTypeOf::create(vm, globalObject, globalObject->JSExpectTypeOfStructure(), nullptr);
init.set(expectTypeOf);
});
m_testMatcherUtilsObject.initLater(
[](const Initializer<JSObject>& init) {
JSValue result = JSValue::decode(ExpectMatcherUtils_createSigleton(init.owner));

View File

@@ -296,6 +296,7 @@ public:
Structure* globalProxyStructure() const { return m_cachedGlobalProxyStructure.getInitializedOnMainThread(this); }
JSObject* lazyTestModuleObject() const { return m_lazyTestModuleObject.getInitializedOnMainThread(this); }
JSObject* lazyPreloadTestModuleObject() const { return m_lazyPreloadTestModuleObject.getInitializedOnMainThread(this); }
JSObject* lazyExpectTypeOfSingleton() const { return m_lazyExpectTypeOfSingleton.getInitializedOnMainThread(this); }
Structure* CommonJSModuleObjectStructure() const { return m_commonJSModuleObjectStructure.getInitializedOnMainThread(this); }
Structure* JSSocketAddressDTOStructure() const { return m_JSSocketAddressDTOStructure.getInitializedOnMainThread(this); }
Structure* ImportMetaObjectStructure() const { return m_importMetaObjectStructure.getInitializedOnMainThread(this); }
@@ -581,6 +582,7 @@ public:
V(public, LazyPropertyOfGlobalObject<Bun::JSCommonJSExtensions>, m_lazyRequireExtensionsObject) \
V(private, LazyPropertyOfGlobalObject<JSObject>, m_lazyTestModuleObject) \
V(private, LazyPropertyOfGlobalObject<JSObject>, m_lazyPreloadTestModuleObject) \
V(private, LazyPropertyOfGlobalObject<JSObject>, m_lazyExpectTypeOfSingleton) \
V(public, LazyPropertyOfGlobalObject<JSObject>, m_testMatcherUtilsObject) \
V(public, LazyPropertyOfGlobalObject<Structure>, m_cachedNodeVMGlobalObjectStructure) \
V(public, LazyPropertyOfGlobalObject<Structure>, m_cachedNodeVMSpecialSandboxStructure) \

View File

@@ -1903,41 +1903,38 @@ pub const ExpectMatcherUtils = struct {
}
};
// Extern function to get the singleton ExpectTypeOf from ZigGlobalObject
extern fn Bun__ExpectTypeOf__getSingleton(globalThis: *JSGlobalObject) JSValue;
fn getExpectTypeOfSingleton(globalThis: *JSGlobalObject) JSValue {
return Bun__ExpectTypeOf__getSingleton(globalThis);
}
pub const ExpectTypeOf = struct {
pub const js = jsc.Codegen.JSExpectTypeOf;
pub const toJS = js.toJS;
pub const fromJS = js.fromJS;
pub const fromJSDirect = js.fromJSDirect;
pub fn finalize(
this: *ExpectTypeOf,
) callconv(.C) void {
VirtualMachine.get().allocator.destroy(this);
}
pub fn create(globalThis: *JSGlobalObject) bun.JSError!JSValue {
var expect = try globalThis.bunVM().allocator.create(ExpectTypeOf);
const value = expect.toJS(globalThis);
value.ensureStillAlive();
return value;
return getExpectTypeOfSingleton(globalThis);
}
pub fn fnOneArgumentReturnsVoid(_: *ExpectTypeOf, _: *JSGlobalObject, _: *CallFrame) bun.JSError!JSValue {
return .js_undefined;
}
pub fn fnOneArgumentReturnsExpectTypeOf(_: *ExpectTypeOf, globalThis: *JSGlobalObject, _: *CallFrame) bun.JSError!JSValue {
return create(globalThis);
return getExpectTypeOfSingleton(globalThis);
}
pub fn getReturnsExpectTypeOf(_: *ExpectTypeOf, globalThis: *JSGlobalObject) bun.JSError!JSValue {
return create(globalThis);
return getExpectTypeOfSingleton(globalThis);
}
pub fn constructor(globalThis: *JSGlobalObject, _: *CallFrame) bun.JSError!*ExpectTypeOf {
return globalThis.throw("expectTypeOf() cannot be called with new", .{});
}
pub fn call(globalThis: *JSGlobalObject, _: *CallFrame) bun.JSError!JSValue {
return create(globalThis);
return getExpectTypeOfSingleton(globalThis);
}
};

View File

@@ -634,7 +634,6 @@ export default [
name: "ExpectTypeOf",
construct: true,
call: true,
finalize: true,
JSType: "0b11101110",
values: [],
configurable: false,

View File

@@ -529,30 +529,13 @@ pub const Jest = struct {
pub fn call(
globalObject: *JSGlobalObject,
callframe: *CallFrame,
_: *CallFrame,
) bun.JSError!JSValue {
const vm = globalObject.bunVM();
if (vm.is_in_preload or runner == null) {
return Bun__Jest__testPreloadObject(globalObject);
}
const arguments = callframe.arguments_old(2).slice();
if (arguments.len < 1 or !arguments[0].isString()) {
return globalObject.throw("Bun.jest() expects a string filename", .{});
}
var str = try arguments[0].toSlice(globalObject, bun.default_allocator);
defer str.deinit();
const slice = str.slice();
if (!std.fs.path.isAbsolute(slice)) {
return globalObject.throw("Bun.jest() expects an absolute file path, got '{s}'", .{slice});
}
const filepath = Fs.FileSystem.instance.filename_store.append([]const u8, slice) catch unreachable;
var scope = runner.?.getOrPutFile(filepath);
scope.push();
return Bun__Jest__testModuleObject(globalObject);
}
@@ -2495,7 +2478,6 @@ const ExpectTypeOf = expect.ExpectTypeOf;
const bun = @import("bun");
const ArrayIdentityContext = bun.ArrayIdentityContext;
const Environment = bun.Environment;
const Fs = bun.fs;
const MutableString = bun.MutableString;
const Output = bun.Output;
const RegularExpression = bun.RegularExpression;

View File

@@ -1816,6 +1816,10 @@ pub const TestCommand = struct {
const file_path = resolution.path_pair.primary.text;
const file_title = bun.path.relative(FileSystem.instance.top_level_dir, file_path);
const filepath = bun.fs.FileSystem.instance.filename_store.append([]const u8, file_path) catch unreachable;
var scope = bun.jsc.Jest.Jest.runner.?.getOrPutFile(filepath);
scope.push();
// In Github Actions, append a special prefix that will group
// subsequent log lines into a collapsable group.
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines

View File

@@ -3,7 +3,7 @@
" == undefined": 0,
"!= alloc.ptr": 0,
"!= allocator.ptr": 0,
".arguments_old(": 279,
".arguments_old(": 278,
".jsBoolean(false)": 0,
".jsBoolean(true)": 0,
".stdDir()": 41,

View File

@@ -0,0 +1,96 @@
import { expect, test } from "bun:test";
import { bunEnv, bunExe, normalizeBunSnapshot, tempDirWithFiles } from "harness";
test("issue #7392", async () => {
const dir = tempDirWithFiles("issue-7392", {
files: {
tests: {
"a.test.js": /*js*/ `
import { test } from "#testing";
test("A: test case", () => {});
test("A: another test case", () => {});
test("A: final test case", () => {});
`,
"b.test.js": /*js*/ `
import { test } from "#testing";
test("B: test case", () => {});
test("B: another test case", () => {});
test("B: final test case", () => {});
`,
"c.test.js": /*js*/ `
import { test } from "#testing";
test("C: test case", () => {});
test("C: another test case", () => {});
test("C: final test case", () => {});
`,
},
"framework.bun.ts": /*ts*/ `
import { describe, it, expect, test, jest } from "bun:test";
const spy = jest.fn;
export { describe, it, expect, test, spy };
`,
"package.json": JSON.stringify({
name: "bun-repro",
imports: {
"#testing": {
bun: "./framework.bun.ts",
default: "./framework.default.js",
},
},
}),
},
});
const { stdout, stderr, exited } = Bun.spawn({
cmd: [bunExe(), "test"],
cwd: dir,
stdio: ["inherit", "pipe", "pipe"],
env: bunEnv,
});
const code = await exited;
expect({
code,
stdout: normalizeBunSnapshot(await stdout.text()),
stderr: (await stderr.text())
.split(/\n{2,}/)
.map(l => l.trim())
.sort()
.map(line => normalizeBunSnapshot(line)),
}).toMatchInlineSnapshot(`
{
"code": 0,
"stderr": [
"9 pass
0 fail
Ran 9 tests across 3 files."
,
"files/tests/a.test.js:
(pass) A: test case
(pass) A: another test case
(pass) A: final test case"
,
"files/tests/b.test.js:
(pass) B: test case
(pass) B: another test case
(pass) B: final test case"
,
"files/tests/c.test.js:
(pass) C: test case
(pass) C: another test case
(pass) C: final test case"
,
],
"stdout": "bun test <version> (<revision>)",
}
`);
});