| // Copyright 2019 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // Flags: --harmony-nullish |
| |
| // Basic sanity checks. |
| assertTrue(true ?? false); |
| assertFalse(false ?? true); |
| assertTrue(undefined ?? true); |
| assertTrue(null ?? true); |
| assertEquals([], [] ?? true); |
| |
| // Chaining nullish. |
| assertTrue(null ?? null ?? true); |
| assertTrue(null ?? null ?? true ?? null); |
| assertTrue(undefined ?? undefined ?? true); |
| assertTrue(undefined ?? undefined ?? true ?? undefined); |
| assertFalse(null ?? false ?? null); |
| assertFalse(undefined ?? false ?? undefined); |
| |
| // Nullish and conditionals. |
| assertTrue(null ?? true ? true : false); |
| assertTrue(null ?? null ?? true ? true : false); |
| assertTrue(undefined ?? true ? true : false); |
| assertTrue(undefined ?? undefined ?? true ? true : false); |
| |
| // Nullish mixed expressions. |
| assertTrue(null ?? 1 == 1); |
| assertTrue(undefined ?? 1 == 1); |
| assertTrue(null ?? null ?? 1 == 1); |
| assertTrue(undefined ??undefined ?? 1 == 1); |
| assertEquals(1, null ?? 1 | 0); |
| assertEquals(1, undefined ?? 1 | 0); |
| assertEquals(1, null ?? null ?? 1 | 0); |
| assertEquals(1, undefined ?? undefined ?? 1 | 0); |
| |
| // Short circuit. |
| { |
| let ran = false; |
| let never_ran = () => { ran = true; } |
| let value = true ?? never_ran(); |
| assertTrue(value); |
| assertFalse(ran); |
| } |
| |
| { |
| let ran = false; |
| let never_ran = () => { ran = true; } |
| let value = undefined ?? true ?? never_ran(); |
| assertTrue(value); |
| assertFalse(ran); |
| } |
| |
| { |
| let ran = false; |
| let never_ran = () => { ran = true; } |
| let value = null ?? true ?? never_ran(); |
| assertTrue(value); |
| assertFalse(ran); |
| } |
| |
| // Nullish in tests evaluates only once. |
| { |
| let run_count = 0; |
| let run = () => { run_count++; return null; } |
| if (run() ?? true) {} else { assertUnreachable(); } |
| assertEquals(1, run_count); |
| } |
| |
| // Nullish may not contain or be contained within || or &&. |
| assertThrows("true || true ?? true", SyntaxError); |
| assertThrows("true ?? true || true", SyntaxError); |
| assertThrows("true && true ?? true", SyntaxError); |
| assertThrows("true ?? true && true", SyntaxError); |
| |
| // Test boolean expressions and nullish. |
| assertTrue((false || true) ?? false); |
| assertTrue(null ?? (false || true)); |
| assertTrue((false || null) ?? true); |
| assertTrue((false || null) ?? (true && null) ?? true); |
| assertTrue((false || undefined) ?? true); |
| assertTrue((false || undefined) ?? (true && undefined) ?? true); |
| assertTrue(null ?? (false || true)); |
| assertTrue(undefined ?? (false || true)); |
| assertTrue(null ?? (false || null) ?? true); |
| assertTrue(undefined ?? (false || undefined) ?? true); |
| assertTrue(null ?? null ?? (false || true)); |
| assertTrue(undefined ?? undefined ?? (false || true)); |
| assertTrue((undefined ?? false) || true); |
| assertTrue((null ?? false) || true); |
| assertTrue((undefined ?? undefined ?? false) || false || true); |
| assertTrue((null ?? null ?? false) || false || true); |
| assertTrue(false || (undefined ?? true)); |
| assertTrue(false || (null ?? true)); |
| assertTrue(false || false || (undefined ?? undefined ?? true)); |
| assertTrue(false || false || (null ?? null ?? true)); |
| |
| // Test use when test true. |
| if (undefined ?? true) {} else { assertUnreachable(); } |
| if (null ?? true) {} else { assertUnreachable(); } |
| |
| if (undefined ?? undefined ?? true) {} else { assertUnreachable(); } |
| if (null ?? null ?? true) {} else { assertUnreachable(); } |
| |
| // test use when test false |
| if (undefined ?? false) { assertUnreachable(); } else {} |
| if (null ?? false) { assertUnreachable(); } else {} |
| |
| if (undefined ?? undefined ?? false) { assertUnreachable(); } else {} |
| if (null ?? null ?? false) { assertUnreachable(); } else {} |
| |
| if (undefined ?? false ?? true) { assertUnreachable(); } else {} |
| if (null ?? false ?? true) { assertUnreachable(); } else {} |
| |
| // Test use with nested boolean. |
| if ((false || undefined) ?? true) {} else { assertUnreachable(); } |
| if ((false || null) ?? true) {} else { assertUnreachable(); } |
| |
| if ((false || undefined) ?? undefined ?? true) {} else { assertUnreachable(); } |
| if ((false || null) ?? null ?? true) {} else { assertUnreachable(); } |
| |
| if (undefined ?? (false || true)) {} else { assertUnreachable(); } |
| if (null ?? (false || true)) {} else { assertUnreachable(); } |
| |
| if (undefined ?? undefined ?? (false || true)) {} else { assertUnreachable(); } |
| if (null ?? null ?? (false || true)) {} else { assertUnreachable(); } |
| |
| if (undefined ?? (false || undefined) ?? true) {} else { assertUnreachable(); } |
| if (null ?? (false || null) ?? true) {} else { assertUnreachable(); } |
| |
| // Nested nullish. |
| if ((null ?? true) || false) {} else { assertUnreachable(); } |
| if ((null ?? null ?? true) || false) {} else { assertUnreachable(); } |
| |
| if (false || (null ?? true)) {} else { assertUnreachable(); } |
| if (false || (null ?? null ?? true)) {} else { assertUnreachable(); } |
| |
| if ((null ?? false) || false) { assertUnreachable(); } else {} |
| if ((null ?? null ?? false) || false) { assertUnreachable(); } else {} |
| |
| if (false || (null ?? false)) { assertUnreachable(); } else {} |
| if (false || (null ?? null ?? false)) { assertUnreachable(); } else {} |