mirror of
https://github.com/fluxscape/fluxscape.git
synced 2026-01-12 07:12:54 +01:00
Initial commit
Co-Authored-By: Eric Tuvesson <eric.tuvesson@gmail.com> Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com> Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com> Co-Authored-By: Anders Larsson <64838990+anders-topp@users.noreply.github.com> Co-Authored-By: Johan <4934465+joolsus@users.noreply.github.com> Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com> Co-Authored-By: victoratndl <99176179+victoratndl@users.noreply.github.com>
This commit is contained in:
325
packages/noodl-editor/tests/git/git-remote.spec.ts
Normal file
325
packages/noodl-editor/tests/git/git-remote.spec.ts
Normal file
@@ -0,0 +1,325 @@
|
||||
import path from 'path';
|
||||
import { app } from '@electron/remote';
|
||||
import { Git } from '@noodl/git';
|
||||
|
||||
import FileSystem from '@noodl-utils/filesystem';
|
||||
import { mergeProject } from '@noodl-utils/projectmerger';
|
||||
import Utils from '@noodl-utils/utils';
|
||||
|
||||
// jest.setTimeout(10_000);
|
||||
|
||||
async function readTextFile(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
FileSystem.instance.readTextFile(path, (text) => {
|
||||
resolve(text);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('Git remote tests', function () {
|
||||
let localGitA: Git, localGitB: Git;
|
||||
let remoteGit: Git;
|
||||
|
||||
let localDirA: string;
|
||||
let localDirB: string;
|
||||
let remoteDir: string;
|
||||
|
||||
beforeEach(async function () {
|
||||
// console.log(`[jest-before]: ${jasmine.currentTest.fullName}`);
|
||||
|
||||
remoteDir = path.join(app.getPath('temp'), '/noodlunittests-git-' + Utils.guid());
|
||||
localDirA = path.join(app.getPath('temp'), '/noodlunittests-git-' + Utils.guid());
|
||||
localDirB = path.join(app.getPath('temp'), '/noodlunittests-git-' + Utils.guid());
|
||||
|
||||
// Logger.log("remoteDir: " + remoteDir);
|
||||
// Logger.log("localDirA: " + localDirA);
|
||||
// Logger.log("localDirB: " + localDirB);
|
||||
|
||||
FileSystem.instance.makeDirectorySync(localDirA);
|
||||
FileSystem.instance.makeDirectorySync(localDirB);
|
||||
FileSystem.instance.makeDirectorySync(remoteDir);
|
||||
|
||||
localGitA = new Git(mergeProject);
|
||||
localGitB = new Git(mergeProject);
|
||||
remoteGit = new Git(mergeProject);
|
||||
|
||||
//init a bare repository as remote
|
||||
await remoteGit.initNewRepo(remoteDir, { bare: true });
|
||||
|
||||
//init a new local repo and push it to A (mimics how a new project is created)
|
||||
await localGitA.initNewRepo(localDirA);
|
||||
|
||||
// The new version doesnt make a first commit
|
||||
FileSystem.instance.writeFileSync(localDirA + 'initial.txt', 'Hello World');
|
||||
await localGitA.commit('initial commit');
|
||||
|
||||
await localGitA.addRemote(remoteDir);
|
||||
await localGitA.push();
|
||||
|
||||
//and clone the project as B to another directory
|
||||
await localGitB.clone({
|
||||
url: remoteDir,
|
||||
directory: localDirB,
|
||||
onProgress: undefined
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
// Logger.log(`\r\n[jest-after]: ${expect.getState().currentTestName}`);
|
||||
|
||||
FileSystem.instance.removeDirectoryRecursive(remoteDir, () => {
|
||||
FileSystem.instance.removeDirectoryRecursive(localDirA, () => {
|
||||
FileSystem.instance.removeDirectoryRecursive(localDirB, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can get remote head', async function () {
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('local commit');
|
||||
|
||||
const remoteHeadId1 = await localGitA.getRemoteHeadCommitId();
|
||||
const localHeadId1 = await localGitA.getHeadCommitId();
|
||||
expect(remoteHeadId1).not.toEqual(localHeadId1);
|
||||
|
||||
await localGitA.push();
|
||||
|
||||
const remoteHeadId2 = await localGitA.getRemoteHeadCommitId();
|
||||
const localHeadId2 = await localGitA.getHeadCommitId();
|
||||
expect(remoteHeadId2).toEqual(localHeadId2);
|
||||
});
|
||||
|
||||
it('can push and fetch remote commits', async function () {
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('localA commit');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.fetch({});
|
||||
|
||||
const commits = await localGitB.getCommitsCurrentBranch();
|
||||
|
||||
expect(commits[0].isLocalAhead).toBe(false);
|
||||
expect(commits[0].isRemoteAhead).toBe(true);
|
||||
expect(commits[0].message).toEqual('localA commit');
|
||||
|
||||
expect(commits[0].isLocalAhead).toBe(false);
|
||||
expect(commits[1].isRemoteAhead).toBe(false);
|
||||
expect(commits[1].message).toEqual('initial commit');
|
||||
|
||||
expect(commits.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('can list local and remote branches', async function () {
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
await localGitB.createAndCheckoutBranch('B');
|
||||
|
||||
await localGitA.push();
|
||||
await localGitB.fetch({});
|
||||
|
||||
const branches = await localGitB.getBranches();
|
||||
|
||||
//alphabetical order
|
||||
expect(branches[0]).toEqual({ name: 'A', remote: true, local: false });
|
||||
expect(branches[1]).toEqual({ name: 'B', remote: false, local: true });
|
||||
expect(branches[2]).toEqual({ name: 'main', remote: true, local: true });
|
||||
|
||||
expect(branches.length).toBe(3);
|
||||
});
|
||||
|
||||
it('can checkout remote branch', async function () {
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'test.txt'), 'remote file');
|
||||
await localGitA.commit('A commit');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.fetch({});
|
||||
await localGitB.checkoutRemoteBranch('A');
|
||||
|
||||
expect(await readTextFile(path.join(localDirB, 'test.txt'))).toBe('remote file');
|
||||
|
||||
const commits = await localGitB.getCommitsCurrentBranch();
|
||||
|
||||
expect(commits[0].message).toEqual('A commit');
|
||||
expect(commits.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('can list remote branch correctly when they have slashes in the name', async function () {
|
||||
await localGitA.createAndCheckoutBranch('test/A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'test.txt'), 'remote file');
|
||||
await localGitA.commit('A commit');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.fetch({});
|
||||
const branches = await localGitB.getBranches();
|
||||
|
||||
expect(branches[1]).toEqual({ name: 'test/A', remote: true, local: false });
|
||||
});
|
||||
|
||||
it('can delete remote branch', async function () {
|
||||
//A creates a new branch
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
await localGitA.push();
|
||||
|
||||
//B fetches the new branch
|
||||
await localGitB.fetch({});
|
||||
let branches = await localGitB.getBranches();
|
||||
expect(branches.length).toEqual(2);
|
||||
|
||||
//B deletes the branch
|
||||
await localGitB.deleteRemoteBranch('A');
|
||||
|
||||
//.. and B now doesn't have it anymore
|
||||
branches = await localGitB.getBranches();
|
||||
expect(branches.length).toEqual(1);
|
||||
|
||||
//A should think it still exists on the remote
|
||||
branches = await localGitA.getBranches();
|
||||
expect(branches.find((b) => b.name === 'A').remote).toEqual(true);
|
||||
|
||||
//but after a fetch it should be local only
|
||||
await localGitA.fetch({});
|
||||
branches = await localGitA.getBranches();
|
||||
const branchA = branches.find((b) => b.name === 'A');
|
||||
expect(branchA.remote).toEqual(false);
|
||||
expect(branchA.local).toEqual(true);
|
||||
});
|
||||
|
||||
it('can delete local branch but leave remote intact', async function () {
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.fetch({});
|
||||
await localGitB.checkoutRemoteBranch('A');
|
||||
|
||||
let branches = await localGitB.getBranches();
|
||||
expect(branches.length).toEqual(2);
|
||||
expect(branches[0]).toEqual({ name: 'A', local: true, remote: true });
|
||||
|
||||
await localGitB.checkoutBranch('main');
|
||||
await localGitB.deleteBranch('A');
|
||||
|
||||
branches = await localGitB.getBranches();
|
||||
expect(branches.length).toEqual(2);
|
||||
|
||||
expect(branches[0]).toEqual({ name: 'A', local: false, remote: true });
|
||||
});
|
||||
|
||||
it('correctly identifies local vs remote commits - one ahead', async function () {
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('A commit');
|
||||
expect(await localGitA.push()).toBe(true);
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a1.txt'), 'Hello World');
|
||||
await localGitA.commit('A1 commit');
|
||||
|
||||
const commits = await localGitA.getCommitsCurrentBranch();
|
||||
expect(commits.length).toBe(3);
|
||||
expect(commits[0].isLocalAhead).toBe(true);
|
||||
expect(commits[1].isLocalAhead).toBeFalsy();
|
||||
});
|
||||
|
||||
it('correctly identifies local vs remote commits - branch not pushed', async function () {
|
||||
await localGitA.createAndCheckoutBranch('A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('A commit');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a1.txt'), 'Hello World');
|
||||
await localGitA.commit('A1 commit');
|
||||
|
||||
const commits = await localGitA.getCommitsCurrentBranch();
|
||||
expect(commits.length).toBe(3);
|
||||
expect(commits[0].isLocalAhead).toBe(true);
|
||||
expect(commits[1].isLocalAhead).toBe(true);
|
||||
});
|
||||
|
||||
it('Push when there are remote changes', async function () {
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('A commit');
|
||||
await localGitA.push({});
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirB, 'a.txt'), 'Hello World2');
|
||||
await localGitB.commit('A commit');
|
||||
|
||||
try {
|
||||
await localGitB.push({});
|
||||
expect(true).toBe(false);
|
||||
} catch (error) {
|
||||
expect(error.toString()).toContain(
|
||||
'Updates were rejected because there are new changes that you do not have locally.'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('getCommitsBetween returns the correct commits (squash)', async function () {
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('A commit');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.pull({});
|
||||
await localGitB.createAndCheckoutBranch('A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirB, 'b.txt'), 'Hello World');
|
||||
await localGitB.commit('B commit');
|
||||
await localGitB.push();
|
||||
|
||||
const headCommitId = await localGitA.getHeadCommitId();
|
||||
const branchCommitId = await localGitB.getHeadCommitId();
|
||||
|
||||
const allCommits = await localGitA.getCommitsCurrentBranch();
|
||||
expect(allCommits.length).toBe(2);
|
||||
expect(allCommits[0].message).toBe('A commit');
|
||||
expect(allCommits[1].message).toBe('initial commit');
|
||||
|
||||
const commits = await localGitB.getCommitsBetween(branchCommitId, headCommitId);
|
||||
expect(commits.length).toBe(1);
|
||||
expect(commits[0].message).toBe('B commit');
|
||||
|
||||
await localGitA.fetch({});
|
||||
await localGitA.mergeToCurrentBranch('origin/A');
|
||||
|
||||
const allCommits2 = await localGitA.getCommitsCurrentBranch();
|
||||
expect(allCommits2.length).toBe(3);
|
||||
expect(allCommits2[0].message).toBe("Squashed commit from branch 'origin/A'");
|
||||
expect(allCommits2[1].message).toBe('A commit');
|
||||
expect(allCommits2[2].message).toBe('initial commit');
|
||||
});
|
||||
|
||||
it('getCommitsBetween returns the correct commits', async function () {
|
||||
FileSystem.instance.writeFileSync(path.join(localDirA, 'a.txt'), 'Hello World');
|
||||
await localGitA.commit('A commit');
|
||||
await localGitA.push();
|
||||
|
||||
await localGitB.pull({});
|
||||
await localGitB.createAndCheckoutBranch('A');
|
||||
|
||||
FileSystem.instance.writeFileSync(path.join(localDirB, 'b.txt'), 'Hello World');
|
||||
await localGitB.commit('B commit');
|
||||
await localGitB.push();
|
||||
|
||||
const headCommitId = await localGitA.getHeadCommitId();
|
||||
const branchCommitId = await localGitB.getHeadCommitId();
|
||||
|
||||
const allCommits = await localGitA.getCommitsCurrentBranch();
|
||||
expect(allCommits.length).toBe(2);
|
||||
expect(allCommits[0].message).toBe('A commit');
|
||||
expect(allCommits[1].message).toBe('initial commit');
|
||||
|
||||
const commits = await localGitB.getCommitsBetween(branchCommitId, headCommitId);
|
||||
expect(commits.length).toBe(1);
|
||||
expect(commits[0].message).toBe('B commit');
|
||||
|
||||
await localGitA.fetch({});
|
||||
await localGitA.mergeToCurrentBranch('origin/A', false);
|
||||
|
||||
const allCommits2 = await localGitA.getCommitsCurrentBranch();
|
||||
expect(allCommits2.length).toBe(3);
|
||||
expect(allCommits2[0].message).toBe('B commit');
|
||||
expect(allCommits2[1].message).toBe('A commit');
|
||||
expect(allCommits2[2].message).toBe('initial commit');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user