tests.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*global describe, it, expect, mergebounce */
  2. describe("mergebounce", function () {
  3. it("merges passed in parameters before invoking the function", function (done) {
  4. let invokedData;
  5. const mergebounced = mergebounce(data => (invokedData = data), 10);
  6. mergebounced({'a': [{ 'b': 2 }, { 'd': 4 }]});
  7. mergebounced({'a': [{ 'c': 3 }, { 'e': 5 }]});
  8. setTimeout(() => {
  9. expect(invokedData).toEqual({ 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] })
  10. done();
  11. }, 15);
  12. });
  13. it("replaces arrays that don't contain objects", function (done) {
  14. let invokedData;
  15. const mergebounced = mergebounce(data => (invokedData = data), 10);
  16. mergebounced([{a: 2}, 4, 5]);
  17. mergebounced([{a: 1}, 2, 3, 4]);
  18. setTimeout(() => {
  19. expect(invokedData).toEqual([{a: 1}, 2, 3, 4]);
  20. done();
  21. }, 15);
  22. });
  23. it("concatenates arrays if concatArrays option is set", function (done) {
  24. let invokedData;
  25. const mergebounced = mergebounce(data => (invokedData = data), 10, {'concatArrays': true});
  26. mergebounced([{a: 2}, 4, 5]);
  27. mergebounced([{a: 1}, 2, 3, 4]);
  28. setTimeout(() => {
  29. expect(invokedData).toEqual([{a: 2}, 4, 5, {a: 1}, 2, 3, 4]);
  30. done();
  31. }, 15);
  32. });
  33. it('should dedupe concatenated arrays if "dedupeArrays" is set to true', function (done) {
  34. let callCount = 0;
  35. const values = [];
  36. let mergebounced = mergebounce((value) => {
  37. ++callCount;
  38. values.push(value);
  39. }, 32, {'dedupeArrays': true});
  40. mergebounced(['a']);
  41. mergebounced(['a']);
  42. mergebounced(['b']);
  43. expect(values.length).toBe(0);
  44. expect(callCount).toBe(0);
  45. setTimeout(() => {
  46. expect(callCount).toBe(1);
  47. expect(values).toEqual([['a', 'b']]);
  48. done();
  49. }, 128);
  50. });
  51. it("returns a promise if the promise option is set to true", function (done) {
  52. const mergebounced = mergebounce(() => {}, 10, {'promise': true});
  53. const result = mergebounced([{a: 2}, 4, 5]);
  54. expect(result instanceof Promise).toBe(true);
  55. expect(result.isResolved).toBe(false);
  56. setTimeout(() => {
  57. expect(result.isResolved).toBe(true);
  58. done();
  59. }, 15);
  60. });
  61. it("merges nested arrays uniquely", function (done) {
  62. let invokedData;
  63. const mergebounced = mergebounce(data => (invokedData = data), 10);
  64. mergebounced({'a': [{ 'b': 2 }, { 'd': [{a: 4}, {b: 6}] }]});
  65. mergebounced({'a': [{ 'c': 3 }, { 'd': [{a: 5}] }]});
  66. setTimeout(() => {
  67. expect(invokedData).toEqual({ 'a': [{ 'b': 2, 'c': 3 }, { 'd': [{a: 5}, {b: 6}] }] })
  68. done();
  69. }, 15);
  70. });
  71. it("gracefully handles no arguments being passed in", function (done) {
  72. let invokedData;
  73. const mergebounced = mergebounce(data => (invokedData = data), 10);
  74. mergebounced({'a': [{ 'b': 2 }, { 'd': [4] }]});
  75. mergebounced();
  76. setTimeout(() => {
  77. expect(invokedData).toEqual({'a': [{ 'b': 2 }, { 'd': [4] }]})
  78. done();
  79. }, 15);
  80. });
  81. it("handles multple arguments being passed in", function (done) {
  82. let args;
  83. const mergebounced = mergebounce(function () {
  84. args = Array.from(arguments);
  85. }, 10);
  86. mergebounced({ 'b': 2 }, { 'd': [4] });
  87. mergebounced({ 'c': 3 }, { 'd': [4, 5]});
  88. setTimeout(() => {
  89. expect(args).toEqual([{ 'b': 2, 'c': 3 }, { 'd': [4, 5] }])
  90. done();
  91. }, 15);
  92. });
  93. it("handles multple arguments of variable length", function (done) {
  94. let args;
  95. const mergebounced = mergebounce(function () {
  96. args = Array.from(arguments);
  97. }, 10);
  98. mergebounced({ 'b': 2 }, { 'd': [4] });
  99. mergebounced({ 'c': 3 });
  100. setTimeout(() => {
  101. expect(args).toEqual([{ 'b': 2, 'c': 3 }, { 'd': [4] }])
  102. done();
  103. }, 15);
  104. });
  105. it("keeps track of multple mergebounce functions", function (done) {
  106. let args1, args2;
  107. const mergebounced = mergebounce(function () {
  108. args1 = Array.from(arguments);
  109. }, 10);
  110. const mergebounced2 = mergebounce(function () {
  111. args2 = Array.from(arguments);
  112. }, 10);
  113. mergebounced({ 'b': 2 }, { 'd': [4] });
  114. mergebounced2({'a': [{ 'b': 2 }, { 'd': [4] }]});
  115. mergebounced({ 'c': 3 });
  116. mergebounced2({'a': [{ 'c': 3 }, { 'd': [4, 5] }]});
  117. setTimeout(() => {
  118. expect(args1).toEqual([{ 'b': 2, 'c': 3 }, { 'd': [4] }])
  119. expect(args2).toEqual([{ 'a': [{ 'b': 2, 'c': 3 }, { 'd': [4, 5] }] }])
  120. done();
  121. }, 15);
  122. });
  123. it('should debounce a function', function (done) {
  124. let callCount = 0;
  125. let mergebounced = mergebounce(function (value) {
  126. ++callCount;
  127. return value;
  128. }, 32);
  129. let results = [mergebounced('a'), mergebounced('b'), mergebounced('c')];
  130. expect(results).toEqual([undefined, undefined, undefined]);
  131. expect(callCount).toBe(0);
  132. setTimeout(function() {
  133. expect(callCount).toBe(1);
  134. const results = [mergebounced(['d']), mergebounced(['e']), mergebounced(['f'])];
  135. expect(results).toEqual(['c', 'c', 'c']);
  136. expect(callCount).toBe(1);
  137. }, 128);
  138. setTimeout(function() {
  139. expect(callCount).toBe(2);
  140. done();
  141. }, 256);
  142. });
  143. it("should not flush if it wasn't called at least once", function (done) {
  144. let callCount = 0;
  145. const mergebounced = mergebounce(() => ++callCount, 15);
  146. mergebounced.flush();
  147. expect(callCount).toBe(0);
  148. done();
  149. });
  150. it('should resolve when flushing', function(done) {
  151. let callCount = 0;
  152. const mergebounced = mergebounce(() => ++callCount, 0, {promise: true});
  153. mergebounced();
  154. mergebounced();
  155. expect(callCount).toBe(0);
  156. mergebounced.flush().then(() => {
  157. expect(callCount).toBe(1);
  158. done();
  159. });
  160. });
  161. it('should not immediately call `func` when `wait` is `0`', function(done) {
  162. let callCount = 0;
  163. const mergebounced = mergebounce(function() { ++callCount; }, 0);
  164. mergebounced();
  165. mergebounced();
  166. expect(callCount).toBe(0);
  167. setTimeout(function() {
  168. expect(callCount).toBe(1);
  169. done();
  170. }, 5);
  171. });
  172. it('should apply default options', function(done) {
  173. let callCount = 0;
  174. const mergebounced = mergebounce(() => callCount++, 32, {});
  175. mergebounced();
  176. expect(callCount).toEqual(0);
  177. setTimeout(function() {
  178. expect(callCount).toEqual(1);
  179. done();
  180. }, 64);
  181. });
  182. it('should support a `maxWait` option', function(done) {
  183. let callCount = 0;
  184. const mergebounced = mergebounce(function(value) {
  185. ++callCount;
  186. return value;
  187. }, 32, { 'maxWait': 64 });
  188. mergebounced();
  189. mergebounced();
  190. expect(callCount).toEqual(0);
  191. setTimeout(function() {
  192. expect(callCount).toEqual(1);
  193. mergebounced();
  194. mergebounced();
  195. expect(callCount).toEqual(1);
  196. }, 128);
  197. setTimeout(function() {
  198. expect(callCount).toEqual(2);
  199. done();
  200. }, 256);
  201. });
  202. it('should support `maxWait` in a tight loop', function(done) {
  203. let limit = 320,
  204. withCount = 0,
  205. withoutCount = 0;
  206. const withMaxWait = mergebounce(function() {
  207. withCount++;
  208. }, 64, { 'maxWait': 128 });
  209. let withoutMaxWait = mergebounce(function() {
  210. withoutCount++;
  211. }, 96);
  212. let start = +new Date;
  213. while ((new Date - start) < limit) {
  214. withMaxWait();
  215. withoutMaxWait();
  216. }
  217. let actual = [Boolean(withoutCount), Boolean(withCount)];
  218. setTimeout(function() {
  219. expect(actual).toEqual([false, true]);
  220. done();
  221. }, 1);
  222. });
  223. it('should queue a trailing call for subsequent mergebounced calls after `maxWait`', function(done) {
  224. let callCount = 0;
  225. let mergebounced = mergebounce(() => ++callCount, 200, { 'maxWait': 200 });
  226. mergebounced();
  227. setTimeout(mergebounced, 190);
  228. setTimeout(mergebounced, 200);
  229. setTimeout(mergebounced, 210);
  230. setTimeout(function() {
  231. expect(callCount).toEqual(2);
  232. done();
  233. }, 500);
  234. });
  235. it('should cancel `maxDelayed` when `delayed` is invoked', function(done) {
  236. let callCount = 0;
  237. let mergebounced = mergebounce(function() {
  238. callCount++;
  239. }, 32, { 'maxWait': 64 });
  240. mergebounced();
  241. setTimeout(function() {
  242. mergebounced();
  243. expect(callCount).toEqual(1);
  244. }, 128);
  245. setTimeout(function() {
  246. expect(callCount).toEqual(2);
  247. done();
  248. }, 192);
  249. });
  250. });