Initial commit
This commit is contained in:
commit
4440bfbe18
18 changed files with 1616 additions and 0 deletions
237
test/gdb_expansion.test.ts
Normal file
237
test/gdb_expansion.test.ts
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
import * as assert from 'assert';
|
||||
import { expandValue, isExpandable } from '../src/backend/gdb_expansion';
|
||||
|
||||
suite("GDB Value Expansion", () => {
|
||||
let variableCreate = (variable) => { return { expanded: variable }; };
|
||||
test("Various values", () => {
|
||||
assert.strictEqual(isExpandable(`false`), 0);
|
||||
assert.equal(expandValue(variableCreate, `false`), "false");
|
||||
assert.strictEqual(isExpandable(`5`), 0);
|
||||
assert.equal(expandValue(variableCreate, `5`), "5");
|
||||
assert.strictEqual(isExpandable(`"hello world!"`), 0);
|
||||
assert.equal(expandValue(variableCreate, `"hello world!"`), `"hello world!"`);
|
||||
assert.strictEqual(isExpandable(`0x0`), 0);
|
||||
assert.equal(expandValue(variableCreate, `0x0`), "<nullptr>");
|
||||
assert.strictEqual(isExpandable(`0xabc`), 2);
|
||||
assert.equal(expandValue(variableCreate, `0x7ffff7ecb480`), "*0x7ffff7ecb480");
|
||||
assert.strictEqual(isExpandable(`{a = b, c = d}`), 1);
|
||||
assert.deepEqual(expandValue(variableCreate, `{a = b, c = d}`), [
|
||||
{
|
||||
name: "a",
|
||||
value: "b",
|
||||
variablesReference: 0
|
||||
}, {
|
||||
name: "c",
|
||||
value: "d",
|
||||
variablesReference: 0
|
||||
}]);
|
||||
assert.strictEqual(isExpandable(`{{a = b}}`), 1);
|
||||
assert.deepEqual(expandValue(variableCreate, `{{a = b}}`), [
|
||||
[
|
||||
{
|
||||
name: "a",
|
||||
value: "b",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
]);
|
||||
assert.deepEqual(expandValue(variableCreate, `{1, 2, 3, 4}`), [1, 2, 3, 4]);
|
||||
});
|
||||
test("Error values", () => {
|
||||
assert.strictEqual(isExpandable(`<No data fields>`), 0);
|
||||
assert.equal(expandValue(variableCreate, `<No data fields>`), "<No data fields>");
|
||||
});
|
||||
test("Nested values", () => {
|
||||
assert.strictEqual(isExpandable(`{a = {b = e}, c = d}`), 1);
|
||||
assert.deepEqual(expandValue(variableCreate, `{a = {b = e}, c = d}`), [
|
||||
{
|
||||
name: "a",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "b",
|
||||
value: "e",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}, {
|
||||
name: "c",
|
||||
value: "d",
|
||||
variablesReference: 0
|
||||
}]);
|
||||
});
|
||||
test("Simple node", () => {
|
||||
assert.strictEqual(isExpandable(`{a = false, b = 5, c = 0x0, d = "foobar"}`), 1);
|
||||
let variables = expandValue(variableCreate, `{a = false, b = 5, c = 0x0, d = "foobar"}`);
|
||||
assert.equal(variables.length, 4);
|
||||
assert.equal(variables[0].name, "a");
|
||||
assert.equal(variables[0].value, "false");
|
||||
assert.equal(variables[1].name, "b");
|
||||
assert.equal(variables[1].value, "5");
|
||||
assert.equal(variables[2].name, "c");
|
||||
assert.equal(variables[2].value, "<nullptr>");
|
||||
assert.equal(variables[3].name, "d");
|
||||
assert.equal(variables[3].value, `"foobar"`);
|
||||
});
|
||||
test("Complex node", () => {
|
||||
let node = `{quit = false, _views = {{view = 0x7ffff7ece1e8, renderer = 0x7ffff7eccc50, world = 0x7ffff7ece480}}, deltaTimer = {_flagStarted = false, _timeStart = {length = 0}, _timeMeasured = {length = 0}}, _start = {callbacks = 0x0}, _stop = {callbacks = 0x0}}`;
|
||||
assert.strictEqual(isExpandable(node), 1);
|
||||
let variables = expandValue(variableCreate, node);
|
||||
assert.deepEqual(variables, [
|
||||
{
|
||||
name: "quit",
|
||||
value: "false",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_views",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
[
|
||||
{
|
||||
name: "view",
|
||||
value: "Object@*0x7ffff7ece1e8",
|
||||
variablesReference: { expanded: "*view" }
|
||||
},
|
||||
{
|
||||
name: "renderer",
|
||||
value: "Object@*0x7ffff7eccc50",
|
||||
variablesReference: { expanded: "*renderer" }
|
||||
},
|
||||
{
|
||||
name: "world",
|
||||
value: "Object@*0x7ffff7ece480",
|
||||
variablesReference: { expanded: "*world" }
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "deltaTimer",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "_flagStarted",
|
||||
value: "false",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_timeStart",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "length",
|
||||
value: "0",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "_timeMeasured",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "length",
|
||||
value: "0",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "_start",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "callbacks",
|
||||
value: "<nullptr>",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "_stop",
|
||||
value: "Object",
|
||||
variablesReference: {
|
||||
expanded: [
|
||||
{
|
||||
name: "callbacks",
|
||||
value: "<nullptr>",
|
||||
variablesReference: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]);
|
||||
});
|
||||
test("Simple node with errors", () => {
|
||||
let node = `{_enableMipMaps = false, _minFilter = <incomplete type>, _magFilter = <incomplete type>, _wrapX = <incomplete type>, _wrapY = <incomplete type>, _inMode = 6408, _mode = 6408, _id = 1, _width = 1024, _height = 1024}`;
|
||||
assert.strictEqual(isExpandable(node), 1);
|
||||
let variables = expandValue(variableCreate, node);
|
||||
assert.deepEqual(variables, [
|
||||
{
|
||||
name: "_enableMipMaps",
|
||||
value: "false",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_minFilter",
|
||||
value: "<incomplete type>",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_magFilter",
|
||||
value: "<incomplete type>",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_wrapX",
|
||||
value: "<incomplete type>",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_wrapY",
|
||||
value: "<incomplete type>",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_inMode",
|
||||
value: "6408",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_mode",
|
||||
value: "6408",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_id",
|
||||
value: "1",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_width",
|
||||
value: "1024",
|
||||
variablesReference: 0
|
||||
},
|
||||
{
|
||||
name: "_height",
|
||||
value: "1024",
|
||||
variablesReference: 0
|
||||
}
|
||||
]);
|
||||
})
|
||||
});
|
||||
22
test/index.ts
Normal file
22
test/index.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
|
||||
//
|
||||
// This file is providing the test runner to use when running extension tests.
|
||||
// By default the test runner in use is Mocha based.
|
||||
//
|
||||
// You can provide your own test runner if you want to override it by exporting
|
||||
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
|
||||
// host can call to run the tests. The test runner is expected to use console.log
|
||||
// to report the results back to the caller. When the tests are finished, return
|
||||
// a possible error to the callback or null if none.
|
||||
|
||||
var testRunner = require('vscode/lib/testrunner');
|
||||
|
||||
// You can directly control Mocha options by uncommenting the following lines
|
||||
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
|
||||
testRunner.configure({
|
||||
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
|
||||
useColors: true // colored output from test results
|
||||
});
|
||||
|
||||
module.exports = testRunner;
|
||||
160
test/mi_parse.test.ts
Normal file
160
test/mi_parse.test.ts
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
import * as assert from 'assert';
|
||||
import { parseMI, MINode } from '../src/backend/mi_parse';
|
||||
|
||||
suite("MI Parse", () => {
|
||||
test("Simple out of band record", () => {
|
||||
let parsed = parseMI(`4=thread-exited,id="3",group-id="i1"`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, 4);
|
||||
assert.equal(parsed.outOfBandRecord.length, 1);
|
||||
assert.equal(parsed.outOfBandRecord[0].isStream, false);
|
||||
assert.equal(parsed.outOfBandRecord[0].asyncClass, "thread-exited");
|
||||
assert.equal(parsed.outOfBandRecord[0].output.length, 2);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[0], ["id", "3"]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[1], ["group-id", "i1"]);
|
||||
assert.equal(parsed.resultRecords, undefined);
|
||||
});
|
||||
test("Console stream output with new line", () => {
|
||||
let parsed = parseMI(`~"[Thread 0x7fffe993a700 (LWP 11002) exited]\\n"`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, undefined);
|
||||
assert.equal(parsed.outOfBandRecord.length, 1);
|
||||
assert.equal(parsed.outOfBandRecord[0].isStream, true);
|
||||
assert.equal(parsed.outOfBandRecord[0].content, "[Thread 0x7fffe993a700 (LWP 11002) exited]\n");
|
||||
assert.equal(parsed.resultRecords, undefined);
|
||||
});
|
||||
test("Empty line", () => {
|
||||
let parsed = parseMI(``);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, undefined);
|
||||
assert.equal(parsed.outOfBandRecord.length, 0);
|
||||
assert.equal(parsed.resultRecords, undefined);
|
||||
});
|
||||
test("'(gdb)' line", () => {
|
||||
let parsed = parseMI(`(gdb)`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, undefined);
|
||||
assert.equal(parsed.outOfBandRecord.length, 0);
|
||||
assert.equal(parsed.resultRecords, undefined);
|
||||
});
|
||||
test("Simple result record", () => {
|
||||
let parsed = parseMI(`1^running`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, 1);
|
||||
assert.equal(parsed.outOfBandRecord.length, 0);
|
||||
assert.notEqual(parsed.resultRecords, undefined);
|
||||
assert.equal(parsed.resultRecords.resultClass, "running");
|
||||
assert.equal(parsed.resultRecords.results.length, 0);
|
||||
});
|
||||
test("Advanced out of band record (Breakpoint hit)", () => {
|
||||
let parsed = parseMI(`*stopped,reason="breakpoint-hit",disp="keep",bkptno="1",frame={addr="0x00000000004e807f",func="D main",args=[{name="args",value="..."}],file="source/app.d",fullname="/path/to/source/app.d",line="157"},thread-id="1",stopped-threads="all",core="0"`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, undefined);
|
||||
assert.equal(parsed.outOfBandRecord.length, 1);
|
||||
assert.equal(parsed.outOfBandRecord[0].isStream, false);
|
||||
assert.equal(parsed.outOfBandRecord[0].asyncClass, "stopped");
|
||||
assert.equal(parsed.outOfBandRecord[0].output.length, 7);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[0], ["reason", "breakpoint-hit"]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[1], ["disp", "keep"]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[2], ["bkptno", "1"]);
|
||||
let frame = [
|
||||
["addr", "0x00000000004e807f"],
|
||||
["func", "D main"],
|
||||
["args", [[["name", "args"], ["value", "..."]]]],
|
||||
["file", "source/app.d"],
|
||||
["fullname", "/path/to/source/app.d"],
|
||||
["line", "157"]
|
||||
];
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[3], ["frame", frame]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[4], ["thread-id", "1"]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[5], ["stopped-threads", "all"]);
|
||||
assert.deepEqual(parsed.outOfBandRecord[0].output[6], ["core", "0"]);
|
||||
assert.equal(parsed.resultRecords, undefined);
|
||||
});
|
||||
test("Advanced result record", () => {
|
||||
let parsed = parseMI(`2^done,asm_insns=[src_and_asm_line={line="134",file="source/app.d",fullname="/path/to/source/app.d",line_asm_insn=[{address="0x00000000004e7da4",func-name="_Dmain",offset="0",inst="push %rbp"},{address="0x00000000004e7da5",func-name="_Dmain",offset="1",inst="mov %rsp,%rbp"}]}]`);
|
||||
assert.ok(parsed);
|
||||
assert.equal(parsed.token, 2);
|
||||
assert.equal(parsed.outOfBandRecord.length, 0);
|
||||
assert.notEqual(parsed.resultRecords, undefined);
|
||||
assert.equal(parsed.resultRecords.resultClass, "done");
|
||||
assert.equal(parsed.resultRecords.results.length, 1);
|
||||
let asm_insns = [
|
||||
"asm_insns",
|
||||
[
|
||||
[
|
||||
"src_and_asm_line",
|
||||
[
|
||||
["line", "134"],
|
||||
["file", "source/app.d"],
|
||||
["fullname", "/path/to/source/app.d"],
|
||||
[
|
||||
"line_asm_insn",
|
||||
[
|
||||
[
|
||||
["address", "0x00000000004e7da4"],
|
||||
["func-name", "_Dmain"],
|
||||
["offset", "0"],
|
||||
["inst", "push %rbp"]
|
||||
],
|
||||
[
|
||||
["address", "0x00000000004e7da5"],
|
||||
["func-name", "_Dmain"],
|
||||
["offset", "1"],
|
||||
["inst", "mov %rsp,%rbp"]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
assert.deepEqual(parsed.resultRecords.results[0], asm_insns);
|
||||
assert.equal(parsed.result("asm_insns.src_and_asm_line.line_asm_insn[1].address"), "0x00000000004e7da5");
|
||||
});
|
||||
test("valueof children", () => {
|
||||
let obj = [
|
||||
[
|
||||
"frame",
|
||||
[
|
||||
["level", "0"],
|
||||
["addr", "0x0000000000435f70"],
|
||||
["func", "D main"],
|
||||
["file", "source/app.d"],
|
||||
["fullname", "/path/to/source/app.d"],
|
||||
["line", "5"]
|
||||
]
|
||||
],
|
||||
[
|
||||
"frame",
|
||||
[
|
||||
["level", "1"],
|
||||
["addr", "0x00000000004372d3"],
|
||||
["func", "rt.dmain2._d_run_main()"]
|
||||
]
|
||||
],
|
||||
[
|
||||
"frame",
|
||||
[
|
||||
["level", "2"],
|
||||
["addr", "0x0000000000437229"],
|
||||
["func", "rt.dmain2._d_run_main()"]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.level"), "0");
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.addr"), "0x0000000000435f70");
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.func"), "D main");
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.file"), "source/app.d");
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.fullname"), "/path/to/source/app.d");
|
||||
assert.equal(MINode.valueOf(obj[0], "@frame.line"), "5");
|
||||
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.level"), "1");
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.addr"), "0x00000000004372d3");
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.func"), "rt.dmain2._d_run_main()");
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.file"), undefined);
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.fullname"), undefined);
|
||||
assert.equal(MINode.valueOf(obj[1], "@frame.line"), undefined);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue