computed-property-sideeffects.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. let calledToStringError = {};
  2. let throwingToString = {
  3. toString: () => {
  4. throw calledToStringError;
  5. },
  6. };
  7. let calledValueOfError = {};
  8. let throwingValueOf = {
  9. toString: undefined,
  10. valueOf: () => {
  11. throw calledValueOfError;
  12. },
  13. };
  14. let calledToStringAccessorError = {};
  15. let throwingToStringAccessor = {
  16. get toString() {
  17. throw calledToStringAccessorError;
  18. },
  19. };
  20. let calledValueOfAccessorError = {};
  21. let throwingValueOfAccessor = {
  22. toString: undefined,
  23. get valueOf() {
  24. throw calledValueOfAccessorError;
  25. },
  26. };
  27. test("Exceptions thrown by computed properties are caught", () => {
  28. var i = 0;
  29. var j = 0;
  30. var k = 0;
  31. expect(() => {
  32. return { first: k++, [throwingToString]: i++, second: j++ };
  33. }).toThrow(calledToStringError);
  34. expect(i).toBe(1);
  35. expect(j).toBe(0);
  36. expect(k).toBe(1);
  37. expect(() => {
  38. return { first: k++, [throwingValueOf]: i++, second: j++ };
  39. }).toThrow(calledValueOfError);
  40. expect(i).toBe(2);
  41. expect(j).toBe(0);
  42. expect(k).toBe(2);
  43. expect(() => {
  44. return { first: k++, [throwingToStringAccessor]: i++, second: j++ };
  45. }).toThrow(calledToStringAccessorError);
  46. expect(i).toBe(3);
  47. expect(j).toBe(0);
  48. expect(k).toBe(3);
  49. expect(() => {
  50. return { first: k++, [throwingValueOfAccessor]: i++, second: j++ };
  51. }).toThrow(calledValueOfAccessorError);
  52. expect(i).toBe(4);
  53. expect(j).toBe(0);
  54. expect(k).toBe(4);
  55. });
  56. test("Test toString and valueOf are only called once", () => {
  57. var counter = 0;
  58. var key1 = {
  59. valueOf: function () {
  60. expect(counter++).toBe(0);
  61. return "a";
  62. },
  63. toString: null,
  64. };
  65. var key2 = {
  66. valueOf: function () {
  67. expect(counter++).toBe(1);
  68. return "b";
  69. },
  70. toString: null,
  71. };
  72. var key3 = {
  73. get toString() {
  74. expect(counter++).toBe(2);
  75. return function () {
  76. return "c";
  77. };
  78. },
  79. };
  80. var key4 = {
  81. get valueOf() {
  82. expect(counter++).toBe(3);
  83. return function () {
  84. return "d";
  85. };
  86. },
  87. toString: null,
  88. };
  89. var key5 = {
  90. valueOf: function () {
  91. expect(counter++).toBe(4);
  92. return 0;
  93. },
  94. toString: null,
  95. };
  96. var key6 = {
  97. valueOf: function () {
  98. expect(counter++).toBe(5);
  99. return 2;
  100. },
  101. toString: null,
  102. };
  103. var key7 = {
  104. get toString() {
  105. expect(counter++).toBe(6);
  106. return function () {
  107. return 4;
  108. };
  109. },
  110. };
  111. var key8 = {
  112. get valueOf() {
  113. expect(counter++).toBe(7);
  114. return function () {
  115. return 8;
  116. };
  117. },
  118. toString: null,
  119. };
  120. var object = {
  121. [key1]: "a",
  122. [key2]: "b",
  123. [key3]: "c",
  124. [key4]: "d",
  125. [key5]: "e",
  126. [key6]: "f",
  127. [key7]: "g",
  128. [key8]: "h",
  129. };
  130. expect(counter).toBe(8);
  131. expect(object.a).toBe("a");
  132. expect(object.b).toBe("b");
  133. expect(object.c).toBe("c");
  134. expect(object.d).toBe("d");
  135. expect(object[0]).toBe("e");
  136. expect(object[2]).toBe("f");
  137. expect(object[4]).toBe("g");
  138. expect(object[8]).toBe("h");
  139. expect(Object.getOwnPropertyNames(object) + "").toBe(
  140. ["0", "2", "4", "8", "a", "b", "c", "d"] + ""
  141. );
  142. });