mirror of
https://github.com/Microsoft/vscode
synced 2024-10-05 19:02:54 +00:00
move git smoke tests to integration tests
This commit is contained in:
parent
491a17bd71
commit
16c7551f36
|
@ -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 {
|
||||
|
|
10
extensions/git/src/api/git.d.ts
vendored
10
extensions/git/src/api/git.d.ts
vendored
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
116
extensions/git/src/test/smoke.test.ts
Normal file
116
extensions/git/src/test/smoke.test.ts
Normal 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);
|
||||
});
|
||||
});
|
|
@ -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 });
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue