index.spec.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const fc = require("fast-check");
  4. const semver_1 = require("semver");
  5. const index_1 = require("./index");
  6. // Evaluate a string into JavaScript
  7. const evalValue = (str) => {
  8. // tslint:disable-next-line no-eval
  9. return eval(`(${str})`);
  10. };
  11. /**
  12. * Create a quick test function wrapper.
  13. */
  14. function test(value, result, indent, options) {
  15. return () => {
  16. expect(index_1.stringify(value, null, indent, options)).toEqual(result);
  17. };
  18. }
  19. /**
  20. * Create a wrapper for round-trip eval tests.
  21. */
  22. function testRoundTrip(expression, indent, options) {
  23. return () => test(evalValue(expression), expression, indent, options)();
  24. }
  25. /**
  26. * Check if syntax is supported.
  27. */
  28. function isSupported(expr) {
  29. try {
  30. // tslint:disable-next-line no-eval
  31. eval(expr);
  32. return true;
  33. }
  34. catch (err) {
  35. if (err.name === "SyntaxError")
  36. return false;
  37. throw err;
  38. }
  39. }
  40. /**
  41. * Generate a list of test cases to run.
  42. */
  43. function cases(cases) {
  44. return () => {
  45. for (const value of cases) {
  46. if (value)
  47. it(value, testRoundTrip(value));
  48. }
  49. };
  50. }
  51. /**
  52. * Conditionally execute test cases.
  53. */
  54. function describeIf(description, condition, fn) {
  55. return condition ? describe(description, fn) : describe.skip(description, fn);
  56. }
  57. describe("javascript-stringify", () => {
  58. describe("types", () => {
  59. describe("booleans", () => {
  60. it("should be stringified", test(true, "true"));
  61. });
  62. describe("strings", () => {
  63. it("should wrap in single quotes", test("string", "'string'"));
  64. it("should escape quote characters", test("'test'", "'\\'test\\''"));
  65. it("should escape control characters", test("multi\nline", "'multi\\nline'"));
  66. it("should escape back slashes", test("back\\slash", "'back\\\\slash'"));
  67. it("should escape certain unicode sequences", test("\u0602", "'\\u0602'"));
  68. });
  69. describe("numbers", () => {
  70. it("should stringify integers", test(10, "10"));
  71. it("should stringify floats", test(10.5, "10.5"));
  72. it('should stringify "NaN"', test(10.5, "10.5"));
  73. it('should stringify "Infinity"', test(Infinity, "Infinity"));
  74. it('should stringify "-Infinity"', test(-Infinity, "-Infinity"));
  75. it('should stringify "-0"', test(-0, "-0"));
  76. });
  77. describe("arrays", () => {
  78. it("should stringify as array shorthand", test([1, 2, 3], "[1,2,3]"));
  79. it("should indent elements", test([{ x: 10 }], "[\n\t{\n\t\tx: 10\n\t}\n]", "\t"));
  80. });
  81. describe("objects", () => {
  82. it("should stringify as object shorthand", test({ key: "value", "-": 10 }, "{key:'value','-':10}"));
  83. it("should stringify undefined keys", test({ a: true, b: undefined }, "{a:true,b:undefined}"));
  84. it("should stringify omit undefined keys", test({ a: true, b: undefined }, "{a:true}", null, {
  85. skipUndefinedProperties: true
  86. }));
  87. it("should quote reserved word keys", test({ if: true, else: false }, "{'if':true,'else':false}"));
  88. it("should not quote Object.prototype keys", test({ constructor: 1, toString: 2 }, "{constructor:1,toString:2}"));
  89. });
  90. describe("functions", () => {
  91. it("should reindent function bodies", test(evalValue(`function() {
  92. if (true) {
  93. return "hello";
  94. }
  95. }`), 'function () {\n if (true) {\n return "hello";\n }\n}', 2));
  96. it("should reindent function bodies in objects", test(evalValue(`
  97. {
  98. fn: function() {
  99. if (true) {
  100. return "hello";
  101. }
  102. }
  103. }
  104. `), '{\n fn: function () {\n if (true) {\n return "hello";\n }\n }\n}', 2));
  105. it("should reindent function bodies in arrays", test(evalValue(`[
  106. function() {
  107. if (true) {
  108. return "hello";
  109. }
  110. }
  111. ]`), '[\n function () {\n if (true) {\n return "hello";\n }\n }\n]', 2));
  112. it("should not need to reindent one-liners", testRoundTrip("{\n fn: function () { return; }\n}", 2));
  113. it("should gracefully handle unexpected Function.toString formats", () => {
  114. const origToString = Function.prototype.toString;
  115. Function.prototype.toString = () => "{nope}";
  116. try {
  117. expect(index_1.stringify(function () {
  118. /* Empty */
  119. })).toEqual("void '{nope}'");
  120. }
  121. finally {
  122. Function.prototype.toString = origToString;
  123. }
  124. });
  125. describe("omit the names of their keys", cases(["{name:function () {}}", "{'tricky name':function () {}}"]));
  126. });
  127. describe("native instances", () => {
  128. describe("Date", () => {
  129. const date = new Date();
  130. it("should stringify", test(date, "new Date(" + date.getTime() + ")"));
  131. });
  132. describe("RegExp", () => {
  133. it("should stringify as shorthand", test(/[abc]/gi, "/[abc]/gi"));
  134. });
  135. describe("Number", () => {
  136. it("should stringify", test(new Number(10), "new Number(10)"));
  137. });
  138. describe("String", () => {
  139. it("should stringify", test(new String("abc"), "new String('abc')"));
  140. });
  141. describe("Boolean", () => {
  142. it("should stringify", test(new Boolean(true), "new Boolean(true)"));
  143. });
  144. describeIf("Buffer", typeof Buffer === "function", () => {
  145. it("should stringify", test(Buffer.from("test"), "new Buffer('test')"));
  146. });
  147. describeIf("BigInt", typeof BigInt === "function", () => {
  148. it("should stringify", test(BigInt("10"), "BigInt('10')"));
  149. });
  150. describe("Error", () => {
  151. it("should stringify", test(new Error("test"), "new Error('test')"));
  152. });
  153. describe("unknown native type", () => {
  154. it("should be omitted", test({
  155. k: typeof process === "undefined"
  156. ? window.navigator
  157. : process
  158. }, "{}"));
  159. });
  160. });
  161. describeIf("ES6", typeof Array.from === "function", () => {
  162. describeIf("Map", typeof Map === "function", () => {
  163. it("should stringify", test(new Map([["key", "value"]]), "new Map([['key','value']])"));
  164. });
  165. describeIf("Set", typeof Set === "function", () => {
  166. it("should stringify", test(new Set(["key", "value"]), "new Set(['key','value'])"));
  167. });
  168. describe("arrow functions", () => {
  169. describe("should stringify", cases([
  170. "(a, b) => a + b",
  171. "o => { return o.a + o.b; }",
  172. "(a, b) => { if (a) { return b; } }",
  173. "(a, b) => ({ [a]: b })",
  174. "a => b => () => a + b"
  175. ]));
  176. it("should reindent function bodies", test(evalValue(" () => {\n" +
  177. " if (true) {\n" +
  178. ' return "hello";\n' +
  179. " }\n" +
  180. " }"), '() => {\n if (true) {\n return "hello";\n }\n}', 2));
  181. describeIf("arrows with patterns", isSupported("({x}) => x"), () => {
  182. describe("should stringify", cases([
  183. "({ x, y }) => x + y",
  184. "({ x, y }) => { if (x === '}') { return y; } }",
  185. "({ x, y = /[/})]/.test(x) }) => { return y ? x : 0; }"
  186. ]));
  187. });
  188. });
  189. describe("generators", () => {
  190. it("should stringify", testRoundTrip("function* (x) { yield x; }"));
  191. });
  192. describe("class notation", () => {
  193. it("should stringify classes", testRoundTrip("class {}"));
  194. it("should stringify class and method", testRoundTrip("class { method() {} }"));
  195. it("should stringify with newline", testRoundTrip("class\n{ method() {} }"));
  196. it("should stringify with comment", testRoundTrip("class/*test*/\n{ method() {} }"));
  197. });
  198. describe("method notation", () => {
  199. it("should stringify", testRoundTrip("{a(b, c) { return b + c; }}"));
  200. it("should stringify generator methods", testRoundTrip("{*a(b) { yield b; }}"));
  201. describe("should not be fooled by tricky names", cases([
  202. "{'function a'(b, c) { return b + c; }}",
  203. "{'a(a'(b, c) { return b + c; }}",
  204. "{'() => function '() {}}",
  205. "{'['() { return x[y]()\n{ return true; }}}",
  206. "{'() { return false;//'() { return true;\n}}"
  207. ]));
  208. it("should not be fooled by tricky generator names", testRoundTrip("{*'function a'(b, c) { return b + c; }}"));
  209. it("should not be fooled by empty names", testRoundTrip("{''(b, c) { return b + c; }}"));
  210. it("should not be fooled by keys that look like functions", () => {
  211. const fn = evalValue('{ "() => ": () => () => 42 }')["() => "];
  212. expect(index_1.stringify(fn)).toEqual("() => () => 42");
  213. });
  214. describe("should not be fooled by arrow functions", cases([
  215. "{a:(b, c) => b + c}",
  216. "{a:a => a + 1}",
  217. "{'() => ':() => () => 42}",
  218. '{\'() => "\':() => "() {//"}',
  219. '{\'() => "\':() => "() {`//"}',
  220. '{\'() => "\':() => "() {`${//"}',
  221. '{\'() => "\':() => "() {/*//"}',
  222. semver_1.satisfies(process.versions.node, "<=4 || >=10")
  223. ? "{'a => function ':a => function () { return a + 1; }}"
  224. : undefined
  225. ]));
  226. describe("should not be fooled by regexp literals", cases([
  227. "{' '(s) { return /}/.test(s); }}",
  228. "{' '(s) { return /abc/ .test(s); }}",
  229. "{' '() { return x / y; // /}\n}}",
  230. "{' '() { return / y; }//* } */}}",
  231. "{' '() { return delete / y; }/.x}}",
  232. "{' '() { switch (x) { case / y; }}/: }}}",
  233. "{' '() { if (x) return; else / y;}/; }}",
  234. "{' '() { return x in / y;}/; }}",
  235. "{' '() { return x instanceof / y;}/; }}",
  236. "{' '() { return new / y;}/.x; }}",
  237. "{' '() { throw / y;}/.x; }}",
  238. "{' '() { return typeof / y;}/; }}",
  239. "{' '() { void / y;}/; }}",
  240. "{' '() { return x, / y;}/; }}",
  241. "{' '() { return x; / y;}/; }}",
  242. "{' '() { return { x: / y;}/ }; }}",
  243. "{' '() { return x + / y;}/.x; }}",
  244. "{' '() { return x - / y;}/.x; }}",
  245. "{' '() { return !/ y;}/; }}",
  246. "{' '() { return ~/ y;}/.x; }}",
  247. "{' '() { return x && / y;}/; }}",
  248. "{' '() { return x || / y;}/; }}",
  249. "{' '() { return x ^ / y;}/.x; }}",
  250. "{' '() { return x * / y;}/.x; }}",
  251. "{' '() { return x / / y;}/.x; }}",
  252. "{' '() { return x % / y;}/.x; }}",
  253. "{' '() { return x < / y;}/.x; }}",
  254. "{' '() { return x > / y;}/.x; }}",
  255. "{' '() { return x <= / y;}/.x; }}",
  256. "{' '() { return x /= / y;}/.x; }}",
  257. "{' '() { return x ? / y;}/ : false; }}"
  258. ]));
  259. describe("should not be fooled by computed names", () => {
  260. it("1", test(evalValue('{ ["foobar".slice(3)](x) { return x + 1; } }'), "{bar(x) { return x + 1; }}"));
  261. it("2", test(evalValue('{[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\",\\"+s(b)+b)(JSON.stringify,",")]() {}")]() {}}'), '{\'[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\\\",\\\\"+s(b)+b)(JSON.stringify,",")]() {}")]() {}\'() {}}'));
  262. it("3", test(evalValue('{[`over${`6${"0".repeat(3)}`.replace("6", "9")}`]() { this.activateHair(); }}'), "{over9000() { this.activateHair(); }}"));
  263. it("4", test(evalValue("{[\"() {'\"]() {''}}"), "{'() {\\''() {''}}"));
  264. it("5", test(evalValue('{["() {`"]() {``}}'), "{'() {`'() {``}}"));
  265. it("6", test(evalValue('{["() {/*"]() {/*`${()=>{/*}*/}}'), "{'() {/*'() {/*`${()=>{/*}*/}}"));
  266. });
  267. // These two cases demonstrate that branching on
  268. // METHOD_NAMES_ARE_QUOTED is unavoidable--you can't write code
  269. // without it that will pass both of these cases on both node.js 4
  270. // and node.js 10. (If you think you can, consider that the name and
  271. // toString of the first case when executed on node.js 10 are
  272. // identical to the name and toString of the second case when
  273. // executed on node.js 4, so good luck telling them apart without
  274. // knowing which node you're on.)
  275. describe("should handle different versions of node correctly", () => {
  276. it("1", test(evalValue('{[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\",\\"+s(b)+b)(JSON.stringify,",")]() { return 0; /*")]() { return 0; /*() {/* */ return 1;}}'), '{\'[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\\\",\\\\"+s(b)+b)(JSON.stringify,",")]() { return 0; /*")]() { return 0; /*\'() { return 0; /*() {/* */ return 1;}}'));
  277. it("2", test(evalValue('{\'[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\\\",\\\\"+s(b)+b)(JSON.stringify,",")]() { return 0; /*")]() { return 0; /*\'() {/* */ return 1;}}'), '{\'[((s,a,b)=>a+s(a)+","+s(b)+b)(JSON.stringify,"[((s,a,b)=>a+s(a)+\\\\",\\\\"+s(b)+b)(JSON.stringify,",")]() { return 0; /*")]() { return 0; /*\'() {/* */ return 1;}}'));
  278. });
  279. it("should not be fooled by comments", test(evalValue("{'method' /* a comment! */ () /* another comment! */ {}}"), "{method() /* another comment! */ {}}"));
  280. it("should stringify extracted methods", () => {
  281. const fn = evalValue("{ foo(x) { return x + 1; } }").foo;
  282. expect(index_1.stringify(fn)).toEqual("function foo(x) { return x + 1; }");
  283. });
  284. it("should stringify extracted generators", () => {
  285. const fn = evalValue("{ *foo(x) { yield x; } }").foo;
  286. expect(index_1.stringify(fn)).toEqual("function* foo(x) { yield x; }");
  287. });
  288. it("should stringify extracted methods with tricky names", () => {
  289. const fn = evalValue('{ "a(a"(x) { return x + 1; } }')["a(a"];
  290. expect(index_1.stringify(fn)).toEqual("function (x) { return x + 1; }");
  291. });
  292. it("should stringify extracted methods with arrow-like tricky names", () => {
  293. const fn = evalValue('{ "() => function "(x) { return x + 1; } }')["() => function "];
  294. expect(index_1.stringify(fn)).toEqual("function (x) { return x + 1; }");
  295. });
  296. it("should stringify extracted methods with empty names", () => {
  297. const fn = evalValue('{ ""(x) { return x + 1; } }')[""];
  298. expect(index_1.stringify(fn)).toEqual("function (x) { return x + 1; }");
  299. });
  300. it("should handle transplanted names", () => {
  301. const fn = evalValue("{ foo(x) { return x + 1; } }").foo;
  302. expect(index_1.stringify({ bar: fn })).toEqual("{bar:function foo(x) { return x + 1; }}");
  303. });
  304. it("should handle transplanted names with generators", () => {
  305. const fn = evalValue("{ *foo(x) { yield x; } }").foo;
  306. expect(index_1.stringify({ bar: fn })).toEqual("{bar:function* foo(x) { yield x; }}");
  307. });
  308. it("should reindent methods", test(evalValue(" {\n" +
  309. " fn() {\n" +
  310. " if (true) {\n" +
  311. ' return "hello";\n' +
  312. " }\n" +
  313. " }\n" +
  314. " }"), '{\n fn() {\n if (true) {\n return "hello";\n }\n }\n}', 2));
  315. });
  316. });
  317. describe("ES2017", () => {
  318. describeIf("async functions", isSupported("(async function () {})"), () => {
  319. it("should stringify", testRoundTrip("async function (x) { await x; }"));
  320. it("should gracefully handle unexpected Function.toString formats", () => {
  321. const origToString = Function.prototype.toString;
  322. Function.prototype.toString = () => "{nope}";
  323. try {
  324. expect(index_1.stringify(evalValue("async function () {}"))).toEqual("void '{nope}'");
  325. }
  326. finally {
  327. Function.prototype.toString = origToString;
  328. }
  329. });
  330. });
  331. describeIf("async arrows", isSupported("async () => {}"), () => {
  332. describe("should stringify", cases([
  333. "async (x) => x + 1",
  334. "async x => x + 1",
  335. "async x => { await x.then(y => y + 1); }"
  336. ]));
  337. describe("should stringify as object properties", cases([
  338. "{f:async a => a + 1}",
  339. semver_1.satisfies(process.versions.node, "<=4 || >=10")
  340. ? "{'async a => function ':async a => function () { return a + 1; }}"
  341. : undefined
  342. ]));
  343. });
  344. });
  345. describe("ES2018", () => {
  346. describeIf("async generators", isSupported("(async function* () {})"), () => {
  347. it("should stringify", testRoundTrip("async function* (x) { yield x; }"));
  348. it("should gracefully handle unexpected Function.toString formats", () => {
  349. const origToString = Function.prototype.toString;
  350. Function.prototype.toString = () => "{nope}";
  351. try {
  352. expect(index_1.stringify(evalValue("async function* () {}"))).toEqual("void '{nope}'");
  353. }
  354. finally {
  355. Function.prototype.toString = origToString;
  356. }
  357. });
  358. });
  359. });
  360. describe("global", () => {
  361. it("should access the global in the current environment", testRoundTrip("Function('return this')()"));
  362. });
  363. });
  364. describe("circular references", () => {
  365. it("should omit circular references", () => {
  366. const obj = { key: "value" };
  367. obj.obj = obj;
  368. const result = index_1.stringify(obj);
  369. expect(result).toEqual("{key:'value'}");
  370. });
  371. it("should restore value", () => {
  372. const obj = { key: "value" };
  373. obj.obj = obj;
  374. const result = index_1.stringify(obj, null, null, { references: true });
  375. expect(result).toEqual("(function(){var x={key:'value'};x.obj=x;return x;}())");
  376. });
  377. it("should omit recursive array value", () => {
  378. const obj = [1, 2, 3];
  379. obj.push(obj);
  380. const result = index_1.stringify(obj);
  381. expect(result).toEqual("[1,2,3,undefined]");
  382. });
  383. it("should restore array value", () => {
  384. const obj = [1, 2, 3];
  385. obj.push(obj);
  386. const result = index_1.stringify(obj, null, null, { references: true });
  387. expect(result).toEqual("(function(){var x=[1,2,3,undefined];x[3]=x;return x;}())");
  388. });
  389. it("should print repeated values when no references enabled", () => {
  390. const obj = {};
  391. const child = {};
  392. obj.a = child;
  393. obj.b = child;
  394. const result = index_1.stringify(obj);
  395. expect(result).toEqual("{a:{},b:{}}");
  396. });
  397. it("should restore repeated values", () => {
  398. const obj = {};
  399. const child = {};
  400. obj.a = child;
  401. obj.b = child;
  402. const result = index_1.stringify(obj, null, null, { references: true });
  403. expect(result).toEqual("(function(){var x={a:{}};x.b=x.a;return x;}())");
  404. });
  405. it("should restore repeated values with indentation", function () {
  406. const obj = {};
  407. const child = {};
  408. obj.a = child;
  409. obj.b = child;
  410. const result = index_1.stringify(obj, null, 2, { references: true });
  411. expect(result).toEqual("(function () {\nvar x = {\n a: {}\n};\nx.b = x.a;\nreturn x;\n}())");
  412. });
  413. });
  414. describe("custom indent", () => {
  415. it("string", () => {
  416. const result = index_1.stringify({
  417. test: [1, 2, 3],
  418. nested: {
  419. key: "value"
  420. }
  421. }, null, "\t");
  422. expect(result).toEqual("{\n" +
  423. "\ttest: [\n\t\t1,\n\t\t2,\n\t\t3\n\t],\n" +
  424. "\tnested: {\n\t\tkey: 'value'\n\t}\n" +
  425. "}");
  426. });
  427. it("integer", () => {
  428. const result = index_1.stringify({
  429. test: [1, 2, 3],
  430. nested: {
  431. key: "value"
  432. }
  433. }, null, 2);
  434. expect(result).toEqual("{\n" +
  435. " test: [\n 1,\n 2,\n 3\n ],\n" +
  436. " nested: {\n key: 'value'\n }\n" +
  437. "}");
  438. });
  439. it("float", () => {
  440. const result = index_1.stringify({
  441. test: [1, 2, 3],
  442. nested: {
  443. key: "value"
  444. }
  445. }, null, 2.6);
  446. expect(result).toEqual("{\n" +
  447. " test: [\n 1,\n 2,\n 3\n ],\n" +
  448. " nested: {\n key: 'value'\n }\n" +
  449. "}");
  450. });
  451. });
  452. describe("replacer function", () => {
  453. it("should allow custom replacements", () => {
  454. let callCount = 0;
  455. const result = index_1.stringify({
  456. test: "value"
  457. }, function (value, indent, next) {
  458. callCount++;
  459. if (typeof value === "string") {
  460. return '"hello"';
  461. }
  462. return next(value);
  463. });
  464. expect(callCount).toEqual(2);
  465. expect(result).toEqual('{test:"hello"}');
  466. });
  467. it("change primitive to object", () => {
  468. const result = index_1.stringify({
  469. test: 10
  470. }, function (value, indent, next) {
  471. if (typeof value === "number") {
  472. return next({ obj: "value" });
  473. }
  474. return next(value);
  475. });
  476. expect(result).toEqual("{test:{obj:'value'}}");
  477. });
  478. it("change object to primitive", () => {
  479. const result = index_1.stringify({
  480. test: 10
  481. }, value => Object.prototype.toString.call(value));
  482. expect(result).toEqual("[object Object]");
  483. });
  484. it("should support object functions", () => {
  485. function makeRaw(str) {
  486. const fn = () => {
  487. /* Noop. */
  488. };
  489. fn.__expression = str;
  490. return fn;
  491. }
  492. const result = index_1.stringify({
  493. "no-console": makeRaw(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`),
  494. "no-debugger": makeRaw(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`)
  495. }, (val, indent, stringify) => {
  496. if (val && val.__expression) {
  497. return val.__expression;
  498. }
  499. return stringify(val);
  500. }, 2);
  501. expect(result).toEqual(`{
  502. 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  503. 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
  504. }`);
  505. });
  506. });
  507. describe("max depth", () => {
  508. const obj = { a: { b: { c: 1 } } };
  509. it("should get all object", test(obj, "{a:{b:{c:1}}}"));
  510. it("should get part of the object", test(obj, "{a:{b:{}}}", null, { maxDepth: 2 }));
  511. it("should get part of the object when tracking references", test(obj, "{a:{b:{}}}", null, { maxDepth: 2, references: true }));
  512. });
  513. describe("property based", () => {
  514. it("should produce string evaluating to the original value", () => {
  515. fc.assert(fc.property(fc.anything(), value => {
  516. expect(evalValue(index_1.stringify(value))).toEqual(value);
  517. }));
  518. });
  519. });
  520. });
  521. //# sourceMappingURL=index.spec.js.map