assignment-operators.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. let x, o;
  2. test("basic functionality", () => {
  3. x = 1;
  4. expect((x = 2)).toBe(2);
  5. expect(x).toBe(2);
  6. x = 1;
  7. expect((x += 2)).toBe(3);
  8. expect(x).toBe(3);
  9. x = 3;
  10. expect((x -= 2)).toBe(1);
  11. expect(x).toBe(1);
  12. x = 3;
  13. expect((x *= 2)).toBe(6);
  14. expect(x).toBe(6);
  15. x = 6;
  16. expect((x /= 2)).toBe(3);
  17. expect(x).toBe(3);
  18. x = 6;
  19. expect((x %= 4)).toBe(2);
  20. expect(x).toBe(2);
  21. x = 2;
  22. expect((x **= 3)).toBe(8);
  23. expect(x).toBe(8);
  24. x = 3;
  25. expect((x &= 2)).toBe(2);
  26. expect(x).toBe(2);
  27. x = 3;
  28. expect((x |= 4)).toBe(7);
  29. expect(x).toBe(7);
  30. x = 6;
  31. expect((x ^= 2)).toBe(4);
  32. expect(x).toBe(4);
  33. x = 2;
  34. expect((x <<= 2)).toBe(8);
  35. expect(x).toBe(8);
  36. x = 8;
  37. expect((x >>= 2)).toBe(2);
  38. expect(x).toBe(2);
  39. x = -(2 ** 32 - 10);
  40. expect((x >>>= 2)).toBe(2);
  41. expect(x).toBe(2);
  42. });
  43. test("logical assignment operators", () => {
  44. // short circuiting evaluation
  45. x = false;
  46. expect((x &&= expect.fail())).toBeFalse();
  47. x = true;
  48. expect((x ||= expect.fail())).toBeTrue();
  49. x = "foo";
  50. expect((x ??= expect.fail())).toBe("foo");
  51. const prepareObject = (shortCircuitValue, assignmentValue) => ({
  52. get shortCircuit() {
  53. return shortCircuitValue;
  54. },
  55. set shortCircuit(_) {
  56. // assignment will short circuit in all test cases
  57. // so its setter must never be called
  58. expect().fail();
  59. },
  60. assignment: assignmentValue,
  61. });
  62. o = prepareObject(false, true);
  63. expect((o.shortCircuit &&= "foo")).toBeFalse();
  64. expect(o.shortCircuit).toBeFalse();
  65. expect((o.assignment &&= "bar")).toBe("bar");
  66. expect(o.assignment).toBe("bar");
  67. o = prepareObject(true, false);
  68. expect((o.shortCircuit ||= "foo")).toBeTrue();
  69. expect(o.shortCircuit).toBeTrue();
  70. expect((o.assignment ||= "bar")).toBe("bar");
  71. expect(o.assignment).toBe("bar");
  72. o = prepareObject("test", null);
  73. expect((o.shortCircuit ??= "foo")).toBe("test");
  74. expect(o.shortCircuit).toBe("test");
  75. expect((o.assignment ??= "bar")).toBe("bar");
  76. expect(o.assignment).toBe("bar");
  77. });
  78. test("evaluation order", () => {
  79. for (const op of [
  80. "=",
  81. "+=",
  82. "-=",
  83. "*=",
  84. "/=",
  85. "%=",
  86. "**=",
  87. "&=",
  88. "|=",
  89. "^=",
  90. "<<=",
  91. ">>=",
  92. ">>>=",
  93. "&&=",
  94. "||=",
  95. "??=",
  96. ]) {
  97. var a = [];
  98. function b() {
  99. b.hasBeenCalled = true;
  100. throw Error();
  101. }
  102. function c() {
  103. c.hasBeenCalled = true;
  104. throw Error();
  105. }
  106. b.hasBeenCalled = false;
  107. c.hasBeenCalled = false;
  108. expect(() => {
  109. new Function(`a[b()] ${op} c()`)();
  110. }).toThrow(Error);
  111. expect(b.hasBeenCalled).toBeTrue();
  112. expect(c.hasBeenCalled).toBeFalse();
  113. }
  114. });