Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions extensions/ql-vscode/src/query-serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ export async function slurpQueryHistory(fsPath: string, config: QueryHistoryConf
}

const data = await fs.readFile(fsPath, 'utf8');
const queries = JSON.parse(data);
const obj = JSON.parse(data);
if (obj.version !== 1) {
void showAndLogErrorMessage(`Unsupported query history format: v${obj.version}. `);
return [];
}

const queries = obj.queries;
const parsedQueries = queries.map((q: QueryHistoryInfo) => {

// Need to explicitly set prototype since reading in from JSON will not
Expand Down Expand Up @@ -82,7 +88,10 @@ export async function splatQueryHistory(queries: QueryHistoryInfo[], fsPath: str
}
// remove incomplete local queries since they cannot be recreated on restart
const filteredQueries = queries.filter(q => q.t === 'local' ? q.completedQuery !== undefined : true);
const data = JSON.stringify(filteredQueries, null, 2);
const data = JSON.stringify({
version: 1,
queries: filteredQueries
}, null, 2);
await fs.writeFile(fsPath, data);
} catch (e) {
throw new Error(`Error saving query history to ${fsPath}: ${e.message}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,30 @@ describe('query-results', () => {
});

describe('splat and slurp', () => {
it('should splat and slurp query history', async () => {
const infoSuccessRaw = createMockFullQueryInfo('a', createMockQueryWithResults(`${queryPath}-a`, false, false, '/a/b/c/a', false));
const infoSuccessInterpreted = createMockFullQueryInfo('b', createMockQueryWithResults(`${queryPath}-b`, true, true, '/a/b/c/b', false));
const infoEarlyFailure = createMockFullQueryInfo('c', undefined, true);
const infoLateFailure = createMockFullQueryInfo('d', createMockQueryWithResults(`${queryPath}-c`, false, false, '/a/b/c/d', false));
const infoInprogress = createMockFullQueryInfo('e');
const allHistory = [

let infoSuccessRaw: LocalQueryInfo;
let infoSuccessInterpreted: LocalQueryInfo;
let infoEarlyFailure: LocalQueryInfo;
let infoLateFailure: LocalQueryInfo;
let infoInprogress: LocalQueryInfo;
let allHistory: LocalQueryInfo[];

beforeEach(() => {
infoSuccessRaw = createMockFullQueryInfo('a', createMockQueryWithResults(`${queryPath}-a`, false, false, '/a/b/c/a', false));
infoSuccessInterpreted = createMockFullQueryInfo('b', createMockQueryWithResults(`${queryPath}-b`, true, true, '/a/b/c/b', false));
infoEarlyFailure = createMockFullQueryInfo('c', undefined, true);
infoLateFailure = createMockFullQueryInfo('d', createMockQueryWithResults(`${queryPath}-c`, false, false, '/a/b/c/d', false));
infoInprogress = createMockFullQueryInfo('e');
allHistory = [
infoSuccessRaw,
infoSuccessInterpreted,
infoEarlyFailure,
infoLateFailure,
infoInprogress
];
});

it('should splat and slurp query history', async () => {
// the expected results only contains the history with completed queries
const expectedHistory = [
infoSuccessRaw,
Expand Down Expand Up @@ -313,6 +323,18 @@ describe('query-results', () => {
}
expect(allHistoryActual.length).to.deep.eq(expectedHistory.length);
});

it('should handle an invalid query history version', async () => {
const badPath = path.join(tmpDir.name, 'bad-query-history.json');
fs.writeFileSync(badPath, JSON.stringify({
version: 2,
queries: allHistory
}), 'utf8');

const allHistoryActual = await slurpQueryHistory(badPath, mockConfig);
// version number is invalid. Should return an empty array.
expect(allHistoryActual).to.deep.eq([]);
});
});

function createMockQueryWithResults(
Expand Down