From 4c3720c1891c8ccc27ad3c01a79af4c016b7e95d Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 May 2018 10:44:21 -0400 Subject: [PATCH 1/4] Use TextEditor model methods rather than manipulating innerText --- lib/views/branch-menu-view.js | 2 +- test/controllers/status-bar-tile-controller.test.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/views/branch-menu-view.js b/lib/views/branch-menu-view.js index 0672fd5b92..de5517f031 100644 --- a/lib/views/branch-menu-view.js +++ b/lib/views/branch-menu-view.js @@ -117,7 +117,7 @@ export default class BranchMenuView extends React.Component { async createBranch() { if (this.state.createNew) { - const branchName = this.editorElement.innerText.trim(); + const branchName = this.editorElement.getModel().getText().trim(); await this.checkout(branchName, {createNew: true}); } else { this.setState({createNew: true}, () => { diff --git a/test/controllers/status-bar-tile-controller.test.js b/test/controllers/status-bar-tile-controller.test.js index ee3e910f95..ce849a3752 100644 --- a/test/controllers/status-bar-tile-controller.test.js +++ b/test/controllers/status-bar-tile-controller.test.js @@ -197,7 +197,7 @@ describe('StatusBarTileController', function() { assert.isTrue(selectList.className.includes('hidden')); assert.isFalse(tip.querySelector('.github-BranchMenuView-editor').className.includes('hidden')); - tip.querySelector('atom-text-editor').innerText = 'new-branch'; + tip.querySelector('atom-text-editor').getModel().setText('new-branch'); tip.querySelector('button').click(); assert.isTrue(editor.hasAttribute('readonly')); @@ -231,7 +231,7 @@ describe('StatusBarTileController', function() { assert.equal(tip.querySelector('select').value, 'branch'); createNewButton.click(); - tip.querySelector('atom-text-editor').innerText = 'master'; + tip.querySelector('atom-text-editor').getModel().setText('master'); createNewButton.click(); assert.isTrue(createNewButton.hasAttribute('disabled')); @@ -245,7 +245,7 @@ describe('StatusBarTileController', function() { assert.isFalse(branch1.isDetached()); assert.lengthOf(tip.querySelectorAll('.github-BranchMenuView-editor'), 1); - assert.equal(tip.querySelector('atom-text-editor').innerText, 'master'); + assert.equal(tip.querySelector('atom-text-editor').getModel().getText(), 'master'); assert.isFalse(createNewButton.hasAttribute('disabled')); }); }); From 6faf9692e92bf70731471cf4927fbbeecb67d157 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 May 2018 10:44:42 -0400 Subject: [PATCH 2/4] Unit test for the desired behavior --- .../status-bar-tile-controller.test.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/controllers/status-bar-tile-controller.test.js b/test/controllers/status-bar-tile-controller.test.js index ce849a3752..436ea22e70 100644 --- a/test/controllers/status-bar-tile-controller.test.js +++ b/test/controllers/status-bar-tile-controller.test.js @@ -248,6 +248,34 @@ describe('StatusBarTileController', function() { assert.equal(tip.querySelector('atom-text-editor').getModel().getText(), 'master'); assert.isFalse(createNewButton.hasAttribute('disabled')); }); + + it('clears the new branch name after successful creation', async function() { + const workdirPath = await cloneRepository('three-files'); + const repository = await buildRepositoryWithPipeline(workdirPath, {confirm, notificationManager, workspace}); + + const wrapper = await mountAndLoad(buildApp({repository})); + + // Open the branch creator, type a branch name, and confirm branch creation. + await wrapper.find('.github-BranchMenuView-button').simulate('click'); + wrapper.find('.github-BranchMenuView-editor atom-text-editor').getDOMNode().getModel() + .setText('new-branch-name'); + await wrapper.find('.github-BranchMenuView-button').simulate('click'); + + await until('branch creation completes', async () => { + const b = await repository.getCurrentBranch(); + return b.getName() === 'new-branch-name' && !b.isDetached(); + }); + repository.refresh(); + await assert.async.isUndefined( + wrapper.update().find('.github-BranchMenuView-editor atom-text-editor').prop('readonly'), + ); + + await wrapper.find('.github-BranchMenuView-button').simulate('click'); + assert.strictEqual( + wrapper.find('.github-BranchMenuView-editor atom-text-editor').getDOMNode().getModel().getText(), + '', + ); + }); }); describe('with a detached HEAD', function() { From 6f63f5db6dee03175fc335124b9e3ff0e1eaeb1f Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 May 2018 10:46:44 -0400 Subject: [PATCH 3/4] Await setState completion --- lib/views/branch-menu-view.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/views/branch-menu-view.js b/lib/views/branch-menu-view.js index de5517f031..0e41f51934 100644 --- a/lib/views/branch-menu-view.js +++ b/lib/views/branch-menu-view.js @@ -120,15 +120,20 @@ export default class BranchMenuView extends React.Component { const branchName = this.editorElement.getModel().getText().trim(); await this.checkout(branchName, {createNew: true}); } else { - this.setState({createNew: true}, () => { - this.editorElement.focus(); + await new Promise(resolve => { + this.setState({createNew: true}, () => { + this.editorElement.focus(); + resolve(); + }); }); } } async checkout(branchName, options) { this.editorElement.classList.remove('is-focused'); - this.setState({checkedOutBranch: branchName}); + await new Promise(resolve => { + this.setState({checkedOutBranch: branchName}, resolve); + }); try { await this.props.checkout(branchName, options); } catch (error) { From 072da04f4262c15f4156db29a1beb029630180f7 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 May 2018 10:47:24 -0400 Subject: [PATCH 4/4] Clear checkedOutBranch and branch editor state after checkout completion --- lib/views/branch-menu-view.js | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/lib/views/branch-menu-view.js b/lib/views/branch-menu-view.js index 0e41f51934..2a67566edb 100644 --- a/lib/views/branch-menu-view.js +++ b/lib/views/branch-menu-view.js @@ -100,16 +100,6 @@ export default class BranchMenuView extends React.Component { ); } - componentDidUpdate() { - const currentBranch = this.props.currentBranch.getName(); - const branchNames = this.props.branches.getNames(); - const hasNewBranch = branchNames.includes(this.state.checkedOutBranch); - if (currentBranch === this.state.checkedOutBranch && hasNewBranch) { - this.editorElement.classList.add('is-focused'); - this.setState({checkedOutBranch: null, createNew: false}); - } - } - async didSelectItem(event) { const branchName = event.target.value; await this.checkout(branchName); @@ -136,13 +126,16 @@ export default class BranchMenuView extends React.Component { }); try { await this.props.checkout(branchName, options); + await new Promise(resolve => { + this.setState({checkedOutBranch: null, createNew: false}, resolve); + }); + this.editorElement.getModel().setText(''); } catch (error) { this.editorElement.classList.add('is-focused'); - this.setState({checkedOutBranch: null}); - if (error instanceof GitError) { - // eslint-disable-next-line no-console - console.warn('Non-fatal', error); - } else { + await new Promise(resolve => { + this.setState({checkedOutBranch: null}, resolve); + }); + if (!(error instanceof GitError)) { throw error; } }