This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-6633-4a3f06d9ae65730020702309a3ed4d7aa3719044
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 13609a6c8a887666112cf9031b40bdee144a9030
Author: Matthew B. <[email protected]>
AuthorDate: Mon Jul 20 15:06:51 2026 -0700

    test(frontend): add unit tests for assertion utilities (#6633)
    
    ### What changes were proposed in this PR?
    - Add `frontend/src/app/common/util/assert.spec.ts`, a new Vitest spec
    for `assert.ts`, which previously had no dedicated unit tests.
    - Cover all seven exports: assertType, assert, isType, asType, isNull,
    isNotNull, and nonNull.
    - Cover throw-vs-pass paths for the guards and assertions, plus
    falsy-but-defined values.
    - Cover primitive vs constructor type checks and the isNull/isNotNull
    inverse equivalence.
    ### Any related issues, documentation, discussions?
    Closes: #6632
    ### How was this PR tested?
    - Run: `cd frontend && node --max-old-space-size=8192
    ./node_modules/nx/dist/bin/nx.js test gui --watch=false
    --include=src/app/common/util/assert.spec.ts`, expect all 22 tests
    passing.
    - Test-only change; no production code is modified.
    ### Was this PR authored or co-authored using generative AI tooling?
    Co-authored with Claude Opus 4.8 in compliance with ASF
    
    ---------
    
    Signed-off-by: Xinyuan Lin <[email protected]>
    Co-authored-by: Xinyuan Lin <[email protected]>
    Co-authored-by: Copilot Autofix powered by AI 
<[email protected]>
---
 frontend/src/app/common/util/assert.spec.ts | 153 ++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/frontend/src/app/common/util/assert.spec.ts 
b/frontend/src/app/common/util/assert.spec.ts
new file mode 100644
index 0000000000..a151d79b7d
--- /dev/null
+++ b/frontend/src/app/common/util/assert.spec.ts
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { assert, assertType, asType, isNotNull, isNull, isType, nonNull } from 
"./assert";
+
+describe("assertType", () => {
+  it("does not throw for defined values, including falsy ones", () => {
+    expect(() => assertType<number>(0)).not.toThrow();
+    expect(() => assertType<string>("")).not.toThrow();
+    expect(() => assertType<boolean>(false)).not.toThrow();
+    expect(() => assertType<object>({})).not.toThrow();
+  });
+
+  it("throws a TypeError for null", () => {
+    expect(() => assertType<number>(null)).toThrow(TypeError);
+  });
+
+  it("throws a TypeError for undefined", () => {
+    expect(() => assertType<number>(undefined)).toThrow(TypeError);
+  });
+
+  it("reports the received value in the error message", () => {
+    expect(() => assertType<number>(null)).toThrow("received null");
+    expect(() => assertType<number>(undefined)).toThrow("received undefined");
+  });
+});
+
+describe("assert", () => {
+  it("does not throw when the condition is true", () => {
+    expect(() => assert(true)).not.toThrow();
+  });
+
+  it("throws an Error when the condition is false", () => {
+    expect(() => assert(false)).toThrow(Error);
+  });
+
+  it("uses the supplied message on failure", () => {
+    expect(() => assert(false, "boom")).toThrow("boom");
+  });
+
+  it("throws with an empty message when none is provided", () => {
+    let err: unknown;
+    try {
+      assert(false);
+    } catch (e) {
+      err = e;
+    }
+    expect(err).toBeInstanceOf(Error);
+    expect((err as Error).message).toBe("");
+  });
+});
+
+describe("isType", () => {
+  it("matches primitive types by typeof", () => {
+    expect(isType(1, "number")).toBe(true);
+    expect(isType("x", "string")).toBe(true);
+    expect(isType(true, "boolean")).toBe(true);
+  });
+
+  it("returns false when the primitive type does not match", () => {
+    expect(isType("1", "number")).toBe(false);
+    expect(isType(1, "string")).toBe(false);
+    expect(isType(0, "boolean")).toBe(false);
+  });
+
+  it("matches instances via instanceof for constructor types", () => {
+    expect(isType(new Date(), Date)).toBe(true);
+    expect(isType([], Array)).toBe(true);
+  });
+
+  it("returns false for instances of an unrelated constructor", () => {
+    expect(isType({}, Date)).toBe(false);
+    expect(isType(new Date(), Array)).toBe(false);
+  });
+});
+
+describe("asType", () => {
+  it("returns the value unchanged when the type matches", () => {
+    expect(asType(5, "number")).toBe(5);
+    const date = new Date();
+    expect(asType(date, Date)).toBe(date);
+  });
+
+  it("throws a TypeError when the type does not match", () => {
+    expect(() => asType("nope", "number")).toThrow(TypeError);
+    expect(() => asType({}, Date)).toThrow(TypeError);
+  });
+});
+
+describe("isNull", () => {
+  it("returns true for null and undefined", () => {
+    expect(isNull(null)).toBe(true);
+    expect(isNull(undefined)).toBe(true);
+  });
+
+  it("returns false for defined values, including falsy ones", () => {
+    expect(isNull(0)).toBe(false);
+    expect(isNull("")).toBe(false);
+    expect(isNull(false)).toBe(false);
+  });
+});
+
+describe("isNotNull", () => {
+  it("returns false for null and undefined", () => {
+    expect(isNotNull(null)).toBe(false);
+    expect(isNotNull(undefined)).toBe(false);
+  });
+
+  it("returns true for defined values, including falsy ones", () => {
+    expect(isNotNull(0)).toBe(true);
+    expect(isNotNull("")).toBe(true);
+    expect(isNotNull(false)).toBe(true);
+  });
+
+  it("is the logical inverse of isNull", () => {
+    for (const value of [null, undefined, 0, "", false, {}, []]) {
+      expect(isNotNull(value)).toBe(!isNull(value));
+    }
+  });
+});
+
+describe("nonNull", () => {
+  it("returns the value unchanged for defined values", () => {
+    expect(nonNull(0)).toBe(0);
+    expect(nonNull("")).toBe("");
+    const obj = { a: 1 };
+    expect(nonNull(obj)).toBe(obj);
+  });
+
+  it("throws a TypeError for null", () => {
+    expect(() => nonNull(null)).toThrow(TypeError);
+  });
+
+  it("throws a TypeError for undefined", () => {
+    expect(() => nonNull(undefined)).toThrow(TypeError);
+  });
+});

Reply via email to