Repository: denoland/deno
Pull request: Fix std/node/assert misnamed exports, close #7102

The re-exports of assertion methods from `std/testing` defined in `std/node/assert` are named incorrectly, because `assertEquals()` performs a [strict deep equality check](https://github.com/denoland/deno/blob/master/std/testing/asserts.ts#L154-L155), so it should be called `deepStrictEqual()` to match the expected behavior described in the corresponding Node.js [docs](https://nodejs.org/dist/latest-v14.x/docs/api/assert.html#assert_assert_deepstrictequal_actual_expected_message). The same applies to `assertNotEquals()` and `notDeepStrictEqual()`. 

In Node, `assert()` is just an [alias](https://nodejs.org/dist/latest-v14.x/docs/api/assert.html#assert_assert_ok_value_message) of `ok()`. This PR adds that alias as well, so it closes #7102.

Node's `equals()` and `notEquals()` methods are deprecated anyway, so I'm not sure we should implement them at all.

This PR also adds `assertNotStrictEquals()` in `std/testing` and re-exports it in `std/node/assert` as `notStrictEqual()`.

Changed files:
filename: std/node/assert.ts
patch: @@ -2,14 +2,21 @@ import {
   assertEquals,
   assertNotEquals,
   assertStrictEquals,
+  assertNotStrictEquals,
   assertMatch,
   assertThrows,
 } from "../testing/asserts.ts";
 
-export { assert, fail } from "../testing/asserts.ts";
+export {
+  assert as default,
+  assert as ok,
+  assert,
+  fail,
+} from "../testing/asserts.ts";
 
-export const equal = assertEquals;
-export const notEqual = assertNotEquals;
+export const deepStrictEqual = assertEquals;
+export const notDeepStrictEqual = assertNotEquals;
 export const strictEqual = assertStrictEquals;
+export const notStrictEqual = assertNotStrictEquals;
 export const match = assertMatch;
 export const throws = assertThrows;

filename: std/node/assert_test.ts
patch: @@ -0,0 +1,65 @@
+import {
+  assert as denoAssert,
+  assertEquals,
+  assertNotEquals,
+  assertStrictEquals,
+  assertNotStrictEquals,
+  assertMatch,
+  assertThrows,
+  fail as denoFail,
+} from "../testing/asserts.ts";
+
+import assert from "./assert.ts";
+
+import {
+  ok,
+  assert as assert_,
+  deepStrictEqual,
+  notDeepStrictEqual,
+  strictEqual,
+  notStrictEqual,
+  match,
+  throws,
+  fail,
+} from "./assert.ts";
+
+Deno.test("API should be exposed", () => {
+  assertStrictEquals(
+    assert_,
+    assert,
+    "`assert()` should be the default export",
+  );
+  assertStrictEquals(assert_, denoAssert, "`assert()` should be exposed");
+  assertStrictEquals(assert_, ok, "`assert()` should be an alias of `ok()`");
+  assertStrictEquals(
+    assertEquals,
+    deepStrictEqual,
+    "`assertEquals()` should be exposed as `deepStrictEqual()`",
+  );
+  assertStrictEquals(
+    assertNotEquals,
+    notDeepStrictEqual,
+    "`assertNotEquals()` should be exposed as `notDeepStrictEqual()`",
+  );
+  assertStrictEquals(
+    assertStrictEquals,
+    strictEqual,
+    "`assertStrictEquals()` should be exposed as `strictEqual()`",
+  );
+  assertStrictEquals(
+    assertNotStrictEquals,
+    notStrictEqual,
+    "`assertNotStrictEquals()` should be exposed as `notStrictEqual()`",
+  );
+  assertStrictEquals(
+    assertMatch,
+    match,
+    "`assertMatch()` should be exposed as `match()`",
+  );
+  assertStrictEquals(
+    assertThrows,
+    throws,
+    "`assertThrows()` should be exposed as `throws()`",
+  );
+  assertStrictEquals(fail, denoFail, "`fail()` should be exposed");
+});

filename: std/testing/asserts.ts
patch: @@ -242,10 +242,20 @@ export function assertNotEquals(
  * assertStrictEquals(1, 2)
  * ```
  */
+export function assertStrictEquals(
+  actual: unknown,
+  expected: unknown,
+  msg?: string,
+): void;
 export function assertStrictEquals<T>(
   actual: T,
   expected: T,
   msg?: string,
+): void;
+export function assertStrictEquals(
+  actual: unknown,
+  expected: unknown,
+  msg?: string,
 ): void {
   if (actual === expected) {
     return;
@@ -285,6 +295,37 @@ export function assertStrictEquals<T>(
   throw new AssertionError(message);
 }
 
+/**
+ * Make an assertion that `actual` and `expected` are not strictly equal.  
+ * If the values are strictly equal then throw.
+ * ```ts
+ * assertNotStrictEquals(1, 1)
+ * ```
+ */
+export function assertNotStrictEquals(
+  actual: unknown,
+  expected: unknown,
+  msg?: string,
+): void;
+export function assertNotStrictEquals<T>(
+  actual: T,
+  expected: T,
+  msg?: string,
+): void;
+export function assertNotStrictEquals(
+  actual: unknown,
+  expected: unknown,
+  msg?: string,
+): void {
+  if (actual !== expected) {
+    return;
+  }
+
+  throw new AssertionError(
+    msg ?? `Expected "actual" to be strictly unequal to: ${_format(actual)}\n`,
+  );
+}
+
 /**
  * Make an assertion that actual contains expected. If not
  * then thrown.

filename: std/testing/asserts_test.ts
patch: @@ -8,6 +8,7 @@ import {
   assertMatch,
   assertEquals,
   assertStrictEquals,
+  assertNotStrictEquals,
   assertThrows,
   assertThrowsAsync,
   AssertionError,
@@ -463,13 +464,42 @@ Deno.test({
 });
 
 Deno.test({
-  name: "assert* functions with specified type paratemeter",
+  name: "strictly unequal pass case",
+  fn(): void {
+    assertNotStrictEquals(true, false);
+    assertNotStrictEquals(10, 11);
+    assertNotStrictEquals("abc", "xyz");
+    assertNotStrictEquals(1, "1");
+
+    const xs = [1, false, "foo"];
+    const ys = [1, true, "bar"];
+    assertNotStrictEquals(xs, ys);
+
+    const x = { a: 1 };
+    const y = { a: 2 };
+    assertNotStrictEquals(x, y);
+  },
+});
+
+Deno.test({
+  name: "strictly unequal fail case",
+  fn(): void {
+    assertThrows(
+      () => assertNotStrictEquals(1, 1),
+      AssertionError,
+    );
+  },
+});
+
+Deno.test({
+  name: "assert* functions with specified type parameter",
   fn(): void {
     assertEquals<string>("hello", "hello");
     assertNotEquals<number>(1, 2);
     assertArrayContains<boolean>([true, false], [true]);
     const value = { x: 1 };
     assertStrictEquals<typeof value>(value, value);
+    assertNotStrictEquals<object>(value, { x: 1 });
   },
 });