mutability.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. 'use strict';
  2. var test = require('tape');
  3. var assert = require('assert');
  4. var traverse = require('../');
  5. var deepEqual = require('./lib/deep_equal');
  6. test('mutate', function (t) {
  7. var obj = { a: 1, b: 2, c: [3, 4] };
  8. var res = traverse(obj).forEach(function (x) {
  9. if (typeof x === 'number' && x % 2 === 0) {
  10. this.update(x * 10);
  11. }
  12. });
  13. t.same(obj, res);
  14. t.same(obj, { a: 1, b: 20, c: [3, 40] });
  15. t.end();
  16. });
  17. test('mutateT', function (t) {
  18. var obj = { a: 1, b: 2, c: [3, 4] };
  19. var res = traverse.forEach(obj, function (x) {
  20. if (typeof x === 'number' && x % 2 === 0) {
  21. this.update(x * 10);
  22. }
  23. });
  24. t.same(obj, res);
  25. t.same(obj, { a: 1, b: 20, c: [3, 40] });
  26. t.end();
  27. });
  28. test('map', function (t) {
  29. var obj = { a: 1, b: 2, c: [3, 4] };
  30. var res = traverse(obj).map(function (x) {
  31. if (typeof x === 'number' && x % 2 === 0) {
  32. this.update(x * 10);
  33. }
  34. });
  35. t.same(obj, { a: 1, b: 2, c: [3, 4] });
  36. t.same(res, { a: 1, b: 20, c: [3, 40] });
  37. t.end();
  38. });
  39. test('mapT', function (t) {
  40. var obj = { a: 1, b: 2, c: [3, 4] };
  41. var res = traverse.map(obj, function (x) {
  42. if (typeof x === 'number' && x % 2 === 0) {
  43. this.update(x * 10);
  44. }
  45. });
  46. t.same(obj, { a: 1, b: 2, c: [3, 4] });
  47. t.same(res, { a: 1, b: 20, c: [3, 40] });
  48. t.end();
  49. });
  50. test('clone', function (t) {
  51. var obj = { a: 1, b: 2, c: [3, 4] };
  52. var res = traverse(obj).clone();
  53. t.same(obj, res);
  54. t.ok(obj !== res);
  55. obj.a += 1;
  56. t.same(res.a, 1);
  57. obj.c.push(5);
  58. t.same(res.c, [3, 4]);
  59. t.end();
  60. });
  61. test('cloneT', function (t) {
  62. var obj = { a: 1, b: 2, c: [3, 4] };
  63. var res = traverse.clone(obj);
  64. t.same(obj, res);
  65. t.ok(obj !== res);
  66. obj.a += 1;
  67. t.same(res.a, 1);
  68. obj.c.push(5);
  69. t.same(res.c, [3, 4]);
  70. t.end();
  71. });
  72. test('reduce', function (t) {
  73. var obj = { a: 1, b: 2, c: [3, 4] };
  74. var res = traverse(obj).reduce(function (acc, x) {
  75. if (this.isLeaf) { acc.push(x); }
  76. return acc;
  77. }, []);
  78. t.same(obj, { a: 1, b: 2, c: [3, 4] });
  79. t.same(res, [1, 2, 3, 4]);
  80. t.end();
  81. });
  82. test('reduceInit', function (t) {
  83. var obj = { a: 1, b: 2, c: [3, 4] };
  84. var res = traverse(obj).reduce(function (acc) {
  85. if (this.isRoot) { assert.fail('got root'); }
  86. return acc;
  87. });
  88. t.same(obj, { a: 1, b: 2, c: [3, 4] });
  89. t.same(res, obj);
  90. t.end();
  91. });
  92. test('remove', function (t) {
  93. var obj = { a: 1, b: 2, c: [3, 4] };
  94. traverse(obj).forEach(function (x) {
  95. if (this.isLeaf && x % 2 === 0) { this.remove(); }
  96. });
  97. t.same(obj, { a: 1, c: [3] });
  98. t.end();
  99. });
  100. test('removeNoStop', function (t) {
  101. var obj = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 5 };
  102. var keys = [];
  103. traverse(obj).forEach(function () {
  104. keys.push(this.key);
  105. if (this.key === 'c') { this.remove(); }
  106. });
  107. t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e', 'f']);
  108. t.end();
  109. });
  110. test('removeStop', function (t) {
  111. var obj = { a: 1, b: 2, c: { d: 3, e: 4 }, f: 5 };
  112. var keys = [];
  113. traverse(obj).forEach(function () {
  114. keys.push(this.key);
  115. if (this.key === 'c') { this.remove(true); }
  116. });
  117. t.same(keys, [undefined, 'a', 'b', 'c', 'f']);
  118. t.end();
  119. });
  120. test('removeMap', function (t) {
  121. var obj = { a: 1, b: 2, c: [3, 4] };
  122. var res = traverse(obj).map(function (x) {
  123. if (this.isLeaf && x % 2 === 0) { this.remove(); }
  124. });
  125. t.same(obj, { a: 1, b: 2, c: [3, 4] });
  126. t.same(res, { a: 1, c: [3] });
  127. t.end();
  128. });
  129. test('delete', function (t) {
  130. var obj = { a: 1, b: 2, c: [3, 4] };
  131. traverse(obj).forEach(function (x) {
  132. if (this.isLeaf && x % 2 === 0) { this.delete(); }
  133. });
  134. t.ok(!deepEqual(obj, { a: 1, c: [3, undefined] }));
  135. t.ok(deepEqual(obj, { a: 1, c: [3] }));
  136. t.ok(!deepEqual(obj, { a: 1, c: [3, null] }));
  137. t.end();
  138. });
  139. test('deleteNoStop', function (t) {
  140. var obj = { a: 1, b: 2, c: { d: 3, e: 4 } };
  141. var keys = [];
  142. traverse(obj).forEach(function () {
  143. keys.push(this.key);
  144. if (this.key === 'c') { this.delete(); }
  145. });
  146. t.same(keys, [undefined, 'a', 'b', 'c', 'd', 'e']);
  147. t.end();
  148. });
  149. test('deleteStop', function (t) {
  150. var obj = { a: 1, b: 2, c: { d: 3, e: 4 } };
  151. var keys = [];
  152. traverse(obj).forEach(function () {
  153. keys.push(this.key);
  154. if (this.key === 'c') { this.delete(true); }
  155. });
  156. t.same(keys, [undefined, 'a', 'b', 'c']);
  157. t.end();
  158. });
  159. test('deleteRedux', function (t) {
  160. var obj = { a: 1, b: 2, c: [3, 4, 5] };
  161. traverse(obj).forEach(function (x) {
  162. if (this.isLeaf && x % 2 === 0) { this.delete(); }
  163. });
  164. t.ok(!deepEqual(obj, { a: 1, c: [3, undefined, 5] }));
  165. t.ok(deepEqual(obj, { a: 1, c: [3,, 5] }));
  166. t.ok(!deepEqual(obj, { a: 1, c: [3, null, 5] }));
  167. t.ok(!deepEqual(obj, { a: 1, c: [3, 5] }));
  168. t.end();
  169. });
  170. test('deleteMap', function (t) {
  171. var obj = { a: 1, b: 2, c: [3, 4] };
  172. var res = traverse(obj).map(function (x) {
  173. if (this.isLeaf && x % 2 === 0) { this.delete(); }
  174. });
  175. t.ok(deepEqual(
  176. obj,
  177. { a: 1, b: 2, c: [3, 4] }
  178. ));
  179. var xs = [3, 4];
  180. delete xs[1];
  181. t.ok(deepEqual(res, { a: 1, c: xs }));
  182. t.ok(deepEqual(res, { a: 1, c: [3,,] })); // eslint-disable-line comma-spacing
  183. t.ok(deepEqual(res, { a: 1, c: [3] }));
  184. t.end();
  185. });
  186. test('deleteMapRedux', function (t) {
  187. var obj = { a: 1, b: 2, c: [3, 4, 5] };
  188. var res = traverse(obj).map(function (x) {
  189. if (this.isLeaf && x % 2 === 0) { this.delete(); }
  190. });
  191. t.ok(deepEqual(
  192. obj,
  193. { a: 1, b: 2, c: [3, 4, 5] }
  194. ));
  195. var xs = [3, 4, 5];
  196. delete xs[1];
  197. t.ok(deepEqual(res, { a: 1, c: xs }));
  198. t.ok(!deepEqual(res, { a: 1, c: [3, 5] }));
  199. t.ok(deepEqual(res, { a: 1, c: [3,, 5] }));
  200. t.end();
  201. });
  202. test('objectToString', function (t) {
  203. var obj = { a: 1, b: 2, c: [3, 4] };
  204. var res = traverse(obj).forEach(function (x) {
  205. if (typeof x === 'object' && !this.isRoot) {
  206. this.update(JSON.stringify(x));
  207. }
  208. });
  209. t.same(obj, res);
  210. t.same(obj, { a: 1, b: 2, c: '[3,4]' });
  211. t.end();
  212. });
  213. test('stringToObject', function (t) {
  214. var obj = { a: 1, b: 2, c: '[3,4]' };
  215. var res = traverse(obj).forEach(function (x) {
  216. if (typeof x === 'string') {
  217. this.update(JSON.parse(x));
  218. } else if (typeof x === 'number' && x % 2 === 0) {
  219. this.update(x * 10);
  220. }
  221. });
  222. t.deepEqual(obj, res);
  223. t.deepEqual(obj, { a: 1, b: 20, c: [3, 40] });
  224. t.end();
  225. });