Skip to content
Open
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
92 changes: 92 additions & 0 deletions src/test/view/treeNodes/gitFileChangeNode.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { default as assert } from 'assert';
import * as vscode from 'vscode';
import { GitChangeType } from '../../../common/file';
import { toReviewUri } from '../../../common/uri';
import { GitFileChangeModel } from '../../../view/fileChangeModel';
import { GitFileChangeNode } from '../../../view/treeNodes/fileChangeNode';
import { TreeNodeParent } from '../../../view/treeNodes/treeNode';

function disposable(): vscode.Disposable {
return { dispose: () => { } };
}

const rootUri = vscode.Uri.file('/root');
const commitSha = '1111111111111111111111111111111111111111';
const headSha = '2222222222222222222222222222222222222222';

describe('GitFileChangeNode', function () {
const parent: TreeNodeParent = {
reveal: async () => { },
refresh: () => { },
children: undefined,
view: { visible: true, onDidChangeVisibility: () => disposable() } as unknown as vscode.TreeView<any>,
} as unknown as TreeNodeParent;

const pullRequest = {
number: 1,
head: { sha: headSha },
fileChangeViewedState: {},
reviewThreadsCache: [],
onDidChangeReviewThreads: () => disposable(),
onDidChangeFileViewedState: () => disposable(),
};

const folderRepositoryManager = {
repository: { rootUri },
setFileViewedContext: () => { },
};

/**
* A file node as created for a commit in the Commits tree: the paths are `review` uris carrying
* the sha of that commit, and the node opens a diff instead of the workspace file.
*/
function createCommitFileNode(fileName: string, status: GitChangeType): GitFileChangeNode {
const uri = vscode.Uri.parse(`commit~11111111/${fileName}`);
const changeModel = new GitFileChangeModel(
folderRepositoryManager as any,
pullRequest as any,
{ status, fileName, blobUrl: undefined },
toReviewUri(uri, fileName, undefined, commitSha, true, { base: false }, rootUri),
toReviewUri(uri, fileName, undefined, commitSha, true, { base: true }, rootUri),
commitSha,
);

const node = new GitFileChangeNode(parent, folderRepositoryManager as any, pullRequest as any, changeModel);
node.useViewChangesCommand();
return node;
}

it('diffs an added file against the head side of the change', async function () {
// The head side has to be `filePath`. With `parentFilePath` the document is the base of the
// diff, and commenting ranges for the base of an added file are always empty, so it isn't
// possible to comment on a file added by the commit being viewed.
const node = createCommitFileNode('data/added.json', GitChangeType.ADD);

await node.resolve();

assert.strictEqual(node.command.command, 'vscode.diff');
const [left, right] = node.command.arguments as vscode.Uri[];
assert.strictEqual(right.toString(), node.changeModel.filePath.toString());
assert.notStrictEqual(right.toString(), node.changeModel.parentFilePath.toString());
// The base side is the empty document, so the whole file reads as added.
assert.deepStrictEqual(JSON.parse(left.query), { path: null, commit: null });
});

it('diffs a deleted file against the base side of the change', async function () {
// The content of a deleted file only exists in the base, so unlike the added case the base
// side is the one holding the document.
const node = createCommitFileNode('data/deleted.json', GitChangeType.DELETE);

await node.resolve();

assert.strictEqual(node.command.command, 'vscode.diff');
const [left, right] = node.command.arguments as vscode.Uri[];
assert.strictEqual(left.toString(), node.changeModel.parentFilePath.toString());
assert.deepStrictEqual(JSON.parse(right.query), { path: null, commit: null });
});
});
6 changes: 5 additions & 1 deletion src/view/treeNodes/fileChangeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,16 @@ export class GitFileChangeNode extends FileChangeNode implements vscode.TreeItem
}),
});

// For added files the content lives on the head side of the diff, so use `filePath`.
// Using `parentFilePath` here would make the commenting range provider treat the
// document as the base, where an added file has no deleted lines and therefore no
// commenting ranges at all.
return {
command: 'vscode.diff',
arguments:
this.status === GitChangeType.DELETE
? [this.changeModel.parentFilePath, emptyFileUri, `${this.fileName}`, {}]
: [emptyFileUri, this.changeModel.parentFilePath, `${this.fileName}`, {}],
: [emptyFileUri, this.changeModel.filePath, `${this.fileName}`, {}],
title: 'Open Diff',
};
}
Expand Down