asmimproved-dbgmits
Version:
Provides the ability to control GDB and LLDB programmatically via GDB/MI.
302 lines • 33.8 kB
JavaScript
// Copyright (c) 2015 Vadim Macagon
// MIT License, see LICENSE file for full terms.
;
require('source-map-support').install();
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
var dbgmits = require('../lib/index');
var test_utils_1 = require('./test_utils');
chai.use(chaiAsPromised);
// aliases
var expect = chai.expect;
// the directory in which Gruntfile.js resides is also Mocha's working directory,
// so any relative paths will be relative to that directory
var localTargetExe = './build/Debug/watch_tests_target';
test_utils_1.logSuite(describe("Debug Session", function () {
describe("Watch Manipulation", function () {
var debugSession;
test_utils_1.beforeEachTestWithLogger(function (logger) {
debugSession = test_utils_1.startDebugSession(logger);
return debugSession.setExecutableFile(localTargetExe);
});
afterEach(function () {
return debugSession.end();
});
describe("#addWatch", function () {
it("adds a new floating watch for a local variable in an outer frame", function () {
return test_utils_1.runToFunc(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
// add a new watch for a local variable in funcWithMoreVariablesToWatch()
return debugSession.addWatch('f', { threadId: 1, frameLevel: 1, isFloating: true })
.then(function (watch) {
expect(watch.id).not.to.be.empty;
expect(watch.childCount).to.equal(0);
expect(watch.value).to.equal('9.5');
expect(watch.expressionType).to.equal('float');
expect(watch.threadId).to.equal(1);
expect(watch.isDynamic).to.be.false;
expect(watch.hasMoreChildren).to.be.false;
expect(watch.displayHint).to.be.undefined;
});
});
});
it("adds a new fixed watch for a local variable in the current frame @skipOnGDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
// add a new watch for a local variable in funcWithMoreVariablesToWatch()
return debugSession.addWatch('e')
.then(function (watch) {
expect(watch.id).not.to.be.empty;
expect(watch.childCount).to.equal(2);
expect(watch.expressionType).to.equal('Point');
expect(watch.threadId).to.equal(1);
expect(watch.isDynamic).to.be.false;
expect(watch.hasMoreChildren).to.be.false;
expect(watch.displayHint).to.be.undefined;
});
});
});
// GDB groups C++ struct/class members under private/public/protected pseudo-members,
// so we need a separate test just for GDB
it("adds a new fixed watch for a local variable in the current frame @skipOnLLDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
// add a new watch for a local variable in funcWithMoreVariablesToWatch()
return debugSession.addWatch('e')
.then(function (watch) {
expect(watch.id).not.to.be.empty;
expect(watch.childCount).to.equal(1);
expect(watch.expressionType).to.equal('Point');
expect(watch.threadId).to.equal(1);
expect(watch.isDynamic).to.be.false;
expect(watch.hasMoreChildren).to.be.false;
expect(watch.displayHint).to.be.undefined;
});
});
});
});
it("#removeWatch", function () {
return test_utils_1.runToFunc(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
// add a new watch for a local variable in funcWithMoreVariablesToWatch()
return debugSession.addWatch('f', { threadId: 1, frameLevel: 1, isFloating: true })
.then(function (watch) { return debugSession.removeWatch(watch.id); });
});
});
describe("#updateWatch", function () {
it("updates a fixed watch for a local variable after the value changes", function () {
// check the change in the value of the variable was detected by the watch
var onStepOverUpdateWatch = function (watch) {
return new Promise(function (resolve, reject) {
debugSession.once(dbgmits.EVENT_STEP_FINISHED, function (stepNotify) {
debugSession.updateWatch(watch.id, dbgmits.VariableDetailLevel.All)
.then(function (changelist) {
expect(changelist.length).to.be.equal(1);
var firstEntry = changelist[0];
expect(firstEntry.id).to.equal(watch.id);
expect(firstEntry.hasTypeChanged).to.be.false;
expect(firstEntry.value).not.to.equal(watch.value);
expect(firstEntry.isInScope).to.be.true;
expect(firstEntry.isObsolete).to.be.false;
})
.then(resolve)
.catch(reject);
});
});
};
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
// create a watch on a variable and step over the line that alters the value of the variable
return debugSession.addWatch('f')
.then(function (watch) {
return Promise.all([
onStepOverUpdateWatch(watch),
debugSession.stepOverLine()
]);
});
});
});
});
describe("#getWatchChildren", function () {
it("gets a list of members of a simple variable under watch", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
return debugSession.addWatch('f')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id);
})
.then(function (children) {
// watches on simple variables shouldn't have any children
expect(children.length).to.equal(0);
});
});
});
it("gets a list of members of a pointer variable under watch", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
return debugSession.addWatch('g')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id);
})
.then(function (children) {
// watches on pointer variables should have a single child
expect(children.length).to.equal(1);
expect(children[0].expressionType).to.equal('float');
});
});
});
it("gets a list of members of a struct variable under watch @skipOnGDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id, { detail: dbgmits.VariableDetailLevel.None });
})
.then(function (children) {
// watches on variables of aggregate types should have one or more children
expect(children.length).to.equal(2);
expect(children[0].expressionType).to.equal('float');
expect(children[1].expressionType).to.equal('float');
});
});
});
// GDB groups C++ struct/class members under private/public/protected pseudo-members,
// so we need a separate test just for GDB
it("gets a list of members of a struct variable under watch @skipOnLLDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id);
})
.then(function (children) {
// should be just one child named 'public'
expect(children.length).to.equal(1);
return debugSession.getWatchChildren(children[0].id, { detail: dbgmits.VariableDetailLevel.None });
})
.then(function (children) {
// watches on variables of aggregate types should have one or more children
expect(children.length).to.equal(2);
expect(children[0].expressionType).to.equal('float');
expect(children[1].expressionType).to.equal('float');
});
});
});
it("gets a subset of members of a struct variable under watch @skipOnGDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id, { detail: dbgmits.VariableDetailLevel.None, from: 0, to: 1 });
})
.then(function (children) {
// watches on variables of aggregate types should have one or more children
expect(children.length).to.equal(1);
expect(children[0].expressionType).to.equal('float');
});
});
});
// GDB groups C++ struct/class members under private/public/protected pseudo-members,
// so we need a separate test just for GDB
it("gets a subset of members of a struct variable under watch @skipOnLLDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchChildren(watch.id);
})
.then(function (children) {
// should be just one child named 'public'
expect(children.length).to.equal(1);
return debugSession.getWatchChildren(children[0].id, { detail: dbgmits.VariableDetailLevel.None, from: 0, to: 1 });
})
.then(function (children) {
// watches on variables of aggregate types should have one or more children
expect(children.length).to.equal(1);
expect(children[0].expressionType).to.equal('float');
});
});
});
});
it("#setWatchValueFormat", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
var watchId;
// watch an integer variable
return debugSession.addWatch('e')
.then(function (watch) {
watchId = watch.id;
return debugSession.setWatchValueFormat(watchId, dbgmits.WatchFormatSpec.Binary);
})
.then(function (value) { expect(value).to.match(/(0b)?101/); })
.then(function () {
return debugSession.setWatchValueFormat(watchId, dbgmits.WatchFormatSpec.Decimal);
})
.then(function (value) { expect(value).to.equal('5'); })
.then(function () {
return debugSession.setWatchValueFormat(watchId, dbgmits.WatchFormatSpec.Hexadecimal);
})
.then(function (value) { expect(value).to.equal('0x5'); })
.then(function () {
return debugSession.setWatchValueFormat(watchId, dbgmits.WatchFormatSpec.Octal);
})
.then(function (value) { expect(value).to.equal('05'); })
.then(function () {
return debugSession.setWatchValueFormat(watchId, dbgmits.WatchFormatSpec.Default);
})
.then(function (value) { expect(value).to.equal('5'); });
});
});
it("#getWatchValue", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchValue(watch.id);
})
.then(function (value) {
expect(value).to.equal('5');
});
});
});
it("#setWatchValue", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
var newValue = '999';
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.setWatchValue(watch.id, newValue);
})
.then(function (value) {
expect(value).to.equal(newValue);
});
});
});
describe("#getWatchAttributes", function () {
it("gets the attributes for a watch on a variable of a simple type", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchAttributes(watch.id);
})
.then(function (attrs) {
expect(attrs.length).to.equal(1);
expect(attrs[0]).to.equal(dbgmits.WatchAttribute.Editable);
});
});
});
// FIXME: re-enable this test for LLDB when LLDB-MI starts returning 'noneditable' attributes
// like it should
it("gets the attributes for a watch on a variable of an aggregate type @skipOnLLDB", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('e')
.then(function (watch) {
return debugSession.getWatchAttributes(watch.id);
})
.then(function (attrs) {
expect(attrs.length).to.equal(1);
expect(attrs[0]).to.equal(dbgmits.WatchAttribute.NonEditable);
});
});
});
});
it("#getWatchExpression", function () {
return test_utils_1.runToFuncAndStepOut(debugSession, 'funcWithMoreVariablesToWatch_Inner', function () {
return debugSession.addWatch('f')
.then(function (watch) {
return debugSession.getWatchExpression(watch.id);
})
.then(function (expr) {
expect(expr).to.equal('f');
});
});
});
});
}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2hfdGVzdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0L3dhdGNoX3Rlc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG1DQUFtQztBQUNuQyxnREFBZ0Q7O0FBRWhELE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBRXhDLElBQVksSUFBSSxXQUFNLE1BQU0sQ0FBQyxDQUFBO0FBQzdCLElBQU8sY0FBYyxXQUFXLGtCQUFrQixDQUFDLENBQUM7QUFFcEQsSUFBWSxPQUFPLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFDeEMsMkJBR08sY0FBYyxDQUFDLENBQUE7QUFFdEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUV6QixVQUFVO0FBQ1YsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUl6QixpRkFBaUY7QUFDakYsMkRBQTJEO0FBQzNELElBQUksY0FBYyxHQUFXLGtDQUFrQyxDQUFDO0FBRWhFLHFCQUFHLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRTtJQUM1QixRQUFRLENBQUMsb0JBQW9CLEVBQUU7UUFDN0IsSUFBSSxZQUEwQixDQUFDO1FBRS9CLHFDQUF3QixDQUFDLFVBQUMsTUFBcUI7WUFDN0MsWUFBWSxHQUFHLDhCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUM7WUFDUixNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtZQUNwQixFQUFFLENBQUMsa0VBQWtFLEVBQUU7Z0JBQ3JFLE1BQU0sQ0FBQyxzQkFBUyxDQUFDLFlBQVksRUFBRSxvQ0FBb0MsRUFBRTtvQkFDbkUseUVBQXlF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