Comparing version 2.0.1 to 3.0.0
44
index.js
@@ -13,3 +13,3 @@ 'use strict' | ||
var LINES_OF_CONTEXT = 7 | ||
var LINES_OF_CONTEXT = 5 | ||
var ESCAPED_REGEX_PATH_SEP = path.sep === '/' ? '/' : '\\\\' | ||
@@ -91,9 +91,13 @@ var MODULE_FOLDER_REGEX = new RegExp('.*node_modules' + ESCAPED_REGEX_PATH_SEP + '([^' + ESCAPED_REGEX_PATH_SEP + ']*)') | ||
opts.inAppLines = opts.inAppLines >= 0 ? opts.inAppLines : (opts.lines || LINES_OF_CONTEXT) | ||
opts.libraryLines = opts.libraryLines >= 0 ? opts.libraryLines : (opts.lines || LINES_OF_CONTEXT) | ||
var next = afterAll(cb) | ||
callsites.forEach(function (callsite) { | ||
if (callsite.isNode()) { | ||
var lines = callsite.isApp() ? opts.inAppLines : opts.libraryLines | ||
if (lines > 0 && !callsite.isNode()) { | ||
callsite.sourceContext(lines, next()) | ||
} else { | ||
next()(null, null) | ||
} else { | ||
callsite.sourceContext(opts, next()) | ||
} | ||
@@ -156,8 +160,15 @@ }) | ||
function sourceContext (opts, cb) { | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
function sourceContext (lines, cb) { | ||
if (typeof lines === 'function') { | ||
cb = lines | ||
lines = LINES_OF_CONTEXT | ||
} | ||
if (lines <= 0) { | ||
process.nextTick(function () { | ||
cb(new Error('Cannot collect less than one line of source context')) | ||
}) | ||
return | ||
} | ||
if (this.isNode()) { | ||
@@ -178,3 +189,3 @@ process.nextTick(function () { | ||
process.nextTick(function () { | ||
cb(null, parseSource(source, callsite, opts)) | ||
cb(null, parseSource(source, callsite, lines)) | ||
}) | ||
@@ -187,3 +198,3 @@ } else { | ||
} else { | ||
cb(null, parseSource(source, callsite, opts)) | ||
cb(null, parseSource(source, callsite, lines)) | ||
} | ||
@@ -194,10 +205,11 @@ }) | ||
function parseSource (source, callsite, opts) { | ||
function parseSource (source, callsite, linesOfContext) { | ||
var lines = source.split(/\r?\n/) | ||
var linesOfContext = opts.lines || LINES_OF_CONTEXT | ||
var lineno = callsite.getLineNumber() | ||
var index = callsite.getLineNumber() - 1 | ||
var preLinesOfContext = Math.ceil((linesOfContext - 1) / 2) | ||
var postLinesOfContext = Math.floor((linesOfContext - 1) / 2) | ||
return { | ||
pre: lines.slice(Math.max(0, lineno - (linesOfContext + 1)), lineno - 1), | ||
line: lines[lineno - 1], | ||
post: lines.slice(lineno, lineno + linesOfContext) | ||
pre: lines.slice(Math.max(0, index - preLinesOfContext), index), | ||
line: lines[index], | ||
post: lines.slice(index + 1, index + 1 + postLinesOfContext) | ||
} | ||
@@ -204,0 +216,0 @@ } |
{ | ||
"name": "stackman", | ||
"version": "2.0.1", | ||
"version": "3.0.0", | ||
"description": "Enhance an error stacktrace with code excerpts and other goodies", | ||
@@ -48,4 +48,4 @@ "main": "index.js", | ||
"coordinates": [ | ||
55.68112989999999, | ||
12.5645466 | ||
55.7532231, | ||
12.571709 | ||
], | ||
@@ -52,0 +52,0 @@ "standard": { |
@@ -13,3 +13,3 @@ # Stackman | ||
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) | ||
[![sponsor](https://img.shields.io/badge/sponsored%20by-Opbeat-3360A3.svg)](https://opbeat.com) | ||
[![sponsor](https://img.shields.io/badge/sponsored%20by-Elastic-3360A3.svg)](https://www.elastic.co) | ||
@@ -114,7 +114,18 @@ ## Install | ||
Each element in the context array matches a call site in the `callsites` | ||
array. The optional `options` object will be passed on to | ||
[`callsite.sourceContext()`](#callsitesourcecontextoptions-callback). | ||
array. | ||
All node core call sites will have the context value `null`. | ||
Options: | ||
- `lines` - Total number of lines of soruce context to be loaded with | ||
the call site line in the center (default: `5`) | ||
- `inAppLines` - Total number of lines of soruce context to be loaded | ||
with the call site line in the center if `callsite.isApp()` is `true`. | ||
Overwrites `lines` (default: `5`) | ||
- `libraryLines` - Number of lines of soruce context to be loaded with | ||
the call site line in the center if `callsite.isApp()` is `false`. | ||
Overwrites `lines` (default: `5`) | ||
All node core call sites and call sites where no lines were collected | ||
due to the above options being `0`, will have the context value `null`. | ||
## CallSite API | ||
@@ -268,6 +279,5 @@ | ||
### `callsite.sourceContext([options, ]callback)` | ||
### `callsite.sourceContext([lines, ]callback)` | ||
Calls the `callback` with an optional error object as the first argument | ||
and a [source context object](#source-context) as the 2nd. | ||
Get the source code surrounding the call site line. | ||
@@ -277,6 +287,9 @@ If the `callsite` is a node core call site, the `callback` will be | ||
Options: | ||
Arguments: | ||
- `lines` - Number of lines of soruce context to be loaded on each side | ||
of the call site line (default: `7`) | ||
- `lines` - Total number of lines of soruce context to be loaded with | ||
the call site line in the center (default: `5`) | ||
- `callback` - called when the source context have been loaded with an | ||
optional error object as the first argument and a [source context | ||
object](#source-context) as the 2nd | ||
@@ -299,3 +312,3 @@ ## Source Context | ||
This project was kindly sponsored by [Opbeat](https://opbeat.com). | ||
This project was kindly sponsored by [Elastic](https://www.elastic.co). | ||
@@ -302,0 +315,0 @@ ## License |
@@ -82,3 +82,3 @@ 'use strict' | ||
t.equal(context.line, 'const generateError = (msg = \'foo\') => new Error(msg)') | ||
t.deepEqual(context.post, ['', 'module.exports = generateError', '']) | ||
t.deepEqual(context.post, ['', 'module.exports = generateError']) | ||
t.end() | ||
@@ -85,0 +85,0 @@ }) |
@@ -67,3 +67,3 @@ 'use strict' | ||
test('callsite.getTypeNameSafely()', function (t) { | ||
// TODO: It would be nice if we could the the non-safe version to | ||
// TODO: It would be nice if we could get the non-safe version to | ||
// throw in a test | ||
@@ -280,4 +280,5 @@ var err = new Error('foo') | ||
t.ok(Array.isArray(context.post), 'should be an array') | ||
t.equal(context.pre.length, 7) | ||
t.equal(context.post.length, 7) | ||
t.equal(context.pre.length, 2) | ||
t.equal(context.post.length, 2) | ||
t.equal(context.line.trim(), 'var err = new Error()') | ||
t.end() | ||
@@ -306,3 +307,3 @@ }) | ||
test('callsite.sourceContext({lines: 2})', function (t) { | ||
test('callsite.sourceContext(0)', function (t) { | ||
var err = new Error() | ||
@@ -312,6 +313,77 @@ stackman.callsites(err, function (err, callsites) { | ||
callsites[0].sourceContext({lines: 2}, function (err, context) { | ||
callsites[0].sourceContext(0, function (err, context) { | ||
t.equal(err.message, 'Cannot collect less than one line of source context') | ||
t.notOk(context) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('callsite.sourceContext(1)', function (t) { | ||
var err = new Error() | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
callsites[0].sourceContext(1, function (err, context) { | ||
t.error(err) | ||
t.equal(context.pre.length, 0) | ||
t.equal(context.line.trim(), 'var err = new Error()') | ||
t.equal(context.post.length, 0) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('callsite.sourceContext(2)', function (t) { | ||
// line before | ||
var err = new Error() | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
callsites[0].sourceContext(2, function (err, context) { | ||
t.error(err) | ||
t.equal(context.pre.length, 1) | ||
t.equal(context.pre[0].trim(), '// line before') | ||
t.equal(context.line.trim(), 'var err = new Error()') | ||
t.equal(context.post.length, 0) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('callsite.sourceContext(3)', function (t) { | ||
// line before | ||
var err = new Error() | ||
// line after | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
callsites[0].sourceContext(3, function (err, context) { | ||
t.error(err) | ||
t.equal(context.pre.length, 1) | ||
t.equal(context.pre[0].trim(), '// line before') | ||
t.equal(context.line.trim(), 'var err = new Error()') | ||
t.equal(context.post.length, 1) | ||
t.equal(context.post[0].trim(), '// line after') | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('callsite.sourceContext(4)', function (t) { | ||
// line before 2 | ||
// line before 1 | ||
var err = new Error() | ||
// line after | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
callsites[0].sourceContext(4, function (err, context) { | ||
t.error(err) | ||
t.equal(context.pre.length, 2) | ||
t.equal(context.post.length, 2) | ||
t.equal(context.pre[0].trim(), '// line before 2') | ||
t.equal(context.pre[1].trim(), '// line before 1') | ||
t.equal(context.line.trim(), 'var err = new Error()') | ||
t.equal(context.post.length, 1) | ||
t.equal(context.post[0].trim(), '// line after') | ||
t.end() | ||
@@ -351,4 +423,4 @@ }) | ||
t.ok(Array.isArray(context.post), 'should be an array') | ||
t.equal(context.pre.length, 7) | ||
t.equal(context.post.length, 7) | ||
t.equal(context.pre.length, 2) | ||
t.equal(context.post.length, 2) | ||
} | ||
@@ -361,3 +433,3 @@ }) | ||
test('stackman.sourceContexts(callsites, {lines: 2})', function (t) { | ||
test('stackman.sourceContexts(callsites, {lines: 7})', function (t) { | ||
var err = new Error() | ||
@@ -367,3 +439,3 @@ stackman.callsites(err, function (err, callsites) { | ||
stackman.sourceContexts(callsites, {lines: 2}, function (err, contexts) { | ||
stackman.sourceContexts(callsites, {lines: 7}, function (err, contexts) { | ||
t.error(err) | ||
@@ -380,4 +452,61 @@ contexts.forEach(function (context, index) { | ||
t.ok(Array.isArray(context.post), 'should be an array') | ||
t.equal(context.pre.length, 3) | ||
t.equal(context.post.length, 3) | ||
} | ||
}) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('stackman.sourceContexts(callsites, {inAppLines: 7, libraryLines: 3})', function (t) { | ||
var err = new Error() | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
stackman.sourceContexts(callsites, {inAppLines: 7, libraryLines: 3}, function (err, contexts) { | ||
t.error(err) | ||
contexts.forEach(function (context, index) { | ||
var callsite = callsites[index] | ||
if (callsite.isNode()) { | ||
t.equal(context, null) | ||
} else { | ||
t.equal(typeof context, 'object') | ||
t.equal(typeof context.line, 'string') | ||
t.ok(Array.isArray(context.pre), 'should be an array') | ||
t.ok(Array.isArray(context.post), 'should be an array') | ||
if (callsite.isApp()) { | ||
t.equal(context.pre.length, 3) | ||
t.equal(context.post.length, 3) | ||
} else { | ||
t.equal(context.pre.length, 1) | ||
t.equal(context.post.length, 1) | ||
} | ||
} | ||
}) | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
test('stackman.sourceContexts(callsites, {libraryLines: 0})', function (t) { | ||
var err = new Error() | ||
stackman.callsites(err, function (err, callsites) { | ||
t.error(err) | ||
stackman.sourceContexts(callsites, {libraryLines: 0}, function (err, contexts) { | ||
t.error(err) | ||
contexts.forEach(function (context, index) { | ||
var callsite = callsites[index] | ||
if (callsite.isApp()) { | ||
t.equal(typeof context, 'object') | ||
t.equal(typeof context.line, 'string') | ||
t.ok(Array.isArray(context.pre), 'should be an array') | ||
t.ok(Array.isArray(context.post), 'should be an array') | ||
t.equal(context.pre.length, 2) | ||
t.equal(context.post.length, 2) | ||
} else { | ||
t.equal(context, null) | ||
} | ||
@@ -384,0 +513,0 @@ }) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
45481
930
313
21