testdouble.js icon indicating copy to clipboard operation
testdouble.js copied to clipboard

RangeError: Maximum call stack size exceeded when a function accepts a deep/complex object as its argument

Open natesilva opened this issue 6 years ago • 1 comments

Description

We are trying to stub a function that accepts as an argument a very large/deep object.

The specific function is graphql(schema, …) where the first argument is a large GraphQL schema object.

Issue

This fails at https://github.com/testdouble/testdouble.js/blob/master/src/store/calls.js#L10 where it calls Lodash cloneDeep -- the object is either too deep or to complex for Lodash to clone.

We tried telling testdouble to expect td.matchers.anything() for the first argument, but this didn’t help because all calls to stubbed functions are logged.

Is there a way to turn off logging for a stubbed function? We don’t need to verify this invocation so there’s no need to log it.

The callstack looks like this:

     RangeError: Maximum call stack size exceeded
      at Object (<anonymous>)
      at /Users/nate/code/companyname/productname/node_modules/testdouble/node_modules/lodash/_overArg.js:11:17
      at initCloneObject (node_modules/testdouble/node_modules/lodash/_initCloneObject.js:14:18)
      at baseClone (node_modules/testdouble/node_modules/lodash/_baseClone.js:118:42)
      at /Users/nate/code/companyname/productname/node_modules/testdouble/node_modules/lodash/_baseClone.js:160:30
      at arrayEach (node_modules/testdouble/node_modules/lodash/_arrayEach.js:15:9)
      
      …many many lines of this…
      
      at baseClone (node_modules/testdouble/node_modules/lodash/_baseClone.js:154:3)
      at /Users/nate/code/companyname/productname/node_modules/testdouble/node_modules/lodash/_baseClone.js:160:30
      at arrayEach (node_modules/testdouble/node_modules/lodash/_arrayEach.js:15:9)
      at baseClone (node_modules/testdouble/node_modules/lodash/_baseClone.js:154:3)
      at Object.cloneDeep (node_modules/testdouble/node_modules/lodash/cloneDeep.js:26:10)
      at Object.log (node_modules/testdouble/lib/store/calls.js:10:112)
      at Object.testDouble (node_modules/testdouble/lib/function.js:32:25)
      at Context.it.only (src/graphql/resolvers/bogus.spec.ts:14:11)
      at process.topLevelDomainCallback (domain.js:126:23)

Environment

  • [x] node -v output: 10.17.0
  • [x] npm -v (or yarn --version) output: 6.11.3
  • [x] npm ls testdouble (or yarn list testdouble) version: 3.12.4

Runkit Notebook

https://runkit.com/natesilva/testdouble---deeply-nested-object-as-function-argument

Our schema isn’t (quite) as ridiculous as the object shown in the Runkit but this was the easiest way to demonstrate the problem.

natesilva avatar Nov 12 '19 20:11 natesilva

Surprised we haven't run into this before.

I worry about exposing an option to turn off logging altogether, because it'd confuse people by affect stubbing behavior that relied on the log (like the number of times a stub can be applied), it'd make td.explain() incorrect, and of course verify calls would stop working.

However, it seems like exposing some kind of option for copying args by reference for specifically this case, or perhaps giving an opportunity to intercept the arg cloner (so that you could short circuit the deep copy in this particular case but let it call through otherwise) might be desirable here. I'd definitely be open to a PR that explored either approach so long as it didn't break anything else

searls avatar Nov 13 '19 01:11 searls

Stale. Closing. Please reopen if still relevant and I will look into it.

giltayar avatar Sep 16 '23 11:09 giltayar