Repository: unexpectedjs/unexpected
Pull request #443 (2018-04-06 14:08:32)

Trim stack traces with windows paths
Encountered this stack trace on windows:

```
 FAIL  Scripts\src\lib\PfgDataCollection.test.js

  ● PfgDataCollections › should deliberately fail

    expected true to be false

      10 | 
      11 |     it('should deliberately fail', function () {
      12 |         expect(true, 'to be', false)
      13 |     });
      14 | 
      15 |     describe('constructor', function () {

      at Function.callInNestedContext (../../node_modules/unexpected/build/lib/createWrappedExpectProto.js:131:30)
      at wrappedExpect (../../node_modules/unexpected/build/lib/Unexpected.js:1212:28)
      at Function.<anonymous> (../../node_modules/unexpected/build/lib/assertions.js:41:5)
      at executeExpect (../../node_modules/unexpected/build/lib/Unexpected.js:1249:77)
      at Unexpected.expect [as _expect] (../../node_modules/unexpected/build/lib/Unexpected.js:1253:18)
      at expect (../../node_modules/unexpected/build/lib/Unexpected.js:888:23)
      at Object.<anonymous> (lib/PfgDataCollection.test.js:12:9)
```

Note the lines pointing at unexpected internals.

When inspecting https://github.com/unexpectedjs/unexpected/blob/061924039188905ed6f59a1851d9a06306a15b6c/lib/UnexpectedError.js#L289-L294 it became clear that the paths have backslashes on windows at this point, meaning the regexes never matched.


Patch:
diff --git a/lib/UnexpectedError.js b/lib/UnexpectedError.js
index 02b3137d..b5cead74 100644
--- a/lib/UnexpectedError.js
+++ b/lib/UnexpectedError.js
@@ -289,8 +289,10 @@ UnexpectedError.prototype.serializeMessage = function(outputFormat) {
       const newStack = lines.filter(
         (line, i) =>
           i < stackStart ||
-          (!/node_modules\/unexpected(?:-[^/]+)?\//.test(line) &&
-            !/executeExpect.*node_modules\/unexpected\//.test(lines[i + 1]))
+          (!/node_modules[/\\]unexpected(?:-[^/\\]+)?[/\\]/.test(line) &&
+            !/executeExpect.*node_modules[/\\]unexpected[/\\]/.test(
+              lines[i + 1]
+            ))
       );
 
       if (newStack.length !== lines.length) {


Test patch:
diff --git a/test/api/UnexpectedError.spec.js b/test/api/UnexpectedError.spec.js
index 9c85c31f..8a160eec 100644
--- a/test/api/UnexpectedError.spec.js
+++ b/test/api/UnexpectedError.spec.js
@@ -89,6 +89,37 @@ describe('UnexpectedError', function() {
       );
     });
 
+    it('trims the stack for node_module\\unexpected\\ and node_module\\unexpected-<plugin-name>\\ (windows paths)', function() {
+      expect(
+        function() {
+          expect.fail('wat');
+        },
+        'to throw',
+        function(err) {
+          err.useFullStackTrace = false;
+          err._hasSerializedErrorMessage = false;
+          err.stack =
+            'wat\n' +
+            '      at oathbreaker (node_modules\\unexpected\\lib\\oathbreaker.js:46:19)\n' +
+            '      at Function.Unexpected.withError (node_modules\\unexpected-sinon\\lib\\unexpected-sinon.js:123:1)\n' +
+            '      at Function.Unexpected.withError (node_modules\\unexpected\\lib\\Unexpected.js:792:12)\n' +
+            '      at Function.<anonymous> (node_modules\\unexpected\\lib\\assertions.js:569:16)\n' +
+            '      at executeExpect (node_modules\\unexpected\\lib\\Unexpected.js:1103:50)\n' +
+            '      at Unexpected.expect (node_modules\\unexpected\\lib\\Unexpected.js:1111:22)\n' +
+            '      at Context.<anonymous> (test\\Insection.spec.js:48:17)';
+
+          err.serializeMessage('text');
+
+          expect(err, 'to satisfy', {
+            stack:
+              'wat\n' +
+              '      at Context.<anonymous> (test\\Insection.spec.js:48:17)\n' +
+              '      set UNEXPECTED_FULL_TRACE=true to see the full stack trace'
+          });
+        }
+      );
+    });
+
     it('trims the stack for custom assertions in the consuming code', () => {
       expect(
         function() {