| <!DOCTYPE html> | |
| <!-- | |
| @license | |
| Copyright (C) 2016 The Android Open Source Project | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| --> | |
| <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> | |
| <title>gr-diff-cursor</title> | |
| <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> | |
| <script src="../../../bower_components/web-component-tester/browser.js"></script> | |
| <link rel="import" href="../../../test/common-test-setup.html"/> | |
| <script src="../../../scripts/util.js"></script> | |
| <link rel="import" href="../gr-diff/gr-diff.html"> | |
| <link rel="import" href="./gr-diff-cursor.html"> | |
| <link rel="import" href="../../shared/gr-rest-api-interface/mock-diff-response_test.html"> | |
| <script>void(0);</script> | |
| <test-fixture id="basic"> | |
| <template> | |
| <mock-diff-response></mock-diff-response> | |
| <gr-diff></gr-diff> | |
| <gr-diff-cursor></gr-diff-cursor> | |
| </template> | |
| </test-fixture> | |
| <script> | |
| suite('gr-diff-cursor tests', () => { | |
| let sandbox; | |
| let cursorElement; | |
| let diffElement; | |
| let mockDiffResponse; | |
| setup(done => { | |
| sandbox = sinon.sandbox.create(); | |
| stub('gr-rest-api-interface', { | |
| getLoggedIn() { return Promise.resolve(false); }, | |
| }); | |
| const fixtureElems = fixture('basic'); | |
| mockDiffResponse = fixtureElems[0]; | |
| diffElement = fixtureElems[1]; | |
| cursorElement = fixtureElems[2]; | |
| // Register the diff with the cursor. | |
| cursorElement.push('diffs', diffElement); | |
| diffElement.comments = {left: [], right: []}; | |
| diffElement.$.restAPI.getDiffPreferences().then(prefs => { | |
| diffElement.prefs = prefs; | |
| }); | |
| sandbox.stub(diffElement, '_getDiff', () => { | |
| return Promise.resolve(mockDiffResponse.diffResponse); | |
| }); | |
| const setupDone = () => { | |
| cursorElement._updateStops(); | |
| cursorElement.moveToFirstChunk(); | |
| diffElement.removeEventListener('render', setupDone); | |
| done(); | |
| }; | |
| diffElement.addEventListener('render', setupDone); | |
| diffElement.reload(); | |
| }); | |
| teardown(() => sandbox.restore()); | |
| test('diff cursor functionality (side-by-side)', () => { | |
| // The cursor has been initialized to the first delta. | |
| assert.isOk(cursorElement.diffRow); | |
| const firstDeltaRow = diffElement.$$('.section.delta .diff-row'); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| cursorElement.moveDown(); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling); | |
| cursorElement.moveUp(); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| }); | |
| test('cursor scroll behavior', () => { | |
| cursorElement._handleDiffRenderStart(); | |
| assert.equal(cursorElement._scrollBehavior, 'keep-visible'); | |
| assert.isTrue(cursorElement._focusOnMove); | |
| cursorElement._handleWindowScroll(); | |
| assert.equal(cursorElement._scrollBehavior, 'never'); | |
| assert.isFalse(cursorElement._focusOnMove); | |
| cursorElement.handleDiffUpdate(); | |
| assert.equal(cursorElement._scrollBehavior, 'keep-visible'); | |
| assert.isTrue(cursorElement._focusOnMove); | |
| }); | |
| suite('unified diff', () => { | |
| setup(done => { | |
| // We must allow the diff to re-render after setting the viewMode. | |
| const renderHandler = function() { | |
| diffElement.removeEventListener('render', renderHandler); | |
| cursorElement.reInitCursor(); | |
| done(); | |
| }; | |
| diffElement.addEventListener('render', renderHandler); | |
| diffElement.viewMode = 'UNIFIED_DIFF'; | |
| }); | |
| test('diff cursor functionality (unified)', () => { | |
| // The cursor has been initialized to the first delta. | |
| assert.isOk(cursorElement.diffRow); | |
| let firstDeltaRow = diffElement.$$('.section.delta .diff-row'); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| firstDeltaRow = diffElement.$$('.section.delta .diff-row'); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| cursorElement.moveDown(); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling); | |
| cursorElement.moveUp(); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| }); | |
| }); | |
| test('cursor side functionality', () => { | |
| // The side only applies to side-by-side mode, which should be the default | |
| // mode. | |
| assert.equal(diffElement.viewMode, 'SIDE_BY_SIDE'); | |
| const firstDeltaSection = diffElement.$$('.section.delta'); | |
| const firstDeltaRow = firstDeltaSection.querySelector('.diff-row'); | |
| // Because the first delta in this diff is on the right, it should be set | |
| // to the right side. | |
| assert.equal(cursorElement.side, 'right'); | |
| assert.equal(cursorElement.diffRow, firstDeltaRow); | |
| const firstIndex = cursorElement.$.cursorManager.index; | |
| // Move the side to the left. Because this delta only has a right side, we | |
| // should be moved up to the previous line where there is content on the | |
| // right. The previous row is part of the previous section. | |
| cursorElement.moveLeft(); | |
| assert.equal(cursorElement.side, 'left'); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow); | |
| assert.equal(cursorElement.$.cursorManager.index, firstIndex - 1); | |
| assert.equal(cursorElement.diffRow.parentElement, | |
| firstDeltaSection.previousSibling); | |
| // If we move down, we should skip everything in the first delta because | |
| // we are on the left side and the first delta has no content on the left. | |
| cursorElement.moveDown(); | |
| assert.equal(cursorElement.side, 'left'); | |
| assert.notEqual(cursorElement.diffRow, firstDeltaRow); | |
| assert.isTrue(cursorElement.$.cursorManager.index > firstIndex); | |
| assert.equal(cursorElement.diffRow.parentElement, | |
| firstDeltaSection.nextSibling); | |
| }); | |
| test('chunk skip functionality', () => { | |
| const chunks = Polymer.dom(diffElement.root).querySelectorAll( | |
| '.section.delta'); | |
| const indexOfChunk = function(chunk) { | |
| return Array.prototype.indexOf.call(chunks, chunk); | |
| }; | |
| // We should be initialized to the first chunk. Since this chunk only has | |
| // content on the right side, our side should be right. | |
| let currentIndex = indexOfChunk(cursorElement.diffRow.parentElement); | |
| assert.equal(currentIndex, 0); | |
| assert.equal(cursorElement.side, 'right'); | |
| // Move to the next chunk. | |
| cursorElement.moveToNextChunk(); | |
| // Since this chunk only has content on the left side. we should have been | |
| // automatically mvoed over. | |
| const previousIndex = currentIndex; | |
| currentIndex = indexOfChunk(cursorElement.diffRow.parentElement); | |
| assert.equal(currentIndex, previousIndex + 1); | |
| assert.equal(cursorElement.side, 'left'); | |
| }); | |
| test('initialLineNumber disabled', done => { | |
| const moveToNumStub = sandbox.stub(cursorElement, 'moveToLineNumber'); | |
| const moveToChunkStub = sandbox.stub(cursorElement, 'moveToFirstChunk'); | |
| function renderHandler() { | |
| diffElement.removeEventListener('render', renderHandler); | |
| assert.isFalse(moveToNumStub.called); | |
| assert.isTrue(moveToChunkStub.called); | |
| done(); | |
| } | |
| diffElement.addEventListener('render', renderHandler); | |
| diffElement.reload(); | |
| }); | |
| test('initialLineNumber enabled', done => { | |
| const moveToNumStub = sandbox.stub(cursorElement, 'moveToLineNumber'); | |
| const moveToChunkStub = sandbox.stub(cursorElement, 'moveToFirstChunk'); | |
| function renderHandler() { | |
| diffElement.removeEventListener('render', renderHandler); | |
| assert.isFalse(moveToChunkStub.called); | |
| assert.isTrue(moveToNumStub.called); | |
| assert.equal(moveToNumStub.lastCall.args[0], 10); | |
| assert.equal(moveToNumStub.lastCall.args[1], 'right'); | |
| done(); | |
| } | |
| diffElement.addEventListener('render', renderHandler); | |
| cursorElement.initialLineNumber = 10; | |
| cursorElement.side = 'right'; | |
| diffElement.reload(); | |
| }); | |
| test('getAddress', () => { | |
| // It should initialize to the first chunk: line 5 of the revision. | |
| assert.deepEqual(cursorElement.getAddress(), | |
| {leftSide: false, number: 5}); | |
| // Revision line 4 is up. | |
| cursorElement.moveUp(); | |
| assert.deepEqual(cursorElement.getAddress(), | |
| {leftSide: false, number: 4}); | |
| // Base line 4 is left. | |
| cursorElement.moveLeft(); | |
| assert.deepEqual(cursorElement.getAddress(), {leftSide: true, number: 4}); | |
| // Moving to the next chunk takes it back to the start. | |
| cursorElement.moveToNextChunk(); | |
| assert.deepEqual(cursorElement.getAddress(), | |
| {leftSide: false, number: 5}); | |
| // The following chunk is a removal starting on line 10 of the base. | |
| cursorElement.moveToNextChunk(); | |
| assert.deepEqual(cursorElement.getAddress(), | |
| {leftSide: true, number: 10}); | |
| // Should be null if there is no selection. | |
| cursorElement.$.cursorManager.unsetCursor(); | |
| assert.isNotOk(cursorElement.getAddress()); | |
| }); | |
| test('_findRowByNumberAndFile', () => { | |
| // Get the first ab row after the first chunk. | |
| const row = Polymer.dom(diffElement.root).querySelectorAll('tr')[8]; | |
| // It should be line 8 on the right, but line 5 on the left. | |
| assert.equal(cursorElement._findRowByNumberAndFile(8, 'right'), row); | |
| assert.equal(cursorElement._findRowByNumberAndFile(5, 'left'), row); | |
| }); | |
| test('expand context updates stops', done => { | |
| sandbox.spy(cursorElement, 'handleDiffUpdate'); | |
| MockInteractions.tap(diffElement.$$('.showContext')); | |
| flush(() => { | |
| assert.isTrue(cursorElement.handleDiffUpdate.called); | |
| done(); | |
| }); | |
| }); | |
| }); | |
| </script> |