move git smoke tests to integration tests

This commit is contained in:
Joao Moreno 2020-02-04 16:58:20 +01:00
parent 491a17bd71
commit 16c7551f36
No known key found for this signature in database
GPG key ID: 9494F5E6167A8E6B
8 changed files with 136 additions and 96 deletions

View file

@ -5,7 +5,7 @@
import { Model } from '../model';
import { Repository as BaseRepository, Resource } from '../repository';
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState } from './git';
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions } from './git';
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
import { mapEvent } from '../util';
import { toGitUri } from '../uri';
@ -202,6 +202,10 @@ export class ApiRepository implements Repository {
log(options?: LogOptions): Promise<Commit[]> {
return this._repository.log(options);
}
commit(message: string, opts?: CommitOptions): Promise<void> {
return this._repository.commit(message, opts);
}
}
export class ApiGit implements Git {

View file

@ -121,6 +121,14 @@ export interface LogOptions {
readonly maxEntries?: number;
}
export interface CommitOptions {
all?: boolean | 'tracked';
amend?: boolean;
signoff?: boolean;
signCommit?: boolean;
empty?: boolean;
}
export interface Repository {
readonly rootUri: Uri;
@ -176,6 +184,8 @@ export interface Repository {
blame(path: string): Promise<string>;
log(options?: LogOptions): Promise<Commit[]>;
commit(message: string, opts?: CommitOptions): Promise<void>;
}
export type APIState = 'uninitialized' | 'initialized';

View file

@ -9,8 +9,8 @@ import * as path from 'path';
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder } from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
import { Branch, GitErrorCodes, Ref, RefType, Status } from './api/git';
import { CommitOptions, ForcePushMode, Git, Stash } from './git';
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git';
import { ForcePushMode, Git, Stash } from './git';
import { Model } from './model';
import { Repository, Resource, ResourceGroupType } from './repository';
import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineChange, toLineRanges } from './staging';

View file

@ -15,7 +15,7 @@ import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes,
import { CancellationToken, Progress, Uri } from 'vscode';
import { URI } from 'vscode-uri';
import { detectEncoding } from './encoding';
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git';
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status, CommitOptions } from './api/git';
import * as byline from 'byline';
import { StringDecoder } from 'string_decoder';
@ -725,14 +725,6 @@ export function parseLsFiles(raw: string): LsFilesElement[] {
.map(([, mode, object, stage, file]) => ({ mode, object, stage, file }));
}
export interface CommitOptions {
all?: boolean | 'tracked';
amend?: boolean;
signoff?: boolean;
signCommit?: boolean;
empty?: boolean;
}
export interface PullOptions {
unshallow?: boolean;
tags?: boolean;

View file

@ -7,10 +7,10 @@ import * as fs from 'fs';
import * as path from 'path';
import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode';
import * as nls from 'vscode-nls';
import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status } from './api/git';
import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions } from './api/git';
import { AutoFetcher } from './autofetch';
import { debounce, memoize, throttle } from './decorators';
import { Commit, CommitOptions, ForcePushMode, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions } from './git';
import { Commit, ForcePushMode, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions } from './git';
import { StatusBarCommands } from './statusbar';
import { toGitUri } from './uri';
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent } from './util';

View file

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as assert from 'assert';
import { workspace, commands, window, Uri, WorkspaceEdit, Range, TextDocument, extensions } from 'vscode';
import * as cp from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { GitExtension, API, Repository, Status } from '../api/git';
import { eventToPromise } from '../util';
suite('git smoke test', function () {
const cwd = workspace.workspaceFolders![0].uri.path;
const file = (relativePath: string) => path.join(cwd, relativePath);
const uri = (relativePath: string) => Uri.file(file(relativePath));
const open = async (relativePath: string) => {
const doc = await workspace.openTextDocument(uri(relativePath));
await window.showTextDocument(doc);
return doc;
};
const type = async (doc: TextDocument, text: string) => {
const edit = new WorkspaceEdit();
const end = doc.lineAt(doc.lineCount - 1).range.end;
edit.replace(doc.uri, new Range(end, end), text);
await workspace.applyEdit(edit);
};
let git: API;
let repository: Repository;
suiteSetup(async function () {
fs.writeFileSync(file('app.js'), 'hello', 'utf8');
fs.writeFileSync(file('index.pug'), 'hello', 'utf8');
cp.execSync('git init', { cwd });
cp.execSync('git config user.name testuser', { cwd });
cp.execSync('git config user.email monacotools@microsoft.com', { cwd });
cp.execSync('git add .', { cwd });
cp.execSync('git commit -m "initial commit"', { cwd });
git = extensions.getExtension<GitExtension>('vscode.git')!.exports.getAPI(1);
if (git.repositories.length === 0) {
await eventToPromise(git.onDidOpenRepository);
}
assert.equal(git.repositories.length, 1);
assert.equal(git.repositories[0].rootUri.path, cwd);
repository = git.repositories[0];
});
test('reflects working tree changes', async function () {
await commands.executeCommand('workbench.view.scm');
const appjs = await open('app.js');
await type(appjs, ' world');
await appjs.save();
await eventToPromise(repository.state.onDidChange);
assert.equal(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.uri.path && r.status === Status.MODIFIED);
fs.writeFileSync(file('newfile.txt'), '');
const newfile = await open('newfile.txt');
await type(newfile, 'hey there');
await newfile.save();
await repository.status();
assert.equal(repository.state.workingTreeChanges.length, 2);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.uri.path && r.status === Status.MODIFIED);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.uri.path && r.status === Status.UNTRACKED);
});
test('opens diff editor', async function () {
const appjs = uri('app.js');
await commands.executeCommand('git.openChange', appjs);
assert(window.activeTextEditor);
assert.equal(window.activeTextEditor!.document.uri.path, appjs.path);
// TODO: how do we really know this is a diff editor?
});
test('stages correctly', async function () {
const appjs = uri('app.js');
const newfile = uri('newfile.txt');
await commands.executeCommand('git.stage', appjs);
assert.equal(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
assert.equal(repository.state.indexChanges.length, 1);
repository.state.indexChanges.some(r => r.uri.path === appjs.path && r.status === Status.INDEX_MODIFIED);
await commands.executeCommand('git.unstage', appjs);
assert.equal(repository.state.workingTreeChanges.length, 2);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.path && r.status === Status.MODIFIED);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
});
test('stages, commits changes and verifies outgoing change', async function () {
const appjs = uri('app.js');
const newfile = uri('newfile.txt');
await commands.executeCommand('git.stage', appjs);
await repository.commit('second commit');
assert.equal(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
assert.equal(repository.state.indexChanges.length, 0);
await commands.executeCommand('git.stageAll', appjs);
await repository.commit('third commit');
assert.equal(repository.state.workingTreeChanges.length, 0);
assert.equal(repository.state.indexChanges.length, 0);
});
});

View file

@ -1,80 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { Application } from '../../../../automation';
const DIFF_EDITOR_LINE_INSERT = '.monaco-diff-editor .editor.modified .line-insert';
const SYNC_STATUSBAR = 'div[id="workbench.parts.statusbar"] .statusbar-item[title$="Synchronize Changes"]';
export function setup() {
describe('Git', () => {
before(async function () {
const app = this.app as Application;
cp.execSync('git config user.name testuser', { cwd: app.workspacePathOrFolder });
cp.execSync('git config user.email monacotools@microsoft.com', { cwd: app.workspacePathOrFolder });
});
it('reflects working tree changes', async function () {
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
await app.workbench.quickopen.openFile('app.js');
await app.workbench.editor.waitForTypeInEditor('app.js', '.foo{}');
await app.workbench.editors.saveOpenedFile();
await app.workbench.quickopen.openFile('index.pug');
await app.workbench.editor.waitForTypeInEditor('index.pug', 'hello world');
await app.workbench.editors.saveOpenedFile();
await app.workbench.scm.refreshSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.waitForChange('index.pug', 'Modified');
});
it('opens diff editor', async function () {
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.openChange('app.js');
await app.code.waitForElement(DIFF_EDITOR_LINE_INSERT);
});
it('stages correctly', async function () {
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.stage('app.js');
await app.workbench.scm.openChange('app.js');
await new Promise(c => setTimeout(c, 1000));
await app.workbench.scm.unstage('app.js');
});
it(`stages, commits changes and verifies outgoing change`, async function () {
const app = this.app as Application;
await app.workbench.scm.openSCMViewlet();
await app.workbench.scm.waitForChange('app.js', 'Modified');
await app.workbench.scm.openChange('app.js');
await app.workbench.scm.stage('app.js');
await app.workbench.scm.commit('first commit');
await app.code.waitForTextContent(SYNC_STATUSBAR, ' 0↓ 1↑');
await app.workbench.quickopen.runCommand('Git: Stage All Changes');
await app.workbench.scm.waitForChange('index.pug', 'Index Modified');
await app.workbench.scm.commit('second commit');
await app.code.waitForTextContent(SYNC_STATUSBAR, ' 0↓ 2↑');
cp.execSync('git reset --hard origin/master', { cwd: app.workspacePathOrFolder });
});
});
}

View file

@ -28,7 +28,6 @@ import { setup as setupDataPreferencesTests } from './areas/preferences/preferen
import { setup as setupDataSearchTests } from './areas/search/search.test';
import { setup as setupDataCSSTests } from './areas/css/css.test';
import { setup as setupDataEditorTests } from './areas/editor/editor.test';
import { setup as setupDataGitTests } from './areas/git/git.test';
import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test';
import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test';
import { setup as setupTerminalTests } from './areas/terminal/terminal.test';
@ -302,7 +301,6 @@ describe('Running Code', () => {
setupDataSearchTests();
setupDataCSSTests();
setupDataEditorTests();
setupDataGitTests();
setupDataStatusbarTests(!!opts.web);
setupDataExtensionTests();
setupTerminalTests();