cjohansen/Sinon.JS — pull request #321 by keithamus (2013-08-29 10:36:45+00:00)
Title: Add additional stack trace information to wrappedMethod errors

### Problem Summary

When stubbing or spying on a function, if you attempt to stub/spy on it again, then you will get an error:

```"Attempted to wrap " + (typeof wrappedMethod) + " property " + property + " as function```

This error does not indicate what line of code the method was originally wrapped on, which -- in large test suites -- can mean developers hunting for where the method was originally stubbed, so they can restore it on teardown.

### Proposal
This error should also indicate the stack trace of the originally wrapped function in the error, so that a developer can see where the already wrapped function was originally wrapped, to amend *that* code and restore the wrapped method after a teardown.

### PR Technical details:
- Upon successful execution of `wrapMethod`, a stack trace is recorded to `method._stack` which gives us the stack trace of the line that stubbed/spied on the method.
- When `wrapMethod` gets into the condition that it will throw an error, it appends the `method._stack` to the errors stack trace, which gives us both the stack trace for the current error, plus the stack trace from the original function call to stub/spy on this method.

Before this PR:

```javascript
TypeError: Attempted to wrap initialize which is already spied on
at Object.wrapMethod (http://localhost:3000/sinon-1.6.0.js:533:25)
at Object.stub (http://localhost:3000/sinon-1.6.0.js:1671:22)
at Object.stub (http://localhost:3000/sinon-1.6.0.js:2533:40)
at Context.obj.stub (http://localhost:3000/sinon-1.6.0.js:2548:33)
at Context. (http://localhost:3000/frontend/views/something.test.js:24:14)
[...]
```

After this PR:

```javascript
TypeError: Attempted to wrap initialize which is already spied on
at Object.wrapMethod (http://localhost:3000/sinon-1.6.0.js:533:25)
at Object.stub (http://localhost:3000/sinon-1.6.0.js:1671:22)
at Object.stub (http://localhost:3000/sinon-1.6.0.js:2533:40)
at Context.obj.stub (http://localhost:3000/sinon-1.6.0.js:2548:33)
at Context. (http://localhost:3000/frontend/views/something.test.js:24:14)
[...]
--------------
Error: Stack Trace for original
at Object.wrapMethod (http://localhost:3000/sinon-1.6.0.js:547:30)
at Object.spy (http://localhost:3000/sinon-1.6.0.js:1090:22)
at Context. (http://localhost:3000/frontend/views/originator.test.js:83:19)
[...]
```

### Testing

I'm unsure if I should test this, primarily for 2 reasons:

- IE<10 does not support stack traces, which means the tests would fail in these browsers (even though Sinon is supported for these browsers)
- Firefox and Chrome produce completely different stack traces, which while they have the correct information are difficult to reliably test the correct output of this.

If you feel tests are needed for this, I'm happy to write them. In the meantime you can manually test by setting up a test which stubs a method twice, the second stub should produce an error with 2 stack traces.